From 0342d542a9830dd70f9333bf1a61240e318c31ed Mon Sep 17 00:00:00 2001 From: "Peter W. Draper" <p.w.draper@durham.ac.uk> Date: Tue, 10 Mar 2020 14:47:21 +0000 Subject: [PATCH] Add a loop to simulate multiple steps from a single data file --- swiftmpiproxies.c | 222 +++++++++++++++++++++++++--------------------- 1 file changed, 119 insertions(+), 103 deletions(-) diff --git a/swiftmpiproxies.c b/swiftmpiproxies.c index e33e47e..e05c9ef 100644 --- a/swiftmpiproxies.c +++ b/swiftmpiproxies.c @@ -35,6 +35,9 @@ int myrank = -1; /* Are we verbose. */ static int verbose = 0; +/* Maximum main loops. */ +static int maxloops = 1000; + /* Integer types of send and recv tasks, must match log. */ static const int task_type_send = 23; static const int task_type_recv = 24; @@ -145,8 +148,8 @@ static void pick_logs(void) { * @brief usage help. */ static void usage(char *argv[]) { - fprintf(stderr, "Usage: %s [-vf] SWIFT_mpiuse-log-file.dat\n", argv[0]); - fprintf(stderr, " options: -v verbose\n"); + fprintf(stderr, "Usage: %s [-vn] SWIFT_mpiuse-log-file.dat\n", argv[0]); + fprintf(stderr, " options: -n maxloops, -v verbose\n"); fflush(stderr); } @@ -169,11 +172,14 @@ int main(int argc, char *argv[]) { if (res != MPI_SUCCESS) error("Call to MPI_Comm_rank failed with error %i.", res); - /* Handle the command-line, we expect a mpiuse data file to read and various - * options. */ + /* Handle the command-line, we expect a mpiuse data file to read and + * various options. */ int opt; - while ((opt = getopt(argc, argv, "v")) != -1) { + while ((opt = getopt(argc, argv, "vn:")) != -1) { switch (opt) { + case 'n': + maxloops = atoi(optarg); + break; case 'v': verbose = 1; break; @@ -213,110 +219,120 @@ int main(int argc, char *argv[]) { MPI_Request req_pcells_out[nr_send_pcells]; int pcells_size[nr_send_pcells]; - /* XXX note in SWIFT we use the threadpool to launch these. That may - * matter. */ - for (int k = 0; k < nr_send_pcells; k++) { - struct mpiuse_log_entry *log = send_pcells[k]; - - /* Need to regenerate the tags for each other communication type. */ - int basetag = myrank * proxy_tag_shift; - - /* Start Isend counts of pcells. Really just the size of the buffer we're - * about to send, SWIFT sends the count. */ - int size = log->size; - res = + /* Loop over next section a number of times to simulate rebuild steps in + * SWIFT. */ + for (int nloop = 0; nloop < maxloops; nloop++) { + MPI_Barrier(MPI_COMM_WORLD); + if (myrank == 0) + message("*** Proxy simulation exchange loop: %d ***", nloop); + + /* XXX note in SWIFT we use the threadpool to launch these. That may + * matter. */ + for (int k = 0; k < nr_send_pcells; k++) { + struct mpiuse_log_entry *log = send_pcells[k]; + + /* Need to regenerate the tags for each other communication type. */ + int basetag = myrank * proxy_tag_shift; + + /* Start Isend counts of pcells. Really just the size of the buffer we're + * about to send, SWIFT sends the count. */ + int size = log->size; + res = MPI_Isend(&size, 1, MPI_INT, log->otherrank, basetag + proxy_tag_count, MPI_COMM_WORLD, &req_send_counts[k]); - if (res != MPI_SUCCESS) error("Counts MPI_Isend failed."); - - /* Start Isend of pcells. */ - log->data = calloc(log->size, 1); - - /* Fill data with a pattern for checking on arrival. */ - datacheck_fill(0, log->size, log->data); - res = MPI_Isend(log->data, log->size, MPI_BYTE, log->otherrank, - basetag + proxy_tag_cells, MPI_COMM_WORLD, - &req_pcells_out[k]); - if (res != MPI_SUCCESS) error("Pcell MPI_Isend failed."); - - /* Start Irecv counts of pcells from other rank. */ - basetag = log->otherrank * proxy_tag_shift; - res = MPI_Irecv(&pcells_size[k], 1, MPI_INT, log->otherrank, - basetag + proxy_tag_count, MPI_COMM_WORLD, - &req_recv_counts[k]); - if (res != MPI_SUCCESS) error("Counts MPI_Irecv failed."); - } - message("All counts requests and pcell sends are launched"); - - /* Now wait for any of the counts irecvs to complete and then create the - * irecv for the pcells. */ - void *pcells_in[nr_send_pcells]; - MPI_Request req_pcells_in[nr_send_pcells]; - for (int k = 0; k < nr_send_pcells; k++) { - int pid = MPI_UNDEFINED; - MPI_Status status; - res = MPI_Waitany(nr_send_pcells, req_recv_counts, &pid, &status); - if (res != MPI_SUCCESS || pid == MPI_UNDEFINED) - error("MPI_Waitany failed."); - if (verbose) message("Counts received for proxy %d", pid); - - struct mpiuse_log_entry *log = send_pcells[pid]; - int basetag = log->otherrank * proxy_tag_shift; - - pcells_in[pid] = calloc(pcells_size[pid], 1); - - /* Fill data with a pattern for checking when overwritten. */ - datacheck_fill(1, pcells_size[pid], pcells_in[pid]); - res = MPI_Irecv(pcells_in[pid], pcells_size[pid], MPI_BYTE, log->otherrank, - basetag + proxy_tag_cells, MPI_COMM_WORLD, - &req_pcells_in[pid]); - - if (res != MPI_SUCCESS) error("Pcell MPI_Irecv failed."); - } - message("All proxy cell counts have arrived"); - - /* Waitall for all Isend counts to complete. */ - res = MPI_Waitall(nr_send_pcells, req_send_counts, MPI_STATUSES_IGNORE); - if (res != MPI_SUCCESS) error("Waitall for counts Isend failed."); - - /* Now wait for the pcell irecvs to complete, so we receive the pcells, - * which would be unpacked in SWIFT. */ - for (int k = 0; k < nr_send_pcells; k++) { - int pid = MPI_UNDEFINED; - MPI_Status status; - res = MPI_Waitany(nr_send_pcells, req_pcells_in, &pid, &status); - if (res != MPI_SUCCESS || pid == MPI_UNDEFINED) - error("MPI_Waitany failed."); - - /* Check the data received is correct. */ - struct mpiuse_log_entry *log = send_pcells[pid]; - if (!datacheck_test(0, pcells_size[pid], pcells_in[pid])) { - if (!datacheck_test(1, pcells_size[pid], pcells_in[pid])) { - error("Received data is not modified"); + if (res != MPI_SUCCESS) error("Counts MPI_Isend failed."); + + /* Start Isend of pcells. */ + log->data = calloc(log->size, 1); + + /* Fill data with a pattern for checking on arrival. */ + datacheck_fill(0, log->size, log->data); + res = MPI_Isend(log->data, log->size, MPI_BYTE, log->otherrank, + basetag + proxy_tag_cells, MPI_COMM_WORLD, + &req_pcells_out[k]); + if (res != MPI_SUCCESS) error("Pcell MPI_Isend failed."); + + /* Start Irecv counts of pcells from other rank. */ + basetag = log->otherrank * proxy_tag_shift; + res = MPI_Irecv(&pcells_size[k], 1, MPI_INT, log->otherrank, + basetag + proxy_tag_count, MPI_COMM_WORLD, + &req_recv_counts[k]); + if (res != MPI_SUCCESS) error("Counts MPI_Irecv failed."); + } + message("All counts requests and pcell sends are launched"); + + /* Now wait for any of the counts irecvs to complete and then create the + * irecv for the pcells. */ + void *pcells_in[nr_send_pcells]; + MPI_Request req_pcells_in[nr_send_pcells]; + for (int k = 0; k < nr_send_pcells; k++) { + int pid = MPI_UNDEFINED; + MPI_Status status; + res = MPI_Waitany(nr_send_pcells, req_recv_counts, &pid, &status); + if (res != MPI_SUCCESS || pid == MPI_UNDEFINED) + error("MPI_Waitany failed."); + if (verbose) message("Counts received for proxy %d", pid); + + struct mpiuse_log_entry *log = send_pcells[pid]; + int basetag = log->otherrank * proxy_tag_shift; + + pcells_in[pid] = calloc(pcells_size[pid], 1); + + /* Fill data with a pattern for checking when overwritten. */ + datacheck_fill(1, pcells_size[pid], pcells_in[pid]); + res = MPI_Irecv(pcells_in[pid], pcells_size[pid], MPI_BYTE, log->otherrank, + basetag + proxy_tag_cells, MPI_COMM_WORLD, + &req_pcells_in[pid]); + + if (res != MPI_SUCCESS) error("Pcell MPI_Irecv failed."); + } + message("All proxy cell counts have arrived"); + + /* Waitall for all Isend counts to complete. */ + res = MPI_Waitall(nr_send_pcells, req_send_counts, MPI_STATUSES_IGNORE); + if (res != MPI_SUCCESS) error("Waitall for counts Isend failed."); + + /* Now wait for the pcell irecvs to complete, so we receive the pcells, + * which would be unpacked in SWIFT. */ + for (int k = 0; k < nr_send_pcells; k++) { + int pid = MPI_UNDEFINED; + MPI_Status status; + res = MPI_Waitany(nr_send_pcells, req_pcells_in, &pid, &status); + if (res != MPI_SUCCESS || pid == MPI_UNDEFINED) + error("MPI_Waitany failed."); + + /* Check the data received is correct. */ + if (!datacheck_test(0, pcells_size[pid], pcells_in[pid])) { + if (!datacheck_test(1, pcells_size[pid], pcells_in[pid])) { + error("Received data is not modified"); + } else { + error("Received data is corrupt"); + } } else { - error("Received data is corrupt"); + message("Received data is correct"); } - } else { - message("Received data is correct"); + free(pcells_in[pid]); + pcells_in[pid] = NULL; } - free(pcells_in[pid]); - } - message("All proxy cells have arrived"); - - /* Waitall for Isend of pcells to complete. */ - res = MPI_Waitall(nr_send_pcells, req_pcells_out, MPI_STATUSES_IGNORE); - if (res != MPI_SUCCESS) error("Waitall for pcells Isend failed."); - - /* Check data is unmodified. */ - for (int k = 0; k < nr_send_pcells; k++) { - struct mpiuse_log_entry *log = send_pcells[k]; - if (!datacheck_test(0, log->size, log->data)) { - error("Sent data has been corrupted"); - } else { - message("Sent data is correct"); + message("All proxy cells have arrived"); + + /* Waitall for Isend of pcells to complete. */ + res = MPI_Waitall(nr_send_pcells, req_pcells_out, MPI_STATUSES_IGNORE); + if (res != MPI_SUCCESS) error("Waitall for pcells Isend failed."); + + /* Check data is unmodified. */ + for (int k = 0; k < nr_send_pcells; k++) { + struct mpiuse_log_entry *log = send_pcells[k]; + if (!datacheck_test(0, log->size, log->data)) { + error("Sent data has been corrupted"); + } else { + message("Sent data is correct"); + } + free(log->data); + log->data = NULL; } - free(log->data); - } + + }/* nloop */ /* Shutdown MPI. */ res = MPI_Finalize(); -- GitLab