diff --git a/mpiuse.c b/mpiuse.c index e5d56aa4921d6f087cc433bd3cb21c6263b76a28..07b6f6f160b1834563a920ee7004513671842d8d 100644 --- a/mpiuse.c +++ b/mpiuse.c @@ -335,19 +335,19 @@ void mpiuse_log_generate(int nr_nodes, int nr_logs, int size, int random, double *values; int nvalues; if (histread(odata, &values, &nvalues)) { - printf("## Read %d occurence values from %s\n", nvalues, odata); + // printf("## Read %d occurence values from %s\n", nvalues, odata); struct histogram *h = calloc(1, sizeof(struct histogram)); histmake(nvalues, values, h); - printf("## Created cumulative histogram with %d values:\n", h->nvalues); - printf("# value sum\n"); + // printf("## Created cumulative histogram with %d values:\n", + // h->nvalues); printf("# value sum\n"); imin[0] = 0.0; imax[0] = h->values[0]; value[0] = h->sums[0]; for (int k = 1; k < h->nvalues; k++) { - imin[k] = h->values[k-1] ; + imin[k] = h->values[k - 1]; imax[k] = h->values[k]; value[k] = h->sums[k]; - printf("%f %24.17g\n", h->values[k], h->sums[k]); + // printf("%f %24.17g\n", h->values[k], h->sums[k]); } nvals = h->nvalues; @@ -404,3 +404,22 @@ void mpiuse_log_generate(int nr_nodes, int nr_logs, int size, int random, tag++; } } + +/** + * Shuffle log pointers randomizing the order. + * + * Note assumes dran48() has been seeded. + * + * @param logs the log pointers to shuffle. + * @param nlogs the number of logs. + */ +void mpiuse_shuffle_logs(struct mpiuse_log_entry **logs, int nlogs) { + + struct mpiuse_log_entry tmp; + for (int k = nlogs - 1; k > 0; k--) { + unsigned int j = (unsigned int)(drand48() * (k + 1)); + memcpy(&tmp, &logs[j], sizeof(struct mpiuse_log_entry *)); + memcpy(&logs[j], &logs[k], sizeof(struct mpiuse_log_entry *)); + memcpy(&logs[k], &tmp, sizeof(struct mpiuse_log_entry *)); + } +} diff --git a/mpiuse.h b/mpiuse.h index 3545b7c5a6ee1eade998008063bba68bb8e2924b..a138a72979e35e7271b6a02bd6c8fba7babf7b73 100644 --- a/mpiuse.h +++ b/mpiuse.h @@ -104,5 +104,6 @@ void mpiuse_dump_logs(int nranks, const char *logfile); void mpiuse_log_generate(int nr_nodes, int nr_logs, int size, int random, long int seed, int uniform, const char *cdf, const char *odata); +void mpiuse_shuffle_logs(struct mpiuse_log_entry **logs, int nlogs); #endif /* SWIFT_MPIUSE_H */ diff --git a/swiftmpifakestepsim.c b/swiftmpifakestepsim.c index 5b8a2047f192ef26a71d3c8b570efebaa05f524c..9939f1a4854c2111c1d72e41559b9d8e87420902 100644 --- a/swiftmpifakestepsim.c +++ b/swiftmpifakestepsim.c @@ -288,22 +288,26 @@ static void *recv_thread(void *arg) { /** * @brief Comparison function for logged times. */ -static int cmp_logs(const void *p1, const void *p2) { - struct mpiuse_log_entry *l1 = *(struct mpiuse_log_entry **)p1; - struct mpiuse_log_entry *l2 = *(struct mpiuse_log_entry **)p2; - - /* Large unsigned values, so take care. */ - if (l1->tic > l2->tic) return 1; - if (l1->tic < l2->tic) return -1; - return 0; -} +// static int cmp_logs(const void *p1, const void *p2) { +// struct mpiuse_log_entry *l1 = *(struct mpiuse_log_entry **)p1; +// struct mpiuse_log_entry *l2 = *(struct mpiuse_log_entry **)p2; +// +// /* Large unsigned values, so take care. */ +// if (l1->tic > l2->tic) return 1; +// if (l1->tic < l2->tic) return -1; +// return 0; +//} /** * @brief Pick out the relevant logging data for our rank, i.e. all * activations of sends and recvs. We ignore the original completions. - * The final list is sorted into increasing time of activation. + * The final list is sorted into increasing time of activation if required, + * otherwise the order is randomized. + * + * @param random randomize injection order, otherwise use order of thr + * original logs. */ -static void pick_logs(void) { +static void pick_logs(int random) { size_t nlogs = mpiuse_nr_logs(); /* Duplicate of logs. */ @@ -327,13 +331,18 @@ static void pick_logs(void) { } /* Sort into increasing time. */ - qsort(reqs_queue, nr_reqs, sizeof(struct mpiuse_log_entry *), cmp_logs); + // qsort(reqs_queue, nr_reqs, sizeof(struct mpiuse_log_entry *), cmp_logs); + + /* Randomize the order, so ranks do not all work in sequence. */ + mpiuse_shuffle_logs(reqs_queue, nr_reqs); /* Check. */ - for (int k = 0; k < nr_reqs - 1; k++) { - if (reqs_queue[k]->tic > reqs_queue[k + 1]->tic) - message("reqs_queue: %lld > %lld", reqs_queue[k]->tic, - reqs_queue[k + 1]->tic); + if (!random) { + for (int k = 0; k < nr_reqs - 1; k++) { + if (reqs_queue[k]->tic > reqs_queue[k + 1]->tic) + message("reqs_queue: %lld > %lld", reqs_queue[k]->tic, + reqs_queue[k + 1]->tic); + } } } @@ -341,13 +350,15 @@ static void pick_logs(void) { * @brief usage help. */ static void usage(char *argv[]) { - fprintf(stderr, "Usage: %s [-vfgcx] nr_messages logfile.dat\n", argv[0]); + fprintf(stderr, "Usage: %s [options] nr_messages logfile.dat\n", argv[0]); fprintf(stderr, " options: -v verbose, -d data check, -s size (bytes/scale), \n" + "\t -f randomize injection order, \n" "\t[-r uniform random from 1 to size, | \n" "\t-r -g half gaussian random from 1 with 2.5 sigma size., | \n" "\t-r -c <file> use cdf from file, size is a scale factor., |\n" - "\t-r -o <file> use occurence sample of values in a file, size is a scale factor.,] \n" + "\t-r -o <file> use occurence sample of values in a file, size is a " + "scale factor.,] \n" "\t-x random seed\n"); fflush(stderr); } @@ -376,12 +387,13 @@ int main(int argc, char *argv[]) { * whether to use a random selections of various kinds. */ int size = 1024; int random = 0; + int randomorder = 0; int uniform = 1; char *cdf = NULL; char *odata = NULL; int opt; unsigned int seed = default_seed; - while ((opt = getopt(argc, argv, "vds:rgx:c:o:")) != -1) { + while ((opt = getopt(argc, argv, "vds:rgx:c:o:f")) != -1) { switch (opt) { case 'd': datacheck = 1; @@ -389,6 +401,9 @@ int main(int argc, char *argv[]) { case 'c': cdf = optarg; break; + case 'f': + randomorder = 1; + break; case 'g': uniform = 0; break; @@ -416,8 +431,9 @@ int main(int argc, char *argv[]) { if (myrank == 0) usage(argv); return 1; } - if (cdf != NULL && odata != NULL) error("Cannot use -c and -o options together"); - + if (cdf != NULL && odata != NULL) + error("Cannot use -c and -o options together"); + int nr_logs = atoi(argv[optind]); if (nr_logs == 0) error("Expected number of messages to exchange, got: %s", argv[optind]); @@ -453,7 +469,8 @@ int main(int argc, char *argv[]) { nr_nodes, size); } } - mpiuse_log_generate(nr_nodes, nr_logs, size, random, seed, uniform, cdf, odata); + mpiuse_log_generate(nr_nodes, nr_logs, size, random, seed, uniform, cdf, + odata); int nranks = mpiuse_nr_ranks(); /* Create communicators for each MPI rank. */ @@ -462,7 +479,7 @@ int main(int argc, char *argv[]) { } /* Each rank requires its own queue, so extract them. */ - pick_logs(); + pick_logs(randomorder); /* Time to start time. Try to make it synchronous across the ranks. */ MPI_Barrier(MPI_COMM_WORLD);