NSSC/Exercise_01/examples/MPI_Send_Recv.cpp

79 lines
2.7 KiB
C++
Raw Normal View History

2022-03-11 17:52:38 +00:00
/**
* Compile
* mpic++ MPI_Send_Recv.cpp -Wall -pedantic -Wpedantic -o MPI_Send_Recv
* Usage
* mpirun -n 4 ./MPI_Send_Recv
*
* Note: An easy way to finde the location of the `mpi.h` file is
* mpic++ --showme:compile
* which might be usefull to configure the intellicense.
*/
#include <iostream>
#include <sstream>
#include <mpi.h>
/** min of two ints (fine for an example) */
int min(int a, int b) { return a < b ? a : b; }
int main(int argn, char* argv[]) {
// Initialize MPI (always required)
MPI_Init(nullptr, nullptr);
// Allocate MPI Settings
int mpi_size; /*< Number of processes */
int mpi_rank; /*< This process rank (a.k.a. the MPI process ID) */
// Set/Get MPI Settings
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
// Write MPI info to stdout
std::cout << "Hello World, i am rank " << mpi_rank << " of " << mpi_size
<< " processes." << std::endl;
// setting this to small truncates the message (Try it, works fine.)
constexpr int max_size = 128; /*< Maximum message length */
// Distinguish between rank 0 and the rest
if (mpi_rank == 0) {
// Send a different message to all other ranks
for (int rank = 1; rank < mpi_size; ++rank) {
// Build message
std::ostringstream message;
message << "Hello rank nr. " << rank;
std::string sendbuf = message.str();
// Send message
MPI_Send(sendbuf.c_str(), min(max_size, sendbuf.size()),
MPI_CHAR, rank, sendbuf.size(), MPI_COMM_WORLD);
// Note: the tag beeing set to the string length (hacky, but :-})
}
// Report your done
std::cout << "Done: rank 0 send all messages." << std::endl;
} else {
char recvbuf[max_size]; /*< MPI_Recv buffer, e.g. memory to write to */
MPI_Status status; /*< MPI Status object, e.g. communication info */
// Each rank listens for a single message from rank 0
MPI_Recv(recvbuf, max_size,
MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
if (status.MPI_ERROR) {
std::cerr << "Error: Recv reported an Error?!" << std::endl;
} else {
// Ensure C-style string is terminated and of propper size as
// the tag encodes the string length.
// Should be null terminated, but better save than sorry.
recvbuf[min(max_size - 1, status.MPI_TAG)] = '\0';
// Print receved message to console
std::cout << "Recv: " << recvbuf << std::endl;
}
}
// Shutdown MPI (always required)
MPI_Finalize();
return 0;
}