diff --git a/swiftmpistepsim.c b/swiftmpistepsim.c index 8a4a257098615243a3811d6250b93f657c938bd9..dc1573d8f20408d11d956cc5803457a931ccf3d8 100644 --- a/swiftmpistepsim.c +++ b/swiftmpistepsim.c @@ -38,6 +38,9 @@ static int verbose = 0; /* Attempt to keep original injection time differences. */ static int usetics = 1; +/* Set a data pattern and check we get this back, slow... */ +static int datacheck = 0; + /* Integer types of send and recv tasks, must match log. */ static const int task_type_send = 22; static const int task_type_recv = 23; @@ -64,6 +67,35 @@ static int volatile todo_send = 0; // XXX need to store this in the data file. static double log_clocks_cpufreq = 2194844448.0; +/** + * @brief fill a data area with a pattern that can be checked for changes. + * + * @param size size of data in bytes. + * @param data the data to fill. + */ +static void datacheck_fill(size_t size, void *data) { + unsigned char *p = (unsigned char *)data; + for (size_t i = 0; i < size; i++) { + p[i] = 170; /* 10101010 in bits. */ + } +} + +/** + * @brief test a filled data area for our pattern. + * + * @param size size of data in bytes. + * @param data the data to fill. + * + * @result 1 on success, 0 otherwise. + */ +static int datacheck_test(size_t size, void *data) { + unsigned char *p = (unsigned char *)data; + for (size_t i = 0; i < size; i++) { + if (p[i] != 170) return 0; + } + return 1; +} + /** * @brief Injection thread, initiates MPI_Isend and MPI_Irecv requests. * @@ -128,6 +160,11 @@ static void *inject_thread(void *arg) { int err = 0; if (log->type == task_type_send) { log->data = calloc(log->size, 1); + + /* Fill data with pattern. */ + if (datacheck) datacheck_fill(log->size, log->data); + + /* And send. */ err = MPI_Isend(log->data, log->size, MPI_BYTE, log->otherrank, log->tag, subtypeMPI_comms[log->subtype], &log->req); @@ -137,6 +174,8 @@ static void *inject_thread(void *arg) { atomic_inc(&todo_send); } else { + + /* Ready to receive. */ log->data = calloc(log->size, 1); err = MPI_Irecv(log->data, log->size, MPI_BYTE, log->otherrank, log->tag, subtypeMPI_comms[log->subtype], &log->req); @@ -229,6 +268,12 @@ static void queue_runner(struct mpiuse_log_entry **logs, int volatile *nr_logs, if (dt > lmaxt) lmaxt = dt; if (res) { + /* Check data sent data is unchanged and received data is as + * expected. */ + if (datacheck && !datacheck_test(log->size, log->data)) { + error("Data mismatch on completion"); + } + /* Done, clean up. */ log->done = 1; log->endtic = getticks(); @@ -392,8 +437,11 @@ int main(int argc, char *argv[]) { /* Handle the command-line, we expect a mpiuse data file to read and various * options. */ int opt; - while ((opt = getopt(argc, argv, "vf")) != -1) { + while ((opt = getopt(argc, argv, "vfd")) != -1) { switch (opt) { + case 'd': + datacheck = 1; + break; case 'f': usetics = 0; break; @@ -438,6 +486,10 @@ int main(int argc, char *argv[]) { if (myrank == 0) { message("Start of MPI tests"); message("=================="); + if (verbose) { + if (usetics) message("using fast untimed injections"); + if (datacheck) message("checking data pattern on send and recv completion"); + } } /* Make three threads, one for injecting tasks and two to check for