Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,8 @@ fmt_js: check_nvm_installed
nvm install $(NODE_VERSION) && \
nvm use $(NODE_VERSION) && \
$(MAKE) -C tfhe/web_wasm_parallel_tests fmt && \
$(MAKE) -C tfhe/js_on_wasm_tests fmt
$(MAKE) -C tfhe/js_on_wasm_tests fmt && \
$(MAKE) -C utils/wasm-par-mq fmt

.PHONY: semgrep_lint_setup_venv # Create venv and install Python dependencies for GPU lint checks
semgrep_lint_setup_venv:
Expand Down Expand Up @@ -339,7 +340,8 @@ check_fmt_js: check_nvm_installed
nvm install $(NODE_VERSION) && \
nvm use $(NODE_VERSION) && \
$(MAKE) -C tfhe/web_wasm_parallel_tests check_fmt && \
$(MAKE) -C tfhe/js_on_wasm_tests check_fmt
$(MAKE) -C tfhe/js_on_wasm_tests check_fmt && \
$(MAKE) -C utils/wasm-par-mq check_fmt

.PHONY: check_fmt_toml # Check TOML files format
check_fmt_toml: install_taplo
Expand Down Expand Up @@ -1413,7 +1415,8 @@ WASM_PAR_MQ_TEST_DIR=utils/wasm-par-mq/web_tests
.PHONY: build_wasm_par_mq_tests # Build the wasm-par-mq test WASM package
build_wasm_par_mq_tests: install_wasm_pack
cd $(WASM_PAR_MQ_TEST_DIR) && \
RUSTFLAGS="$(WASM_RUSTFLAGS)" wasm-pack build --target=web --out-dir pkg
RUSTFLAGS="$(WASM_RUSTFLAGS)" wasm-pack build --target=web --out-dir pkg && \
find pkg/snippets -type f -iname worker_helpers.js -exec sed -i 's|import("../../..")|import("../../../wasm_par_mq_web_tests.js")|g' {} \;

# This is an internal target, not meant to be called on its own.
run_wasm_par_mq_tests: build_wasm_par_mq_tests setup_venv
Expand Down
12 changes: 6 additions & 6 deletions tfhe/web_wasm_parallel_tests/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions utils/wasm-par-mq/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ sync-api = [
wasm-bindgen = { workspace = true }
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Blob",
"BlobPropertyBag",
"DedicatedWorkerGlobalScope",
"ErrorEvent",
"Location",
Expand All @@ -50,6 +48,8 @@ web-sys = { version = "0.3", features = [
"Url",
"Window",
"Worker",
"WorkerOptions",
"WorkerType",
"console",
] }
js-sys = { workspace = true }
Expand Down
9 changes: 9 additions & 0 deletions utils/wasm-par-mq/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.PHONY: fmt # Format Javascript code
fmt:
npm install
npm run format

.PHONY: check_fmt # Check Javascript code format
check_fmt:
npm install
npm run check-format
48 changes: 17 additions & 31 deletions utils/wasm-par-mq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ register_fn!(double, u32, u32);
```

Current limitations (may be lifted in the future):

- Closures are not supported
- Only functions with exactly one parameter are supported

### 2. Run parallel operations

At the call site, wrap the function in the `par_fn!` macro to retrieve its registry ID:

```rust
Expand Down Expand Up @@ -69,10 +71,10 @@ pub async fn init_parallel(
```

```javascript
import init, { init_parallel } from './pkg/your_crate.js';
import init, { init_parallel } from "./pkg/your_crate.js";

await init();
await init_parallel(4, './pkg/your_crate_bg.wasm', './pkg/your_crate.js');
await init_parallel(4, "./pkg/your_crate_bg.wasm", "./pkg/your_crate.js");
```

## Sync Executor
Expand Down Expand Up @@ -191,26 +193,13 @@ the SyncExecutor.

#### 3. Deploy the Coordinator Service Worker

Sync mode uses a Service Worker to coordinate blocking XHR. You need to create a
small Service Worker file whose scope covers your page. The scope defaults to the
directory where the SW file is served, so placing it next to your page is sufficient.

Create a `sw.js`:

```javascript
// sw.js
import { setupCoordinator } from './pkg/coordinator.js';
setupCoordinator();
```

`coordinator.js` ships with the npm package (or can be copied from `js/coordinator.js`
in this repository). It must be served at the path you import from above.

**Bundler users** (Vite, webpack, etc.): the bundler resolves the import, so
`coordinator.js` is inlined automatically, no extra file to deploy.
Sync mode uses a Service Worker to coordinate blocking XHR. You need to copy the `coordinator.js`
file at a location whose scope covers your page. The scope defaults to the directory where
the SW file is served, so placing it next to your page is sufficient.

**Static file users**: copy `coordinator.js` next to your wasm-bindgen output
(e.g. into `pkg/`) and adjust the import path in `sw.js` accordingly.
Examples:
**npm users**: `cp node_modules/<your-package>/coordinator.js public/`
**Static file users**: copy `coordinator.js` next to your HTML entry point.

#### 4. Initialize in sync mode

Expand All @@ -220,8 +209,6 @@ use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub async fn init_parallel_sync(
num_workers: u32,
wasm_url: &str,
bindgen_url: &str,
coordinator_url: &str,
) -> Result<(), JsValue> {
// register_coordinator must be called from the main thread.
Expand All @@ -236,18 +223,18 @@ pub async fn init_parallel_sync(
wasm_par_mq::register_coordinator(coordinator_url)
.await
.map_err(|e| JsValue::from_str(&e))?;
wasm_par_mq::init_pool_sync(Some(num_workers), wasm_url, bindgen_url)
wasm_par_mq::init_pool_sync(Some(num_workers))
.await
.map_err(|e| JsValue::from_str(&e))
}
```

```javascript
import init, { init_parallel_sync } from './pkg/your_crate.js';
import init, { init_parallel_sync } from "./pkg/your_crate.js";

await init();
// The coordinator_url must point to the SW file created above.
await init_parallel_sync(4, './pkg/your_crate_bg.wasm', './pkg/your_crate.js', '/sw.js');
// The coordinator_url must point to the coordinator.js deployed above.
await init_parallel_sync(4, "/coordinator.js");
```

## API
Expand All @@ -265,11 +252,10 @@ await init_parallel_sync(4, './pkg/your_crate_bg.wasm', './pkg/your_crate.js', '

### Functions

- `init_pool_async(num_workers, wasm_url, bindgen_url)` - Initialize the worker pool in async mode
- `init_pool_async(num_workers)` - Initialize the worker pool in async mode
- `register_coordinator(coordinator_url)` - Register the coordinator service worker (sync mode)
- `init_pool_sync(num_workers, wasm_url, bindgen_url)` - Initialize the worker pool in sync mode (coordinator must be registered first)
- `init_pool_sync_from_worker(num_workers, wasm_url, bindgen_url)` - Initialize in sync mode, reusing the current worker as SyncExecutor
- `start_worker()` - Entry point for compute workers
- `init_pool_sync(num_workers)` - Initialize the worker pool in sync mode (coordinator must be registered first)
- `init_pool_sync_from_worker(num_workers)` - Initialize in sync mode, reusing the current worker as SyncExecutor

## Examples

Expand Down
6 changes: 2 additions & 4 deletions utils/wasm-par-mq/examples/msm/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ echo "Building WASM..."
# Use web target for ES modules (workers use dynamic import())
wasm-pack build --target web --out-dir pkg

echo "Copying JS files..."
# worker.js and sync_executor.js are embedded in the WASM (no need to copy)
# coordinator.js is imported by sw.js (the user's Service Worker)
cp ../../js/coordinator.js pkg/
echo "Copying coordinator service worker..."
cp ../../js/coordinator.js .

echo ""
echo "Build complete! To run:"
Expand Down
Loading
Loading