-
Notifications
You must be signed in to change notification settings - Fork 2k
[wasm] Add support for pthreads. #3627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hey @Maratyszcza - just wanted to add you as an FYI - no need to fully review :) |
| [`var _scriptDir = undefined; var WasmBackendModuleSimd = ` + | ||
| wasmFactoryThreadedSimd.toString()], | ||
| {type: 'text/javascript'}); | ||
| // } else if (simdSupported) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you still need this else if branch. E.g. Chrome Android supports only SIMD, but not threads
tfjs-backend-wasm/src/cc/backend.cc
Outdated
| } | ||
|
|
||
| size_t xnn_operator_count = 0; | ||
| pthreadpool *threadpool = pthreadpool_create(4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is best to not hardcode the number of threads, but get it dynamically from emscripten_num_logical_cores. I suggest to use std::min(emscripten_num_logical_cores(), 4).
tafsiri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 16 of 32 files at r1, 17 of 25 files at r3.
Reviewable status: 0 of 1 approvals obtained (waiting on @annxingyuan, @lina128, @pyu10055, and @tafsiri)
tfjs-backend-wasm/README.md, line 193 at r3 (raw file):
### Do you support SIMD and multi-threading? Yes. We take advantage of SIMD and multi-threading wherever they are supported by testing the capabilities of your runtime and serving the appropriate WASM binary. If you intend to serve the WASM binaries from a custom location (via `setWasmPaths`), please note that the SIMD-enabled and threading-enabled binaries are separate from the vanilla binary.
nit: serving => loading.
vanilla binary => regular (or non-simd/non-threaded) wasm binary
tfjs-backend-wasm/scripts/build-wasm.sh, line 33 at r3 (raw file):
# Threaded + SIMD build. yarn bazel build -c opt //src/cc:tfjs-backend-wasm-threaded-simd.js --config=wasm --copt="-pthread" --copt="-msimd128"
Question, during local development which build is used in testing? I'm guessing it could depend on your browser? Is there a way to split these out so that locally you don't have to build everything for a local test run?
tfjs-backend-wasm/src/backend_wasm.ts, line 208 at r3 (raw file):
function getWasmPath( simdSupported: boolean, threadsSupported: boolean, prefix = '') { let path = 'tfjs-backend-wasm.wasm';
could this have a more descriptive name, reading this section it looks more like this is wasmModuleName or something like this, and together with a prefix that forms a path.
Related to naming should prefix be called path or even folderPath/wasmModuleFolder for more clarity? I think prefix is too ambiguous.
Also small nit here could you move this below the early return just below.
tfjs-backend-wasm/src/backend_wasm.ts, line 228 at r3 (raw file):
} console.warn(
I think this should be an error. If a user is trying to customize this, they should probably fail fast rather than fallback to something they may not anticipate. Also the if they have custom paths the default location may still not have the expected file.
tfjs-backend-wasm/src/backend_wasm.ts, line 234 at r3 (raw file):
} if (wasmPathPrefix != null) {
Why not just call this function with wasmPathPrefix as the value for prefix? (and default it to empty string), then you can remove the default value from this functions signature. Another confusion that this may help resolve for me is that as I read it, it looks like passing in prefix in factoryConfig.locateFile = (path, prefix) => { part cannot override wasmPathPrefix, makes wonder why its passed around (as opposed to just setting wasmPathPrefix).
tfjs-backend-wasm/src/backend_wasm.ts, line 351 at r3 (raw file):
let wasmPath: string = null; let wasmPathPrefix: string = null; let wasmFileMap: {[key: string]: string} = {};
could you enumerate the valid keys? i'm assuming they are some fixed set that the loader will look for.
tfjs-backend-wasm/src/backend_wasm.ts, line 404 at r3 (raw file):
/** @doc {heading: 'Environment', namespace: 'wasm'} */ export function setWasmPaths( prefix: string, fileMap: {[key: string]: string} = {},
are prefix and fileMap exclusive params? can you pass both and have that work? If not (which is my suspicion since the doc says its full paths in fileMap), can you take one param that is either a string or your filemap. Then a user does not need to pass null if they want to use fileMap.
tfjs-backend-wasm/src/flags_wasm.ts, line 42 at r3 (raw file):
new MessageChannel().port1.postMessage(new SharedArrayBuffer(1)); return WebAssembly.validate(new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 5,
Just wondering, is there significance to these specific numbers? if so i'd mention that in the comment so that people aren't tempted to change it in future.
tfjs-backend-wasm/src/cc/backend.cc, line 64 at r3 (raw file):
pthreadpool *threadpool = pthreadpool_create(std::min(std::max(num_cores, 1), 4));
nit: could we turn the 4 into a named variable.
annxingyuan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 1 approvals obtained (waiting on @annxingyuan, @lina128, @Maratyszcza, @pyu10055, and @tafsiri)
tfjs-backend-wasm/README.md, line 193 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
nit: serving => loading.
vanilla binary => regular (or non-simd/non-threaded) wasm binary
Done
tfjs-backend-wasm/scripts/build-wasm.sh, line 33 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
Question, during local development which build is used in testing? I'm guessing it could depend on your browser? Is there a way to split these out so that locally you don't have to build everything for a local test run?
It will depend on your browser, but for the near term it should end up using the regular binary. I added an option yarn test-dev to build only the regular binary.
tfjs-backend-wasm/src/backend_wasm.ts, line 249 at r2 (raw file):
Previously, Maratyszcza (Marat Dukhan) wrote…
I think you still need this
else ifbranch. E.g. Chrome Android supports only SIMD, but not threads
Done
Although now we don't need the else if branch because in standalone mode the same module works for SIMD and vanilla.
tfjs-backend-wasm/src/backend_wasm.ts, line 208 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
could this have a more descriptive name, reading this section it looks more like this is wasmModuleName or something like this, and together with a prefix that forms a path.
Related to naming should prefix be called path or even folderPath/wasmModuleFolder for more clarity? I think prefix is too ambiguous.
Also small nit here could you move this below the early return just below.
Done
tfjs-backend-wasm/src/backend_wasm.ts, line 228 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
I think this should be an error. If a user is trying to customize this, they should probably fail fast rather than fallback to something they may not anticipate. Also the if they have custom paths the default location may still not have the expected file.
What if the user just wants to supply a custom URL for one of the 3 binaries though?
tfjs-backend-wasm/src/backend_wasm.ts, line 234 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
Why not just call this function with wasmPathPrefix as the value for prefix? (and default it to empty string), then you can remove the default value from this functions signature. Another confusion that this may help resolve for me is that as I read it, it looks like passing in prefix in
factoryConfig.locateFile = (path, prefix) => {part cannot override wasmPathPrefix, makes wonder why its passed around (as opposed to just setting wasmPathPrefix).
Done
I think it still makes sense to have wasmPathPrefix default to null though, to distinguish between it being unset, and a user setting it to empty string? That way if locateFile is called with a prefix and wasmPathPrefix has not been set, we can pass in the prefix to getPathToWasmBinary.
tfjs-backend-wasm/src/backend_wasm.ts, line 351 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
could you enumerate the valid keys? i'm assuming they are some fixed set that the loader will look for.
Done
tfjs-backend-wasm/src/backend_wasm.ts, line 404 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
are prefix and fileMap exclusive params? can you pass both and have that work? If not (which is my suspicion since the doc says its full paths in fileMap), can you take one param that is either a string or your filemap. Then a user does not need to pass null if they want to use fileMap.
Done
tafsiri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Reviewed 1 of 25 files at r3, 5 of 6 files at r4.
Reviewable status:complete! 1 of 1 approvals obtained (waiting on @annxingyuan, @lina128, @Maratyszcza, and @pyu10055)
tfjs-backend-wasm/scripts/build-wasm.sh, line 33 at r3 (raw file):
Previously, annxingyuan (Ann Yuan) wrote…
It will depend on your browser, but for the near term it should end up using the regular binary. I added an option
yarn test-devto build only the regular binary.
Thanks!
tfjs-backend-wasm/src/backend_wasm.ts, line 228 at r3 (raw file):
Previously, annxingyuan (Ann Yuan) wrote…
What if the user just wants to supply a custom URL for one of the 3 binaries though?
ah so in this scheme the user can set one custom wasm module file path to whatever they want and the rest will be resolved against a default wasmModuleFolder value? (which i guess is the empty string) and they need to make sure those binaries are at that location? That makes sense.
I wonder if you can warn about this when reading the wasmFileMap. I say this because unless they dev tests in all these environments they will only see one warning (for whatever their main browser is) and may not realize that the others are falling back (or indeed may come into play at all) until they deploy. Just a suggestion for you to think about.
tfjs-backend-wasm/src/backend_wasm.ts, line 351 at r3 (raw file):
Previously, annxingyuan (Ann Yuan) wrote…
Done
So this will give you typescript checking, but you may want to add a javascript run time check that it is one of those values if a fileMap is passed in. This might avoid issues being filed because of typos.
tfjs-backend-wasm/src/flags_wasm.ts, line 42 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
Just wondering, is there significance to these specific numbers? if so i'd mention that in the comment so that people aren't tempted to change it in future.
Still curious about this, adding a comment about these may be sufficient.
annxingyuan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! 1 of 1 approvals obtained (waiting on @annxingyuan, @lina128, @Maratyszcza, @pyu10055, and @tafsiri)
tfjs-backend-wasm/src/backend_wasm.ts, line 228 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
ah so in this scheme the user can set one custom wasm module file path to whatever they want and the rest will be resolved against a default wasmModuleFolder value? (which i guess is the empty string) and they need to make sure those binaries are at that location? That makes sense.
I wonder if you can warn about this when reading the wasmFileMap. I say this because unless they dev tests in all these environments they will only see one warning (for whatever their main browser is) and may not realize that the others are falling back (or indeed may come into play at all) until they deploy. Just a suggestion for you to think about.
Yeah that makes a lot of sense! Done.
tfjs-backend-wasm/src/backend_wasm.ts, line 351 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
So this will give you typescript checking, but you may want to add a javascript run time check that it is one of those values if a fileMap is passed in. This might avoid issues being filed because of typos.
Done
The warning I just added to address the previous comment should take care of this case I think.
tfjs-backend-wasm/src/flags_wasm.ts, line 42 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
Still curious about this, adding a comment about these may be sufficient.
Done
tfjs-backend-wasm/src/cc/backend.cc, line 64 at r3 (raw file):
Previously, tafsiri (Yannick Assogba) wrote…
nit: could we turn the 4 into a named variable.
Done
This fixes #3718
Changes
setWasmPathin favor ofsetWasmPathswhich allows users to specify location of multiple WASM binaries.Bundle sizes:
masterthreads_wasmTo see the logs from the Cloud Build CI, please join either our discussion or announcement mailing list.
This change is