79 lines
2.7 KiB
C++
79 lines
2.7 KiB
C++
|
/**
|
||
|
* 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;
|
||
|
}
|