diff --git a/func/mpi/CMakeLists.txt b/func/mpi/CMakeLists.txt index 8b0be946..b8515c89 100644 --- a/func/mpi/CMakeLists.txt +++ b/func/mpi/CMakeLists.txt @@ -29,6 +29,7 @@ mpi_func(mpi_isendrecv mpi_isendrecv.cpp) mpi_func(mpi_onesided mpi_onesided.cpp) mpi_func(mpi_order mpi_order.cpp) mpi_func(mpi_probe mpi_probe.cpp) +mpi_func(mpi_put mpi_put.cpp) mpi_func(mpi_reduce mpi_reduce.cpp) mpi_func(mpi_reduce_dbl mpi_reduce_dbl.cpp) mpi_func(mpi_scan mpi_scan.cpp) @@ -36,6 +37,7 @@ mpi_func(mpi_scatter mpi_scatter.cpp) mpi_func(mpi_sendrecv mpi_sendrecv.cpp) mpi_func(mpi_status mpi_status.cpp) mpi_func(mpi_typesize mpi_typesize.cpp) +mpi_func(mpi_wincreate mpi_wincreate.cpp) mpi_func(hellompi hellompi.cpp) diff --git a/func/mpi/mpi_put.cpp b/func/mpi/mpi_put.cpp new file mode 100644 index 00000000..19c589bd --- /dev/null +++ b/func/mpi/mpi_put.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +#define NUM_ELEMENT 4 + +int main(int argc, char* argv[]) +{ + MPI_Init(NULL, NULL); + + int rank; + int worldSize; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &worldSize); + + size_t elemSize = sizeof(int); + + int* sharedData; + MPI_Alloc_mem(elemSize * NUM_ELEMENT, MPI_INFO_NULL, &sharedData); + + MPI_Win window; + MPI_Win_create(sharedData, + NUM_ELEMENT * elemSize, + 1, + MPI_INFO_NULL, + MPI_COMM_WORLD, + &window); + MPI_Win_fence(0, window); + + // Put values from rank 1 to rank 0 + int putData[NUM_ELEMENT]; + if (rank == 1) { + for (int i = 0; i < NUM_ELEMENT; i++) { + putData[i] = 10 + i; + } + + MPI_Put( + putData, NUM_ELEMENT, MPI_INT, 0, 0, NUM_ELEMENT, MPI_INT, window); + } + + MPI_Win_fence(0, window); + + // Check expectation on rank 1 + if (rank == 0) { + int expected[NUM_ELEMENT]; + for (int i = 0; i < NUM_ELEMENT; i++) { + expected[i] = 10 + i; + } + + bool asExpected = + faasm::compareArrays(sharedData, expected, NUM_ELEMENT); + if (!asExpected) { + return 1; + } + printf("Rank %i - MPI_Put as expected\n", rank); + } + + MPI_Win_free(&window); + MPI_Finalize(); + + return 0; +} diff --git a/func/mpi/mpi_wincreate.cpp b/func/mpi/mpi_wincreate.cpp new file mode 100644 index 00000000..0bced2cc --- /dev/null +++ b/func/mpi/mpi_wincreate.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include + +#define NUM_ELEMENT 4 + +bool checkIntAttr(MPI_Win window, + int attr, + long expected, + const std::string& name) +{ + void* resPtr; + int flag; + MPI_Win_get_attr(window, attr, (void*)&resPtr, &flag); + + MPI_Aint actual = *reinterpret_cast(resPtr); + + if (actual != expected || flag != 1) { + printf("%s not as expected (%li != %li (%i))\n", + name.c_str(), + actual, + expected, + flag); + return false; + } + + return true; +} + +int main(int argc, char* argv[]) +{ + MPI_Init(NULL, NULL); + + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + int dataSize = sizeof(int); + int* sharedData = new int[NUM_ELEMENT]; + int* expectedPutData = new int[NUM_ELEMENT]; + + // Populate some data in shared region and not + for (int i = 0; i < NUM_ELEMENT; i++) { + sharedData[i] = 10 * rank + i; + expectedPutData[i] = 10 * rank + i; + } + + // Create a window + MPI_Win window; + int winSize = NUM_ELEMENT * dataSize; + MPI_Win_create( + sharedData, winSize, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &window); + + // Check that the memory has not been corrupted (happens when pointer to + // MPI_Win is handled wrongly) + if (rank < 3) { + bool putDataEqual = + faasm::compareArrays(sharedData, expectedPutData, NUM_ELEMENT); + + if (!putDataEqual) { + printf("Rank %i - stack corrupted by win_create\n", rank); + return 1; + } else if (rank < 3) { + printf("Rank %i - stack OK\n", rank); + } + } + + if (rank == 0) { + // Check base of window + void* actualBase; + int baseFlag; + MPI_Win_get_attr(window, MPI_WIN_BASE, &actualBase, &baseFlag); + if (actualBase != sharedData || baseFlag != 1) { + printf("MPI_WIN_BASE not as expected (%p != %p (%i))\n", + actualBase, + sharedData, + baseFlag); + return 1; + } + + // Check size of window + if (!checkIntAttr(window, MPI_WIN_SIZE, winSize, "MPI_WIN_SIZE")) { + return 1; + } + if (!checkIntAttr(window, MPI_WIN_DISP_UNIT, 1, "MPI_WIN_DISP_UNIT")) { + return 1; + } + + printf("Win attr checks complete\n"); + } + + delete[] sharedData; + delete[] expectedPutData; + + MPI_Win_free(&window); + MPI_Finalize(); + + return 0; +}