#[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(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();
assert!(size >= 2, "ring requires at least 2 ranks");
let next = (rank + 1) % size;
let prev = (rank - 1 + size) % size;
let payload = [rank, rank * 10];
world.process_at_rank(next).send_slice(&payload);
let (received, _status) = world.process_at_rank(prev).receive_vec::<i32>();
log::info!(
"[ring] rank {rank} sent {:?} -> {next}, received {:?} <- {prev}",
payload,
received
);
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();
assert!(size >= 2, "ring requires at least 2 ranks");
let next = (rank + 1) % size;
let prev = (rank - 1 + size) % size;
let payload = vec![rank, rank * 10];
let send_tag = 30;
runtime
.send(rank, next, send_tag, &payload)
.expect("ring send failed");
let (received, _status) = runtime
.receive_with_timeout_async::<Vec<i32>>(Some(prev), Some(send_tag), Duration::from_secs(15))
.await
.expect("ring receive failed");
log::info!(
"[ring] rank {rank} sent {:?} -> {next}, received {:?} <- {prev}",
payload,
received
);
runtime.barrier_async().await.expect("barrier failed");
}
fn main() {
#[cfg(not(target_arch = "wasm32"))]
{
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
run();
}
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub async fn jsmpi_main() {
console_error_panic_hook::set_once();
let _ = console_log::init_with_level(log::Level::Info);
run_async().await;
let _ = mpi::runtime::mark_finished();
}