Skip to content

Commit 39e585f

Browse files
authored
[web] revise flag ort.env.wasm.simd (microsoft#24314)
### Description This PR revised the flag `ort.env.wasm.simd` to enhance its usage so that more use scenarios are covered. - Allow setting to `false` explicitly to disable SIMD checking. resolves microsoft#24292 (@Eldow) - Allow setting to `'relaxed'` to enable Relaxed SIMD checking. Relaxed SIMD is introduced first in microsoft#22794 (@jing-bao) - Behavior is not changed when not setting (ie. `undefined`) or setting to `true` - Added a warning message when setting to unknown value, and reset to `false` in this case
1 parent d7a38a5 commit 39e585f

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

js/common/lib/env.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,22 @@ export declare namespace Env {
4141
numThreads?: number;
4242

4343
/**
44-
* set or get a boolean value indicating whether to enable SIMD. If set to false, SIMD will be forcely disabled.
44+
* set a value indicating whether to enable SIMD.
45+
*
46+
* ONNX Runtime will perform feature detection based on the value of this property. Specifically, when the value is
47+
* set to:
48+
* - `undefined`, `true` or `"fixed"`: will check availability of Fixed-width SIMD.
49+
* - `"relaxed"`: will check availability of Relaxed SIMD.
50+
* - `false`: will not perform SIMD feature checking.
51+
*
52+
* Setting this property does not make ONNX Runtime to switch to the corresponding runtime automatically. User need
53+
* to set `wasmPaths` or `wasmBinary` property to load the corresponding runtime.
4554
*
4655
* This setting is available only when WebAssembly SIMD feature is available in current context.
4756
*
4857
* @defaultValue `true`
49-
*
50-
* @deprecated This property is deprecated. Since SIMD is supported by all major JavaScript engines, non-SIMD
51-
* build is no longer provided. This property will be removed in future release.
5258
*/
53-
simd?: boolean;
59+
simd?: boolean | 'fixed' | 'relaxed';
5460

5561
/**
5662
* set or get a boolean value indicating whether to enable trace.

js/web/lib/backend-wasm.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ export const initializeFlags = (): void => {
1717
env.wasm.initTimeout = 0;
1818
}
1919

20-
if (env.wasm.simd === false) {
20+
const simd = env.wasm.simd;
21+
if (typeof simd !== 'boolean' && simd !== undefined && simd !== 'fixed' && simd !== 'relaxed') {
2122
// eslint-disable-next-line no-console
2223
console.warn(
23-
'Deprecated property "env.wasm.simd" is set to false. ' +
24-
'non-SIMD build is no longer provided, and this setting will be ignored.',
24+
`Property "env.wasm.simd" is set to unknown value "${simd}". Reset it to \`false\` and ignore SIMD feature checking.`,
2525
);
26+
env.wasm.simd = false;
2627
}
2728

2829
if (typeof env.wasm.proxy !== 'boolean') {

js/web/lib/wasm/wasm-factory.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,34 @@ const isSimdSupported = (): boolean => {
6464
}
6565
};
6666

67+
const isRelaxedSimdSupported = (): boolean => {
68+
try {
69+
// Test for WebAssembly Relaxed SIMD capability (for both browsers and Node.js)
70+
// This typed array is a WebAssembly program containing Relaxed SIMD instructions.
71+
72+
// The binary data is generated from the following code by wat2wasm:
73+
// (module
74+
// (func (result v128)
75+
// i32.const 1
76+
// i8x16.splat
77+
// i32.const 2
78+
// i8x16.splat
79+
// i32.const 3
80+
// i8x16.splat
81+
// i32x4.relaxed_dot_i8x16_i7x16_add_s
82+
// )
83+
// )
84+
return WebAssembly.validate(
85+
new Uint8Array([
86+
0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 19, 1, 17, 0, 65, 1, 253, 15, 65, 2, 253,
87+
15, 65, 3, 253, 15, 253, 147, 2, 11,
88+
]),
89+
);
90+
} catch (e) {
91+
return false;
92+
}
93+
};
94+
6795
export const initializeWebAssembly = async (flags: Env.WebAssemblyFlags): Promise<void> => {
6896
if (initialized) {
6997
return Promise.resolve();
@@ -82,7 +110,14 @@ export const initializeWebAssembly = async (flags: Env.WebAssemblyFlags): Promis
82110
let numThreads = flags.numThreads!;
83111

84112
// ensure SIMD is supported
85-
if (!isSimdSupported()) {
113+
if (flags.simd === false) {
114+
// skip SIMD feature checking as it is disabled explicitly by user
115+
} else if (flags.simd === 'relaxed') {
116+
// check if relaxed SIMD is supported
117+
if (!isRelaxedSimdSupported()) {
118+
throw new Error('Relaxed WebAssembly SIMD is not supported in the current environment.');
119+
}
120+
} else if (!isSimdSupported()) {
86121
throw new Error('WebAssembly SIMD is not supported in the current environment.');
87122
}
88123

0 commit comments

Comments
 (0)