rust_mpi/
lib.rs

1extern crate libc;
2use libc::{c_int, c_char, c_void};
3
4use std::ptr;
5use std::default::Default;
6
7mod constants;
8pub use constants::*;
9mod types;
10pub use types::*;
11
12pub type MpiComm = c_int;
13pub type MpiDatatype = c_int;
14pub type MpiOp = c_int;
15
16// This, again, seems to only be valid for MPICH.
17#[repr(C)]
18#[derive(Default)]
19pub struct MPI_Status {
20    count_lo: c_int,
21    count_hi_and_cancelled: c_int,
22    mpi_source: c_int,
23    mpi_tag: c_int,
24    mpi_error: c_int,
25}
26
27#[link(name = "mpi")]
28extern "C" {
29    fn MPI_Init(argc: *const c_int, argv: *const c_char) -> c_int;
30    fn MPI_Finalize() -> c_int;
31    fn MPI_Comm_rank(comm: MpiComm, rank: *mut c_int) -> c_int;
32    fn MPI_Comm_size(comm: MpiComm, size: *mut c_int) -> c_int;
33    fn MPI_Send(buf: *const c_void, count: c_int, datatype: MpiDatatype, dest: c_int,
34        tag: c_int, comm: MpiComm) -> c_int;
35    fn MPI_Recv(buf: *mut c_void, count: c_int, datatype: MpiDatatype, source: c_int,
36        tag: c_int, comm: MpiComm, status: *mut MPI_Status) -> c_int;
37}
38
39pub fn mpi_init() -> i32 {
40    unsafe {
41        let argc = ptr::null();
42        let argv = ptr::null();
43        let ret = MPI_Init(argc, argv);
44        return ret;
45    }
46}
47
48pub fn mpi_finalize() -> i32 {
49    unsafe {
50        let ret = MPI_Finalize();
51        return ret;
52    }
53}
54
55pub fn mpi_comm_rank(comm: MpiComm, rank: *mut i32) -> i32 {
56    unsafe {
57        let c_comm:MpiComm = comm as MpiComm;
58        let ret: i32 = MPI_Comm_rank(c_comm, rank);
59        return ret;
60    }
61}
62
63pub fn mpi_comm_size(comm: MpiComm, size: *mut i32) -> i32 {
64    unsafe {
65        let c_comm:MpiComm = comm as MpiComm;
66        let ret: i32 = MPI_Comm_size(c_comm, size);
67        return ret;
68    }
69}
70
71pub fn mpi_send_scalar<T: MpiType>(buf: &T, dest: i32, tag: i32, comm: MpiComm) -> i32 {
72    unsafe {
73        let c_buf: *const c_void = buf as *const _ as *const c_void;
74        let count = 1;
75        let mpi_type = buf.get_mpi_type();
76        let ret: i32 = MPI_Send(c_buf, count, mpi_type, dest, tag, comm);
77        return ret;
78    }
79}
80
81pub fn mpi_send_slice<T: MpiType + Default>(buf: &[T], dest: i32, tag: i32, comm: MpiComm) -> i32 {
82    unsafe {
83        let c_buf: *const c_void = buf.as_ptr() as *const c_void;
84        let count = buf.len() as i32;
85        // Meh, a bit of a faff. Better than getting 0th value since count may be 0.
86        let array_type: T = Default::default();
87        let mpi_type = array_type.get_mpi_type();
88        let ret: i32 = MPI_Send(c_buf, count, mpi_type, dest, tag, comm);
89        return ret;
90    }
91}
92
93pub fn mpi_recv_scalar<T: MpiType>(buf: &mut T, dest: i32, tag: i32, comm: MpiComm) -> i32 {
94    unsafe {
95        let mut status: MPI_Status = Default::default();
96        let c_buf: *mut c_void = buf as *mut _ as *mut c_void;
97        let count = 1;
98        let mpi_type = buf.get_mpi_type();
99        let ret: i32 = MPI_Recv(c_buf, count, mpi_type, dest, tag, comm, &mut status);
100        return ret;
101    }
102}
103
104pub fn mpi_recv_slice<T: MpiType + Default>(buf: &mut [T], dest: i32, tag: i32, comm: MpiComm) -> i32 {
105    unsafe {
106        let mut status: MPI_Status = Default::default();
107        let c_buf: *mut c_void = buf.as_ptr() as *mut c_void;
108        let count = buf.len() as i32;
109        // Meh, a bit of a faff. Better than getting 0th value since count may be 0.
110        let array_type: T = Default::default();
111        let mpi_type = array_type.get_mpi_type();
112        let ret: i32 = MPI_Recv(c_buf, count, mpi_type, dest, tag, comm, &mut status);
113        return ret;
114    }
115}
116
117#[cfg(test)]
118mod test;