mpi_fork_fnsp/
lib.rs

1#![deny(missing_docs)]
2#![warn(missing_copy_implementations)]
3#![warn(trivial_casts)]
4#![warn(trivial_numeric_casts)]
5#![warn(unused_extern_crates)]
6#![warn(unused_import_braces)]
7#![warn(unused_qualifications)]
8#![allow(renamed_and_removed_lints)]
9#![allow(clippy::needless_doctest_main)]
10#![warn(clippy::cast_possible_truncation)]
11#![warn(clippy::cast_possible_wrap)]
12#![warn(clippy::cast_precision_loss)]
13#![warn(clippy::cast_sign_loss)]
14#![warn(clippy::enum_glob_use)]
15#![warn(clippy::mut_mut)]
16#![warn(clippy::mutex_integer)]
17#![warn(clippy::non_ascii_literal)]
18#![warn(clippy::nonminimal_bool)]
19#![warn(clippy::option_unwrap_used)]
20#![warn(clippy::result_unwrap_used)]
21#![warn(clippy::single_match_else)]
22#![warn(clippy::string_add)]
23#![warn(clippy::string_add_assign)]
24#![warn(clippy::unicode_not_nfc)]
25#![warn(clippy::wrong_pub_self_convention)]
26#![allow(clippy::unseparated_literal_suffix)]
27#![allow(clippy::must_use_candidate)]
28//! Message Passing Interface bindings for Rust
29//!
30//! The [Message Passing Interface][MPI] (MPI) is a specification for a
31//! message-passing style concurrency library. Implementations of MPI are often used to structure
32//! parallel computation on High Performance Computing systems. The MPI specification describes
33//! bindings for the C programming language (and through it C++) as well as for the Fortran
34//! programming language. This library tries to bridge the gap into a more rustic world.
35//!
36//! [MPI]: http://www.mpi-forum.org
37//!
38//!
39//! This crate is forked from [RSMPI](https://github.com/rsmpi/rsmpi).
40//!
41//! # Main differences to original library
42//! - Uses most recent version, older version on crates.io does not compile
43//! - Add support for complex numbers
44//! - Merge workspace into a single crate
45//!
46//! # Usage
47//!
48//! Add the `mpi` crate as a dependency in your `Cargo.toml`:
49//!
50//! ```toml
51//! [dependencies]
52//! mpi = { path = "mpi-fork-fnsp",  version = "0.6" }
53//! ```
54//!
55//! Then use it in your program like this:
56//!
57//! ```no_run
58//! extern crate mpi_fork_fnsp as mpi;
59//!
60//! use mpi::traits::*;
61//!
62//! fn main() {
63//!     let universe = mpi::initialize().unwrap();
64//!     let world = universe.world();
65//!     let size = world.size();
66//!     let rank = world.rank();
67//!
68//!     if size != 2 {
69//!         panic!("Size of MPI_COMM_WORLD must be 2, but is {}!", size);
70//!      }
71//!
72//!     match rank {
73//!         0 => {
74//!             let msg = vec![4.0f64, 8.0, 15.0];
75//!             world.process_at_rank(rank + 1).send(&msg[..]);
76//!         }
77//!         1 => {
78//!             let (msg, status) = world.any_process().receive_vec::<f64>();
79//!             println!("Process {} got message {:?}.\nStatus is: {:?}", rank, msg, status);
80//!         }
81//!         _ => unreachable!()
82//!     }
83//! }
84//! ```
85//!
86//! # Features
87//!
88//! The bindings follow the MPI 3.1 specification.
89//!
90//! Currently supported:
91//!
92//! - **Groups, Contexts, Communicators**:
93//!   - Group and (Intra-)Communicator management from section 6 is mostly complete.
94//!   - no Inter-Communicators
95//!   - no process topologies
96//! - **Point to point communication**:
97//!   - standard, buffered, synchronous and ready mode send in blocking and non-blocking variants
98//!   - receive in blocking and non-blocking variants
99//!   - send-receive
100//!   - probe
101//!   - matched probe/receive
102//! - **Collective communication**:
103//!   - barrier
104//!   - broadcast
105//!   - (all) gather
106//!   - scatter
107//!   - all to all
108//!   - varying counts operations
109//!   - reductions/scans
110//!   - blocking and non-blocking variants
111//! - **Datatypes**: Bridging between Rust types and MPI basic types as well as custom MPI datatypes
112//! which can act as views into buffers.
113//!
114//! Not supported (yet):
115//!
116//! - Process management
117//! - One-sided communication (RMA)
118//! - MPI parallel I/O
119//! - A million small things
120//!
121//! The sub-modules contain a more detailed description of which features are and are not
122//! supported.
123//!
124//! # Further Reading
125//!
126//! While every publicly defined item in this crate should have some documentation attached to it,
127//! most of the descriptions are quite terse for now and to the uninitiated will only make sense in
128//! combination with the [MPI specification][MPIspec].
129//!
130//! [MPIspec]: http://www.mpi-forum.org/docs/docs.html
131use std::mem::MaybeUninit;
132use std::os::raw::c_int;
133pub mod mpi_sys;
134
135/// The raw C language MPI API
136///
137/// Documented in the [Message Passing Interface specification][spec]
138///
139/// [spec]: http://www.mpi-forum.org/docs/docs.html
140#[allow(missing_docs, dead_code, non_snake_case, non_camel_case_types)]
141#[macro_use]
142pub mod ffi {
143    pub use crate::mpi_sys::*;
144}
145pub mod collective;
146pub mod datatype;
147pub mod environment;
148pub mod point_to_point;
149pub mod raw;
150pub mod request;
151pub mod topology;
152
153#[cfg(feature = "derive")]
154pub mod mpi_derive;
155
156/// Re-exports all traits.
157pub mod traits {
158    pub use crate::collective::traits::*;
159    pub use crate::datatype::traits::*;
160    pub use crate::point_to_point::traits::*;
161    pub use crate::raw::traits::*;
162    pub use crate::topology::traits::*;
163
164    // Re-export derives
165    #[cfg(feature = "derive")]
166    pub use mpi_derive::Equivalence;
167}
168
169/// These crates are used by mpi-derive, and so must be public, but shouldn't be used by dependent
170/// crates
171#[doc(hidden)]
172pub mod internal {
173    pub use memoffset;
174    pub use once_cell;
175}
176
177#[doc(inline)]
178pub use crate::environment::{
179    initialize, initialize_with_threading, time, time_resolution, Threading,
180};
181
182use crate::ffi::MPI_Aint;
183
184/// Encodes error values returned by MPI functions.
185pub type Error = c_int;
186/// Encodes number of values in multi-value messages.
187pub type Count = c_int;
188/// Can be used to tag messages on the sender side and match on the receiver side.
189pub type Tag = c_int;
190/// An address in memory
191pub type Address = MPI_Aint;
192
193/// `IntArray` is used to translate Rust bool values to and from the int-bool types preferred by MPI
194/// without incurring allocation in the common case.
195type IntArray = smallvec::SmallVec<[c_int; 8]>;
196
197unsafe fn with_uninitialized<F, U, R>(f: F) -> (R, U)
198where
199    F: FnOnce(*mut U) -> R,
200{
201    let mut uninitialized = MaybeUninit::uninit();
202    let res = f(uninitialized.as_mut_ptr());
203    (res, uninitialized.assume_init())
204}
205
206unsafe fn with_uninitialized2<F, U1, U2, R>(f: F) -> (R, U1, U2)
207where
208    F: FnOnce(*mut U1, *mut U2) -> R,
209{
210    let mut uninitialized1 = MaybeUninit::uninit();
211    let mut uninitialized2 = MaybeUninit::uninit();
212    let res = f(uninitialized1.as_mut_ptr(), uninitialized2.as_mut_ptr());
213    (
214        res,
215        uninitialized1.assume_init(),
216        uninitialized2.assume_init(),
217    )
218}