@synsci/openscience 2.0.83 → 2.0.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/openscience +63 -9
- package/package.json +12 -12
- package/postinstall.mjs +6 -0
package/bin/openscience
CHANGED
|
@@ -35,7 +35,11 @@ function detectMusl(platform = os.platform()) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function
|
|
38
|
+
function darwinSysctl(name) {
|
|
39
|
+
return childProcess.spawnSync("sysctl", ["-n", name], { encoding: "utf8" })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function cpuSupportsAvx2(platform = os.platform(), arch = os.arch(), linuxInfo, sysctl = darwinSysctl) {
|
|
39
43
|
if (arch !== "x64") return undefined
|
|
40
44
|
if (platform === "linux") {
|
|
41
45
|
const info = (() => {
|
|
@@ -51,10 +55,35 @@ function cpuSupportsAvx2(platform = os.platform(), arch = os.arch(), linuxInfo)
|
|
|
51
55
|
if (!flags) return undefined
|
|
52
56
|
return flags.toLowerCase().split(/\s+/).includes("avx2")
|
|
53
57
|
}
|
|
58
|
+
// Windows exposes no CPU feature flags to Node; the illegal-instruction exit
|
|
59
|
+
// status is recognised after launch instead (see illegalInstruction).
|
|
54
60
|
if (platform !== "darwin") return undefined
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
// hw.optional.avx2_0 answers 0/1 on every Mac, including x64 Node under
|
|
62
|
+
// Rosetta where machdep.cpu.leaf7_features is an unknown oid.
|
|
63
|
+
const optional = sysctl("hw.optional.avx2_0")
|
|
64
|
+
const flag = optional.status === 0 ? String(optional.stdout).trim() : undefined
|
|
65
|
+
if (flag === "1") return true
|
|
66
|
+
if (flag === "0") return false
|
|
67
|
+
const leaf7 = sysctl("machdep.cpu.leaf7_features")
|
|
68
|
+
if (leaf7.status !== 0) return undefined
|
|
69
|
+
return String(leaf7.stdout).toLowerCase().split(/\s+/).includes("avx2")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Windows has no signals: an illegal instruction ends the process with
|
|
73
|
+
// STATUS_ILLEGAL_INSTRUCTION (0xC000001D), which spawnSync reports as an
|
|
74
|
+
// unsigned status (or its signed form from some shells) with signal null.
|
|
75
|
+
const WINDOWS_ILLEGAL_INSTRUCTION = 3221225501
|
|
76
|
+
|
|
77
|
+
function illegalInstruction(result) {
|
|
78
|
+
if (result.signal === "SIGILL") return true
|
|
79
|
+
return result.status === WINDOWS_ILLEGAL_INSTRUCTION || result.status === WINDOWS_ILLEGAL_INSTRUCTION - 2 ** 32
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// The `-baseline` build of the same package (openscience-linux-x64-musl ->
|
|
83
|
+
// openscience-linux-x64-baseline-musl) runs on x86-64 CPUs without AVX2.
|
|
84
|
+
function baselineSibling(prefix, entry) {
|
|
85
|
+
if (!entry.startsWith(prefix) || entry.includes("-baseline")) return undefined
|
|
86
|
+
return `${prefix}-baseline${entry.slice(prefix.length)}`
|
|
58
87
|
}
|
|
59
88
|
|
|
60
89
|
function expectedPlatformPackages(platform, arch, musl) {
|
|
@@ -97,7 +126,7 @@ function exitCodeForResult(result) {
|
|
|
97
126
|
return 1
|
|
98
127
|
}
|
|
99
128
|
|
|
100
|
-
function run(target) {
|
|
129
|
+
function run(target, fallback) {
|
|
101
130
|
const kernelProblem = linuxKernelProblem()
|
|
102
131
|
if (kernelProblem) {
|
|
103
132
|
console.error(kernelProblem)
|
|
@@ -114,6 +143,16 @@ function run(target) {
|
|
|
114
143
|
process.exit(1)
|
|
115
144
|
}
|
|
116
145
|
|
|
146
|
+
// Only a read-only startup probe may fall back. A real command can perform
|
|
147
|
+
// side effects before SIGILL, so never replay it after a crash.
|
|
148
|
+
if (fallback) {
|
|
149
|
+
const probe = childProcess.spawnSync(target, ["--version"], { timeout: 10_000, stdio: "ignore" })
|
|
150
|
+
if (illegalInstruction(probe)) {
|
|
151
|
+
console.error(`openscience startup probe failed; using the baseline build at ${fallback}.`)
|
|
152
|
+
target = fallback
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
117
156
|
const result = childProcess.spawnSync(target, process.argv.slice(2), {
|
|
118
157
|
stdio: "inherit",
|
|
119
158
|
})
|
|
@@ -122,15 +161,18 @@ function run(target) {
|
|
|
122
161
|
console.error(`Detected runtime: ${runtimeDescription(os.platform(), os.arch(), detectMusl())}`)
|
|
123
162
|
process.exit(1)
|
|
124
163
|
}
|
|
125
|
-
|
|
164
|
+
const crashed = illegalInstruction(result)
|
|
165
|
+
if (result.signal || crashed) {
|
|
126
166
|
console.error(
|
|
127
|
-
`openscience was terminated by ${result.signal
|
|
167
|
+
`openscience was terminated by ${result.signal || "an illegal instruction (exit status 0xC000001D)"}. ` +
|
|
168
|
+
`The prebuilt native binary may be ` +
|
|
128
169
|
`incompatible with this host (platform ${os.platform()}, arch ${os.arch()}). ` +
|
|
129
170
|
`Some ARM64 hosts (e.g. 64KB page-size kernels) and x86-64 hosts without AVX2 ` +
|
|
130
171
|
`cannot run the optimized prebuilt binary. ` +
|
|
131
172
|
`Try reinstalling, set OPENSCIENCE_BIN_PATH to a compatible binary, or report at ` +
|
|
132
173
|
`https://github.com/synthetic-sciences/openscience/issues`,
|
|
133
174
|
)
|
|
175
|
+
console.error(`Detected runtime: ${runtimeDescription(os.platform(), os.arch(), detectMusl())}`)
|
|
134
176
|
}
|
|
135
177
|
process.exit(exitCodeForResult(result))
|
|
136
178
|
}
|
|
@@ -167,6 +209,13 @@ function matchingVariants(prefix, entries, preferMusl, preferBaseline = false) {
|
|
|
167
209
|
)
|
|
168
210
|
}
|
|
169
211
|
|
|
212
|
+
function baselineFallback(modules, prefix, entry, binary) {
|
|
213
|
+
const sibling = baselineSibling(prefix, entry)
|
|
214
|
+
if (!sibling) return undefined
|
|
215
|
+
const candidate = path.join(modules, sibling, "bin", binary)
|
|
216
|
+
return isBinary(candidate) ? candidate : undefined
|
|
217
|
+
}
|
|
218
|
+
|
|
170
219
|
function main() {
|
|
171
220
|
const envPath = process.env.OPENSCIENCE_BIN_PATH
|
|
172
221
|
if (envPath && isBinary(envPath)) {
|
|
@@ -197,7 +246,7 @@ function main() {
|
|
|
197
246
|
const entries = fs.readdirSync(modules)
|
|
198
247
|
for (const entry of matchingVariants(base, entries, musl, baseline)) {
|
|
199
248
|
const candidate = path.join(modules, entry, "bin", binary)
|
|
200
|
-
if (isBinary(candidate)) run(candidate)
|
|
249
|
+
if (isBinary(candidate)) run(candidate, baselineFallback(modules, base, entry, binary))
|
|
201
250
|
}
|
|
202
251
|
// Check scoped packages (@synsci/openscience-darwin-arm64)
|
|
203
252
|
const scoped = path.join(modules, "@synsci")
|
|
@@ -205,7 +254,7 @@ function main() {
|
|
|
205
254
|
const scopedEntries = fs.readdirSync(scoped)
|
|
206
255
|
for (const entry of matchingVariants(scopedBase, scopedEntries, musl, baseline)) {
|
|
207
256
|
const candidate = path.join(scoped, entry, "bin", binary)
|
|
208
|
-
if (isBinary(candidate)) run(candidate)
|
|
257
|
+
if (isBinary(candidate)) run(candidate, baselineFallback(scoped, scopedBase, entry, binary))
|
|
209
258
|
}
|
|
210
259
|
}
|
|
211
260
|
} catch {}
|
|
@@ -219,6 +268,9 @@ function main() {
|
|
|
219
268
|
console.error(`OpenScience binary not found for ${platform}-${arch}.`)
|
|
220
269
|
console.error(`Detected runtime: ${runtimeDescription(platform, arch, musl)}`)
|
|
221
270
|
console.error(`Expected npm package: ${expectedPackages[0]}`)
|
|
271
|
+
console.error(
|
|
272
|
+
"A common cause is installing with `npm install --omit=optional` or `--ignore-scripts`, which skips that package.",
|
|
273
|
+
)
|
|
222
274
|
console.error("Check npm's platform selection with:")
|
|
223
275
|
console.error(" npm config get cpu")
|
|
224
276
|
console.error(` npm ls -g @synsci/openscience ${expectedPackages[0]} --depth=0`)
|
|
@@ -228,10 +280,12 @@ function main() {
|
|
|
228
280
|
}
|
|
229
281
|
|
|
230
282
|
module.exports = {
|
|
283
|
+
baselineSibling,
|
|
231
284
|
cpuSupportsAvx2,
|
|
232
285
|
detectMusl,
|
|
233
286
|
exitCodeForResult,
|
|
234
287
|
expectedPlatformPackages,
|
|
288
|
+
illegalInstruction,
|
|
235
289
|
linuxArm64PageSizeProblem,
|
|
236
290
|
linuxKernelProblem,
|
|
237
291
|
matchingVariants,
|
package/package.json
CHANGED
|
@@ -7,22 +7,22 @@
|
|
|
7
7
|
"preinstall": "node ./preinstall.mjs || exit 0",
|
|
8
8
|
"postinstall": "bun ./postinstall.mjs || node ./postinstall.mjs || exit 0"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.0.
|
|
10
|
+
"version": "2.0.84",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
13
|
"url": "git+https://github.com/synthetic-sciences/openscience.git"
|
|
14
14
|
},
|
|
15
15
|
"optionalDependencies": {
|
|
16
|
-
"@synsci/openscience-linux-x64": "2.0.
|
|
17
|
-
"@synsci/openscience-windows-x64-baseline": "2.0.
|
|
18
|
-
"@synsci/openscience-linux-x64-baseline-musl": "2.0.
|
|
19
|
-
"@synsci/openscience-windows-x64": "2.0.
|
|
20
|
-
"@synsci/openscience-linux-x64-musl": "2.0.
|
|
21
|
-
"@synsci/openscience-linux-arm64-musl": "2.0.
|
|
22
|
-
"@synsci/openscience-darwin-x64": "2.0.
|
|
23
|
-
"@synsci/openscience-darwin-x64-baseline": "2.0.
|
|
24
|
-
"@synsci/openscience-linux-x64-baseline": "2.0.
|
|
25
|
-
"@synsci/openscience-linux-arm64": "2.0.
|
|
26
|
-
"@synsci/openscience-darwin-arm64": "2.0.
|
|
16
|
+
"@synsci/openscience-linux-x64": "2.0.84",
|
|
17
|
+
"@synsci/openscience-windows-x64-baseline": "2.0.84",
|
|
18
|
+
"@synsci/openscience-linux-x64-baseline-musl": "2.0.84",
|
|
19
|
+
"@synsci/openscience-windows-x64": "2.0.84",
|
|
20
|
+
"@synsci/openscience-linux-x64-musl": "2.0.84",
|
|
21
|
+
"@synsci/openscience-linux-arm64-musl": "2.0.84",
|
|
22
|
+
"@synsci/openscience-darwin-x64": "2.0.84",
|
|
23
|
+
"@synsci/openscience-darwin-x64-baseline": "2.0.84",
|
|
24
|
+
"@synsci/openscience-linux-x64-baseline": "2.0.84",
|
|
25
|
+
"@synsci/openscience-linux-arm64": "2.0.84",
|
|
26
|
+
"@synsci/openscience-darwin-arm64": "2.0.84"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/postinstall.mjs
CHANGED
|
@@ -74,6 +74,12 @@ function cpuSupportsAvx2(platform, arch, linuxInfo) {
|
|
|
74
74
|
return flags.toLowerCase().split(/\s+/).includes("avx2")
|
|
75
75
|
}
|
|
76
76
|
if (platform !== "darwin") return undefined
|
|
77
|
+
// hw.optional.avx2_0 answers 0/1 on every Mac, including x64 Node under
|
|
78
|
+
// Rosetta where machdep.cpu.leaf7_features is an unknown oid.
|
|
79
|
+
const optional = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], { encoding: "utf8" })
|
|
80
|
+
const flag = optional.status === 0 ? String(optional.stdout).trim() : undefined
|
|
81
|
+
if (flag === "1") return true
|
|
82
|
+
if (flag === "0") return false
|
|
77
83
|
const result = childProcess.spawnSync("sysctl", ["-n", "machdep.cpu.leaf7_features"], { encoding: "utf8" })
|
|
78
84
|
if (result.status !== 0) return undefined
|
|
79
85
|
return result.stdout.toLowerCase().split(/\s+/).includes("avx2")
|