https://github.com/yaozhenghangma/messaging
Messaging is a modern C++20 MPI wrapper.
https://github.com/yaozhenghangma/messaging
cpp mpi
Last synced: 5 months ago
JSON representation
Messaging is a modern C++20 MPI wrapper.
- Host: GitHub
- URL: https://github.com/yaozhenghangma/messaging
- Owner: yaozhenghangma
- License: apache-2.0
- Created: 2023-06-21T09:06:06.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-06-29T07:59:51.000Z (almost 3 years ago)
- Last Synced: 2024-01-27T07:42:29.889Z (about 2 years ago)
- Topics: cpp, mpi
- Language: C++
- Homepage: https://github.com/yaozhenghangma/Messaging/
- Size: 27.3 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Messaging
[](https://github.com/yaozhenghangma/Messaging/actions/workflows/Open-MPI.yml)
[](https://github.com/yaozhenghangma/Messaging/actions/workflows/MPICH.yml)
[](https://github.com/yaozhenghangma/Messaging/actions/workflows/Intel-MPI.yml)
Messaging is a modern C++20 MPI wrapper, inspired by Boost.MPI and mpi4py.
## Abstract
Multiprocess paralleling using MPI is the standard approach in high-performance
computing. However, implementing message passing can be a tedious task due to the
limited support for data types in MPI. Although there's library like Boost.MPI
that offers high-level interfaces, it necessitates building the entire Boost library,
which can be burdensome for users. In light of this, I decide to
develop this simple library to wrap the basic operators in MPI.
The data serialization part of this library is based on
[zpp_bits](https://github.com/eyalz800/zpp_bits), which is serialization library
only supports C++20 and newer standard. Consequently, to utilize this library, your
project must be set to C++20 or a newer standard.
Since this library is build with CMake toolkit, you can use this library by
simply adding it to subdirectory and linking it. For example:
```cmake
add_subdirectory(lib/Messaging)
target_link_libraries(project_name PUBLIC Messaging)
```
## Usage
### MPI environment
A C++ object named `CommWorld` is provided to set up the environment and communicator.
```c++
#include
#include
int main() {
messaging::CommWorld comm;
int rank = comm.Rank();
int size = comm.Size();
std::cout << "This is the number " << rank << "process of " << size << "processes."
<< std::endl;
return 0;
}
```
### Point-to-point communication
#### Blocking communication
The blocking communication is realized by two methods named `Send` and `Recv`.
```c++
template
messaging::CommWorld::Send(T &data, int dest, int tag);
```
```c++
template
messaging::CommWorld::Recv(T &data, int source, int tag);
```
Parameters:
* data: data to be sent or saved
* dest: rank of processor where the data will be sent to
* source: rank of processor where the data will be sent from
* tag: tag labeling the message
```c++
#include
class Coordinate {
public:
double x;
double y;
double z;
};
int main() {
Coordinate coord;
messaging::CommWorld comm;
if(comm.Rank() == 0) {
coord.x = 0;
coord.y = 1;
coord.z = 2;
comm.Send(coord, 1, 99);
} else if(comm.Rank() == 1) {
comm.Recv(coord, 0, 99);
}
}
```
### Collective communication
#### Broadcast
```c++
template
messaging::CommWorld::Broadcast(T &data, int root);
```
Parameters:
* data: data to be broadcast
* root: rank of the processor that will broadcast data
```c++
#include
class Coordinate {
public:
double x;
double y;
double z;
};
int main() {
messaging::CommWorld comm;
Coordinate coord;
std::vector coord_vec;
int rank = comm.Rank();
int size = comm.Size();
if(rank == 0) {
coord.x = 1;
coord.y = 2;
coord.z = 3;
}
comm.Broadcast(coord, 0);
return 0;
}
```
#### Gather
```c++
template
messaging::CommWorld::Gather(T &data, std::vector &all_data, int root);
```
Parameters:
* data: data to be sent
* all_data: vector to save the gathered data (stored in root processor)
* root: rank of root processor
```c++
#include
class Coordinate {
public:
double x;
double y;
double z;
};
int main() {
messaging::CommWorld comm;
Coordinate coord;
std::vector coord_vec;
int rank = comm.Rank();
int size = comm.Size();
coord.x = rank;
coord.y = rank+10;
coord.z = rank+100;
comm.Gather(coord, coord_vec, 0);
return 0;
}
```
#### Scatter
```c++
template
messaging::CommWorld::Scatter(std::vector &all_data, T &data, int root);
```
Parameters:
* all_data: data to be scattered from root processor
* data: received data
* root: rank of root processor
```c++
#include
class Coordinate {
public:
double x;
double y;
double z;
};
int main() {
messaging::CommWorld comm;
Coordinate coord;
std::vector coord_vec;
int rank = comm.Rank();
int size = comm.Size();
if(rank == 0) {
for(int i=0; i