Commit 9a9de155 authored by Matthieu Dorier's avatar Matthieu Dorier
Browse files

added tests for sendrecv, barrier, and bcast, and refactores cmake file

parent 41261961
......@@ -376,7 +376,51 @@ na_return_t mona_comm_bcast(
// - scatter recursive doubling allgather
// - scatter ring allgather
// These could be added as alternatives
int rank, comm_size, src, dst;
int relative_rank, mask;
na_return_t na_ret;
comm_size = comm->size;
rank = comm->rank;
// If there is only one process, return
if(comm_size == 1)
return NA_SUCCESS;
relative_rank = (rank >= root) ? rank - root : rank - root + comm_size;
// Use short message algorithm, namely, binomial tree
// operations to recieve the data
mask = 0x1;
while(mask < comm_size) {
if(relative_rank & mask) {
src = rank - mask;
if(src < 0) src += comm_size;
na_ret = mona_comm_recv(comm, buf, size, src, tag, NULL, NULL, NULL);
if(na_ret != NA_SUCCESS) {
return na_ret;
}
break;
}
mask <<= 1;
}
mask >>= 1;
// operations to send the data
while(mask > 0) {
if(relative_rank + mask < comm_size) {
dst = rank + mask;
if(dst >= comm_size) dst -= comm_size;
na_ret = mona_comm_send(comm, buf, size, dst, tag);
if(na_ret != NA_SUCCESS) {
return na_ret;
}
}
mask >>= 1;
}
return na_ret;
#if 0
na_return_t na_ret;
int i = 0, r = 0;
int comm_size = (int)comm->size;
......@@ -400,11 +444,13 @@ na_return_t mona_comm_bcast(
continue;
if(relative_dst == relative_rank) {
src = (r + root) % comm_size;
printf("Rank %d receives from rank %d\n", rank, src);
na_ret = mona_comm_recv(comm, buf, size, src, tag, NULL, NULL, NULL);
if(na_ret != NA_SUCCESS) goto fn_exit;
}
if(r == relative_rank) {
dst = (relative_dst + root) % comm_size;
printf("Rank %d sends to rank %d\n", rank, dst);
na_ret = mona_comm_isend(comm, buf, size, dst, tag, reqs + req_count);
if(na_ret != NA_SUCCESS) goto fn_exit;
}
......@@ -423,6 +469,7 @@ na_return_t mona_comm_bcast(
fn_exit:
free(reqs);
return na_ret;
#endif
}
typedef struct ibcast_args {
......
add_executable (test-init test-init.c munit/munit.c)
target_include_directories (test-init PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-init mona)
add_executable (test-send-recv test-send-recv.c munit/munit.c)
target_include_directories (test-send-recv PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-send-recv mona)
add_executable (test-send-recv-self test-send-recv-self.c munit/munit.c)
target_include_directories (test-send-recv-self PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-send-recv-self mona)
add_executable (test-isend-irecv test-isend-irecv.c munit/munit.c)
target_include_directories (test-isend-irecv PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-isend-irecv mona)
add_executable (test-isend-irecv-multi test-isend-irecv-multi.c munit/munit.c)
target_include_directories (test-isend-irecv-multi PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-isend-irecv-multi mona)
add_executable (test-send-recv-unexpected test-send-recv-unexpected.c munit/munit.c)
target_include_directories (test-send-recv-unexpected PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-send-recv-unexpected mona)
add_executable (test-send-recv-expected test-send-recv-expected.c munit/munit.c)
target_include_directories (test-send-recv-expected PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-send-recv-expected mona)
add_executable (test-put-get test-put-get.c munit/munit.c)
target_include_directories (test-put-get PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-put-get mona)
add_executable (test-na test-na.c munit/munit.c)
target_include_directories (test-na PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-na mona)
add_executable (test-send-recv-coll test-send-recv-coll.c munit/munit.c)
target_include_directories (test-send-recv-coll PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (test-send-recv-coll mona)
add_test (NAME TestInit COMMAND ./test-init)
add_test (NAME TestSendRecv COMMAND mpirun -np 2 ./test-send-recv --no-fork)
add_test (NAME TestSendRecvSelf COMMAND mpirun -np 2 ./test-send-recv-self --no-fork)
add_test (NAME TestISendIRecv COMMAND mpirun -np 2 ./test-isend-irecv --no-fork)
add_test (NAME TestISendIRecvMulti COMMAND mpirun -np 2 ./test-isend-irecv-multi --no-fork)
add_test (NAME TestSendRecvUnexpected COMMAND mpirun -np 2 ./test-send-recv-unexpected --no-fork)
add_test (NAME TestSendRecvExpected COMMAND mpirun -np 2 ./test-send-recv-expected --no-fork)
add_test (NAME TestPutGet COMMAND mpirun -np 2 ./test-put-get --no-fork)
add_test (NAME TestNA COMMAND mpirun -np 2 ./test-na --no-fork)
add_test (NAME TestSendRecvColl COMMAND mpirun -np 2 ./test-send-recv-coll --no-fork)
function (add_munit_test)
set(prefix MUNIT_TEST)
set(flags MPI)
set(singleValues NAME NUM_PROCS)
set(multiValues SOURCES)
include(CMakeParseArguments)
cmake_parse_arguments(${prefix}
"${flags}"
"${singleValues}"
"${multiValues}"
${ARGN})
add_executable (${MUNIT_TEST_NAME} ${MUNIT_TEST_SOURCES} munit/munit.c)
target_include_directories (${MUNIT_TEST_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/munit
${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_link_libraries (${MUNIT_TEST_NAME} mona)
if(${MUNIT_TEST_MPI})
add_test(NAME ${MUNIT_TEST_NAME} COMMAND mpirun -np ${MUNIT_TEST_NUM_PROCS} ${CMAKE_CURRENT_BINARY_DIR}/${MUNIT_TEST_NAME} --no-fork)
else()
add_test(NAME ${MUNIT_TEST_NAME} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${MUNIT_TEST_NAME} --no-fork)
endif()
endfunction ()
# Base API tests
add_munit_test (NAME TestNA MPI NUM_PROCS 2 SOURCES test-na.c)
add_munit_test (NAME TestInit SOURCES test-init.c)
add_munit_test (NAME TestSendRecv MPI NUM_PROCS 2 SOURCES test-send-recv.c)
add_munit_test (NAME TestISendIRecv MPI NUM_PROCS 2 SOURCES test-isend-irecv.c)
add_munit_test (NAME TestISendIRecvMulti MPI NUM_PROCS 2 SOURCES test-isend-irecv-multi.c)
#add_munit_test (NAME TestSendRecvSelf MPI NUM_PROCS 2 SOURCES test-send-recv-self.c)
add_munit_test (NAME TestSendRecvUnexpected MPI NUM_PROCS 2 SOURCES test-send-recv-unexpected.c)
add_munit_test (NAME TestSendRecvExpected MPI NUM_PROCS 2 SOURCES test-send-recv-expected.c)
add_munit_test (NAME TestPutGet MPI NUM_PROCS 2 SOURCES test-put-get.c)
# Collective API tests
add_munit_test (NAME TestSendRecvColl MPI NUM_PROCS 2 SOURCES test-send-recv-coll.c)
add_munit_test (NAME TestBarrier MPI NUM_PROCS 5 SOURCES test-barrier.c)
add_munit_test (NAME TestBcast MPI NUM_PROCS 5 SOURCES test-bcast.c)
#include <mpi.h>
#include "munit/munit.h"
#include "mona.h"
#include "mona-coll.h"
typedef struct {
mona_instance_t mona;
mona_comm_t comm;
} test_context;
static void* test_context_setup(const MunitParameter params[], void* user_data)
{
(void)params;
(void)user_data;
int ret;
MPI_Init(NULL, NULL);
ABT_init(0, NULL);
mona_instance_t mona = mona_init("ofi+tcp", NA_TRUE, NULL);
na_addr_t self_addr;
ret = mona_addr_self(mona, &self_addr);
munit_assert_int(ret, ==, NA_SUCCESS);
char self_addr_str[128];
na_size_t self_addr_size = 128;
ret = mona_addr_to_string(mona, self_addr_str, &self_addr_size, self_addr);
munit_assert_int(ret, ==, NA_SUCCESS);
int num_procs;
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
char* other_addr_str = malloc(128*num_procs);
MPI_Allgather(self_addr_str, 128, MPI_BYTE,
other_addr_str, 128, MPI_BYTE,
MPI_COMM_WORLD);
na_addr_t* other_addr = malloc(num_procs*sizeof(*other_addr));
int i;
for(i = 0; i < num_procs; i++) {
ret = mona_addr_lookup(mona, other_addr_str + 128*i, other_addr + i);
munit_assert_int(ret, ==, NA_SUCCESS);
}
free(other_addr_str);
mona_comm_t comm;
ret = mona_comm_create(mona, num_procs, other_addr, &comm);
munit_assert_int(ret, ==, NA_SUCCESS);
for(i = 0; i < num_procs; i++) {
ret = mona_addr_free(mona, other_addr[i]);
munit_assert_int(ret, ==, NA_SUCCESS);
}
free(other_addr);
test_context* context = (test_context*)calloc(1, sizeof(*context));
context->mona = mona;
context->comm = comm;
return context;
}
static void test_context_tear_down(void* fixture)
{
MPI_Barrier(MPI_COMM_WORLD);
test_context* context = (test_context*)fixture;
mona_comm_free(context->comm);
mona_finalize(context->mona);
free(context);
ABT_finalize();
MPI_Finalize();
}
static MunitResult test_barrier(const MunitParameter params[], void* data)
{
(void)params;
test_context* context = (test_context*)data;
na_return_t ret;
ret = mona_comm_barrier(context->comm, 1234);
munit_assert_int(ret, ==, NA_SUCCESS);
return MUNIT_OK;
}
static MunitTest test_suite_tests[] = {
{ (char*) "/barrier", test_barrier, test_context_setup, test_context_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
static const MunitSuite test_suite = {
(char*) "/mona/collectives", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
};
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
return munit_suite_main(&test_suite, (void*) "mona", argc, argv);
}
#include <mpi.h>
#include "munit/munit.h"
#include "mona.h"
#include "mona-coll.h"
typedef struct {
mona_instance_t mona;
mona_comm_t comm;
} test_context;
static void* test_context_setup(const MunitParameter params[], void* user_data)
{
(void)params;
(void)user_data;
int ret;
MPI_Init(NULL, NULL);
ABT_init(0, NULL);
mona_instance_t mona = mona_init("ofi+tcp", NA_TRUE, NULL);
na_addr_t self_addr;
ret = mona_addr_self(mona, &self_addr);
munit_assert_int(ret, ==, NA_SUCCESS);
char self_addr_str[128];
na_size_t self_addr_size = 128;
ret = mona_addr_to_string(mona, self_addr_str, &self_addr_size, self_addr);
munit_assert_int(ret, ==, NA_SUCCESS);
int num_procs;
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
char* other_addr_str = malloc(128*num_procs);
MPI_Allgather(self_addr_str, 128, MPI_BYTE,
other_addr_str, 128, MPI_BYTE,
MPI_COMM_WORLD);
na_addr_t* other_addr = malloc(num_procs*sizeof(*other_addr));
int i;
for(i = 0; i < num_procs; i++) {
ret = mona_addr_lookup(mona, other_addr_str + 128*i, other_addr + i);
munit_assert_int(ret, ==, NA_SUCCESS);
}
free(other_addr_str);
mona_comm_t comm;
ret = mona_comm_create(mona, num_procs, other_addr, &comm);
munit_assert_int(ret, ==, NA_SUCCESS);
for(i = 0; i < num_procs; i++) {
ret = mona_addr_free(mona, other_addr[i]);
munit_assert_int(ret, ==, NA_SUCCESS);
}
free(other_addr);
test_context* context = (test_context*)calloc(1, sizeof(*context));
context->mona = mona;
context->comm = comm;
return context;
}
static void test_context_tear_down(void* fixture)
{
MPI_Barrier(MPI_COMM_WORLD);
test_context* context = (test_context*)fixture;
mona_comm_free(context->comm);
mona_finalize(context->mona);
free(context);
ABT_finalize();
MPI_Finalize();
}
static MunitResult test_bcast(const MunitParameter params[], void* data)
{
(void)params;
test_context* context = (test_context*)data;
na_return_t ret;
int rank, size, i;
ret = mona_comm_size(context->comm, &size);
munit_assert_int(ret, ==, NA_SUCCESS);
ret = mona_comm_rank(context->comm, &rank);
munit_assert_int(ret, ==, NA_SUCCESS);
char buf[10000];
memset(buf, 0, 10000);
int value = rank == 0 ? 42 : 0;
// small broadcast from rank 0
ret = mona_comm_bcast(context->comm, &value, sizeof(value), 0, 1234);
munit_assert_int(ret, ==, NA_SUCCESS);
munit_assert_int(value, ==, 42);
// small broadcast from another root
int root = size/2;
value = rank == root ? 4563 : 0;
ret = mona_comm_bcast(context->comm, &value, sizeof(value), root, 1234);
munit_assert_int(ret, ==, NA_SUCCESS);
munit_assert_int(value, ==, 4563);
if(rank == 0) {
memset(buf, 'A', 10000);
}
// large broadcast from rank 0
ret = mona_comm_bcast(context->comm, buf, 10000, 0, 1234);
munit_assert_int(ret, ==, NA_SUCCESS);
for(i = 0; i < 10000; i++) {
munit_assert_int(buf[i], ==, 'A');
}
memset(buf, 0, 10000);
// small broadcast from another root
if(rank == root) {
memset(buf, 'B', 10000);
}
ret = mona_comm_bcast(context->comm, buf, 10000, root, 1234);
munit_assert_int(ret, ==, NA_SUCCESS);
for(i = 0; i < 10000; i++) {
munit_assert_int(buf[i], ==, 'B');
}
return MUNIT_OK;
}
static MunitTest test_suite_tests[] = {
{ (char*) "/bcast", test_bcast, test_context_setup, test_context_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};
static const MunitSuite test_suite = {
(char*) "/mona/collectives", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
};
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
return munit_suite_main(&test_suite, (void*) "mona", argc, argv);
}
......@@ -66,6 +66,7 @@ static MunitResult test_send_recv(const MunitParameter params[], void* data)
na_return_t ret;
mona_instance_t mona = context->mona;
int i;
char* buf = malloc(8192);
na_size_t msg_len = 8192;
mona_comm_t comm;
......@@ -77,7 +78,6 @@ static MunitResult test_send_recv(const MunitParameter params[], void* data)
munit_assert_int(ret, ==, NA_SUCCESS);
if(context->rank == 0) { // sender
int i;
for(i = 0; i < (int)msg_len; i++) {
buf[i] = i % 32;
}
......@@ -94,7 +94,6 @@ static MunitResult test_send_recv(const MunitParameter params[], void* data)
}
} else { // receiver
int i;
na_size_t recv_size;
ret = mona_comm_recv(comm, buf, msg_len, 0, 1234, &recv_size, NULL, NULL);
......@@ -111,6 +110,30 @@ static MunitResult test_send_recv(const MunitParameter params[], void* data)
munit_assert_int(ret, ==, NA_SUCCESS);
}
// test sendrecv function
memset(buf, 0, msg_len);
for(i = 0; i < (int)msg_len/2; i++) {
int j = i + context->rank*msg_len/2;
buf[j] = 'A' + context->rank;
}
ret = mona_comm_sendrecv(comm,
buf + context->rank*msg_len/2,
msg_len/2,
(context->rank + 1) % 2,
1234,
buf + ((context->rank + 1)%2)*msg_len/2,
msg_len/2,
(context->rank + 1) % 2,
1234,
NULL, NULL, NULL);
munit_assert_int(ret, ==, NA_SUCCESS);
for(i = 0; i < (int)msg_len; i++) {
char expected = i < (int)msg_len/2 ? 'A' : 'B';
munit_assert_int(buf[i], ==, expected);
}
ret = mona_comm_free(comm);
munit_assert_int(ret, ==, NA_SUCCESS);
return MUNIT_OK;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment