jsmpi 0.1.0

A browser-oriented MPI compatibility layer for Rust/WASM using Web Workers
Documentation
# `jsmpi` 技术规范(草案 v0.1)

## 1. 目标

`jsmpi` 是一个面向浏览器运行时的 Rust crate,目标是在 **Rust MPI 程序编译为 WebAssembly 后,通过 Web Worker 在浏览器中模拟/实现 MPI 执行模型**。

核心要求:

- **API 与 `rsmpi` 尽可能保持一致**- 对现有 `rsmpi` Rust 程序,除**程序入口与初始化方式**外,业务逻辑代码应当**几乎无需改动**- 支持在现代浏览器中运行多 worker 并完成消息传递、同步与常用 collective。
- 优先保证**单页应用内、本地浏览器环境**下的可用性与可调试性。

---

## 2. 非目标(当前阶段)

以下内容不作为 v0.1 首要目标:

- 与原生 MPI 二进制网络互通。
- 多浏览器、多设备、跨网络集群部署。
- 完整覆盖所有 MPI 扩展接口、拓扑通信器、RMA/One-sided、MPI-IO。
- 强实时性能对标原生 OpenMPI / MPICH。

---

## 3. 兼容性原则

## 3.1 API 对齐目标

`jsmpi` 应尽量复刻 `rsmpi` 的以下使用模式:

```rust
use mpi::traits::*;

fn main() {
    let universe = mpi::initialize().unwrap();
    let world = universe.world();
    let rank = world.rank();
    let size = world.size();

    if rank == 0 {
        world.process_at_rank(1).send(&42_i32);
    } else if rank == 1 {
        let (msg, _status) = world.any_process().receive::<i32>();
        println!("{msg}");
    }
}
```

兼容目标分级:

| 级别 | 含义 |
|---|---|
| L1 | 现有 `use mpi::traits::*` 风格基本不变 |
| L2 | `initialize` / `world` / `rank` / `size` / `send` / `receive` / `broadcast` / `barrier` 等常用接口保持一致 |
| L3 | 泛型、traits、返回值结构尽量贴近 `rsmpi` |
| L4 | 仅在入口层增加 `jsmpi` 浏览器启动胶水代码 |

## 3.2 允许改动点

仅允许下列最小改动:

1. 程序入口从原生 `fn main()` 调整为浏览器/WASM 入口包装。
2. 构建目标从本地 target 改为 `wasm32-unknown-unknown`3. 在 HTML/JS 启动层指定 worker 数量、模块 URL、启动参数。

业务计算逻辑、通信调用、collective 调用方式应尽量保持不变。

---

## 4. 总体架构

## 4.1 运行模型

浏览器中的一次 MPI 作业由以下组件组成:

- **主线程(Coordinator)**
  - 负责创建 Web Workers。
  - 分配 rank / size / job_id。
  - 维护 worker 生命周期。
  - 作为默认消息路由与 barrier/collective 协调者。

- **Worker(Rank Runtime)**
  - 每个 Web Worker 对应一个 MPI rank。
  - 加载同一份 WASM 模块。
  - 调用 Rust 导出的 rank 执行入口。

- **WASM 模块(Rust + `jsmpi`**
  - 提供与 `rsmpi` 对齐的 API 层。
  - 将 MPI 调用映射为对 JS runtime bridge 的请求。

## 4.2 逻辑分层

```text
应用代码(rsmpi 风格)
jsmpi 兼容 API 层
浏览器运行时抽象层(Runtime Adapter)
        ├─ Worker 内消息收发
        ├─ 主线程调度/路由
        └─ 序列化/同步机制
```

---

## 5. 模块划分

建议 crate 初始目录结构如下:

```text
jsmpi/
├─ src/
│  ├─ lib.rs
│  ├─ environment.rs      # initialize / Universe
│  ├─ topology.rs         # SystemCommunicator / Process
│  ├─ point_to_point.rs   # send / receive / probe
│  ├─ collective.rs       # barrier / broadcast / reduce(逐步)
│  ├─ request.rs          # 非阻塞接口预留
│  ├─ datatype.rs         # Rust <-> message payload 映射
│  ├─ runtime/
│  │  ├─ mod.rs
│  │  ├─ browser.rs       # wasm 环境桥接
│  │  ├─ protocol.rs      # worker/coordinator 协议
│  │  └─ state.rs         # rank 本地状态机
│  └─ error.rs
├─ js/
│  ├─ coordinator.js
│  ├─ worker.js
│  └─ bootstrap.js
├─ examples/
└─ docs/
```

---

## 6. 初始化与生命周期规范

## 6.1 初始化接口

目标接口:

- `mpi::initialize()`
- `Universe::world()`
- `Communicator::rank()`
- `Communicator::size()`

浏览器语义下:

- `initialize()` 从 worker 注入环境或全局 JS bridge 中读取:
  - `rank`
  - `size`
  - `job_id`
  - runtime 通信端口
- `Universe` 为轻量上下文句柄,不负责真正的系统级 MPI runtime 关闭。

## 6.2 退出语义

- Worker 执行结束后,应向 Coordinator 发送 `rank_finished` 事件。
- 所有 rank 完成后,Coordinator 汇总作业状态。
- `abort` 在 v0.1 可以退化为:记录错误并结束整个 job。

P0 已实现的生命周期状态语义:

- `running`:作业已启动并开始接收 rank 事件。
- `finished`:所有 rank 发出 `finished` 事件。
- `stopped`:出现 worker crash 或协议级错误(如 envelope 校验失败)。
- `timeout``send/receive/barrier` 的超时路径返回 `Error::Timeout`
P1 已补齐的可靠性语义:

- 提供 `RetryPolicy`(重试次数、初始退避、最大退避、退避倍数)。
- `send/receive/barrier` 提供带重试的超时接口。
- 在持续超时场景下,重试遵循预算上限并保证退避时间有上界。

---

## 7. 通信协议规范

## 7.1 消息基本结构

建议统一使用结构化消息:

```ts
interface JsmpiEnvelope {
  protocolVersion: number;
  kind: "point_to_point";
  jobId: string;
  src: number;
  dst: number;
  tag: number;
  seq: number;
  kind: "send" | "deliver" | "barrier" | "broadcast" | "reduce" | "control";
  payload?: ArrayBuffer | Uint8Array | unknown;
}
```

当前实现基线(P0):

- `protocol_version = 1`
- 版本不匹配返回 `PROTO_UNSUPPORTED_VERSION`
- 非法 rank / 非法 envelope 返回 `PROTO_INVALID_ENVELOPE`
- worker 与 launcher 双侧都执行 envelope 基础校验

## 7.2 点对点通信

首阶段支持:

- `send`
- `receive`
- `receive_into`
- `any_process().receive`
- `process_at_rank(n)`

设计原则:

- 默认由 Coordinator 进行路由,简化 worker 间拓扑控制。
- 先实现**可靠、有序、阻塞式**语义。
- 使用本地队列缓存尚未匹配的消息。
- `tag``source` 匹配规则尽量贴近 MPI。

## 7.3 Collective 通信

v0.1 优先级:

1. `barrier`
2. `broadcast`
3. `gather`
4. `scatter`
5. `reduce` / `all_reduce`

实现建议:

- 首版全部由 Coordinator 聚合协调。
- 后续版本可优化为树形广播/归约。

---

## 8. 数据类型与序列化

## 8.1 v0.1 支持范围

优先支持:

- 标量:`i32`, `i64`, `u32`, `u64`, `f32`, `f64`, `bool`
- 连续切片:`&[T]`, `&mut [T]`
- 常见 `Vec<T>` 接收场景

## 8.2 编码方式

推荐两层策略:

1. **TypedArray 直传**:用于数值类型切片,提高效率。
2. **Serde/二进制编码**:用于复杂结构,作为扩展层。

首版可先聚焦 POD/基础数值类型,避免过早引入复杂 datatype 系统。

---

## 9. Rust API 设计约束

## 9.1 命名兼容

公共 API 命名、traits、模块路径应尽量接近 `rsmpi`。

建议:

- 暴露 `traits` 模块
- 暴露 `topology`, `environment`, `datatype` 等模块
- 为常见调用链提供同名方法

## 9.2 trait 兼容策略

- 首先兼容用户最常用的 trait 导入路径。
- 对暂未支持的 API,使用清晰的 `unimplemented` / feature gate / 文档标注。
- 避免为了兼容而暴露明显错误的假语义。

---

## 10. 浏览器运行时要求

- 目标平台:`wasm32-unknown-unknown`
- 建议配套:`wasm-bindgen`, `js-sys`, `web-sys`
- 需要支持:
  - `Worker`
  - `MessageChannel` / `postMessage`
  - `structured clone`
  - `Promise` / 事件循环

可选增强:

- `SharedArrayBuffer` + `Atomics`(后续优化)
- OffscreenCanvas(若示例涉及可视化)

---

## 11. 错误处理与调试

- 所有 runtime 协议错误应映射到统一的 `jsmpi::Error`- 在 debug 模式下输出:
  - rank 启动日志
  - 消息发送/接收日志
  - barrier 进入/退出日志
- 推荐增加 `console_error_panic_hook` 便于浏览器内排障。

---

## 12. 性能策略

初期优先级:**正确性 > 兼容性 > 可调试性 > 性能**。

后续优化方向:

- 零拷贝/转移 `ArrayBuffer`
- 批量消息投递
- collective 树形算法
- `SharedArrayBuffer` 降低 coordinator 瓶颈

---

## 13. 里程碑计划

## M1:最小可运行版本

交付内容:

- `initialize`, `world`, `rank`, `size`
- `process_at_rank().send`
- `any_process().receive`
- `barrier`
- 浏览器示例:2~4 rank hello world / ping-pong

## M2:常用 collectives

交付内容:

- `broadcast`
- `gather` / `scatter`
- `reduce` / `all_reduce`(基础数值类型)

## M3:兼容性增强

交付内容:

- 更多 `rsmpi` trait 对齐
- 示例迁移:将已有 `rsmpi` demo 以最小改动迁移到浏览器
- 初步文档与对比矩阵

---

## 14. 测试规范

测试必须分层:

1. **单元测试**:协议匹配、队列、tag/source 过滤。
2. **wasm 浏览器集成测试**:多 worker 真正收发。
3. **兼容性样例测试**:直接运行 `rsmpi` 风格示例,验证改动最小。

关键验证项:

- 消息顺序正确
- barrier 不死锁
- broadcast 数据一致
- rank/size 赋值正确
- 异常作业能被主线程感知

---

## 15. 风险与待确认项

- 浏览器 event loop 与阻塞式 MPI 语义存在天然张力,需要通过异步桥接 + 同步外观设计。
- `rsmpi` 完整 datatype/trait 体系较复杂,应分阶段兼容。
- 若需要更高性能,后续可能引入 `SharedArrayBuffer`,同时要求 COOP/COEP 头配置。

---

## 16. 下一步实施建议

下一阶段应按以下顺序推进:

1. 初始化 crate 基础结构与 feature flags。
2. 打通 `coordinator.js` + `worker.js` + Rust WASM 入口。
3. 实现 `initialize/world/rank/size`4. 实现阻塞式 `send/receive` 最小闭环。
5. 基于真实浏览器示例验证 2-rank ping-pong。

> 结论:`jsmpi` 应先以“**浏览器内 MPI 兼容层**”定位落地,优先建立 `rsmpi` 风格 API 与 Web Worker runtime 之间的稳定桥接。