#[cfg(target_arch = "wasm32")]
use jsmpi as mpi;
#[cfg(not(target_arch = "wasm32"))]
use mpi::traits::*;
#[cfg(target_arch = "wasm32")]
use std::time::Duration;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_futures::spawn_local;
#[cfg(not(target_arch = "wasm32"))]
fn run() {
let universe = mpi::initialize().expect("failed to initialize MPI runtime");
let world = universe.world();
let rank = world.rank();
let size = world.size();
let root = 0;
let input: Vec<i32> = if rank == root {
(0..size).map(|v| 100 + v).collect()
} else {
Vec::new()
};
let mut local = -1_i32;
world
.process_at_rank(root)
.scatter_into_root(&input, &mut local);
log::info!("[scatter] rank {rank} received value={local}");
world.barrier();
}
#[cfg(target_arch = "wasm32")]
async fn run_async() {
let runtime = mpi::runtime::Runtime::detect().expect("failed to initialize MPI runtime");
let rank = runtime.rank();
let size = runtime.size();
let root = 0;
let tag = 22;
let local = if rank == root {
let input: Vec<i32> = (0..size).map(|v| 100 + v).collect();
for dst in 1..size {
runtime
.send(root, dst, tag, &input[dst as usize])
.expect("scatter send failed");
}
input[0]
} else {
let (value, _status) = runtime
.receive_with_timeout_async::<i32>(Some(root), Some(tag), Duration::from_secs(15))
.await
.expect("scatter receive failed");
value
};
log::info!("[scatter] rank {rank} received value={local}");
runtime.barrier_async().await.expect("barrier failed");
}
fn main() {
#[cfg(not(target_arch = "wasm32"))]
env_logger::init();
#[cfg(not(target_arch = "wasm32"))]
run();
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn jsmpi_main() {
let _ = console_log::init();
spawn_local(async {
run_async().await;
mpi::runtime::mark_finished().expect("failed to mark worker as finished");
});
}