Skip to main content

thread_multiple/
thread_multiple.rs

1//! Stress test for `MPI_THREAD_MULTIPLE`: every rank runs several threads that
2//! concurrently perform tagged point-to-point exchanges. Verifies the transport
3//! (connection writes, inbox matching) is safe under concurrent MPI calls.
4
5use mpi::traits::*;
6use std::thread;
7
8const THREADS: i32 = 8;
9
10fn main() {
11    let universe = mpi::initialize().unwrap();
12    let world = universe.world();
13    let rank = world.rank();
14    let size = world.size();
15
16    let next = (rank + 1) % size;
17    let prev = (rank - 1 + size) % size;
18
19    let handles: Vec<_> = (0..THREADS)
20        .map(|t| {
21            let w = world.clone(); // SimpleCommunicator is Send + Sync (Arc)
22            thread::spawn(move || {
23                let tag = 1000 + t;
24                let msg = [rank * 100 + t, rank, t];
25                // Concurrent send + receive on this thread's own tag.
26                w.process_at_rank(next).send_with_tag(&msg[..], tag);
27                let (got, status) = w.process_at_rank(prev).receive_vec_with_tag::<i32>(tag);
28                assert_eq!(status.tag(), tag, "tag mismatch");
29                assert_eq!(
30                    got,
31                    vec![prev * 100 + t, prev, t],
32                    "thread {t} payload mismatch"
33                );
34            })
35        })
36        .collect();
37
38    for h in handles {
39        h.join().expect("thread panicked");
40    }
41
42    world.barrier();
43    if rank == 0 {
44        println!(
45            "THREAD PASS: {THREADS} threads/rank did concurrent tagged exchanges on {size} ranks."
46        );
47    }
48}