#mpi #parallel #cluster

msgpass

Thin wrapper to a Message Passing Interface (MPI)

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

MIT license

94KB
1.5K SLoC

Rust 1.5K SLoC // 0.0% comments C 160 SLoC // 0.1% comments BASH 65 SLoC // 0.1% comments

Thin wrapper to a Message Passing Interface (MPI)

Documentation Test on macOS Test on Linux Test on Linux with Intel MPI

Contents

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:

  • 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

Crates.io

👆 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