6 releases (3 breaking)
0.4.0 | Jan 18, 2024 |
---|---|
0.3.0 | Jan 17, 2024 |
0.2.2 | Jan 15, 2024 |
0.1.0 | Jan 14, 2024 |
#102 in Science
38 downloads per month
94KB
1.5K
SLoC
Thin wrapper to a Message Passing Interface (MPI)
Contents
- Introduction
- Installation on Debian/Ubuntu/Linux
- Installation on macOS
- Setting Cargo.toml
- Examples
- Todo list
Introduction
MsgPass (Message Passing) is a thin Rust wrapper to MPI. We consider a small subset of MPI functions. This subset will grow as our projects require more functionality. We implement (by hand) C functions that Rust can easily call using the FFI (in the c_code
directory).
We try to test all functions as much as possible, but test coverage could be better. The tests must be called with mpiexec
, thus it is easy to use the run-tests.bash
script.
Documentation:
Note: We can communicate strings by converting them to an array of bytes. For instance:
let mut bytes = vec![0_u8; MAX];
str_to_bytes(&mut bytes, "Hello World 😊");
comm.broadcast_bytes(0, &mut bytes)?;
Installation on Debian/Ubuntu/Linux
On Ubuntu/Linux, install OpenMPI, MPICH, or Intel MPI. For instance,
sudo apt install libopenmpi-dev
or
sudo apt install libmpich-dev
or
bash ./zscripts/install-intel-mpi-debian.bash
For MPICH, the following environment variable is required:
export MSGPASS_USE_MPICH=1
For Intel MPI, the following commands are required:
source /opt/intel/oneapi/setvars.sh
export MSGPASS_USE_INTEL_MPI=1
Installation on macOS
On macOS, install the following packages:
brew install llvm@13 open-mpi
Also, export the following environment variable:
export echo TMPDIR=/tmp
Setting Cargo.toml
👆 Check the crate version and update your Cargo.toml accordingly:
[dependencies]
msgpass = "*"
Examples
See also:
The example below (available in the examples
directory) will send an array from ROOT to all the other processors.
use msgpass::*;
fn main() -> Result<(), StrError> {
mpi_init()?;
let mut comm = Communicator::new()?;
let rank = comm.rank()?;
let size = comm.size()?;
const ROOT: i32 = 0;
const TAG: i32 = 70;
if rank == ROOT as usize {
let x = vec![1.0, 2.0, 3.0];
for to in 1..size {
comm.send_f64(&x, to, TAG)?;
}
println!("{}: x = {:?}", rank, x);
} else {
let mut y = vec![0.0, 0.0, 0.0];
comm.receive_f64(&mut y, ROOT, TAG)?;
println!("{}: y = {:?}", rank, y);
}
mpi_finalize()
}
Running the code above with mpiexec -np 4 ex_send_receive
(see run-examples.bash
), we get an output similar to the one below:
### ex_send_receive ######################################################
2: y = [1.0, 2.0, 3.0]
0: x = [1.0, 2.0, 3.0]
3: y = [1.0, 2.0, 3.0]
1: y = [1.0, 2.0, 3.0]
Todo list
- Implement basic functionality
- Initialize and finalize
- Abort and barrier
- Wrap more MPI functions
- Implement send/receive
- Implement reduce/allreduce
- Implement scatter/gather/allgather
- Handle complex numbers
Dependencies
~210–445KB