From 7a188b8f5f96b7349653cc7ba6259cbc5245e2db Mon Sep 17 00:00:00 2001 From: Chris Chambreau Date: Wed, 22 Dec 2021 12:29:51 -0800 Subject: [PATCH] New MPI_T Events tests and example Signed-off-by: Chris Chambreau --- events/Makefile | 33 ++++ events/README.md | 45 +++++ events/events_callbacks.c | 395 ++++++++++++++++++++++++++++++++++++++ events/events_common.c | 248 ++++++++++++++++++++++++ events/events_common.h | 63 ++++++ events/events_dropped.c | 122 ++++++++++++ events/events_example.c | 165 ++++++++++++++++ events/events_meta_data.c | 124 ++++++++++++ events/events_read_data.c | 269 ++++++++++++++++++++++++++ events/events_source.c | 108 +++++++++++ events/events_types.c | 222 +++++++++++++++++++++ 11 files changed, 1794 insertions(+) create mode 100644 events/Makefile create mode 100644 events/README.md create mode 100644 events/events_callbacks.c create mode 100644 events/events_common.c create mode 100644 events/events_common.h create mode 100644 events/events_dropped.c create mode 100644 events/events_example.c create mode 100644 events/events_meta_data.c create mode 100644 events/events_read_data.c create mode 100644 events/events_source.c create mode 100644 events/events_types.c diff --git a/events/Makefile b/events/Makefile new file mode 100644 index 0000000..89c27a2 --- /dev/null +++ b/events/Makefile @@ -0,0 +1,33 @@ + +EXES = events_types events_callbacks events_read_data events_meta_data events_source events_dropped events_example + +CC= mpicc + +CFLAGS= -O2 -g -Wall +LIBS=events_common.o + +def: clean ${EXES} + +events_types : events_types.o events_common.o + $(CC) $(CFLAGS) -o $@ $< ${LIBS} + +events_callbacks : events_callbacks.o events_common.o + $(CC) $(CFLAGS) -o $@ $< ${LIBS} + +events_read_data : events_read_data.o events_common.o + $(CC) $(CFLAGS) -o $@ $< ${LIBS} + +events_meta_data : events_meta_data.o events_common.o + $(CC) $(CFLAGS) -o $@ $< ${LIBS} + +events_source : events_source.o events_common.o + $(CC) $(CFLAGS) -o $@ $< ${LIBS} + +events_dropped : events_dropped.o events_common.o + $(CC) $(CFLAGS) -o $@ $< ${LIBS} + +events_example : events_example.o + $(CC) $(CFLAGS) -o $@ $< + +clean: + rm -f ${EXES} core.* *.o diff --git a/events/README.md b/events/README.md new file mode 100644 index 0000000..454d87e --- /dev/null +++ b/events/README.md @@ -0,0 +1,45 @@ +# MPI_T Events Tests + +If the MPI implementation includes support for the MPI_T Events functions as defined in [MPI Standard 4.0](https://www.mpi-forum.org/docs/mpi-4.0/mpi40-report.pdf) and includes some implemented events, these tests will confirm basic functionality as well as some error checking. + +## Events Callback Test Requirements +In order to confirm the MPI_T Events callback functionality, a callback must be registered and triggered by performing relevant MPI activity. + +The events_types test will print the list of events available by providing the command line '-l' flag. + +The events_callbacks event index can be set for the events_callbacks test with the `-i [number]` flag. + +If the default MPI activity in the function generate\_callback\_activity() in events_common.c does not trigger the event callback, custom MPI activity will need to be added. + +## Test Behavior + +The behavior of each test can be modified with the following command line arguments: + +- -d : print internal debugging messages [default: off] +- -e : print error messages [default: off] +- -f : perform failure tests [default: off] +- -i [number] : event index for specific tests [default: 0] +- -l : list available events (events_types only) [default: off] + +## Test Descriptions + +- events_callbacks + - Register and free a callback function for an event + - Get and set event handle and callback info +- events_dropped + - Register a callback function for dropped events +- events\_meta_data + - Get event timestamp and source +- events\_read_data + - Read and copy event data +- events_source + - Get number of source, source info object, and source timestamp +- events_types + - Get number of events and event info object + +## Event Callback and Read Data Example +The events_example.c file has been provided as an example of registering an event callback and reading event data. + +## Test Suite And MPI Implementations + +Tested with [Open MPI PR #8057](https://github.com/open-mpi/ompi/pull/8057) with pml ob1 module events. \ No newline at end of file diff --git a/events/events_callbacks.c b/events/events_callbacks.c new file mode 100644 index 0000000..805e9dc --- /dev/null +++ b/events/events_callbacks.c @@ -0,0 +1,395 @@ +/* + * events_callbacks.c + * + * Test event callback registration and free + * Test handle and callback get/set info + * + */ + +#include "events_common.h" + +char user_data_string[MAX_STRING] = "Test String"; + +// Test flags +int event_cb_success = 0; +int event_free_cb_success = 0; +int event_free_cb_user_data_access = 1; +int event_handle_get_info_success = 1; +int event_handle_set_info_success = 1; +int event_handle_set_info_updated = 0; +int event_callback_get_info_success = 1; +int event_callback_set_info_success = 1; +int event_callback_set_info_updated = 0; +int event_handle_alloc_event_index_exceed_handled = 1; +int event_handle_alloc_event_index_negative_handled = 1; + + +void print_results() { + + if ( 0 != rank ) return; + + print_pf_result("MPI_T_event_register_callback", "Event Callback Success", event_cb_success); + print_pf_result("MPI_T_event_handle_free", "Event Free Callback Success", event_free_cb_success); + print_pf_result("MPI_T_event_handle_free", "Event Free user_data access", event_free_cb_user_data_access); + print_pf_result("MPI_T_event_handle_get_info", "Successful call", event_handle_get_info_success); + print_pf_result("MPI_T_event_handle_set_info", "Successful call", event_handle_set_info_success); + print_pf_result("MPI_T_event_handle_set_info", "Key added to Info object", event_handle_set_info_updated); + print_pf_result("MPI_T_event_callback_get_info", "Successful call", event_callback_get_info_success); + print_pf_result("MPI_T_event_callback_set_info", "Successful call", event_callback_set_info_success); + print_pf_result("MPI_T_event_callback_set_info", "Key added to Info object", event_callback_set_info_updated); + + if ( do_failure_tests ) { + print_pf_result("MPI_T_event_handle_alloc", "Handled event index too large", event_handle_alloc_event_index_exceed_handled); + print_pf_result("MPI_T_event_handle_alloc", "Handled negative event index", event_handle_alloc_event_index_negative_handled); + } + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "TOTAL ERROR COUNT", metric_width, "", error_count); + +} + + +void test_event_cb_function(MPI_T_event_instance event, MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + print_debug("In cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); + //print_debug("user_data is :%s:\n", (char*)user_data); + //print_debug("user_data_string is :%s:\n", (char*)user_data_string); + + event_cb_success = 1; + + if ( NULL == user_data || strcmp(user_data, user_data_string) ) + print_error("test_event_cb_function could not access user_data", NO_MPI_ERROR_CODE, TEST_CONTINUE); +} + + +void test_free_event_cb_function(MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + print_debug("In cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); + print_debug("user_data is :%s:\n", (char*)user_data); + event_free_cb_success = 1; + if ( NULL == user_data || strcmp(user_data, user_data_string) ) { + print_error("test_event_free_cb_function could not access user_data", NO_MPI_ERROR_CODE, TEST_CONTINUE); + event_free_cb_user_data_access = 0; + } +} + + +void test_handle_alloc_register_free() { + + int retval; + + MPI_T_event_registration event_registration; + + // TEST MPI_T_event_handle_alloc + // + + print_debug("Testing expected success for index %d\n", event_index); + retval = MPI_T_event_handle_alloc(event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &event_registration) ; + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_alloc did not return MPI_SUCCESS", retval, TEST_EXIT); + + + // Test MPI_T_event_handle_alloc invalid arguments + + if ( do_failure_tests ) { + + int bad_event_index; + MPI_T_event_registration bad_event_registration; + + bad_event_index = 11111111; + print_debug("Testing expected failure for index %d\n", bad_event_index); + + retval = MPI_T_event_handle_alloc(bad_event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &bad_event_registration) ; + if ( retval == MPI_SUCCESS ) { + print_error("MPI_T_event_handle_alloc returned MPI_SUCCESS with too large index", retval, TEST_EXIT); + event_handle_alloc_event_index_exceed_handled = 0; + } + else + print_debug("MPI_T_event_handle_alloc handled too large index\n", retval, TEST_EXIT); + + bad_event_index = -1; + print_debug("Testing expected failure for index %d\n", bad_event_index); + + retval = MPI_T_event_handle_alloc(bad_event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &bad_event_registration) ; + if ( retval == MPI_SUCCESS ) { + print_error("MPI_T_event_handle_alloc returned MPI_SUCCESS with negative index", retval, TEST_EXIT); + event_handle_alloc_event_index_negative_handled = 0; + } + else + print_debug("MPI_T_event_handle_alloc handled negative index\n", retval, TEST_EXIT); + } + + + // TEST MPI_T_event_register_callback + // + cb_user_data = (void*)user_data_string; + print_debug("cb_user_data is %s\n", cb_user_data); + + print_debug("Testing expected MPI_T_event_register_callback success for index %d\n", event_index); + retval = MPI_T_event_register_callback(event_registration, MPI_T_CB_REQUIRE_ASYNC_SIGNAL_SAFE, MPI_INFO_NULL, cb_user_data, test_event_cb_function); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_register_callback did not return MPI_SUCCESS", retval, TEST_EXIT); + + if ( do_failure_tests ) { + } + + generate_callback_activity(); + + //} + + // TEST MPI_T_event_handle_free + // + + retval = MPI_T_event_handle_free(event_registration, cb_user_data, test_free_event_cb_function); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_free did not return MPI_SUCCESS", retval, TEST_EXIT); + + if ( do_failure_tests ) { + } + +} + +void print_info_obj(MPI_Info info) { + + int i, retval, vallen = MPI_MAX_INFO_VAL, nkeys, flag; + char key[MPI_MAX_INFO_KEY]; + char value[MPI_MAX_INFO_VAL+1]; + + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + print_debug("MPI_Info_get_nkeys nkeys is %d\n", nkeys); + + for ( i = 0; i < nkeys; i++ ) { + + MPI_Info_get_nthkey( info, i, key ); + retval = MPI_Info_get( info, key, vallen, value, &flag ); + if ( retval != MPI_SUCCESS ) { + print_error("MPI_Info_get did not return MPI_SUCCESS", retval, TEST_CONTINUE); + } + else + print_debug("Info entry index %2d - %d:%s:%s:%d\n", i, flag, key, value); + } + +} + + +void test_info() { + + int retval, vallen = MPI_MAX_INFO_VAL, nkeys, flag, initial_nkeys = 0; + MPI_T_event_registration event_registration; + char key[MPI_MAX_INFO_KEY]; + char value[MPI_MAX_INFO_VAL+1]; + MPI_Info info; + MPI_T_cb_safety cb_safety = MPI_T_CB_REQUIRE_ASYNC_SIGNAL_SAFE; + + // + // Tests + // + // - Test for successful calls to all get/set info + // - Check to see if set info calls add values for get calls + // - Record initial nkeys count + // - Add unique key + // - get_info + // - See if nkeys has increased + + + // + // Set Up Test + // + // Allocate a handle to use for testing + retval = MPI_T_event_handle_alloc(event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &event_registration) ; + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_alloc did not return MPI_SUCCESS", retval, TEST_EXIT); + + + // + // Get Handle Info + // + retval = MPI_T_event_handle_get_info(event_registration, &info); + + if ( retval != MPI_SUCCESS ) { + print_error("MPI_T_event_handle_get_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + event_handle_get_info_success = 0; + } + + + // + // Get And Store Handle Info Key Count + // + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + else + initial_nkeys = nkeys; + + print_debug("MPI_Info_get_nkeys nkeys is %d\n", nkeys); + + + // + // Add Entry To Handle Info + // + retval = MPI_Info_set(info, "randomkey", "randomkeyvalue"); + if ( retval != MPI_SUCCESS ) + print_error("MPI_info_set did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + print_info_obj(info); + + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + print_debug("After MPI_Info_set, MPI_Info_get_nkeys nkeys is %d\n", nkeys); + + + // + // Confirm Entry Has Been Added + // + MPI_Info_get_nthkey( info, 0, key ); + retval = MPI_Info_get( info, key, vallen, value, &flag ); + if ( retval != MPI_SUCCESS ) { + print_error("MPI_Info_get did not return MPI_SUCCESS", retval, TEST_CONTINUE); + } + else + print_debug("Verifying that info values are %d:%s:%s:%d\n", flag, key, value); + + + // + // Set Handle Info + // + retval = MPI_T_event_handle_set_info(event_registration, info); + if ( retval != MPI_SUCCESS ) { + print_error("MPI_T_event_handle_set_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + event_handle_set_info_success = 0; + } + + // + // Get Event Handle Info + // + retval = MPI_T_event_handle_get_info(event_registration, &info); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_get_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + // + // Test For Increase In Nkeys To Confirm Update + // + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + if ( nkeys > initial_nkeys ) + event_handle_set_info_updated = 1; + else + print_error("MPI_T_event_handle_set_info did not update info object", NO_MPI_ERROR_CODE, TEST_CONTINUE); + + print_debug("MPI_T_event_handle_get_info nkeys is %d\n", nkeys); + + + + // Register Callback + retval = MPI_T_event_register_callback(event_registration, cb_safety, MPI_INFO_NULL, cb_user_data, test_event_cb_function); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_register_callback did not return MPI_SUCCESS", retval, TEST_EXIT); + + // + // Get Handle Info + // + retval = MPI_T_event_callback_get_info(event_registration, cb_safety, &info); + + if ( retval != MPI_SUCCESS ) { + print_error("MPI_T_event_callback_get_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + event_callback_get_info_success = 0; + } + + + // + // Get And Store Callback Info Key Count + // + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + else + initial_nkeys = nkeys; + + print_debug("MPI_Info_get_nkeys nkeys is %d\n", nkeys); + + + // + // Add Entry To Callback Info + // + retval = MPI_Info_set(info, "randomkey", "randomkeyvalue"); + if ( retval != MPI_SUCCESS ) + print_error("MPI_info_set did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + print_info_obj(info); + + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + print_debug("After MPI_Info_set, MPI_Info_get_nkeys nkeys is %d\n", nkeys); + + + // + // Confirm Entry Has Been Added + // + MPI_Info_get_nthkey( info, 0, key ); + retval = MPI_Info_get( info, key, vallen, value, &flag ); + if ( retval != MPI_SUCCESS ) { + print_error("MPI_Info_get did not return MPI_SUCCESS", retval, TEST_CONTINUE); + } + else + print_debug("Verifying that info values are %d:%s:%s:%d\n", flag, key, value); + + + // + // Set Callback Info + // + retval = MPI_T_event_callback_set_info(event_registration, cb_safety, info); + if ( retval != MPI_SUCCESS ) { + print_error("MPI_T_event_callback_set_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + event_callback_set_info_success = 0; + } + + // + // Get Event Callback Info + // + retval = MPI_T_event_callback_get_info(event_registration, cb_safety, &info); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_callback_get_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + // + // Test For Increase In Nkeys To Confirm Update + // + retval = MPI_Info_get_nkeys(info, &nkeys); + if ( retval != MPI_SUCCESS ) + print_error("MPI_Info_get_nkeys did not return MPI_SUCCESS", retval, TEST_CONTINUE); + + if ( nkeys > initial_nkeys ) + event_callback_set_info_updated = 1; + else + print_error("MPI_T_event_callback_set_info did not update info object", NO_MPI_ERROR_CODE, TEST_CONTINUE); + + print_debug("MPI_T_event_callback_get_info nkeys is %d\n", nkeys); +} + + +int main (int argc, char** argv) +{ + + test_init("MPI_T Events Callback Tests", argc, argv); + + test_handle_alloc_register_free(); + + test_info(); + + print_results(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} + diff --git a/events/events_common.c b/events/events_common.c new file mode 100644 index 0000000..1708843 --- /dev/null +++ b/events/events_common.c @@ -0,0 +1,248 @@ +/* + * events_common.c + * + * Common functionality available for all events tests + * + */ + +#include "events_common.h" +#include + + +FILE* errout; +int error_count = 0; +int print_events = 0; +int print_errors = 0; +int debug_level = 0; +int do_failure_tests = 0; +int event_index = 0; +char *cb_user_data; +int rank, wsize; +FILE *outstream; +int func_width = 35; +int metric_width = 35; +char *pass_str = "PASS"; +char *fail_str = "FAIL"; + + +char* bind_str(int b) +{ + + switch(b) { + case MPI_T_BIND_NO_OBJECT: + return "No Binding"; + break; + case MPI_T_BIND_MPI_COMM: + return "Communicator Binding"; + break; + case MPI_T_BIND_MPI_DATATYPE: + return "Datatype Binding"; + break; + case MPI_T_BIND_MPI_ERRHANDLER: + return "Errorhandler Binding"; + break; + case MPI_T_BIND_MPI_FILE: + return "File Binding"; + break; + case MPI_T_BIND_MPI_GROUP: + return "Group Binding"; + break; + case MPI_T_BIND_MPI_OP: + return "Reduction Op Binding"; + break; + case MPI_T_BIND_MPI_REQUEST: + return "Request Binding"; + break; + case MPI_T_BIND_MPI_WIN: + return "Windows Binding"; + break; + case MPI_T_BIND_MPI_MESSAGE: + return "Message Binding"; + break; + case MPI_T_BIND_MPI_INFO: + return "Info Binding"; + break; + } + + return "Undefined binding"; +} + + +void generate_callback_activity() { + +#define GENERATE_BUFFER_SIZE 32 + + char buf[GENERATE_BUFFER_SIZE]; + int i, lim = 4; + MPI_Status stat; + MPI_Request req; + + print_debug("In %s %s %d\n", __func__, __FILE__, __LINE__); + + + if ( wsize < 2 ) { + print_error("Need at least 2 MPI processes to generate activity", NO_MPI_ERROR_CODE, TEST_CONTINUE); + return; + } + + for ( i = 0; i < lim; i++ ) { + if ( rank == 0 ) { + strcpy(cb_user_data, "Irecv"); + MPI_Irecv(buf, GENERATE_BUFFER_SIZE, MPI_CHAR, 1, 27, MPI_COMM_WORLD, &req); + } + else { + strcpy(buf, "cat"); + strcpy(cb_user_data, "Isend"); + MPI_Isend(buf, GENERATE_BUFFER_SIZE, MPI_CHAR, 0, 27, MPI_COMM_WORLD, &req); + } + + strcpy(cb_user_data, "Wait"); + MPI_Wait(&req, &stat); + + strcpy(cb_user_data, "Barrier"); + MPI_Barrier(MPI_COMM_WORLD); + } +} + + +void print_error(char *errstr, int errcode, int exit_flag) { + + FILE* errout = stderr; + char mpi_err_msg[MPI_MAX_ERROR_STRING]; + int mpi_err_msg_len = MPI_MAX_ERROR_STRING - 1; + + if ( rank > 0 ) return; + + error_count++; + + if ( print_errors ) { + if ( errcode != NO_MPI_ERROR_CODE ) { + if ( errcode != -18 ) { + MPI_Error_string(errcode, mpi_err_msg, &mpi_err_msg_len); + } + else { + strcpy(mpi_err_msg, "Encountered error with code -18"); + } + + fprintf(errout, "*** ERROR: %s - %s\n", errstr, mpi_err_msg); + } + else { + fprintf(errout, "*** ERROR: %s\n", errstr); + } + } + + if ( 0 != exit_flag ) { + + fprintf(errout, "Exiting.\n"); + exit(-1); + } +} + + + +void print_debug(const char * format, ... ) { + va_list args; + + va_start (args, format); + + if ( rank > 0 ) return; + if ( debug_level ) { + fprintf (errout, "DEBUG: "); + vfprintf (errout, format, args); + } + + va_end (args); +} + +void get_options(int ac, char **av) { + + int c; + + while (1) + { + static struct option long_options[] = + { + {"print-debug", no_argument, 0, 'd'}, + {"print-errors", no_argument, 0, 'e'}, + {"do-failure-tests", no_argument, 0, 'f'}, + {"event-index", required_argument, 0, 'i'}, + {"print-events", no_argument, 0, 'l'}, + {0, 0, 0, 0} + }; + + int option_index = 0; + + c = getopt_long (ac, av, "defi:l", long_options, &option_index); + + if (c == -1) + break; + + switch (c) + { + case 'd': + debug_level = 1; + break; + + case 'e': + print_errors = 1; + break; + + case 'f': + do_failure_tests = 1; + break; + + case 'i': + event_index = atoi(optarg); + break; + + case 'l': + print_events = 1; + break; + + case '?': + break; + + default: + break; + } + } +} + + +void test_init(char *test_name, int ac, char**av) { + + int retval; + + errout = stderr; + outstream = stdout; + + retval = MPI_Init(&ac, &av); + + if (MPI_SUCCESS != retval) { + print_error("Failed to initialize MPI", retval, TEST_EXIT); + } + + get_options(ac, av); + + MPI_Comm_size(MPI_COMM_WORLD, &wsize); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + int required = MPI_THREAD_SINGLE; + int provided = 0; + + retval = MPI_T_init_thread(required, &provided); + + if (MPI_SUCCESS != retval) { + print_error("Failed to initialize MPI tool interface", retval, TEST_EXIT); + } + + if ( 0 == rank ) { + fprintf(outstream, "\n\n%s\n\n", test_name); + } +} + + +void print_pf_result(char* function, char *testname, int flag) { + fprintf(outstream, "%-*s - %-*s : %6s\n", func_width, function, metric_width, testname, flag ? pass_str : fail_str); +} + diff --git a/events/events_common.h b/events/events_common.h new file mode 100644 index 0000000..c66155a --- /dev/null +++ b/events/events_common.h @@ -0,0 +1,63 @@ +/* + * events_common.h + * + * Common functionality available for all events tests + * + */ + +#if !defined INCLUDE_EVENT_COMMON +#include +#include +#include +#include +#include +#include + +#define MAX_STRING 4096 + +enum { TEST_CONTINUE = 0, TEST_EXIT = 1 }; +typedef struct event_info_t { + int event_index; + char *name; + int name_len; + int verbosity; + MPI_Datatype *array_of_datatypes; + MPI_Aint *array_of_displacements; + int num_elements; + MPI_T_enum enumtype; + MPI_Info info; + char *desc; + int desc_len; + int bind; + +} EVENT_INFO; + +extern FILE* errout; +extern int error_count; +extern int print_events; +extern int debug_level; +extern int print_errors; +extern int do_failure_tests; +extern int event_index; +extern char *cb_user_data; +extern int rank; +extern int wsize; +extern FILE *outstream; +extern int func_width; +extern int metric_width; +extern char *pass_str; +extern char *fail_str; + +enum { NO_MPI_ERROR_CODE = -1 }; + +extern char* bind_str(int b); +extern void print_error(char *errstr, int errcode, int exit_flag); +extern void print_debug(const char * format, ... ); +extern void generate_callback_activity(void); +extern void generate_callback_activity_1proc(void); +extern void test_init(char *test_name, int ac, char**av); +extern void print_pf_result(char* function, char *testname, int flag); + + +#define INCLUDE_EVENT_COMMON +#endif diff --git a/events/events_dropped.c b/events/events_dropped.c new file mode 100644 index 0000000..5e5e687 --- /dev/null +++ b/events/events_dropped.c @@ -0,0 +1,122 @@ +/* + * events_dropped.c + * + * Test dropped event callback registration and execution + * + */ + +#include "events_common.h" + + +char user_data_string[256] = "Test String"; + +// Test flags +int event_cb_success = 0; +int event_free_cb_success = 0; +int event_free_cb_user_data_access = 1; +int event_handle_get_info_success = 1; +int event_handle_set_info_success = 1; +int event_handle_set_info_updated = 0; +int event_callback_get_info_success = 1; +int event_callback_set_info_success = 1; +int event_callback_set_info_updated = 0; +int event_handle_alloc_event_index_exceed_handled = 1; +int event_handle_alloc_event_index_negative_handled = 1; + +int event_set_dropped_handler_success = 0; +int event_dropped_cb_success = 0; + + +void print_results() { + + if ( 0 != rank ) return; + + if ( 0 == event_dropped_cb_success ) + error_count++; + + print_pf_result("MPI_T_event_set_dropped_handler", "Event Set Dropped Callback Success", event_set_dropped_handler_success); + print_pf_result("MPI_T_event_set_dropped_handler", "Event Set Dropped Callback Called", event_dropped_cb_success); + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "TOTAL ERROR COUNT", metric_width, "", error_count); + +} + + +void test_event_dropped_cb_function(MPI_Count count, MPI_T_event_registration event_registration, int source_index, MPI_T_cb_safety cb_safety, void *user_data) { + + print_debug("In dropped_cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); + //print_debug("user_data is :%s:\n", (char*)user_data); + //print_debug("user_data_string is :%s:\n", (char*)user_data_string); + + event_dropped_cb_success = 1; + + if ( NULL == user_data || strcmp(user_data, user_data_string) ) + print_error("test_event_cb_function could not access user_data", NO_MPI_ERROR_CODE, TEST_CONTINUE); +} + + +void test_dropped() { + + int i, retval; + + /* + * int MPI_T_event_set_dropped_handler( + * MPI_T_event_registration event_registration, + * MPI_T_event_dropped_cb_function dropped_cb_function) + * + * typedef void MPI_T_event_dropped_cb_function(MPI_Count count, + * MPI_T_event_registration event_registration, int source_index, + * MPI_T_cb_safety cb_safety, void *user_data); + * + */ + int event_index; + MPI_T_event_registration event_registration; + + for ( i = 0; i < 1; i++ ) { + event_index = i; + + print_debug("Testing expected success for index %d\n", event_index); + retval = MPI_T_event_handle_alloc(event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &event_registration) ; + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_alloc did not return MPI_SUCCESS", retval, TEST_EXIT); + + /* + * int MPI_T_event_set_dropped_handler( + * MPI_T_event_registration event_registration, + * MPI_T_event_dropped_cb_function dropped_cb_function) + */ + + cb_user_data = (void*)user_data_string; + print_debug("cb_user_data is %s\n", cb_user_data); + + print_debug("Testing expected MPI_T_event_register_callback success for index %d\n", event_index); + retval = MPI_T_event_set_dropped_handler(event_registration, test_event_dropped_cb_function); + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_set_dropped_handler did not return MPI_SUCCESS", retval, TEST_EXIT); + else + event_set_dropped_handler_success = 1; + + if ( do_failure_tests ) { + } + + generate_callback_activity(); + } +} + +int main (int argc, char** argv) +{ + + test_init("MPI_T Events Callback Tests", argc, argv); + + test_dropped(); + + print_results(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} + diff --git a/events/events_example.c b/events/events_example.c new file mode 100644 index 0000000..6057b3a --- /dev/null +++ b/events/events_example.c @@ -0,0 +1,165 @@ +/* + * events_example.c + * + * Events example that registers callback, generates callback activity, and reports event data + * + */ + +#include +#include +#include +#include + + +char *cb_user_data; +int rank, wsize; +int event_index = 0; +char user_data_string[256] = "Test String"; +MPI_T_event_registration event_registration; + + +void event_cb_function(MPI_T_event_instance event, MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + MPI_Count event_timestamp; + int sequence_index = 3; + short seq; + + MPI_T_event_get_timestamp(event, &event_timestamp); + MPI_T_event_read(event, sequence_index, &seq); + + if ( !rank ) fprintf(stdout, "In %s %s %d ts=%lu idx=%hd\n", __func__, __FILE__, __LINE__, (unsigned long)event_timestamp, seq); +} + + +void free_event_cb_function(MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + if ( !rank ) fprintf(stdout, "In %s %s %d\n", __func__, __FILE__, __LINE__); +} + + +void register_callback() { + + int name_len, desc_len, num_elements; + char *name, *desc; + + // int MPI_T_event_get_info(int event_index, char *name, int *name_len, + // int *verbosity, MPI_Datatype *array_of_datatypes, + // MPI_Aint *array_of_displacements, int *num_elements, + // MPI_T_enum *enumtype, MPI_Info* info, + // char *desc, int *desc_len, int *bind) + // + + MPI_T_event_get_info ( + event_index, + NULL, + &name_len, + NULL, + NULL, + NULL, + &num_elements, + NULL, + NULL, + NULL, + &desc_len, + NULL + ); + + name = (char*) malloc(name_len+1); + desc = (char*) malloc(desc_len+1); + + MPI_T_event_get_info ( + event_index, + name, + &name_len, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + desc, + &desc_len, + NULL + ); + + if ( !rank ) fprintf(stdout, "Registering event index %d : %s : %s\n", event_index, name, desc); + MPI_T_event_handle_alloc(event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &event_registration) ; + + cb_user_data = (void*)user_data_string; + + MPI_T_event_register_callback(event_registration, MPI_T_CB_REQUIRE_ASYNC_SIGNAL_SAFE, MPI_INFO_NULL, cb_user_data, event_cb_function); + + free(name); + free(desc); +} + + +void free_event() { + + MPI_T_event_handle_free(event_registration, cb_user_data, free_event_cb_function); +} + + +void generate_callback_activity() { + +#define GENERATE_BUFFER_SIZE 32 + + char buf[GENERATE_BUFFER_SIZE]; + int i, lim = 5; + MPI_Status stat; + MPI_Request req; + + for ( i = 0; i < lim; i++ ) { + if ( rank == 0 ) { + strcpy(cb_user_data, "Irecv"); + MPI_Irecv(buf, GENERATE_BUFFER_SIZE, MPI_CHAR, 1, 27, MPI_COMM_WORLD, &req); + } + else { + strcpy(buf, "cat"); + strcpy(cb_user_data, "Isend"); + MPI_Isend(buf, GENERATE_BUFFER_SIZE, MPI_CHAR, 0, 27, MPI_COMM_WORLD, &req); + } + + strcpy(cb_user_data, "Wait"); + MPI_Wait(&req, &stat); + + strcpy(cb_user_data, "Barrier"); + MPI_Barrier(MPI_COMM_WORLD); + } +} + + +int main (int argc, char** argv) +{ + + MPI_Init(&argc, &argv); + + MPI_Comm_size(MPI_COMM_WORLD, &wsize); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + int required = MPI_THREAD_SINGLE; + int provided = 0; + + if ( argc > 1 ) + event_index = atoi(argv[1]); + else + event_index = 0; + + MPI_T_init_thread(required, &provided); + + register_callback(); + + if ( !rank ) fprintf(stdout,"Registered callback, Generate callback activity.\n"); + generate_callback_activity(); + + free_event(); + + if ( !rank ) fprintf(stdout,"Freed callback, should not generate callback activity.\n"); + generate_callback_activity(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} + diff --git a/events/events_meta_data.c b/events/events_meta_data.c new file mode 100644 index 0000000..ff8c356 --- /dev/null +++ b/events/events_meta_data.c @@ -0,0 +1,124 @@ +/* + * events_meta_data.c + * + * Test events metadata functions for timestamp and source + * + */ + +#include "events_common.h" + +char user_data_string[MAX_STRING] = "Test String"; + + +// Test flags +int event_read_time_success = 0; +int event_increasing_time_success = 0; +int event_get_source_success = 0; + + +void print_results() { + + if ( 0 == rank ) { + print_pf_result("MPI_T_event_get_timestamp", "Successful return", event_read_time_success); + print_pf_result("MPI_T_event_get_timestamp", "Increasing timestamps", event_increasing_time_success); + print_pf_result("MPI_T_event_get_source", "Successful return", event_get_source_success); + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "TOTAL ERROR COUNT", metric_width, "", error_count); + } +} + + +/* + * typedef void (*MPI_T_event_cb_function) (MPI_T_event_instance event, + MPI_T_event_registration handle, + MPI_T_cb_safety cb_safety, + void *user_data); + */ + +void test_event_cb_function(MPI_T_event_instance event, MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + int retval; + MPI_Count event_timestamp, previous_timestamp = 0; + int source_index; + + print_debug("In cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); + + retval = MPI_T_event_get_timestamp(event, &event_timestamp); + + if ( retval != MPI_SUCCESS ) { + print_error("MPI_T_event_get_timestamp did not return MPI_SUCCESS", retval, TEST_CONTINUE); + event_read_time_success = 0; + } + else { + print_debug("MPI_T_event_get_timestamp provided MPI_Count %lu\n", event_timestamp); + event_read_time_success = 1; + previous_timestamp = event_timestamp; + } + + if ( previous_timestamp > 0 && previous_timestamp <= event_timestamp ) + event_increasing_time_success = 1; + + retval = MPI_T_event_get_source(event, &source_index); + + if ( retval != MPI_SUCCESS ) { + print_error("MPI_T_event_get_source did not return MPI_SUCCESS", retval, TEST_CONTINUE); + event_get_source_success = 0; + } + else { + print_debug("MPI_T_event_get_source provided source_index %d\n", source_index); + event_get_source_success = 1; + } +} + + +void test_free_event_cb_function(MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + print_debug("In cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); +} + + +void test_meta_data() { + int retval; + int event_index; + MPI_T_event_registration event_registration; + char *event_name = "ompi_pml_ob1_request_complete"; + + retval = MPI_T_event_get_index(event_name, &event_index); + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_get_index did not return MPI_SUCCESS", retval, TEST_EXIT); + + retval = MPI_T_event_handle_alloc(event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &event_registration) ; + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_alloc did not return MPI_SUCCESS", retval, TEST_EXIT); + + cb_user_data = user_data_string; + print_debug("Testing expected MPI_T_event_register_callback success for index %d\n", event_index); + + retval = MPI_T_event_register_callback(event_registration, MPI_T_CB_REQUIRE_ASYNC_SIGNAL_SAFE, MPI_INFO_NULL, cb_user_data, test_event_cb_function); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_register_callback did not return MPI_SUCCESS", retval, TEST_EXIT); + + if ( do_failure_tests ) { + } + + generate_callback_activity(); +} + + +int main (int argc, char** argv) +{ + + test_init("MPI_T Events Event Meta Data Tests", argc, argv); + + test_meta_data(); + + print_results(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} + diff --git a/events/events_read_data.c b/events/events_read_data.c new file mode 100644 index 0000000..793fc25 --- /dev/null +++ b/events/events_read_data.c @@ -0,0 +1,269 @@ +/* + * events_read_data.c + * + * Test events data access functions for success and behavior + * + */ + +#include "events_common.h" + +#define ELEMENT_BUFFER_SIZE 256 + + +char user_data_string[MAX_STRING] = "Test String"; + +// Test flags +int event_read_data_success = 0; +int event_read_data_confirm = 0; +int event_copy_data_success = 1; +int event_copy_data_match = 1; +int event_element_index_exceed_handled = 0; +int event_element_index_negative_handled = 0; + + +void print_results() { + + if ( 0 != rank ) return; + + print_pf_result("MPI_T_event_read", "Event Read Data Success", event_read_data_success); + print_pf_result("MPI_T_event_read", "Event Read Data Confirm", event_read_data_confirm); + print_pf_result("MPI_T_event_copy", "Event Copy Data Success", event_copy_data_success); + print_pf_result("MPI_T_event_copy", "Event Copy Data Verified", event_copy_data_match); + + if ( do_failure_tests ) { + print_pf_result("MPI_T_event_read", "Handled element index too large", event_element_index_exceed_handled); + print_pf_result("MPI_T_event_read", "Handled negative element index", event_element_index_negative_handled); + } + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "TOTAL ERROR COUNT", metric_width, "", error_count); +} + + +/* + * typedef void (*MPI_T_event_cb_function) (MPI_T_event_instance event, + MPI_T_event_registration handle, + MPI_T_cb_safety cb_safety, + void *user_data); + */ + +void test_event_cb_function(MPI_T_event_instance event, MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + int i, retval, num_elements, event_idx = 0; + void *element_buffer, *element_test_buffer; + int element_buffer_length; + MPI_Datatype *array_of_datatypes; + MPI_Aint *array_of_displacements; + char type_name[MPI_MAX_OBJECT_NAME]; + int resultlen, type_size; + static int seq_num = 1; + + print_debug("In cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); + + if ( rank != 0 ) return; + + /* Get data element count */ + retval = MPI_T_event_get_info ( + event_idx, + NULL, + NULL, + NULL, + NULL, + NULL, + &num_elements, + NULL, + NULL, + NULL, + NULL, + NULL + ); + + if (MPI_SUCCESS != retval) { + print_error("MPI_T_event_get_info failed", NO_MPI_ERROR_CODE, TEST_CONTINUE); + } + + array_of_datatypes = (MPI_Datatype*)malloc(sizeof(MPI_Datatype)*num_elements); + array_of_displacements = (MPI_Aint*)malloc(sizeof(MPI_Aint)*num_elements); + + retval = MPI_T_event_get_info ( + event_idx, + NULL, + NULL, + NULL, + array_of_datatypes, + array_of_displacements, + &num_elements, + NULL, + NULL, + NULL, + NULL, + NULL + ); + + element_buffer = malloc(ELEMENT_BUFFER_SIZE); + element_test_buffer = malloc(ELEMENT_BUFFER_SIZE); + + event_read_data_success = 1; + event_read_data_confirm = 1; + + for ( i = 0; i < num_elements; i++ ) { + + print_debug("Testing callback event_read for element %d\n", i); + retval = MPI_T_event_read(event, i, element_buffer); + + if (MPI_SUCCESS != retval) { + print_error("MPI_T_event_read failed", retval, TEST_CONTINUE); + event_read_data_success = 0; + error_count++; + } + + // Event index 0 uses match header names + static char *mca_pml_ob1_match_hdr_names[] = { + "context id", "source", "tag", "sequence number", NULL, + }; + + if ( array_of_datatypes[i] != 0 ) { + + MPI_Type_get_name( array_of_datatypes[i], type_name, &resultlen); + MPI_Type_size(array_of_datatypes[i], &type_size); + + if ( type_size == 2 ) { + print_debug(" [%d] Datatype : %20s Displacement : %2lu Size : %d : name : %20s val %hd\n", + i, type_name, (unsigned long)array_of_displacements[i], type_size, mca_pml_ob1_match_hdr_names[i], *(short*)element_buffer); + } + else if ( type_size == 4 ) { + print_debug(" [%d] Datatype : %20s Displacement : %2lu Size : %d : name : %20s val %d\n", + i, type_name, (unsigned long)array_of_displacements[i], type_size, mca_pml_ob1_match_hdr_names[i], *(int*)element_buffer); + } + + print_debug("element_test_buffer copy is at %d of size %d\n", (array_of_displacements[i]-type_size), type_size); + memcpy(element_test_buffer+(array_of_displacements[i]), element_buffer, type_size); + + // Check sequence number for increasing integers + // Specific to OMPI event ID 0, counter index 3 with current MPI activity + if ( 3 == i ) + print_debug("i is %d, seq_num is %d, sequence counter is %d\n", i, seq_num, *(short*)element_buffer); + + if ( 3 == i && 1 == event_read_data_confirm && seq_num != *(short*)element_buffer ) { + event_read_data_confirm = 0; + error_count++; + } + } + } + + seq_num++; + + + // For MPI_T_EVENT_COPY, the argument array_of_displacements returns an array of byte displacements in the event buffer in ascending order starting with zero. + retval = MPI_T_event_copy(event, element_buffer); + if (MPI_SUCCESS != retval) { + print_error("MPI_T_event_failed failed", retval, TEST_CONTINUE); + if ( 1 == event_copy_data_success ) { + event_copy_data_success = 0; + error_count++; + } + } + + for ( i = 0; i < 12; i++ ) { + print_debug(" %d : %x - %x \n", i, *(char*)(element_test_buffer+i), *(char*)(element_buffer+i)); + } + + // Length of buffer is last offset + size of last element + MPI_Type_size(array_of_datatypes[num_elements-1], &type_size); + element_buffer_length = array_of_displacements[num_elements-1] + type_size; + + if ( 0 == memcmp(element_test_buffer, element_buffer, element_buffer_length) ) { + print_debug("event_copy buffers match for length %d!\n", element_buffer_length); + } else { + print_error("event_copy buffers do not match!\n", NO_MPI_ERROR_CODE, TEST_CONTINUE); + event_copy_data_match = 0; + } + + if ( do_failure_tests ) { + retval = MPI_T_event_read(event, num_elements+1, element_buffer); + + if (MPI_SUCCESS != retval) { + event_element_index_exceed_handled = 1; + } + else { + print_error("MPI_T_event_read invalid event element index num_elements+1 not handled", retval, TEST_CONTINUE); + } + + retval = MPI_T_event_read(event, -1, element_buffer); + + if (MPI_SUCCESS != retval) { + event_element_index_negative_handled = 1; + } + else { + print_error("MPI_T_event_read invalid event element index -1 not handled", retval, TEST_CONTINUE); + } + } + + free(array_of_datatypes); + free(array_of_displacements); + free(element_buffer); + free(element_test_buffer); +} + + +void test_free_event_cb_function(MPI_T_event_registration handle, MPI_T_cb_safety cb_safety, void *user_data) { + + print_debug("In cb_function : %s %s %d\n", __func__, __FILE__, __LINE__); +} + + +void test_handle_alloc_register_generate_free() { + + int retval; + + int event_index; + MPI_T_event_registration event_registration; + char *event_name = "ompi_pml_ob1_message_arrived"; + + print_debug("Event Name is %s\n", event_name); + retval = MPI_T_event_get_index(event_name, &event_index); + + // TEST MPI_T_event_handle_alloc + // + + print_debug("Testing expected success for index %d\n", event_index); + //retval = MPI_T_event_handle_alloc(event_index, NULL, MPI_INFO_NULL, &event_registration) ; + retval = MPI_T_event_handle_alloc(event_index, MPI_COMM_WORLD, MPI_INFO_NULL, &event_registration) ; + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_alloc did not return MPI_SUCCESS", retval, TEST_EXIT); + + + // TEST MPI_T_event_register_callback + // + cb_user_data = user_data_string; + print_debug("Testing expected MPI_T_event_register_callback success for index %d\n", event_index); + retval = MPI_T_event_register_callback(event_registration, MPI_T_CB_REQUIRE_ASYNC_SIGNAL_SAFE, MPI_INFO_NULL, cb_user_data, test_event_cb_function); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_register_callback did not return MPI_SUCCESS", retval, TEST_EXIT); + + generate_callback_activity(); + + // TEST MPI_T_event_handle_free + // + + retval = MPI_T_event_handle_free(event_registration, cb_user_data, test_free_event_cb_function); + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_handle_free did not return MPI_SUCCESS", retval, TEST_EXIT); +} + + +int main (int argc, char** argv) +{ + + test_init("MPI_T Events Read Event Data Tests", argc, argv); + + test_handle_alloc_register_generate_free(); + + print_results(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} + diff --git a/events/events_source.c b/events/events_source.c new file mode 100644 index 0000000..98a3fac --- /dev/null +++ b/events/events_source.c @@ -0,0 +1,108 @@ +/* + * events_source.c + * + * Test events source functions + * + */ + +#include "events_common.h" + + +// Test flags +int event_source_get_num_success = 0; +int event_source_get_info_success = 0; +int event_source_get_timestamp_success = 0; + + +void print_results() { + + if ( 0 != rank ) return; + + print_pf_result("MPI_T_source_get_num", "Get Number of Sources Success", event_source_get_num_success); + print_pf_result("MPI_T_source_get_info", "Get Source Info Success", event_source_get_info_success); + print_pf_result("MPI_T_source_get_timestamp", "Get Source Timestamp Success", event_source_get_timestamp_success); + + if ( do_failure_tests ) { + } + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "TOTAL ERROR COUNT", metric_width, "", error_count); +} + + +void test_source() { + + int retval; + + int num_sources, source_index; + MPI_Count timestamp; + char name[MAX_STRING], desc[MAX_STRING]; + int name_len, desc_len; + MPI_Count ticks_per_second, max_ticks; + MPI_Info info; + MPI_T_source_order ordering; + + /* + * + * int MPI_T_source_get_num(int *num_sources) + * int MPI_T_source_get_info(int source_index, char *name, int *name_len, + * char *desc, int *desc_len, MPI_T_source_order *ordering, + * MPI_Count *ticks_per_second, MPI_Count *max_ticks, + * MPI_Info *info) + * int MPI_T_source_get_timestamp(int source_index, MPI_Count *timestamp) + */ + + retval = MPI_T_source_get_num(&num_sources); + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_source_get_num did not return MPI_SUCCESS", retval, TEST_CONTINUE); + else + event_source_get_num_success = 1; + + + print_debug("num_sources is %d\n", num_sources); + + if ( num_sources > 0 ) + source_index = 0; + + retval = MPI_T_source_get_info(source_index, name, &name_len, + desc, &desc_len, &ordering, &ticks_per_second, &max_ticks, &info); + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_source_get_info did not return MPI_SUCCESS", retval, TEST_CONTINUE); + else { + + event_source_get_info_success = 1; + + print_debug("source %3d : %s : %s : %lu : %lu\n", source_index, name, desc, ticks_per_second, max_ticks); + } + + + retval = MPI_T_source_get_timestamp(source_index, ×tamp); + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_source_get_timestamp did not return MPI_SUCCESS", retval, TEST_CONTINUE); + else + event_source_get_timestamp_success = 1; + + + if ( do_failure_tests ) { + } + +} + + +int main (int argc, char** argv) +{ + + test_init("MPI_T Events Source Tests", argc, argv); + + test_source(); + + print_results(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} + diff --git a/events/events_types.c b/events/events_types.c new file mode 100644 index 0000000..821c647 --- /dev/null +++ b/events/events_types.c @@ -0,0 +1,222 @@ +/* + * events_types.c + * + * Test events type functions for event count and info + * + */ + +#include "events_common.h" + + +int event_count = 0; + + +// Test flags +int event_info_success = 0; +int event_info_failed = 0; +int event_info_displacements_start_at_0 = 1; +int event_count_result = 0; +int event_get_num_handle_null = 0; + + +void print_results() { + + if ( 0 != rank ) return; + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "MPI_T_event_get_num", metric_width, "Event count", event_count); + print_pf_result("MPI_T_event_get_num", "Successful return", event_count_result); + print_pf_result("MPI_T_event_get_info", "Successful return", event_info_success); + print_pf_result("MPI_T_event_get_info", "Displacements start at 0", event_info_displacements_start_at_0); + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "MPI_T_event_get_info", metric_width, "Successful event calls", event_info_success); + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "MPI_T_event_get_info", metric_width, "Unexpected Failed event calls", event_info_failed); + + if ( do_failure_tests ) { + print_pf_result("MPI_T_event_get_num", "Handle NULL argument", event_get_num_handle_null); + } + + fprintf(outstream, "%-*s - %-*s : %6d\n", func_width, "TOTAL ERROR COUNT", metric_width, "", error_count); +} + + +void test_get_num() { + + int retval; + + retval = MPI_T_event_get_num(&event_count); + + if ( retval != MPI_SUCCESS ) + print_error("MPI_T_event_get_num did not return MPI_SUCCESS", retval, TEST_EXIT); + else + event_count_result = 1; + + + if ( do_failure_tests ) { + + retval = MPI_T_event_get_num(NULL); + + if ( retval != MPI_ERR_ARG ) { + fprintf(errout, "Expected value %d, got %d\n", MPI_ERR_ARG, retval); + print_error("MPI_T_event_get_num did not return MPI_ERR_ARG", retval, TEST_CONTINUE); + } + else + event_get_num_handle_null = 1; + } +} + + +void test_get_info() { + int i, d; + char type_name[MPI_MAX_OBJECT_NAME]; + int retval, resultlen; + + EVENT_INFO *infos; + EVENT_INFO ci; + + infos = (EVENT_INFO*)malloc (event_count * sizeof(EVENT_INFO)); + if ( NULL == infos ) + print_error("Failed to allocate event info object!!!", -1, TEST_EXIT); + + /* + * get_info requirements + * + * subsequent calls to this routine that query information about the same event type must return the same information + * returns MPI_T_ERR_INVALID_INDEX if event_index does not match a valid event type index + */ + + for ( i = 0; i < event_count; i++ ) + { + + ci.event_index = i; + + // int MPI_T_event_get_info(int event_index, char *name, int *name_len, + // int *verbosity, MPI_Datatype *array_of_datatypes, + // MPI_Aint *array_of_displacements, int *num_elements, + // MPI_T_enum *enumtype, MPI_Info* info, + // char *desc, int *desc_len, int *bind) + // + /* Get lengths */ + retval = MPI_T_event_get_info ( + ci.event_index, + NULL, + &(ci.name_len), + &(ci.verbosity), + NULL, + NULL, + &(ci.num_elements), + &(ci.enumtype), + NULL, + NULL, + &(ci.desc_len), + &(ci.bind) + ); + + if (MPI_SUCCESS != retval && MPI_T_ERR_INVALID_INDEX != retval ) { + if ( MPI_T_ERR_INVALID_INDEX != retval ) { + fprintf(errout, "Expected value %d, got %d\n", MPI_T_ERR_INVALID_INDEX, retval); + } + print_error("MPI_T_event_get_info Invalid return value", -1, TEST_CONTINUE); + } + + if (MPI_SUCCESS != retval ) { + print_error("Failed to get event info", retval, TEST_CONTINUE); + event_info_failed++; + ci.name_len = 0; + memcpy(&infos[i], &ci, sizeof(EVENT_INFO)); + continue; + } + else { + event_info_success++; + } + + // allocate strings and arrays for datatypes and displacements + ci.name = (char*)malloc(ci.name_len); + ci.array_of_datatypes = (MPI_Datatype*)malloc(ci.num_elements*sizeof(MPI_Datatype)); + ci.array_of_displacements = (MPI_Aint*)malloc(ci.num_elements*sizeof(MPI_Aint)); + ci.desc = (char*)malloc(ci.desc_len); + + if ( !ci.name || ! ci.array_of_datatypes || !ci.array_of_displacements || !ci.desc ) + print_error("Failed to allocate info name and description buffers", retval, TEST_EXIT); + + /* Get data */ + retval = MPI_T_event_get_info( + ci.event_index, + ci.name, + &(ci.name_len), + &(ci.verbosity), + ci.array_of_datatypes, + ci.array_of_displacements, + &(ci.num_elements), + &(ci.enumtype), + &(ci.info), + ci.desc, + &(ci.desc_len), + &(ci.bind) + ) ; + if (MPI_SUCCESS != retval ) { + print_error("Failed to get event info", retval, TEST_CONTINUE); + event_info_failed++; + } + else { + event_info_success++; + } + + memcpy(&infos[i], &ci, sizeof(EVENT_INFO)); + + if ( 1 == event_info_displacements_start_at_0 && 0 != ci.array_of_displacements[0] ) { + print_error("Event_info displacements do not start at 0", retval, TEST_CONTINUE); + event_info_displacements_start_at_0 = 0; + } + } + + // Print event info and elements + if ( print_events && !rank ) { + for ( i = 0; i < event_count; i++ ) { + + if ( infos[i].name_len < 1 ) { + print_debug("Event[%7d] : Unavailable\n", infos[i].event_index); + continue; + } + + fprintf(outstream, "Event[%7d] : %-40s : %-50.*s : %5d : %s\n", + infos[i].event_index, + infos[i].name, + MAX_STRING-1, + infos[i].desc, + infos[i].num_elements, + bind_str(infos[i].bind) + ); + + for ( d = 0; d < infos[i].num_elements; d++ ) { + + if ( infos[i].array_of_datatypes[d] != 0 ) { + MPI_Type_get_name( infos[i].array_of_datatypes[d], type_name, &resultlen); + fprintf(outstream, " [%d] Datatype : %20s Displacement : %lu\n", d, type_name, (unsigned long)infos[i].array_of_displacements[d]); + } + } + + fprintf(outstream, "\n"); + + } + } + + free(ci.name); + free(ci.desc); + free(infos); +} + + +int main (int argc, char** argv) +{ + test_init("MPI_T Events Type Tests", argc, argv); + + test_get_num(); + test_get_info(); + + print_results(); + + MPI_T_finalize(); + MPI_Finalize(); + + return 0; +} +