jsmpi
A browser-oriented Rust MPI compatibility layer: run rsmpi-style programs in the browser by compiling them to WebAssembly and executing ranks through Web Workers.
Project Goals
jsmpi aims to preserve the rsmpi developer experience as much as possible when moving Rust MPI programs to the browser:
- Keep the
use mpi::traits::*style. - Keep the main call flow such as
mpi::initialize(),world.rank(),send(),receive(), andbarrier(). - Minimize code changes outside imports and entry-point wrapping.
Current Status
The repository currently includes the following:
Implemented
- Base
jsmpicrate skeleton. initialize(),Universe::world(),rank(), andsize().- Minimal API surface for
send,receive,broadcast_into, andbarrier. - Browser runtime chain with
Coordinator + Worker + WASM. - Blocking synchronization bridge prototype based on
SharedArrayBuffer + Atomics. - Demo page with switchable examples.
- Build scripts and local static serving workflow.
MPI API Completion Status
jsmpi is intentionally incremental. The list below tracks practical compatibility with common rsmpi usage.
Core Environment / Communicator
-
initialize() -
Universe::world() -
world.rank()/world.size() -
world.barrier()
Point-to-Point (Blocking)
-
process_at_rank(rank).send()/send_with_tag() -
process_at_rank(rank).receive()/receive_with_tag() -
receive_into()/receive_into_with_tag() - Slice/vector helpers:
send_slice*,receive_vec*,receive_slice_into* - Raw bytes path:
send_bytes*,receive_bytes* - Chunked bytes path (length-prefix framing):
send_bytes_chunked*,receive_bytes_chunked* - [~] Wildcard semantics:
any_process().receive*()is available; full MPI wildcard/tag matching parity is still evolving
Point-to-Point (Non-Blocking, First Version)
- Immediate send:
immediate_send()/immediate_send_with_tag()with requesttest()/wait() - Immediate receive:
immediate_receive()/immediate_receive_with_tag()with requesttest()/wait()/wait_into() - Multi-request helpers:
ImmediateReceiveRequest::test_any()/wait_any()/test_all()/wait_all()/test_some()/wait_some() - [~] Lifecycle semantics (first version): requests expose
state()(Pending/Completed/Canceled/Freed),cancel()transitions pending requests toCanceled, andfree()marks requests asFreed - [~] Current semantics are lightweight wrappers over existing runtime behavior; full MPI request lifecycle parity (
MPI_Requestedge cases) is still evolving
Collectives (Common)
- Broadcast:
broadcast_intoand communicator conveniencebroadcast_into_from - Gather:
gather_into_root(root process form) and communicator conveniencegather_into_root - Scatter:
scatter_into_root(root process form) and communicator conveniencescatter_into_root - Reduce sum:
reduce_sum_into_root/reduce_into_root(SystemOperation::sum()) - All-reduce sum:
all_reduce_sum_into/all_reduce_into(SystemOperation::sum()) - All-gather:
all_gather_into - Broadcast dissemination now uses a tree-style fan-out (virtual-rank doubling), reducing root hot-spot pressure on larger communicator sizes
-
all_reduce_sum_intoandall_gather_intonow reuse broadcast dissemination for result fan-out - Broadcast timeout/retry:
broadcast_into_from_with_timeout(...)/broadcast_into_from_with_retry_timeout(...) - Gather timeout/retry:
gather_into_root_with_timeout(...)/gather_into_root_with_retry_timeout(...) - Scatter timeout/retry:
scatter_into_root_with_timeout(...)/scatter_into_root_with_retry_timeout(...) - Timeout path:
all_gather_into_with_timeout(...) -> Result<()> - Retry+timeout path:
all_reduce_sum_into_from_with_retry_timeout(...) -> Result<()>
Not Yet Implemented (Planned)
- [~] Non-blocking request family: first-version
isend/irecv-style flow is available (immediate_send*,immediate_receive*,test*/wait*orchestration); full MPI request parity remains in progress - Full datatype and custom operation parity with
rsmpi - Advanced communicator/topology APIs (
split, cartesian topology, etc.) - Full algorithmic/performance parity for large-scale collectives
Current Examples
examples/hello_ranks.rsexamples/ping_pong.rsexamples/immediate_requests.rsexamples/broadcast_seed.rs
Current Documentation
docs/jsmpi-technical-spec.mddocs/jsmpi-development-guide.mddocs/protocol-versioning-plan.mddocs/production-release-checklist.mddocs/browser-compatibility-matrix.mdexamples/README.mddemo/index.html
Production Engineering Assets
.github/workflows/ci.yml.github/ISSUE_TEMPLATE/protocol-versioning-task.md.github/ISSUE_TEMPLATE/release-readiness-task.md
Repository Layout
jsmpi/
├─ src/ # Core Rust crate
├─ src/launcher/ # Browser launcher / worker bridge
├─ examples/ # Shared native/wasm examples
├─ demo/ # Yew browser demo app
├─ scripts/ # Build and run scripts
└─ docs/ # Technical spec and development guide
Quick Start
1. Build browser demo artifacts
This runs trunk build inside demo/.
2. Start local static server
3. Open the app
http://127.0.0.1:8080/
In the UI, you can:
- Switch between examples.
- Set the rank count.
- Inspect runtime logs, communication events, and error output.
The current demo is built and served through Trunk.
4. Deploy to GitHub Pages
The repository includes a Pages workflow:
.github/workflows/pages.yml
The workflow automatically:
- Compiles
examples/*.rstowasm32-unknown-unknown. - Runs
wasm-bindgento generatedemo/pkg/*. - Runs
trunk build --release. - Publishes
demo/distto GitHub Pages.
For project pages repositories, it uses /<repo>/ as public-url automatically.
For <user>.github.io repositories, it uses the root path /.
Example Migration Pattern
Recommended pattern: keep cross-target differences limited to imports and entry points.
use jsmpi as mpi;
use *;
use *;
Current Limitations
This project is still in an early prototype stage. The following areas are not complete yet:
- Full
rsmpiAPI/trait coverage. - Broader tag/wildcard semantics and non-blocking request family (
isend/irecv/wait*). - More complete collective algorithm family and large-scale optimization strategy.
- More robust error propagation and job termination semantics.
- Higher-performance data paths and typed-array optimizations.
Development and Validation
Validated key commands: