Giter VIP home page Giter VIP logo

rsmpi's Introduction

MPI bindings for Rust

GitHub Actions Documentation Crates.io License: Apache License 2.0 or MIT

The Message Passing Interface (MPI) is a specification for a message-passing style concurrency library. Implementations of MPI are often used to structure parallel computation on High Performance Computing systems. The MPI specification describes bindings for the C programming language (and through it C++) as well as for the Fortran programming language. This library tries to bridge the gap into a more rustic world.

Requirements

An implementation of the C language interface that conforms to MPI-3.1. rsmpi is currently tested with these implementations:

Users have also had success with these MPI implementations, but they are not tested in CI:

For a reasonable chance of success with rsmpi with any MPI implementation, you must have one of:

  • export MPI_PKG_CONFIG to be the name or path for pkg-config for your implementation
    • rsmpi automatically uses CRAY_MPICH_DIR on Cray environments so the above need not be set
    • mpich and ompi are tried by default as a last resort
    • Tip: test with a command like pkg-config --cflags --libs mpich
  • The implementation provides a C compiler wrapper mpicc
    • export MPICC=/path/to/mpicc to specify fully
    • otherwise tries mpicc in $PATH
    • mpicc -show should print the full command line that is used to invoke the wrapped C compiler in gcc-compatible syntax (e.g., -lmpi, -I/usr/local/include, ...)
  • On Windows, the variables MSMPI_INC and either MSMPI_LIB32 or MSMPI_LIB64 should be set

Since the MPI standard leaves some details of the C API unspecified (whether to implement certain constants and even functions using preprocessor macros or native C constructs, the details of most types, etc.) rsmpi takes a two step approach to generating functional low-level bindings.

First, it uses a thin static library written in C (see rsmpi.h and rsmpi.c) that tries to capture the underspecified identifiers and re-exports them with a fixed C API. This library is built from build.rs using the gcc crate.

Second, to generate FFI definitions tailored to each MPI implementation, rsmpi uses rust-bindgen which needs libclang. See the bindgen project page for more information.

Furthermore, rsmpi uses the libffi crate which installs the native libffi which depends on certain build tools. See the libffi project page for more information.

Usage

Add the mpi crate as a dependency in your Cargo.toml:

# "features" is optional
[dependencies]
mpi = { version = "0.7.0", features = ["user-operations", "derive"] }

Then use it in your program like this:

use mpi::request::WaitGuard;
use mpi::traits::*;

fn main() {
    let universe = mpi::initialize().unwrap();
    let world = universe.world();
    let size = world.size();
    let rank = world.rank();

    let next_rank = (rank + 1) % size;
    let previous_rank = (rank - 1 + size) % size;

    let msg = vec![rank, 2 * rank, 4 * rank];
    mpi::request::scope(|scope| {
        let _sreq = WaitGuard::from(
            world
                .process_at_rank(next_rank)
                .immediate_send(scope, &msg[..]),
        );

        let (msg, status) = world.any_process().receive_vec();

        println!(
            "Process {} got message {:?}.\nStatus is: {:?}",
            rank, msg, status
        );
        let x = status.source_rank();
        assert_eq!(x, previous_rank);
        assert_eq!(vec![x, 2 * x, 4 * x], msg);

        let root_rank = 0;
        let root_process = world.process_at_rank(root_rank);

        let mut a;
        if world.rank() == root_rank {
            a = vec![2, 4, 8, 16];
            println!("Root broadcasting value: {:?}.", &a[..]);
        } else {
            a = vec![0; 4];
        }
        root_process.broadcast_into(&mut a[..]);
        println!("Rank {} received value: {:?}.", world.rank(), &a[..]);
        assert_eq!(&a[..], &[2, 4, 8, 16]);
    });
}

Features

The bindings follow the MPI 3.1 specification.

Currently supported:

  • Groups, Contexts, Communicators:
    • Group and (Intra-)Communicator management from section 6 is mostly complete.
    • no Inter-Communicators
    • no process topologies
  • Point to point communication:
    • standard, buffered, synchronous and ready mode send in blocking and non-blocking variants
    • receive in blocking and non-blocking variants
    • send-receive
    • probe
    • matched probe/receive
  • Collective communication:
    • barrier
    • broadcast
    • (all) gather
    • scatter
    • all to all
    • varying counts operations
    • reductions/scans
    • blocking and non-blocking variants
  • Datatypes: Bridging between Rust types and MPI basic types as well as custom MPI datatypes which can act as views into buffers.

Not supported (yet):

  • One-sided communication (RMA)
  • MPI parallel I/O
  • A million small things

Optional Cargo Features

These optional features can be enabled in your cargo manifest. See the Usage section above.

user-operations enables capturing lambdas and safe creation in UserOperation. This feature requires the libffi system library, which is not available on all systems out-of-the-box.

let mut h = 0;
comm.all_reduce_into(
    &(rank + 1),
    &mut h,
    &UserOperation::commutative(|x, y| {
        let x: &[Rank] = x.downcast().unwrap();
        let y: &mut [Rank] = y.downcast().unwrap();
        for (&x_i, y_i) in x.iter().zip(y) {
            *y_i += x_i;
        }
    }),
);

derive enables the Equivalence derive macro, which makes it easy to send structs over-the-wire without worrying about safety around padding, and allowing arbitrary datatype matching between structs with the same field order but different layout.

#[derive(Equivalence)]
struct MyProgramOpts {
    name: [u8; 100],
    num_cycles: u32,
    material_properties: [f64; 20],
}

Documentation

Every public item of rsmpi should at least have a short piece of documentation associated with it. Documentation can be generated via:

cargo doc

Documentation for the latest version of the crate released to crates.io is hosted on Github pages.

Examples

See files in examples/. These examples also act as integration tests.

Python integration

It is possible to use rsmpi with a communicator provided by mpi4py. An example project demonstrating this is mpi4py_with_rsmpi.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

rsmpi's People

Contributors

adamreichold avatar andrewgaspar avatar bsteinb avatar colin-daniels avatar cydhra avatar dependabot[bot] avatar emberian avatar hestela avatar hhirtz avatar holothedrunk avatar iwahbe avatar jedbrown avatar jtronge avatar keefehuang avatar marmistrz avatar mscroggs avatar niklas-uhl avatar raviqqe avatar rufflewind avatar tbetcke avatar zackjorquera avatar zolkko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rsmpi's Issues

Move mpi::ffi into separate crate

There's a couple reasons to do this -

  1. For people hacking on rsmpi, it means shorter incremental compile times since bindgen doesn't have to be re-run on every compile
  2. If published separately, it would allow users to just take mpi::ffi if they don't want to use rsmpi's API - they can just call MPI directly.

This is pretty low priority.

Add prelude module

rsmpi should have a prelude module. Currently we recommend writing use mpi::traits::*; at the top of any file that is using rsmpi, but use mpi::prelude::*; is more conventional.

Building fails. Not an issue, but I'd appreciate any help

I've been trying to set up my system to use rsmpi, but so far no luck. When I try to build the example code on the README.md I get the following output:

error: failed to run custom build command for 'mpi-sys v0.1.1' process didn't exit successfully: '/home/.../target/debug/build/mpi-sys-0cd2cc8ff5ab6071/build-script-build' (exit code: 101)
--- stdout
TARGET = Some("x86_64-unknown-linux-gnu")
OPT_LEVEL = Some("0")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("x86_64-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("x86_64-unknown-linux-gnu")
CC_x86_64-unknown-linux-gnu = None
CC_x86_64_unknown_linux_gnu = None
HOST_CC = None
CC = Some("mpicc")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("x86_64-unknown-linux-gnu")
CFLAGS_x86_64-unknown-linux-gnu = None
CFLAGS_x86_64_unknown_linux_gnu = None
HOST_CFLAGS = None
CFLAGS = None
DEBUG = Some("true")
running: "mpicc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-m64" "-Wall" "-Wextra" "-o" "/home/.../target/debug/build/mpi-sys-0284a3d3321aaaf4/out/src/rsmpi.o" "-c" "src/rsmpi.c"
cargo:warning=In file included from src/rsmpi.c:1:0:
cargo:warning=src/rsmpi.h:38:14: error: unknown type name ‘MPI_Message’
cargo:warning= extern const MPI_Message RSMPI_MESSAGE_NULL;
cargo:warning=              ^~~~~~~~~~~
cargo:warning=src/rsmpi.h:39:14: error: unknown type name ‘MPI_Message’
cargo:warning= extern const MPI_Message RSMPI_MESSAGE_NO_PROC;
cargo:warning=              ^~~~~~~~~~~

< more messages like these >

cargo:warning=src/rsmpi.c:81:12: note: in definition of macro ‘RSMPI_c2f_def_base’
cargo:warning=     return type ## _f2c(argname); \
cargo:warning=            ^~~~
cargo:warning=src/rsmpi.c:91:1: note: in expansion of macro ‘RSMPI_c2f_def’
cargo:warning= RSMPI_c2f_def(MPI_Message, message);
cargo:warning= ^~~~~~~~~~~~~
cargo:warning=mpicc: No such file or directory
exit code: 1

--- stderr
thread 'main' panicked at '

Internal error occurred: Command "mpicc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-m64" "-Wall" "-Wextra" "-o" "/home/..../target/debug/build/mpi-sys-0284a3d3321aaaf4/out/src/rsmpi.o" "-c" "src/rsmpi.c" with args "mpicc" did not execute successfully (status code exit code: 1).

', /home/.../.cargo/registry/src/github.com-1ecc6299db9ec823/gcc-0.3.54/src/lib.rs:1670:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: build failed

I use openSUSE Tumbleweed. I have installed openMPI 3.0.0 from the official repos, along with the required packages (lam, clang etc).

mpicc -show returns this:

gcc -pthread libtool: link: -pthread -L/usr/lib64 -llammpio -llamf77mpi -lmpi -llam -lutil -ldl

I tried using MPICH instead of openMPI, I even made a clean install in a VM.

I guess it's a C compilation related issue, but I don't know how to proceed (or where else to ask for help).

Confusing argument layouts (send_receive_into)

The argument layout of point_to_point::send_receive_into(msg, destination, buffer, source) doesn't feel very intuitive. I read the arguments as pairs "msg - dest, buf - src".

How it reads at the moment is "Message to destination, in to buffer on source" - or something similar.. I think there's a few more functions like this.

I feel it should be send_receive_into(source, msg, destination, buffer) so that it reads as if it is implying that "the source is sending a message to destinations buffer" -> "src - msg, dest - buf", this feels more natural.

docs.rs failed to build the docs

E.g. see here for the error log: https://docs.rs/crate/mpi-sys/0.1.2/builds/122941

docs.rs is very configurable, supports building the docs for different, user-defined targets, etc.

If there is anything special that you need to build the docs there it might be worth it to open an issue on docs.rs now that it has been moved to the rust-lang organization and get it sorted out :)

Let me know if I can help!

Add support for inter-communication

The code currently operates under the assumption that all communicators are intra-communicators, but inter-communicators have slightly different semantics that should be captured in the type system.

There are places we check the value of MPI_Comm_size for safety purposes, but should actually be MPI_Comm_remote_size when dealing with an inter-communicator. Considering adding a routine fn target_size(&self) -> Rank on the Communicator trait with no default implementation. Evaluates to self.size() on intra-communicators and self.remote_size() on inter-communicators.

The proposed implementation would:

  • Capture inter-communicators in the type system as separate entities from intra-communicators
  • Add support for creating inter-communicators via MPI_Intercomm_create
  • Add support for creating an intra-communicator from an inter-communicator via MPI_Intercomm_merge

I have related changes in the AndrewGaspar/intercomm branch, but I'll probably restructure that branches' changes and submit under a separate branch.

Cannot build 32-bit MS-MPI application on 64-bit Windows

NOTE: This is just a note for my own sake. Low priority.

We pick the link library location to use for MS-MPI based on target_arch:

    let lib_env = if cfg!(target_arch = "i686") {
        "MSMPI_LIB32"
    } else if cfg!(target_arch = "x86_64") {
        "MSMPI_LIB64"
    } else {
        panic!("rsmpi does not support your windows architecture!");
    };

Of course, build scripts are always compiled for the host architecture. We need to use the "TARGET" environment variable to get the triple for the actual target.

Build error because of different clang-sys/bindgen requirements

When I tried to build a project depending on this crate I get the following error:

error: multiple packages link to native library clang, but a native library can be linked only once

package clang-sys v0.21.2
... which is depended on by bindgen v0.31.3
... which is depended on by libffi-sys v0.6.0
... which is depended on by libffi v0.6.3
... which is depended on by mpi v0.5.2
... which is depended on by project-using-mpi v0.1.0 (file:///path/to/project-folder)
links to native library clang

package clang-sys v0.22.0
... which is depended on by bindgen v0.33.2
... which is depended on by mpi-sys v0.1.1
... which is depended on by mpi v0.5.2
... which is depended on by project-using-mpi v0.1.0 (file:///path/to/project-folder)
also links to native library clang

The project has only mpi as dependency (Cargo.toml):

[dependencies]
mpi = "*"

Maybe mpi-sys could depend on bindgen v0.31.3 (libffi-sys depends explicitly on bindgen = "0.31.3"), too. Or do you think it is better to wait for libffi-sys to update to the current bindgen?

Thanks a bunch for this crate, I am excited to try it.

crabtw's bindgen repo has ceased to exist

I cannot build current master because it depends on https://github.com/crabtw/rust-bindgen.git?rev=0433980286a5264e3d69214aa42e314c37238cf6. That repository has been deleted and the only crates.io release of rust-bindgen has been yanked.

To replicate this you would need to clear out your cargo crates registry and git checkouts or try to build on a clean install of cargo which does not have rust-bindgen cached.

The bindgen package by servo looks like a newer version of the same base, so I assume rsmpi needs porting to use this.

failure to compile with OpenMPI 4.0 due to removed symbols

error[E0425]: cannot find function `MPI_Type_hvector` in module `ffi` 
  --> /home/cc/.cargo/registry/src/github.com-1ecc6299db9ec823/mpi-0.5.4/src/datatype.rs:212:18 
   | 
212 |             ffi::MPI_Type_hvector(count, blocklength, stride, oldtype.as_raw(), &mut newtype); 
   |                  ^^^^^^^^^^^^^^^^ did you mean `MPI_Type_vector`? 

error: aborting due to previous error

OpenMPI 4.0 (which recently landed on arch) removes some symbols that were eliminated from the MPI standard 3.0.

https://www.open-mpi.org/faq/?category=mpi-removed

Why are some constants like MPI_REQUEST_NULL statics ?

I've noticed that some constants like MPI_REQUEST_NULL, MPI_COMM_WORLD, etc. are static muts instead of consts. Why is this ? In particular, when can I not read their values because it is undefined behavior to do so ? (e.g. before initializing MPI ?)

static mut is almost impossible to use correctly - rust-lang/rust#53639

Please don't pin dependencies

https://github.com/bsteinb/rsmpi/blob/09668b8e12d4a62d55c74a33eb0f03a4c4803e9e/Cargo.toml#L26

For as long as they can be avoided, = version dependencies should not be the solution. They sweep the problem under the rug, and may eventually lead to a problem for someone else when multiple crates have conflicting = versions.

The proper way to fix this mess is:

  • libffi-sys 0.6.4 should be yanked and rereleased as libffi-sys 0.7.0
  • mpi should release a major version bump mpi 0.6.0 that uses libffi-sys = "0.7.0", without pinning
  • Similarly, there should be a major version bump for mpi-sys 0.2.0 to use the new bindgen.

I created tov/libffi-sys-rs#21 to inform the upstream author.

Compilation failed, 'stddef.h' file not found

I tried to run the example provided in the README.md file. However, the compilation of the mpi crate failed for me with the following output:

   Compiling mpi v0.1.7
failed to run custom build command for `mpi v0.1.7`
Process didn't exit successfully: `/home/jgreitemann/Documents/Programming/rust/rsmpi-test/target/debug/build/mpi-4dd1b45724a1a7b9/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-unknown-linux-gnu")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-unknown-linux-gnu")
debug=true opt-level=0
TARGET = Some("x86_64-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("x86_64-unknown-linux-gnu")
CC_x86_64-unknown-linux-gnu = None
CC_x86_64_unknown_linux_gnu = None
HOST_CC = None
CC = Some("mpicc")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("x86_64-unknown-linux-gnu")
CFLAGS_x86_64-unknown-linux-gnu = None
CFLAGS_x86_64_unknown_linux_gnu = None
HOST_CFLAGS = None
CFLAGS = None
running: "mpicc" "-O0" "-c" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-fPIC" "-o" "/home/jgreitemann/Documents/Programming/rust/rsmpi-test/target/debug/build/mpi-4dd1b45724a1a7b9/out/src/rsmpi.o" "src/rsmpi.c"
TARGET = Some("x86_64-unknown-linux-gnu")
TARGET = Some("x86_64-unknown-linux-gnu")
HOST = Some("x86_64-unknown-linux-gnu")
AR_x86_64-unknown-linux-gnu = None
AR_x86_64_unknown_linux_gnu = None
HOST_AR = None
AR = None
TARGET = Some("x86_64-unknown-linux-gnu")
running: "ar" "crus" "/home/jgreitemann/Documents/Programming/rust/rsmpi-test/target/debug/build/mpi-4dd1b45724a1a7b9/out/librsmpi.a" "/home/jgreitemann/Documents/Programming/rust/rsmpi-test/target/debug/build/mpi-4dd1b45724a1a7b9/out/src/rsmpi.o"
cargo:rustc-link-lib=static=rsmpi
cargo:rustc-link-search=native=/home/jgreitemann/Documents/Programming/rust/rsmpi-test/target/debug/build/mpi-4dd1b45724a1a7b9/out
cargo:rustc-link-search=native=/usr/lib64/openmpi/lib

--- stderr
ar: `u' modifier ignored since `D' is the default (see `U')
warning: argument unused during compilation: '-L/usr/lib64/openmpi/lib' [-Wunused-command-line-argument]
/usr/include/openmpi-x86_64/mpi.h:223:10: fatal error: 'stddef.h' file not found
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: ()', ../src/libcore/result.rs:732

I'm running Fedora 22, Rust 1.3.0, and openmpi 1.8.7-1 from the Fedora repos.

Broken on recent nightlies

mpi does not build on recent nightlies, I have not yet tried to figured out when this first broke. This is what is broken:

error[E0308]: mismatched types
  --> src/request.rs:65:1
   |
65 | / pub struct Request<'a, S: Scope<'a> = StaticScope> {
66 | |     request: MPI_Request,
67 | |     scope: S,
68 | |     phantom: PhantomData<Cell<&'a ()>>,
69 | | }
   | |_^ lifetime mismatch
   |
   = note: expected type `request::Scope<'a>`
              found type `request::Scope<'static>`
note: the lifetime 'a as defined on the struct at 65:1...
  --> src/request.rs:65:1
   |
65 | pub struct Request<'a, S: Scope<'a> = StaticScope> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: ...does not necessarily outlive the static lifetime

error[E0308]: mismatched types
   --> src/request.rs:230:1
    |
230 | pub struct WaitGuard<'a, S: Scope<'a> = StaticScope>(Option<Request<'a, S>>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
    = note: expected type `request::Scope<'a>`
               found type `request::Scope<'static>`
note: the lifetime 'a as defined on the struct at 230:1...
   --> src/request.rs:230:1
    |
230 | pub struct WaitGuard<'a, S: Scope<'a> = StaticScope>(Option<Request<'a, S>>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...does not necessarily outlive the static lifetime

error[E0308]: mismatched types
   --> src/request.rs:274:1
    |
274 | pub struct CancelGuard<'a, S: Scope<'a> = StaticScope>(WaitGuard<'a, S>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
    = note: expected type `request::Scope<'a>`
               found type `request::Scope<'static>`
note: the lifetime 'a as defined on the struct at 274:1...
   --> src/request.rs:274:1
    |
274 | pub struct CancelGuard<'a, S: Scope<'a> = StaticScope>(WaitGuard<'a, S>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...does not necessarily outlive the static lifetime

error: aborting due to 3 previous errors

@Rufflewind any idea what this might be?

Possible undefined behaviour in matched_receive_vec

MatchedReceiveVec::matched_receive_vec currently allocates and fills the receive buffer via

let mut res = Vec::with_capacity(count);
unsafe {
    res.set_len(count);
}
let status = message.matched_receive_into(&mut res[..]);

where res: Vec<M> and hence &mut res[..]: &mut [M].

Even when it is assumed that the receive bytes form valid instances of M, i.e. ignoring #54, the uninitialized memory backing res could certainly contain arbitrary bit patterns which are invalid when e.g. M == bool. Therefore, the call to set_len and the creation of a mutable reference to the unformed instances of M is undefined behavior AFAIU.

Maybe this could be worked around by going for res: Vec<MaybeUninit<M>> and transmuting to Vec<M> only after the receive operation, but I guess this would require something along the lines of impl<M> Equivalence for MaybeUninit<M> where M: Equivalence?

More generally speaking and thinking about #54 again, the API could be changed so that receive operations generally handle only instances of MaybeUninit<M> instead of M so the required unsafety would be "concentrated" into calling assume_init in user code, at least in places where M: FromAnyBytes does not apply. Using MaybeUninit<M> could also steer user code towards avoiding the overhead of initializing memory beforing receive data into it which is required to produce a valid &mut M (as the API would take only &mut MaybeUninit<M> or even *mut M).

Make user-operations a non-default feature for 0.6

I personally use a lot of platforms where libffi is not built-in (including Windows and macOS), and it's unfortunate that I have to manually opt out of default features to avoid taking this dependency. I think it would be nice to move user-operations to a disabled-by-default state for the next API breaking release.

Re-structure for use in multi-language scenarios

rsmpi does not currently support multi-language MPI programs very well. This issue is tracking the work needed to make it more embed-able.

Outstanding Issues:

  • Expose mpi::is_initialized
  • Expose UserCommunicator::from_raw
  • Support for external initialization of MPI

Original Comment

A scenario for rsmpi, which I imagine would be common, is to use it inside a static lib that is linked into a larger application. This larger application is likely written in another language like Fortran, C, or C++. The larger application is probably already initializing MPI with its preferred parameters. In this case, the Rust library could would not "own" the MPI initialization, and therefore would not call mpi::initialize*. However, it may still want to check if MPI has already been initialized, even if it is just to panic and tell the user that MPI needs to be initialized first.

Of course, ffi::MPI_Initialized is available, but it seems like making the Rust-native version of it available is pretty low-cost.

0.6 Release

I'd like to release v0.6 of rsmpi - I think all I want is to finish merging these pull requests. So if I could get reviews on each of those PRs, merge them, and we can go ahead and cut a release.

cc @adamreichold @fzyzcjy @benruijl

Run `cargo fmt`

I noticed that the code is out of date with the rustfmt.toml checked in to the repo, at least with the new version of rustfmt I'm using. If may be good to run a cargo fmt at some point.

Remove dependency on bindgen

Hi !

I would love to use this crate in my application, but I have a single issue with it, which is that the ffi bindings are generated at compile time for the specific mpi implementation used by using bindgen.

While I like bindgen, it has a lot of issues, especially when using it at compile time: the final user needs to have libclang installed, at the right version and at the right place to be sure that code generation works.

I think this can be a big hurdle when trying to use this crate. Here are a few examples:

  • I had hard time just compiling the example, because I am using CentOS 7, which comes with clang 3.4, which is too old for bindgen. Then I tried using linuxbrew to get a more modern libclang, and got weird errors concerning GLIBC_VERSION symbols.
  • On a big HPC cluster, there is a very low probability to have a modern libclang installed, and most users will not bother trying to install one. This prevent them from using any application based on this crate.
  • Just on this repo, issues #1, #6, #20 and #22 are build errors related to bindgen.

Why is bindgen used

This is my understanding of why bindgen is used at compile time in this crate, please correct me if I am wrong!

MPI does not have any stable ABI, only a specification and a C API. This crate uses a small C shim to ensure #defined symbols are available to Rust, and bindgen to parse the mpi headers and then generate corresponding ffi declaration for Rust.

Removing bindgen dependency

I think it could be possible to remove bindgen dependency at build time by pre-generating the FFI declaration for all the different MPI implementations and versions, and then detecting which one to use in build.rs by parsing the output of mpicc.

Of course generating the declaration for every single implementation and every single version is not going to be practical, and thus one could generate the declaration for some implementation/versions couples (starting with the latest release of OpenMPI and MPICH for example), and then defaulting to use bindgen for all the others cases.This would keep the benefits of having an easy way to use this crate, even with exotic MPI implementation, while having smaller build time and simpler build for 80% of the cases.

Please tell me what you think of this! Is there something I overlooked?

If you agree with this proposal, I could try to implement it, I have some experience with bindgen and Rust FFI.

MS-MPI cannot support user-operations feature on 32-bit Windows

This issue is purely to track this problem and point any user who asks about this issue to.

As of this writing, libffi doesn't support the "stdcall" calling convention, which is what MS-MPI uses for callback functions. This is OK on x86-64 because on 64-bit, stdcall is the same as the default calling convention. But on 32-bit, it is different. Therefore, the "user-operations" feature, which requires libffi, does not support MS-MPI on 32-bit Windows.

panicked: "attempted to leave type `&mpi::request::LocalScope` uninitialized, which is invalid"

I am running the example code in README.md.

Command: RUST_BACKTRACE=full cargo mpirun --all-features --verbose -n 2 --bin trans_sort

It goes well and output correctly. But when exiting the mpi::request::scope(|| ... ) it panicks.

Looking into stacktrace (mpi-0.5.4/src/request.rs:109), there is:

...
    /// Unregister the request object from its scope and deconstruct it into its raw parts.
    ///
    /// This is unsafe because the request may outlive its associated buffers.
    pub unsafe fn into_raw(mut self) -> (MPI_Request, S) {
        let request = mem::replace(&mut self.request, mem::uninitialized());
        let scope = mem::replace(&mut self.scope, mem::uninitialized()); // <-- 109!!!
        let _ = mem::replace(&mut self.phantom, mem::uninitialized());
        mem::forget(self);
        scope.unregister();
        (request, scope)
    }
...

And I see from rust-lang/rust#66059 that, in 2020 March, a new PR is merged. It says "panic on types that do not permit zero-initialization".

Moreover, when I read mem::uninitialized's documentation, it says it is deprecated and cannot be used correctly.

So I guess this is the problem, and maybe mem::uninitialized() should be changed to something like MaybeUninit::uninit().assume_init()?

Sorry if I am wrong. I am really new to Rust. Anyway thanks very much for this lib!

P.S. The Travis CI is even passing... https://travis-ci.org/github/rsmpi/rsmpi I am confused why it can happen...

Stacktrace:

thread 'main' panicked at 'attempted to leave type `&mpi::request::LocalScope` uninitialized, which is invalid', /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/mem/mod.rs:664:9
stack backtrace:
   0:     0x5564c17b9005 - backtrace::backtrace::libunwind::trace::h14d338b30b3ea0a7
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1:     0x5564c17b9005 - backtrace::backtrace::trace_unsynchronized::h73ea91d74a3fd67f
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2:     0x5564c17b9005 - std::sys_common::backtrace::_print_fmt::hd42948c952866e12
                               at src/libstd/sys_common/backtrace.rs:78
   3:     0x5564c17b9005 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::ha8f928866ff7571e
                               at src/libstd/sys_common/backtrace.rs:59
   0:     0x5607ab178005 - backtrace::backtrace::libunwind::trace::h14d338b30b3ea0a7
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1:     0x5607ab178005 - backtrace::backtrace::trace_unsynchronized::h73ea91d74a3fd67f
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2:     0x5607ab178005 - std::sys_common::backtrace::_print_fmt::hd42948c952866e12
                               at src/libstd/sys_common/backtrace.rs:78
   3:     0x5607ab178005 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::ha8f928866ff7571e
                               at src/libstd/sys_common/backtrace.rs:59
   4:     0x5564c17d5d4c - core::fmt::write::he0c1e5f7426d2718
                               at src/libcore/fmt/mod.rs:1076
   5:     0x5564c17b73f2 - std::io::Write::write_fmt::hf3afc6cfd57d0033
                               at src/libstd/io/mod.rs:1537
   6:     0x5564c17bb440 - std::sys_common::backtrace::_print::hfc0110703f3696fd
                               at src/libstd/sys_common/backtrace.rs:62
   7:     0x5564c17bb440 - std::sys_common::backtrace::print::h3f77c6990ddfaa22
                               at src/libstd/sys_common/backtrace.rs:49
   8:     0x5564c17bb440 - std::panicking::default_hook::{{closure}}::heae49580a8d62d75
                               at src/libstd/panicking.rs:198
   9:     0x5564c17bb18c - std::panicking::default_hook::hecc34e3f729e213c
                               at src/libstd/panicking.rs:217
  10:     0x5564c17bba83 - std::panicking::rust_panic_with_hook::he82f5d0644692441
                               at src/libstd/panicking.rs:526
  11:     0x5564c17bb67b - rust_begin_unwind
                               at src/libstd/panicking.rs:437
  12:     0x5564c17d5151 - core::panicking::panic_fmt::h09c929f06bb87c98
                               at src/libcore/panicking.rs:85
  13:     0x5564c17d509d - core::panicking::panic::h7ece43057e5422d4
                               at src/libcore/panicking.rs:50
  14:     0x5564c17a6bf1 - core::mem::uninitialized::hb13e4a6bd3d9fb2f
                               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/mem/mod.rs:664
  15:     0x5564c17a6bf1 - mpi::request::Request<S>::into_raw::haa729e7e2738a9f3
                               at /home/cuhksz_csc/.cargo/registry/src/github.com-1ecc6299db9ec823/mpi-0.5.4/src/request.rs:109
  16:     0x5564c17a6ce7 - mpi::request::Request<S>::wait_with::hc3e821c32602b74e
                               at /home/cuhksz_csc/.cargo/registry/src/github.com-1ecc6299db9ec823/mpi-0.5.4/src/request.rs:121
  17:     0x5564c17a6a10 - mpi::request::Request<S>::wait::h344d92dd4ef4055e
                               at /home/cuhksz_csc/.cargo/registry/src/github.com-1ecc6299db9ec823/mpi-0.5.4/src/request.rs:144
  18:     0x5564c17a7be4 - <mpi::request::WaitGuard<S> as core::ops::drop::Drop>::drop::h99e86b377587ee7f
                               at /home/cuhksz_csc/.cargo/registry/src/github.com-1ecc6299db9ec823/mpi-0.5.4/src/request.rs:234
  19:     0x5564c17a7a32 - core::ptr::drop_in_place::h056458675d996bd3
                               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
  20:     0x5564c17a9067 - trans_sort::main::{{closure}}::h0b6ea2009f297340
                               at src/main.rs:55
  21:     0x5564c17a6de2 - mpi::request::scope::h388effd1a74050b9
                               at /home/cuhksz_csc/.cargo/registry/src/github.com-1ecc6299db9ec823/mpi-0.5.4/src/request.rs:403
  22:     0x5564c17a6638 - trans_sort::main::haba3f992747c3029
                               at src/main.rs:19
  23:     0x5564c17a7c5b - std::rt::lang_start::{{closure}}::heb816d03eafe061e
                               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/rt.rs:67
  24:     0x5564c17bbe53 - std::rt::lang_start_internal::{{closure}}::h5d3ea623498f5f43
                               at src/libstd/rt.rs:52
  25:     0x5564c17bbe53 - std::panicking::try::do_call::hac65e71be769a440
                               at src/libstd/panicking.rs:348
  26:     0x5564c17bbe53 - std::panicking::try::hd4706e264bcf6712
                               at src/libstd/panicking.rs:325
  27:     0x5564c17bbe53 - std::panic::catch_unwind::h948a0fb4a8b3ee82
                               at src/libstd/panic.rs:394
  28:     0x5564c17bbe53 - std::rt::lang_start_internal::h72cc068ed2d0ac53
                               at src/libstd/rt.rs:51
  29:     0x5564c17a7c37 - std::rt::lang_start::h335e4fe997dbbc83
                               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/rt.rs:67
  30:     0x5564c17a67ea - main
  31:     0x7f4f98c26b97 - __libc_start_main
  32:     0x5564c17a612a - _start
  33:                0x0 - <unknown>

What does the version of clang need?

Hello!

I tried to compile example/simple and I had an error "thread 'main' panicked at 'function not loaded: clang_Type_getNumTemplateArguments', ../.cargo/registry/src/github.com-1ecc6299db9ec823/clang-sys-0.21.2/src/lib.rs:1456:1"

I have:
clang version 7.0.0 (trunk 326027) (llvm/trunk 326026)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/clang/bin

On another PC I have:
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

And it works.

Derive macro for the Equivalence trait

Hi,

I wrote a derive macro to automatically implement the mpi::datatype::Equivalence trait on plain structures: rsmpi-derive.
However I'm new to Rust and not experienced with MPI, so the quality may be low.

Is this a good place to share it and look for feedback?
Should I publish it on crates.io, and is it OK to use the name mpi-derive?

Regards,
Brice DAVIER

The example does not compile on Arch Linux

If I try to compile the example code in the readme with Arch I run into issue #64.

If I instead change to the git version mpi = { git = "https://github.com/bsteinb/rsmpi" } I get

error: multiple packages link to native library `clang`, but a native library can be linked only once

package `clang-sys v0.21.2`
    ... which is depended on by `bindgen v0.31.3`
    ... which is depended on by `libffi-sys v0.6.3`
    ... which is depended on by `libffi v0.6.4`
    ... which is depended on by `mpi v0.5.4 (https://github.com/bsteinb/rsmpi#09668b8e)`
    ... which is depended on by `mpi v0.1.0 (/home/ben/mpi)`
links to native library `clang`

package `clang-sys v0.28.0`
    ... which is depended on by `bindgen v0.49.0`
    ... which is depended on by `mpi-sys v0.1.2 (https://github.com/bsteinb/rsmpi#09668b8e)`
    ... which is depended on by `mpi v0.5.4 (https://github.com/bsteinb/rsmpi#09668b8e)`
    ... which is depended on by `mpi v0.1.0 (/home/ben/mpi)`
also links to native library `clang`

Bindgen Cargo dependencies cause rsmpi build to fail

syntex_syntax is the dependency that fails to build and is relied on by bindgen. Below, is the output of a cargo build on a Linux x64 system using the MPICH implementation:

➜  mpi-test git:(master) ✗ cargo run
   Compiling custom_derive v0.1.4
   Compiling rustc-serialize v0.3.16
   Compiling bindgen v0.15.0
   Compiling winapi-build v0.1.1
   Compiling libc v0.2.5
   Compiling unicode-xid v0.0.3
   Compiling bitflags v0.4.0
   Compiling libc v0.1.12
   Compiling winapi v0.2.5
   Compiling gcc v0.3.21
   Compiling conv v0.3.1
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/libc-0.1.12/rust/src/liblibc/lib.rs:81:21: 81:39 warning: lint raw_pointer_derive has been removed: using derive with raw pointers is ok
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/libc-0.1.12/rust/src/liblibc/lib.rs:81 #![allow(bad_style, raw_pointer_derive)]
                                                                                                                                                       ^~~~~~~~~~~~~~~~~~
   Compiling kernel32-sys v0.2.1
   Compiling log v0.3.5
   Compiling term v0.4.0
   Compiling syntex_syntax v0.7.0
<rustc_bitflags macros>:8:29: 8:43 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:8 bits : $ value } ; ) + impl $ crate:: __core:: fmt:: Debug for $ BitFlags {
                                                      ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:8:29: 8:43 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:8:29: 8:59 error: use of undeclared trait name `rustc_bitflags::__core::fmt::Debug` [E0405]
<rustc_bitflags macros>:8 bits : $ value } ; ) + impl $ crate:: __core:: fmt:: Debug for $ BitFlags {
                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:8:29: 8:59 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:9:29: 9:43 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:9 fn fmt ( & self , f : & mut $ crate:: __core:: fmt:: Formatter ) -> $ crate::
                                                      ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:9:29: 9:43 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:9:29: 9:63 error: use of undeclared type name `rustc_bitflags::__core::fmt::Formatter` [E0412]
<rustc_bitflags macros>:9 fn fmt ( & self , f : & mut $ crate:: __core:: fmt:: Formatter ) -> $ crate::
                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:9:29: 9:63 help: run `rustc --explain E0412` to see a detailed explanation
<rustc_bitflags macros>:9:69: 10:5 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>: 9 fn fmt ( & self , f : & mut $ crate:: __core:: fmt:: Formatter ) -> $ crate::
<rustc_bitflags macros>:10 __core:: fmt:: Result {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:9:69: 10:5 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:9:69: 10:22 error: use of undeclared type name `rustc_bitflags::__core::fmt::Result` [E0412]
<rustc_bitflags macros>: 9 fn fmt ( & self , f : & mut $ crate:: __core:: fmt:: Formatter ) -> $ crate::
<rustc_bitflags macros>:10 __core:: fmt:: Result {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:9:69: 10:22 help: run `rustc --explain E0412` to see a detailed explanation
<rustc_bitflags macros>:14:42: 14:56 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:14 self_ : & super:: $ BitFlags , f : & mut $ crate:: __core:: fmt:: Formatter )
                                                                    ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:14:42: 14:56 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:14:42: 14:76 error: use of undeclared type name `rustc_bitflags::__core::fmt::Formatter` [E0412]
<rustc_bitflags macros>:14 self_ : & super:: $ BitFlags , f : & mut $ crate:: __core:: fmt:: Formatter )
                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:14:42: 14:76 help: run `rustc --explain E0412` to see a detailed explanation
<rustc_bitflags macros>:15:4: 15:18 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:15 -> $ crate:: __core:: fmt:: Result {
                              ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:15:4: 15:18 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:15:4: 15:35 error: use of undeclared type name `rustc_bitflags::__core::fmt::Result` [E0412]
<rustc_bitflags macros>:15 -> $ crate:: __core:: fmt:: Result {
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:15:4: 15:35 help: run `rustc --explain E0412` to see a detailed explanation
<rustc_bitflags macros>:33:50: 33:64 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:33  # [ inline ] pub fn from_bits ( bits : $ T ) -> $ crate:: __core:: option::
                                                                            ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:33:50: 33:64 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:33:50: 34:22 error: use of undeclared type name `rustc_bitflags::__core::option::Option` [E0412]
<rustc_bitflags macros>:33  # [ inline ] pub fn from_bits ( bits : $ T ) -> $ crate:: __core:: option::
<rustc_bitflags macros>:34 Option < $ BitFlags > {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:33:50: 34:22 help: run `rustc --explain E0412` to see a detailed explanation
<rustc_bitflags macros>:36:1: 36:15 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:36 $ crate:: __core:: option:: Option:: None } else {
                           ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:36:1: 36:15 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:36:1: 36:42 error: unresolved name `rustc_bitflags::__core::option::Option::None` [E0425]
<rustc_bitflags macros>:36 $ crate:: __core:: option:: Option:: None } else {
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:36:1: 36:42 help: run `rustc --explain E0425` to see a detailed explanation
<rustc_bitflags macros>:37:1: 37:15 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:37 $ crate:: __core:: option:: Option:: Some ( $ BitFlags { bits : bits } ) } }
                           ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:37:1: 37:15 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:37:1: 37:42 error: unresolved name `rustc_bitflags::__core::option::Option::Some` [E0425]
<rustc_bitflags macros>:37 $ crate:: __core:: option:: Option:: Some ( $ BitFlags { bits : bits } ) } }
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:37:1: 37:42 help: run `rustc --explain E0425` to see a detailed explanation
<rustc_bitflags macros>:59:40: 59:54 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:59 self . bits ^= other . bits ; } } impl $ crate:: __core:: ops:: BitOr for $
                                                                  ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:59:40: 59:54 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:59:40: 59:70 error: use of undeclared trait name `rustc_bitflags::__core::ops::BitOr` [E0405]
<rustc_bitflags macros>:59 self . bits ^= other . bits ; } } impl $ crate:: __core:: ops:: BitOr for $
                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:59:40: 59:70 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:63:59: 63:73 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:63 $ BitFlags { bits : self . bits | other . bits } } } impl $ crate:: __core::
                                                                                     ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:63:59: 63:73 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:63:59: 64:13 error: use of undeclared trait name `rustc_bitflags::__core::ops::BitXor` [E0405]
<rustc_bitflags macros>:63 $ BitFlags { bits : self . bits | other . bits } } } impl $ crate:: __core::
<rustc_bitflags macros>:64 ops:: BitXor for $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:63:59: 64:13 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:68:59: 68:73 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:68 $ BitFlags { bits : self . bits ^ other . bits } } } impl $ crate:: __core::
                                                                                     ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:68:59: 68:73 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:68:59: 69:13 error: use of undeclared trait name `rustc_bitflags::__core::ops::BitAnd` [E0405]
<rustc_bitflags macros>:68 $ BitFlags { bits : self . bits ^ other . bits } } } impl $ crate:: __core::
<rustc_bitflags macros>:69 ops:: BitAnd for $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:68:59: 69:13 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:73:59: 73:73 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:73 $ BitFlags { bits : self . bits & other . bits } } } impl $ crate:: __core::
                                                                                     ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:73:59: 73:73 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:73:59: 74:10 error: use of undeclared trait name `rustc_bitflags::__core::ops::Sub` [E0405]
<rustc_bitflags macros>:73 $ BitFlags { bits : self . bits & other . bits } } } impl $ crate:: __core::
<rustc_bitflags macros>:74 ops:: Sub for $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:73:59: 74:10 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:78:61: 78:75 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:78 $ BitFlags { bits : self . bits & ! other . bits } } } impl $ crate:: __core::
                                                                                       ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:78:61: 78:75 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:78:61: 79:10 error: use of undeclared trait name `rustc_bitflags::__core::ops::Not` [E0405]
<rustc_bitflags macros>:78 $ BitFlags { bits : self . bits & ! other . bits } } } impl $ crate:: __core::
<rustc_bitflags macros>:79 ops:: Not for $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:78:61: 79:10 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:82:70: 83:5 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:82 $ BitFlags { bits : ! self . bits } & $ BitFlags:: all (  ) } } impl $ crate::
<rustc_bitflags macros>:83 __core:: iter:: FromIterator < $ BitFlags > for $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:82:70: 83:5 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:82:70: 83:44 error: use of undeclared trait name `rustc_bitflags::__core::iter::FromIterator` [E0405]
<rustc_bitflags macros>:82 $ BitFlags { bits : ! self . bits } & $ BitFlags:: all (  ) } } impl $ crate::
<rustc_bitflags macros>:83 __core:: iter:: FromIterator < $ BitFlags > for $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:82:70: 83:44 help: run `rustc --explain E0405` to see a detailed explanation
<rustc_bitflags macros>:84:20: 84:34 error: failed to resolve. Maybe a missing `extern crate rustc_bitflags`? [E0433]
<rustc_bitflags macros>:84 fn from_iter < T : $ crate:: __core:: iter:: IntoIterator < Item = $ BitFlags
                                              ^~~~~~~~~~~~~~
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:84:20: 84:34 help: run `rustc --explain E0433` to see a detailed explanation
<rustc_bitflags macros>:84:20: 85:2 error: use of undeclared trait name `rustc_bitflags::__core::iter::IntoIterator` [E0405]
<rustc_bitflags macros>:84 fn from_iter < T : $ crate:: __core:: iter:: IntoIterator < Item = $ BitFlags
<rustc_bitflags macros>:85 >> ( iterator : T ) -> $ BitFlags {
<rustc_bitflags macros>:91:1: 93:63 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
/Users/jalmeida/.multirust/toolchains/stable/cargo/registry/src/github.com-88ac128001ac3a9a/syntex_syntax-0.7.0/src/parse/parser.rs:88:1: 93:2 note: in this expansion of bitflags! (defined in <rustc_bitflags macros>)
<rustc_bitflags macros>:84:20: 85:2 help: run `rustc --explain E0405` to see a detailed explanation
error: aborting due to 30 previous errors
Could not compile `syntex_syntax`.

To learn more, run the command again with --verbose.
➜  mpi-test git:(master) ✗

Make libffi dependency an optional, default feature

On one of the platforms I'm running on, the libffi dependency fails to build. Since it seems like the libffi use is not required in general usage of the API, it would be nice to be able to remove the libffi dependency by making it an optional, default feature in the Cargo manifest.

It would be helpful if an additional UserOperation constructor could be added that takes a simple function pointer rather than a closure, though for my use case mpi::ffi will suffice.

Require unsafe for receive operations on types with invalid bit patterns, like bool

12/6/2019: May be overzealous to make everything unsafe. Tentatively, we just need to make it unsafe to receive into types with invalid bit patterns, like bool and structs. We could potentially provide a "safe" version with a little overhead to check the output buffer.


Original issue: Mis-matching datatypes when performing communication results in undefined behavior.

Documentation should indicate that the unsafe here need not infect the whole code base. A routine that properly matches its own communications is itself safe. You only get unsafety if another routine incorrectly matches their own sends and receives. Ergo, it is possible to expose a safe interface on top of MPI communications, even if the atoms are unsafe.

See #51 for discussion on this.

Relicense under dual MIT/Apache-2.0

This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic on IRC to discuss.

You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.

TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that
license is good for interoperation. The MIT license as an add-on can be nice
for GPLv2 projects to use your code.

Why?

The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.

Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it
.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.

How?

To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright) and then add the following to
your README:

## License

Licensed under either of
 * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.

and in your license headers, use the following boilerplate (based on that used in Rust):

// Copyright (c) 2016 rsmpi developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these
from the Rust repo for a plain-text
version.

And don't forget to update the license metadata in your Cargo.toml to:

license = "MIT/Apache-2.0"

I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!

Contributor checkoff

To agree to relicensing, comment with :

I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option

Or, if you're a contributor, you can check the box in this repo next to your
name. My scripts will pick this exact phrase up and check your checkbox, but
I'll come through and manually review this issue later as well.

Check that code is formatted in CI

It's kind of irritating when I go to make a change, but the code isn't already formatted. It would be nice if the CI checked that the code was formatted so all merges resulted in a formatted code base.

Building with --no-default-features fails

It looks like too many use statements are being gated on the "user-operations" feature.

It might be worth adding a CI test for this case.

pn1707994:rsmpi agaspar$ cargo mpirun --no-default-features --example immediate
   Compiling mpi v0.5.1 (file:///Users/agaspar/Code/rsmpi)
error[E0433]: failed to resolve. Use of undeclared type or module `fmt`
    --> src/collective.rs:1678:6
     |
1678 | impl fmt::Debug for UnsafeUserOperation {
     |      ^^^ Use of undeclared type or module `fmt`

error[E0433]: failed to resolve. Use of undeclared type or module `fmt`
    --> src/collective.rs:1679:27
     |
1679 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     |                           ^^^ Use of undeclared type or module `fmt`

error[E0433]: failed to resolve. Use of undeclared type or module `fmt`
    --> src/collective.rs:1679:46
     |
1679 |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     |                                              ^^^ Use of undeclared type or module `fmt`

error[E0412]: cannot find type `c_void` in this scope
    --> src/collective.rs:1705:31
     |
1705 |     unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_int, *mut ffi::MPI_Datatype);
     |                               ^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
     |
12   | use std::os::raw::c_void;
     |

error[E0412]: cannot find type `c_void` in this scope
    --> src/collective.rs:1705:44
     |
1705 |     unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_int, *mut ffi::MPI_Datatype);
     |                                            ^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
     |
12   | use std::os::raw::c_void;
     |

error[E0412]: cannot find type `c_int` in this scope
    --> src/collective.rs:1705:57
     |
1705 |     unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_int, *mut ffi::MPI_Datatype);
     |                                                         ^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
     |
12   | use std::os::raw::c_int;
     |

error: cannot continue compilation due to previous error

error: Could not compile `mpi`.

To learn more, run the command again with --verbose.

Tracking Issue: Multiple Completion of Requests

Just putting some notes here on some observations from using this library -

It's kind of a pain point right now that there's no MPI_Waitall equivalent in this library. It's not too bad since you can always use mpi::ffi, but the interop experience with the existing mpi::request::Request object is poor. MPI_Waitall expects a contiguous array of MPI_Request objects, but the definition of Request makes it impossible to satisfy this requirement without allocating a separate slice of MPI_Request objects, since each MPI_Request is separated by a Scope object.

The easiest and most naive option would be to just add a wait_all operation that takes a slice (or perhaps an Iterator) of mpi::request::Request objects. It would have to internally move the MPI_Request handles into a contiguous array. APIs like MPI_Waitsome or MPI_Waitany would have some additional indirection, since they must invalidate some of the MPI_Request objects that are passed in, but not all of them. You would need to pass in a &mut [Option<mpi::request::Request>], and then wait_some or wait_any would need to update the slice to remove any request objects that have been completed.

I don't love this option since it imposes overhead in the name of keeping the API simple, especially for any calls that are likely to be called many times on the same set of requests such as MPI_Waitsome, MPI_Waitany, MPI_Testsome, and MPI_Testany.

The second option is to add some sort of RequestCollection object. For example:

pub struct RequestCollection<'a, S: Scope<'a> = StaticScope> {
    requests: Vec<MPI_Request>,
    scope: S,
    phantom: PhantomData<Cell<&'a ()>>,
}

This would allow the layout of the request objects to be directly composable with existing MPI_ multiple completion operations, while still tracking the request objects via the Scope.

This type would ideally have these features:

  • It can be constructed from an iterator of mpi::request::Request objects, or via a .push(request) operation. This allows all existing APIs to be used to construct mpi::request::Request objects that will then be added to the collection.
  • It would have member routines such as wait_all, wait_some, test_some, etc.
  • It would support stable indexing.
  • It likely would have to return Option<Request> rather than Request when indexing since wait_* may invalidate request objects.

Awaiting a new release with support of MS-MPI

Hi! Thank you for your excellent work! Today I could successfully install your library on macOS and Windows 10. Unfortunately, there was some trouble with Windows initially. Therefore, I would like to suggest to update the documentation so that it would be easier for others to install rsmpi on Windows. It seems there is a lack of documentation in the Internet.

So, I had to install clang+LLVM after MS-MPI, then I had to use the recent Git version of rsmpi instead of that one, which is currently known as release 0.5.4. The release has no support of MS-MPI. Finally, when creating a dependency on the cloned rsmpi repository, I had to reset the default features in Cargo.toml so that they would not use libffi, which I could not build with help of MSYS2. It seems that libffi has indeed some issues on Windows. Only then I could use rsmpi on Windows 10.

Thus, I am actually asking when are you going to make a new release with support of MS-MPI? Also I'm interesting in that how are you going to treat the mentioned Windows-only issue with default features? Probably, it could be documented in some way.

Thanks,
David Sorokin

LocalScope Drop impl is not panic safe

This code with no uses of unsafe leaks a buffer to MPI.

use mpi::traits::*;

fn main() {
    let universe = mpi::initialize().unwrap();

    let comm = universe.world();

    {
        let x = 0.0;
        std::panic::catch_unwind(|| {
            mpi::request::scope(|scope| {
                // Leaks the Request
                std::mem::forget(
                    comm.process_at_rank(comm.rank()).immediate_send(scope, &x),
                );
            });
        });
    }

    println!("Oh no, we leaked a buffer to MPI without unsafe!")
}

We probably need to change the Drop impl for LocalScope to a call to std::process::abort.

No-longer builds with openMPI 1.1.x

I haven't had time to check much further, but it seems rsmpi no-longer builds with openMPI 1.1.6/7

src/ffi/rsmpi.h:32:14: error: unknown type name 'MPI_Message', err: true
src/ffi/rsmpi.h:33:14: error: unknown type name 'MPI_Message', err: true

Just the above error. I compiled and installed openMPI 2.2.1 from source, and rsmpi builds fine. I'll be submitting a PR to update openSUSE to use 2.2.1 soon so hopefully this will become a non-issue (for openSUSE at least).

I couldn't compile example

Hello!
I read the issue #15
and after that I tried to compile example "simple" from the branch rsmpi (bindgen-hack)
But I received error:

Compiling mpi v0.4.0 (file:///.../rsmpi)
error[E0425]: unresolved name bindgen::get_include_dir
--> build.rs:43:38
|
43 | if let Some(clang_include_dir) = bindgen::get_include_dir() {
| ^^^^^^^^^^^^^^^^^^^^^^^^ unresolved name

error: aborting due to previous error

Translate MPI thread support levels into Rust Send and Sync

MPI defines several levels of thread support that indicate "how thread safe" the currently initialized MPI environment is. This level is only known at run-time and could be changed by re-initializing MPI (?).

In Rust, the thread safety of an API is defined by having its types implement the Send and Sync traits, which is a compile-time contract.

These traits are automatically derived by the compiler which currently leads to wrong results for rsmpi, e.g.:

  • when building against MPICH which uses integers for its handle types, the Rust compiler always deem them safe to Send and Sync,
  • when building against OpenMPI which uses pointers for its handle types, the Rust compiler will always deem them not safe to Send and Sync.

Plan: Add markers to rsmpi types so they can have variants that statically are or are not thread safe and have sources such as world() or equivalent_type() return enum values that return one of those variants depending on the current level of thread support of the environment.

Strange Error Codes

I executed the send_receive.rs example. My GCC version is 4.9.2 on a cluster running CentOS 6. My MPICH is 3.1.4. The program seems to produce the correct output except that it is returning strange error codes from Status (see attached). I also tried a few other examples and this behavior happened for them as well. Do you know what might be causing this? My rust-bindgen is using a libclang.so file instead of a libclang.a file but otherwise nothing else seems to be different.

foo.txt

Profiling

Is it possible to profile your rsmpi using application with a MPI aware profiler like VampirTrace or Valgrind?

Excuse me, if this is not the place to ask such questions.

Add MPI implementation detection to build-probe-mpi

It should be possible to detect the version of MPI being built against. One of the main reasons to do this is that it allows us to patch around issues in specific MPI implementations.

OpenMPI: Look for ompi_info next to mpicc
MPICH: Look for mpichversion next to mpicc
Intel MPI: impi_info -h
Spectrum MPI: ompi_info, but look for e.g. Spectrum MPI: 10.3.0.01rtm3
MS-MPI: Already done.

We'll want to output cfgs that correspond to each of these so they can be used in the rsmpi code for feature detection. build-probe-mpi should add some capability to just automatically output all the cfgs so it's easy for downstream crates to get all the same cfgs.

Considerations:
Intel MPI is based off MPICH and Spectrum MPI is based off OpenMPI - should they emit cfg=openmpi and cfg=mpich respectively, in addition to vendor-specific cfgs? I think probably so.

MPICH ignores input buffer size in `MPI_Unpack`

MPICH completely ignores the input buffer size in MPI_Unpack, which is a soundness problem. #79 (comment)

We need to consider the broader implications of this. Does this effect receive routines, too?

To address this, we need to add checks to Communicator::unpack_into. However, this only needs to be done for MPICH. Requires #102

Run on several processes

Hello, bsteinb!

Thanks for your previous answer on my question!!!
But I've one more Q, may be a stupid one, but important for me:
If I compiled in C then I would enter such commands to run, for example, 10 processes:
mpicc test.c –o test.o
mpirun –np 10 test.o

How can I do like this using your Lib and Rust?
For example: simple.rs run on 10 processes.

We should initialize it here, right? :
let universe = mpi::initialize().unwrap();
let world = universe.world();
let size = world.size();
let rank = world.rank();
But how?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.