Closed felipellrocha closed 10 months ago
See https://github.com/GoogleChromeLabs/wasm-bindgen-rayon/issues/18#issuecomment-960949808 for deeper explanation:
Right, the wording there could certainly be improved. It's hard to convey difference between "main thread" as in "main thread from PoV of Rust code" vs "main thread" as in "browser main thread used for UI work".
What that comment meant is that
init
&initThreadPool
need to be invoked from main thread from Rust PoV, even though it actually lives in the worker as per caveats.It might be helpful to also look at the demo code which invokes those functions in a worker file: https://github.com/GoogleChromeLabs/wasm-bindgen-rayon/blob/5f54573052ea70986e1d23d3ebe876702c671335/demo/wasm-worker.js#L31-L32
I admit it's confusing and open to better rewording PRs.
See https://github.com/GoogleChromeLabs/wasm-bindgen-rayon/issues/18#issuecomment-960949808 for deeper explanation:
@RReverser for me this is not working :( Js fails on await multiThread.initThreadPool(navigator.hardwareConcurrency);
with
Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Worker': #<Memory> could not be cloned.
Did you build with all required flags from README? Most likely, you're missing +atomics
and company, as that error indicates a non-shared memory.
@RReverser I run
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals' && rustup run nightly-2022-03-14 wasm-pack build --target web --out-dir pkg
and build the pkg
successfully but after installing it I get the same issue.
Changing to nightly-2022-04-07
does not help
That is weird. Are you running in a browser that supports Wasm threads? (e.g. if you're on older Safari, it might be not available)
@RReverser
For context, I've implemented a genetic algorithm in Rust and would like to run it in wasm on the browser.
This works well without multithread, however as the computation it's fairly expensive I've used Rayon for parallelism (that's were wasm-bindgen-rayon
comes in play.
Running on Chrome.
This is my wasm-worker.js
import { threads } from 'wasm-feature-detect';
import * as Comlink from 'comlink';
// Wrap wasm-bindgen exports (the `run_ga_wasm` function) to add time measurement.
function wrapExports({ run_ga_wasm }) {
return ({ run_data, data }) => {
console.log("Nsdsadsadsadasdasdsa");
const start = performance.now();
const dd = run_ga_wasm(run_data, data);
const time = performance.now() - start;
return {
// Little perf boost to transfer data to the main thread w/o copying.
dd: Comlink.transfer(dd, [dd.buffer]),
time
};
};
}
async function initHandlers() {
const startThread = async () => {
const multiThread = await import('fantaga');
await multiThread.default();
console.log("NN", navigator.hardwareConcurrency);
await multiThread.initThreadPool(navigator.hardwareConcurrency); <--- fails here
return wrapExports(multiThread);
}
let multiThreadStarted = await startThread();
return Comlink.proxy({
multiThreadStarted
});
// return Comlink.proxy( multiThreadStarted );
}
Comlink.expose({
handlers: initHandlers()
});
It's called in App.tsx
like this :
[...]
import * as Comlink from 'comlink';
function App(this: any) {
const [sss, setCard] = useState<Number>();
const [wasm_init, setWasmInit] = useState<number>();
const [team, setTeam] = useState<Array<Player>>();
/// need to 'start' the wasm module with init()
/// it is async so we need to wait
useEffect(() => {
const fetchData = async () => {
let handlers = await Comlink.wrap(
new Worker(new URL('./wasm-worker.js', import.meta.url), {
type: 'module'
})
);
console.log(handlers);
setCard(3);
};
fetchData();
}, [])
[...]
Also I noticed I cannot do . handlers
(as in the example) on the above Comlink.wrap
, I can just do
not sure that's an issue
Latest version of wasm-bindgen-rayon allows to use Rayon directly from the main thread, without extra Worker and Comlink.
Which is it? :)