From 511a0b1435ae3d9a46d34ac01068e3e9e7564b01 Mon Sep 17 00:00:00 2001 From: "Christopher J. Morrone" Date: Mon, 12 Dec 2011 21:00:18 -0800 Subject: [PATCH] Refactor the test summary code. Only print total summary after all tests run. Put calculated results from each iteration of a test in a separate IOR_results_t structure. Clean up the allocation and freeing code for these caluclated bits, which allowing us to hang onto the results until the end of all tests. That in turn allows us to perform one big summary at the end of all of the tests. --- src/ior.c | 829 ++++++++++++++++++++++++-------------------- src/ior.h | 31 +- src/parse_options.c | 215 ++++++------ src/parse_options.h | 2 +- src/utilities.c | 21 +- 5 files changed, 596 insertions(+), 502 deletions(-) diff --git a/src/ior.c b/src/ior.c index 64c43cd..6df458c 100644 --- a/src/ior.c +++ b/src/ior.c @@ -62,7 +62,7 @@ ior_aiori_t *available_aiori[] = { static void AioriBind(char *); static void CheckForOutliers(IOR_param_t *, double **, int, int); -static void CheckFileSize(IOR_param_t *, IOR_offset_t, int); +static void CheckFileSize(IOR_test_t *test, IOR_offset_t dataMoved, int rep); static char *CheckTorF(char *); static size_t CompareBuffers(void *, void *, size_t, IOR_offset_t, IOR_param_t *, int); @@ -70,6 +70,7 @@ static int CountErrors(IOR_param_t *, int, int); static int CountTasksPerNode(int, MPI_Comm); static void *CreateBuffer(size_t); static void DelaySecs(int); +static void DestroyTests(IOR_test_t *tests_head); static void DisplayFreespace(IOR_param_t *); static void DisplayOutliers(int, double, char *, int, int); static void DisplayUsage(char **); @@ -87,16 +88,17 @@ static void PrintHeader(int argc, char **argv); static void ReadCheck(void *, void *, void *, void *, IOR_param_t *, IOR_offset_t, IOR_offset_t, IOR_offset_t *, IOR_offset_t *, int, int *); -static void ReduceIterResults(IOR_param_t *, double **, int, int); +static void ReduceIterResults(IOR_test_t *test, double **timer, + int rep, int access); static void RemoveFile(char *, int, IOR_param_t *); static void SetupXferBuffers(void **, void **, void **, IOR_param_t *, int, int); -static IOR_queue_t *SetupTests(int, char **); +static IOR_test_t *SetupTests(int, char **); static void ShowTestInfo(IOR_param_t *); -static void ShowSetup(IOR_param_t *); +static void ShowSetup(IOR_param_t *params); static void ShowTest(IOR_param_t *); -static void SummarizeResults(IOR_param_t *); -static void TestIoSys(IOR_param_t *); +static void PrintSummaryAllTests(IOR_test_t *tests_head); +static void TestIoSys(IOR_test_t *); static double TimeDeviation(void); static void ValidTests(IOR_param_t *); static IOR_offset_t WriteOrRead(IOR_param_t *, void *, int); @@ -107,7 +109,8 @@ static void WriteTimes(IOR_param_t *, double **, int, int); int main(int argc, char **argv) { int i; - IOR_queue_t *tests; + IOR_test_t *tests_head; + IOR_test_t *tptr; /* * check -h option from commandline without starting MPI; @@ -136,35 +139,38 @@ int main(int argc, char **argv) } /* setup tests before verifying test validity */ - tests = SetupTests(argc, argv); - verbose = tests->testParameters.verbose; - tests->testParameters.testComm = MPI_COMM_WORLD; + tests_head = SetupTests(argc, argv); + verbose = tests_head->params.verbose; + tests_head->params.testComm = MPI_COMM_WORLD; /* check for commandline usage */ - if (rank == 0 && tests->testParameters.showHelp == TRUE) { + if (rank == 0 && tests_head->params.showHelp == TRUE) { DisplayUsage(argv); } PrintHeader(argc, argv); /* perform each test */ - while (tests != NULL) { - verbose = tests->testParameters.verbose; + for (tptr = tests_head; tptr != NULL; tptr = tptr->next) { + verbose = tptr->params.verbose; if (rank == 0 && verbose >= VERBOSE_0) { - ShowTestInfo(&tests->testParameters); + ShowTestInfo(&tptr->params); } if (rank == 0 && verbose >= VERBOSE_3) { - ShowTest(&tests->testParameters); + ShowTest(&tptr->params); } - TestIoSys(&tests->testParameters); - tests = tests->nextTest; + TestIoSys(tptr); } + PrintSummaryAllTests(tests_head); + /* display finish time */ if (rank == 0 && verbose >= VERBOSE_0) { fprintf(stdout, "Finish: %s", CurrentTimeString()); } + DestroyTests(tests_head); + MPI_CHECK(MPI_Finalize(), "cannot finalize MPI"); return (totalErrorCount); @@ -293,34 +299,37 @@ static void CheckForOutliers(IOR_param_t * test, double **timer, int rep, * Check if actual file size equals expected size; if not use actual for * calculating performance rate. */ -static void CheckFileSize(IOR_param_t * test, IOR_offset_t dataMoved, int rep) +static void CheckFileSize(IOR_test_t *test, IOR_offset_t dataMoved, int rep) { - MPI_CHECK(MPI_Allreduce(&dataMoved, &test->aggFileSizeFromXfer[rep], + IOR_param_t *params = &test->params; + IOR_results_t *results = test->results; + + MPI_CHECK(MPI_Allreduce(&dataMoved, &results->aggFileSizeFromXfer[rep], 1, MPI_LONG_LONG_INT, MPI_SUM, testComm), "cannot total data moved"); - if (strcmp(test->api, "HDF5") != 0 && strcmp(test->api, "NCMPI") != 0) { + if (strcmp(params->api, "HDF5") != 0 && strcmp(params->api, "NCMPI") != 0) { if (verbose >= VERBOSE_0 && rank == 0) { - if ((test->aggFileSizeFromCalc[rep] - != test->aggFileSizeFromXfer[rep]) - || (test->aggFileSizeFromStat[rep] - != test->aggFileSizeFromXfer[rep])) { + if ((params->expectedAggFileSize + != results->aggFileSizeFromXfer[rep]) + || (results->aggFileSizeFromStat[rep] + != results->aggFileSizeFromXfer[rep])) { fprintf(stdout, "WARNING: Expected aggregate file size = %lld.\n", (long long) - test->aggFileSizeFromCalc[rep]); + params->expectedAggFileSize); fprintf(stdout, "WARNING: Stat() of aggregate file size = %lld.\n", (long long) - test->aggFileSizeFromStat[rep]); + results->aggFileSizeFromStat[rep]); fprintf(stdout, "WARNING: Using actual aggregate bytes moved = %lld.\n", (long long) - test->aggFileSizeFromXfer[rep]); + results->aggFileSizeFromXfer[rep]); } } } - test->aggFileSizeForBW[rep] = test->aggFileSizeFromXfer[rep]; + results->aggFileSizeForBW[rep] = results->aggFileSizeFromXfer[rep]; } /* @@ -345,7 +354,7 @@ static size_t CompareBuffers(void *expectedBuffer, void *unknownBuffer, size_t size, - IOR_offset_t transferCount, IOR_param_t * test, int access) + IOR_offset_t transferCount, IOR_param_t *test, int access) { char testFileName[MAXPATHLEN]; char bufferLabel1[MAX_STR]; @@ -553,27 +562,94 @@ static void *CreateBuffer(size_t size) tmp = aligned - sizeof(void *); *(void **)tmp = buf; - return ((void *)aligned); + return (void *)aligned; } +void AllocResults(IOR_test_t *test) +{ + int reps; + if (test->results != NULL) + return; + + reps = test->params.repetitions; + test->results = (IOR_results_t *)malloc(sizeof(IOR_results_t)); + if (test->results == NULL) + ERR("malloc of IOR_results_t failed"); + + test->results->writeTime = (double *)malloc(reps * sizeof(double)); + if (test->results->writeTime == NULL) + ERR("malloc of writeTime array failed"); + memset(test->results->writeTime, 0, reps * sizeof(double)); + + test->results->readTime = (double *)malloc(reps * sizeof(double)); + if (test->results->readTime == NULL) + ERR("malloc of readTime array failed"); + memset(test->results->readTime, 0, reps * sizeof(double)); + + test->results->aggFileSizeFromStat = + (IOR_offset_t *)malloc(reps * sizeof(IOR_offset_t)); + if (test->results->aggFileSizeFromStat == NULL) + ERR("malloc of aggFileSizeFromStat failed"); + + test->results->aggFileSizeFromXfer = + (IOR_offset_t *)malloc(reps * sizeof(IOR_offset_t)); + if (test->results->aggFileSizeFromXfer == NULL) + ERR("malloc of aggFileSizeFromXfer failed"); + + test->results->aggFileSizeForBW = + (IOR_offset_t *)malloc(reps * sizeof(IOR_offset_t)); + if (test->results->aggFileSizeForBW == NULL) + ERR("malloc of aggFileSizeForBW failed"); + +} + +void FreeResults(IOR_test_t *test) +{ + if (test->results != NULL) { + free(test->results->aggFileSizeFromStat); + free(test->results->aggFileSizeFromXfer); + free(test->results->aggFileSizeForBW); + free(test->results->readTime); + free(test->results->writeTime); + free(test->results); + } +} + + /* * Create new test for list of tests. */ -IOR_queue_t *CreateNewTest(int test_num) +IOR_test_t *CreateTest(IOR_param_t *init_params, int test_num) { - IOR_queue_t *newTest = NULL; + IOR_test_t *newTest = NULL; - newTest = (IOR_queue_t *) malloc(sizeof(IOR_queue_t)); + newTest = (IOR_test_t *) malloc(sizeof(IOR_test_t)); if (newTest == NULL) - ERR("out of memory"); - newTest->testParameters = initialTestParams; - GetPlatformName(newTest->testParameters.platform); - newTest->testParameters.nodes = - initialTestParams.numTasks / tasksPerNode; - newTest->testParameters.tasksPerNode = tasksPerNode; - newTest->testParameters.id = test_num; - newTest->nextTest = NULL; - return (newTest); + ERR("malloc() of IOR_test_t failed"); + newTest->params = *init_params; + GetPlatformName(newTest->params.platform); + newTest->params.nodes = init_params->numTasks / tasksPerNode; + newTest->params.tasksPerNode = tasksPerNode; + newTest->params.id = test_num; + newTest->next = NULL; + newTest->results = NULL; + return newTest; +} + +static void DestroyTest(IOR_test_t *test) +{ + FreeResults(test); + free(test); +} + +static void DestroyTests(IOR_test_t *tests_head) +{ + IOR_test_t *tptr, *next; + + for (tptr = tests_head; tptr != NULL; tptr = next) { + next = tptr->next; + DestroyTest(tptr); + } } /* @@ -1103,11 +1179,11 @@ ReadCheck(void *fd, void *buffer, void *checkBuffer, void *readCheckBuffer, - IOR_param_t * test, + IOR_param_t *params, IOR_offset_t transfer, IOR_offset_t blockSize, - IOR_offset_t * amtXferred, - IOR_offset_t * transferCount, int access, int *errors) + IOR_offset_t *amtXferred, + IOR_offset_t *transferCount, int access, int *errors) { int readCheckToRank, readCheckFromRank; MPI_Status status; @@ -1115,18 +1191,18 @@ ReadCheck(void *fd, IOR_offset_t segmentSize, segmentNum; memset(buffer, 'a', transfer); - *amtXferred = backend->xfer(access, fd, buffer, transfer, test); - tmpOffset = test->offset; - if (test->filePerProc == FALSE) { + *amtXferred = backend->xfer(access, fd, buffer, transfer, params); + tmpOffset = params->offset; + if (params->filePerProc == FALSE) { /* offset changes for shared file, not for file-per-proc */ - segmentSize = test->numTasks * blockSize; - segmentNum = test->offset / segmentSize; + segmentSize = params->numTasks * blockSize; + segmentNum = params->offset / segmentSize; /* work in current segment */ - test->offset = (((test->offset % segmentSize) + params->offset = (((params->offset % segmentSize) /* offset to neighbor's data */ - + ((test->reorderTasks ? - test->tasksPerNode : 0) * blockSize)) + + ((params->reorderTasks ? + params->tasksPerNode : 0) * blockSize)) /* stay within current segment */ % segmentSize) /* return segment to actual file offset */ @@ -1138,38 +1214,38 @@ ReadCheck(void *fd, #if USE_UNDOC_OPT /* corruptFile */ MPI_CHECK(MPI_Barrier(testComm), "barrier error"); /* intentionally corrupt file to determine if check works */ - if (test->corruptFile) { - CorruptFile(test->testFileName, test, 0, READCHECK); + if (params->corruptFile) { + CorruptFile(params->testFileName, params, 0, READCHECK); } #endif /* USE_UNDOC_OPT - corruptFile */ MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (test->filePerProc) { - *amtXferred = backend->xfer(access, test->fd_fppReadCheck, - checkBuffer, transfer, test); + if (params->filePerProc) { + *amtXferred = backend->xfer(access, params->fd_fppReadCheck, + checkBuffer, transfer, params); } else { *amtXferred = - backend->xfer(access, fd, checkBuffer, transfer, test); + backend->xfer(access, fd, checkBuffer, transfer, params); } - test->offset = tmpOffset; + params->offset = tmpOffset; if (*amtXferred != transfer) ERR("cannot reread from file read check"); (*transferCount)++; /* exchange buffers */ memset(readCheckBuffer, 'a', transfer); - readCheckToRank = (rank + (test->reorderTasks ? test->tasksPerNode : 0)) - % test->numTasks; - readCheckFromRank = (rank + (test->numTasks + readCheckToRank = (rank + (params->reorderTasks ? params->tasksPerNode : 0)) + % params->numTasks; + readCheckFromRank = (rank + (params->numTasks - - (test-> - reorderTasks ? test->tasksPerNode : 0))) - % test->numTasks; + (params-> + reorderTasks ? params->tasksPerNode : 0))) + % params->numTasks; MPI_CHECK(MPI_Barrier(testComm), "barrier error"); MPI_Sendrecv(checkBuffer, transfer, MPI_CHAR, readCheckToRank, 1, readCheckBuffer, transfer, MPI_CHAR, readCheckFromRank, 1, testComm, &status); MPI_CHECK(MPI_Barrier(testComm), "barrier error"); *errors += CompareBuffers(buffer, readCheckBuffer, transfer, - *transferCount, test, READCHECK); + *transferCount, params, READCHECK); return; } /* ReadCheck() */ @@ -1178,7 +1254,7 @@ ReadCheck(void *fd, * Reduce test results, and show if verbose set. */ -static void ReduceIterResults(IOR_param_t * test, double **timer, int rep, +static void ReduceIterResults(IOR_test_t *test, double **timer, int rep, int access) { double reduced[12] = { 0 }; @@ -1211,21 +1287,21 @@ static void ReduceIterResults(IOR_param_t * test, double **timer, int rep, } if (access == WRITE) { totalTime = reduced[5] - reduced[0]; - test->writeTime[rep] = totalTime; + test->results->writeTime[rep] = totalTime; diff_subset = &diff[0]; } else { /* READ */ totalTime = reduced[11] - reduced[6]; - test->readTime[rep] = totalTime; + test->results->readTime[rep] = totalTime; diff_subset = &diff[4]; } #if USE_UNDOC_OPT /* fillTheFileSystem */ - if (test->fillTheFileSystem && rep == 0 && verbose >= VERBOSE_1) { + if (test->params.fillTheFileSystem && rep == 0 && verbose >= VERBOSE_1) { fprintf(stdout, " . . . skipping iteration results output . . .\n"); fflush(stdout); } - if (verbose < VERBOSE_0 || test->fillTheFileSystem) { + if (verbose < VERBOSE_0 || test->params.fillTheFileSystem) { #else if (verbose < VERBOSE_0) { #endif @@ -1233,10 +1309,10 @@ static void ReduceIterResults(IOR_param_t * test, double **timer, int rep, } fprintf(stdout, "%-10s", access == WRITE ? "write" : "read"); - bw = (double)test->aggFileSizeForBW[rep] / totalTime; + bw = (double)test->results->aggFileSizeForBW[rep] / totalTime; PPDouble(LEFT, bw / MEBIBYTE, " "); - PPDouble(LEFT, (double)test->blockSize / KIBIBYTE, " "); - PPDouble(LEFT, (double)test->transferSize / KIBIBYTE, " "); + PPDouble(LEFT, (double)test->params.blockSize / KIBIBYTE, " "); + PPDouble(LEFT, (double)test->params.transferSize / KIBIBYTE, " "); PPDouble(LEFT, diff_subset[0], " "); PPDouble(LEFT, diff_subset[1], " "); PPDouble(LEFT, diff_subset[2], " "); @@ -1276,9 +1352,9 @@ static void RemoveFile(char *testFileName, int filePerProc, IOR_param_t * test) /* * Setup tests by parsing commandline and creating test script. */ -static IOR_queue_t *SetupTests(int argc, char **argv) +static IOR_test_t *SetupTests(int argc, char **argv) { - IOR_queue_t *tests, *testsHead; + IOR_test_t *tests, *testsHead; /* count the tasks per node */ tasksPerNode = CountTasksPerNode(numTasksWorld, MPI_COMM_WORLD); @@ -1293,8 +1369,8 @@ static IOR_queue_t *SetupTests(int argc, char **argv) /* check validity of tests and create test queue */ while (tests != NULL) { - ValidTests(&tests->testParameters); - tests = tests->nextTest; + ValidTests(&tests->params); + tests = tests->next; } /* check for skew between tasks' start times */ @@ -1410,23 +1486,24 @@ static void ShowTestInfo(IOR_param_t * test) /* * Show simple test output with max results for iterations. */ -static void ShowSetup(IOR_param_t * test) +static void ShowSetup(IOR_param_t *params) { - if (strcmp(test->debug, "") != 0) { + + if (strcmp(params->debug, "") != 0) { fprintf(stdout, "\n*** DEBUG MODE ***\n"); - fprintf(stdout, "*** %s ***\n\n", test->debug); + fprintf(stdout, "*** %s ***\n\n", params->debug); } fprintf(stdout, "\nSummary:\n"); - fprintf(stdout, "\tapi = %s\n", test->apiVersion); - fprintf(stdout, "\ttest filename = %s\n", test->testFileName); + fprintf(stdout, "\tapi = %s\n", params->apiVersion); + fprintf(stdout, "\ttest filename = %s\n", params->testFileName); fprintf(stdout, "\taccess = "); - if (test->filePerProc) { + if (params->filePerProc) { fprintf(stdout, "file-per-process"); } else { fprintf(stdout, "single-shared-file"); } - if (verbose >= VERBOSE_1 && strcmp(test->api, "POSIX") != 0) { - if (test->collective == FALSE) { + if (verbose >= VERBOSE_1 && strcmp(params->api, "POSIX") != 0) { + if (params->collective == FALSE) { fprintf(stdout, ", independent"); } else { fprintf(stdout, ", collective"); @@ -1434,56 +1511,56 @@ static void ShowSetup(IOR_param_t * test) } fprintf(stdout, "\n"); if (verbose >= VERBOSE_1) { - if (test->segmentCount > 1) { + if (params->segmentCount > 1) { fprintf(stdout, "\tpattern = strided (%d segments)\n", - (int)test->segmentCount); + (int)params->segmentCount); } else { fprintf(stdout, "\tpattern = segmented (1 segment)\n"); } } fprintf(stdout, "\tordering in a file ="); - if (test->randomOffset == FALSE) { + if (params->randomOffset == FALSE) { fprintf(stdout, " sequential offsets\n"); } else { fprintf(stdout, " random offsets\n"); } fprintf(stdout, "\tordering inter file="); - if (test->reorderTasks == FALSE && test->reorderTasksRandom == FALSE) { + if (params->reorderTasks == FALSE && params->reorderTasksRandom == FALSE) { fprintf(stdout, " no tasks offsets\n"); } - if (test->reorderTasks == TRUE) { + if (params->reorderTasks == TRUE) { fprintf(stdout, " constant task offsets = %d\n", - test->taskPerNodeOffset); + params->taskPerNodeOffset); } - if (test->reorderTasksRandom == TRUE) { + if (params->reorderTasksRandom == TRUE) { fprintf(stdout, " random task offsets >= %d, seed=%d\n", - test->taskPerNodeOffset, test->reorderTasksRandomSeed); + params->taskPerNodeOffset, params->reorderTasksRandomSeed); } fprintf(stdout, "\tclients = %d (%d per node)\n", - test->numTasks, test->tasksPerNode); - fprintf(stdout, "\trepetitions = %d\n", test->repetitions); + params->numTasks, params->tasksPerNode); + fprintf(stdout, "\trepetitions = %d\n", params->repetitions); fprintf(stdout, "\txfersize = %s\n", - HumanReadable(test->transferSize, BASE_TWO)); + HumanReadable(params->transferSize, BASE_TWO)); fprintf(stdout, "\tblocksize = %s\n", - HumanReadable(test->blockSize, BASE_TWO)); + HumanReadable(params->blockSize, BASE_TWO)); fprintf(stdout, "\taggregate filesize = %s\n", - HumanReadable(test->aggFileSizeFromCalc[0], BASE_TWO)); + HumanReadable(params->expectedAggFileSize, BASE_TWO)); #ifdef HAVE_LUSTRE_LUSTRE_USER_H fprintf(stdout, "\tLustre stripe size = %s\n", - ((test->lustre_stripe_size == 0) ? "Use default" : - HumanReadable(test->lustre_stripe_size, BASE_TWO))); - if (test->lustre_stripe_count == 0) { + ((params->lustre_stripe_size == 0) ? "Use default" : + HumanReadable(params->lustre_stripe_size, BASE_TWO))); + if (params->lustre_stripe_count == 0) { fprintf(stdout, "\t stripe count = %s\n", "Use default"); } else { fprintf(stdout, "\t stripe count = %d\n", - test->lustre_stripe_count); + params->lustre_stripe_count); } #endif /* HAVE_LUSTRE_LUSTRE_USER_H */ - if (test->deadlineForStonewalling > 0) { + if (params->deadlineForStonewalling > 0) { fprintf(stdout, "\tUsing stonewalling = %d second(s)\n", - test->deadlineForStonewalling); + params->deadlineForStonewalling); } fprintf(stdout, "\n"); /*fprintf(stdout, "\n ================================\n\n"); */ @@ -1657,8 +1734,10 @@ static struct results *ops_values(int reps, int num_tasks, /* * Summarize results, showing max rates (and min, mean, stddev if verbose) */ -static void SummarizeResults(IOR_param_t * test) +static void PrintSummaryOneTest(IOR_test_t *test) { + IOR_param_t *params = &test->params; + IOR_results_t *results = test->results; struct results *write_bw; struct results *read_bw; struct results *write_ops; @@ -1666,108 +1745,87 @@ static void SummarizeResults(IOR_param_t * test) int reps; int i, j; - reps = test->repetitions; + if (rank != 0) + return; - write_bw = bw_values(reps, test->aggFileSizeForBW, test->writeTime); - read_bw = bw_values(reps, test->aggFileSizeForBW, test->readTime); - write_ops = ops_values(reps, test->numTasks, test->blockSize, - test->transferSize, test->writeTime); - read_ops = ops_values(reps, test->numTasks, test->blockSize, - test->transferSize, test->readTime); + reps = params->repetitions; - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "\n"); - fprintf(stdout, - "Operation Max(MiB) Min(MiB) Mean(MiB) StdDev Max(OPs) Min(OPs) Mean(OPs) StdDev Mean(s) "); - if (verbose >= VERBOSE_1) - fprintf(stdout, - "#Tasks tPN reps fPP reord reordoff reordrand seed segcnt blksiz xsize aggsize TestNum API"); - fprintf(stdout, "\n"); - fprintf(stdout, - "--------- --------- --------- ---------- ------- --------- --------- ---------- ------- --------\n"); - if (test->writeFile) { - fprintf(stdout, "%s ", "write"); - fprintf(stdout, "%10.2f ", write_bw->max / MEBIBYTE); - fprintf(stdout, "%10.2f ", write_bw->min / MEBIBYTE); - fprintf(stdout, "%10.2f", write_bw->mean / MEBIBYTE); - fprintf(stdout, "%10.2f ", write_bw->sd / MEBIBYTE); - fprintf(stdout, "%10.2f ", write_ops->max); - fprintf(stdout, "%10.2f ", write_ops->min); - fprintf(stdout, "%10.2f", write_ops->mean); - fprintf(stdout, "%10.2f", write_ops->sd); - fprintf(stdout, "%10.5f ", - mean_of_array_of_doubles(test->writeTime, - test->repetitions)); - if (verbose >= VERBOSE_1) { - fprintf(stdout, "%d ", test->numTasks); - fprintf(stdout, "%d ", test->tasksPerNode); - fprintf(stdout, "%d ", test->repetitions); - fprintf(stdout, "%d ", test->filePerProc); - fprintf(stdout, "%d ", test->reorderTasks); - fprintf(stdout, "%d ", test->taskPerNodeOffset); - fprintf(stdout, "%d ", - test->reorderTasksRandom); - fprintf(stdout, "%d ", - test->reorderTasksRandomSeed); - fprintf(stdout, "%lld ", test->segmentCount); - fprintf(stdout, "%lld ", test->blockSize); - fprintf(stdout, "%lld ", test->transferSize); - fprintf(stdout, "%lld ", - test->aggFileSizeForBW[0]); - fprintf(stdout, "%d ", test->TestNum); - fprintf(stdout, "%s ", test->api); - } - fprintf(stdout, "\n"); - } - if (test->readFile) { - fprintf(stdout, "%s ", "read"); - fprintf(stdout, "%10.2f ", read_bw->max / MEBIBYTE); - fprintf(stdout, "%10.2f ", read_bw->min / MEBIBYTE); - fprintf(stdout, "%10.2f", read_bw->mean / MEBIBYTE); - fprintf(stdout, "%10.2f ", read_bw->sd / MEBIBYTE); - fprintf(stdout, "%10.2f ", read_ops->max); - fprintf(stdout, "%10.2f ", read_ops->min); - fprintf(stdout, "%10.2f", read_ops->mean); - fprintf(stdout, "%10.2f", read_ops->sd); - fprintf(stdout, "%10.5f ", - mean_of_array_of_doubles(test->readTime, - test->repetitions)); - if (verbose >= VERBOSE_1) { - fprintf(stdout, "%d ", test->numTasks); - fprintf(stdout, "%d ", test->tasksPerNode); - fprintf(stdout, "%d ", test->repetitions); - fprintf(stdout, "%d ", test->filePerProc); - fprintf(stdout, "%d ", test->reorderTasks); - fprintf(stdout, "%d ", test->taskPerNodeOffset); - fprintf(stdout, "%d ", - test->reorderTasksRandom); - fprintf(stdout, "%d ", - test->reorderTasksRandomSeed); - fprintf(stdout, "%lld ", test->segmentCount); - fprintf(stdout, "%lld ", test->blockSize); - fprintf(stdout, "%lld ", test->transferSize); - fprintf(stdout, "%lld ", - test->aggFileSizeForBW[0]); - fprintf(stdout, "%d ", test->TestNum); - fprintf(stdout, "%s ", test->api); - } - fprintf(stdout, "\n"); - } - fflush(stdout); - } + write_bw = bw_values(reps, results->aggFileSizeForBW, results->writeTime); + read_bw = bw_values(reps, results->aggFileSizeForBW, results->readTime); + write_ops = ops_values(reps, params->numTasks, params->blockSize, + params->transferSize, results->writeTime); + read_ops = ops_values(reps, params->numTasks, params->blockSize, + params->transferSize, results->readTime); - if (rank == 0 && verbose >= VERBOSE_0) { - fprintf(stdout, "\n"); - if (test->writeFile) { - fprintf(stdout, "Max Write: %.2f MiB/sec (%.2f MB/sec)\n", - write_bw->max/MEBIBYTE, write_bw->max / MEGABYTE); - } - if (test->readFile) { - fprintf(stdout, "Max Read: %.2f MiB/sec (%.2f MB/sec)\n", - read_bw->max/MEBIBYTE, read_bw->max/MEGABYTE); - } - fprintf(stdout, "\n"); - } + if (params->writeFile) { + fprintf(stdout, "%s ", "write"); + fprintf(stdout, "%10.2f ", write_bw->max / MEBIBYTE); + fprintf(stdout, "%10.2f ", write_bw->min / MEBIBYTE); + fprintf(stdout, "%10.2f", write_bw->mean / MEBIBYTE); + fprintf(stdout, "%10.2f ", write_bw->sd / MEBIBYTE); + fprintf(stdout, "%10.2f ", write_ops->max); + fprintf(stdout, "%10.2f ", write_ops->min); + fprintf(stdout, "%10.2f", write_ops->mean); + fprintf(stdout, "%10.2f", write_ops->sd); + fprintf(stdout, "%10.5f ", + mean_of_array_of_doubles(results->writeTime, + params->repetitions)); + if (verbose >= VERBOSE_0) { + fprintf(stdout, "%d ", params->numTasks); + fprintf(stdout, "%d ", params->tasksPerNode); + fprintf(stdout, "%d ", params->repetitions); + fprintf(stdout, "%d ", params->filePerProc); + fprintf(stdout, "%d ", params->reorderTasks); + fprintf(stdout, "%d ", params->taskPerNodeOffset); + fprintf(stdout, "%d ", + params->reorderTasksRandom); + fprintf(stdout, "%d ", + params->reorderTasksRandomSeed); + fprintf(stdout, "%lld ", params->segmentCount); + fprintf(stdout, "%lld ", params->blockSize); + fprintf(stdout, "%lld ", params->transferSize); + fprintf(stdout, "%lld ", + results->aggFileSizeForBW[0]); + fprintf(stdout, "%d ", params->TestNum); + fprintf(stdout, "%s ", params->api); + } + fprintf(stdout, "\n"); + } + if (params->readFile) { + fprintf(stdout, "%s ", "read"); + fprintf(stdout, "%10.2f ", read_bw->max / MEBIBYTE); + fprintf(stdout, "%10.2f ", read_bw->min / MEBIBYTE); + fprintf(stdout, "%10.2f", read_bw->mean / MEBIBYTE); + fprintf(stdout, "%10.2f ", read_bw->sd / MEBIBYTE); + fprintf(stdout, "%10.2f ", read_ops->max); + fprintf(stdout, "%10.2f ", read_ops->min); + fprintf(stdout, "%10.2f", read_ops->mean); + fprintf(stdout, "%10.2f", read_ops->sd); + fprintf(stdout, "%10.5f ", + mean_of_array_of_doubles(results->readTime, + params->repetitions)); + if (verbose >= VERBOSE_0) { + fprintf(stdout, "%d ", params->numTasks); + fprintf(stdout, "%d ", params->tasksPerNode); + fprintf(stdout, "%d ", params->repetitions); + fprintf(stdout, "%d ", params->filePerProc); + fprintf(stdout, "%d ", params->reorderTasks); + fprintf(stdout, "%d ", params->taskPerNodeOffset); + fprintf(stdout, "%d ", + params->reorderTasksRandom); + fprintf(stdout, "%d ", + params->reorderTasksRandomSeed); + fprintf(stdout, "%lld ", params->segmentCount); + fprintf(stdout, "%lld ", params->blockSize); + fprintf(stdout, "%lld ", params->transferSize); + fprintf(stdout, "%lld ", + results->aggFileSizeForBW[0]); + fprintf(stdout, "%d ", params->TestNum); + fprintf(stdout, "%s ", params->api); + } + fprintf(stdout, "\n"); + } + fflush(stdout); free(write_bw); free(write_ops); @@ -1775,11 +1833,69 @@ static void SummarizeResults(IOR_param_t * test) free(read_ops); } +static void PrintSummaryAllTests(IOR_test_t *tests_head) +{ + IOR_test_t *tptr; + int i; + + + if (rank !=0) + return; + + fprintf(stdout, "\n"); + fprintf(stdout, "Summary of all tests:"); + fprintf(stdout, "\n"); + fprintf(stdout, "Operation Max(MiB) Min(MiB) Mean(MiB) StdDev Max(OPs) Min(OPs) Mean(OPs) StdDev Mean(s) #Tasks tPN reps fPP reord reordoff reordrand seed segcnt blksiz xsize aggsize TestNum API\n"); + + for (tptr = tests_head; tptr != NULL; tptr = tptr->next) { + PrintSummaryOneTest(tptr); + } + + fprintf(stdout, "\n"); +} + +static void PrintShortSummary(IOR_test_t * test) +{ + IOR_param_t *params = &test->params; + IOR_results_t *results = test->results; + double max_write = 0.0; + double max_read = 0.0; + double bw; + int reps; + int i; + + if (rank != 0 || verbose < VERBOSE_0) + return; + + reps = params->repetitions; + + max_write = results->writeTime[0]; + max_read = results->readTime[0]; + for (i = 0; i < reps; i++) { + bw = (double)results->aggFileSizeForBW[i]/results->writeTime[i]; + max_write = MAX(bw, max_write); + bw = (double)results->aggFileSizeForBW[i]/results->readTime[i]; + max_read = MAX(bw, max_read); + } + + fprintf(stdout, "\n"); + if (params->writeFile) { + fprintf(stdout, "Max Write: %.2f MiB/sec (%.2f MB/sec)\n", + max_write/MEBIBYTE, max_write/MEGABYTE); + } + if (params->readFile) { + fprintf(stdout, "Max Read: %.2f MiB/sec (%.2f MB/sec)\n", + max_read/MEBIBYTE, max_read/MEGABYTE); + } +} + /* * Using the test parameters, run iteration(s) of single test. */ -static void TestIoSys(IOR_param_t * test) +static void TestIoSys(IOR_test_t *test) { + IOR_param_t *params = &test->params; + IOR_results_t *results = test->results; char testFileName[MAX_STR]; double *timer[12]; double startTime; @@ -1790,119 +1906,87 @@ static void TestIoSys(IOR_param_t * test) IOR_offset_t dataMoved; /* for data rate calculation */ /* set up communicator for test */ - if (test->numTasks > numTasksWorld) { + if (params->numTasks > numTasksWorld) { if (rank == 0) { fprintf(stdout, "WARNING: More tasks requested (%d) than available (%d),", - test->numTasks, numTasksWorld); + params->numTasks, numTasksWorld); fprintf(stdout, " running on %d tasks.\n", numTasksWorld); } - test->numTasks = numTasksWorld; + params->numTasks = numTasksWorld; } MPI_CHECK(MPI_Comm_group(MPI_COMM_WORLD, &orig_group), "MPI_Comm_group() error"); range[0] = 0; /* first rank */ - range[1] = test->numTasks - 1; /* last rank */ + range[1] = params->numTasks - 1; /* last rank */ range[2] = 1; /* stride */ MPI_CHECK(MPI_Group_range_incl(orig_group, 1, &range, &new_group), "MPI_Group_range_incl() error"); MPI_CHECK(MPI_Comm_create(MPI_COMM_WORLD, new_group, &testComm), "MPI_Comm_create() error"); - test->testComm = testComm; + params->testComm = testComm; if (testComm == MPI_COMM_NULL) { /* tasks not in the group do not participate in this test */ MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); return; } if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "Participating tasks: %d\n", test->numTasks); + fprintf(stdout, "Participating tasks: %d\n", params->numTasks); fflush(stdout); } - if (rank == 0 && test->reorderTasks == TRUE && verbose >= VERBOSE_1) { + if (rank == 0 && params->reorderTasks == TRUE && verbose >= VERBOSE_1) { fprintf(stdout, "Using reorderTasks '-C' (expecting block, not cyclic, task assignment)\n"); fflush(stdout); } - test->tasksPerNode = CountTasksPerNode(test->numTasks, testComm); + params->tasksPerNode = CountTasksPerNode(params->numTasks, testComm); /* setup timers */ for (i = 0; i < 12; i++) { - timer[i] = (double *)malloc(test->repetitions * sizeof(double)); + timer[i] = (double *)malloc(params->repetitions * sizeof(double)); if (timer[i] == NULL) ERR("malloc failed"); } - test->writeTime = (double *)malloc(test->repetitions * sizeof(double)); - if (test->writeTime == NULL) - ERR("malloc failed"); - memset(test->writeTime, 0, test->repetitions * sizeof(double)); - test->readTime = (double *)malloc(test->repetitions * sizeof(double)); - if (test->readTime == NULL) - ERR("malloc failed"); - memset(test->readTime, 0, test->repetitions * sizeof(double)); - - test->aggFileSizeFromCalc = - (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeFromCalc == NULL) - ERR("malloc failed"); - test->aggFileSizeFromStat = - (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeFromStat == NULL) - ERR("malloc failed"); - test->aggFileSizeFromXfer = - (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeFromXfer == NULL) - ERR("malloc failed"); - test->aggFileSizeForBW = - (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeForBW == NULL) - ERR("malloc failed"); - /* bind I/O calls to specific API */ - AioriBind(test->api); - - /* file size is first calculated on for comparison */ - for (rep = 0; rep < test->repetitions; rep++) { - test->aggFileSizeFromCalc[rep] = - test->blockSize * test->segmentCount * test->numTasks; - } + AioriBind(params->api); /* show test setup */ if (rank == 0 && verbose >= VERBOSE_0) - ShowSetup(test); + ShowSetup(params); startTime = GetTimeStamp(); - maxTimeDuration = test->maxTimeDuration * 60; /* convert to seconds */ + maxTimeDuration = params->maxTimeDuration * 60; /* convert to seconds */ #if USE_UNDOC_OPT /* fillTheFileSystem */ - if (rank == 0 && test->fillTheFileSystem && verbose >= VERBOSE_0) { + if (rank == 0 && params->fillTheFileSystem && verbose >= VERBOSE_0) { fprintf(stdout, "Run started: %s", CurrentTimeString()); } #endif /* USE_UNDOC_OPT - fillTheFileSystem */ /* loop over test iterations */ - for (rep = 0; rep < test->repetitions; rep++) { + for (rep = 0; rep < params->repetitions; rep++) { /* Get iteration start time in seconds in task 0 and broadcast to all tasks */ if (rank == 0) { - if (test->setTimeStampSignature) { - test->timeStampSignatureValue = - (unsigned int)test->setTimeStampSignature; + if (params->setTimeStampSignature) { + params->timeStampSignatureValue = + (unsigned int)params->setTimeStampSignature; } else { time_t currentTime; if ((currentTime = time(NULL)) == -1) { ERR("cannot get current time"); } - test->timeStampSignatureValue = + params->timeStampSignatureValue = (unsigned int)currentTime; } if (verbose >= VERBOSE_2) { fprintf(stdout, "Using Time Stamp %u (0x%x) for Data Signature\n", - test->timeStampSignatureValue, - test->timeStampSignatureValue); + params->timeStampSignatureValue, + params->timeStampSignatureValue); } if (rep == 0) { fprintf(stdout, "access bw(MiB/s) block(KiB) xfer(KiB) open(s) wr/rd(s) close(s) total(s) iter\n"); @@ -1910,50 +1994,50 @@ static void TestIoSys(IOR_param_t * test) } } MPI_CHECK(MPI_Bcast - (&test->timeStampSignatureValue, 1, MPI_UNSIGNED, 0, + (¶ms->timeStampSignatureValue, 1, MPI_UNSIGNED, 0, testComm), "cannot broadcast start time value"); #if USE_UNDOC_OPT /* fillTheFileSystem */ - if (test->fillTheFileSystem && + if (params->fillTheFileSystem && rep > 0 - && rep % (test->fillTheFileSystem / test->numTasks) == 0) { + && rep % (params->fillTheFileSystem / params->numTasks) == 0) { if (rank == 0 && verbose >= VERBOSE_0) { fprintf(stdout, "at file #%d, time: %s", - rep * test->numTasks, + rep * params->numTasks, CurrentTimeString()); fflush(stdout); } } #endif /* USE_UNDOC_OPT - fillTheFileSystem */ /* use repetition count for number of multiple files */ - if (test->multiFile) - test->repCounter = rep; + if (params->multiFile) + params->repCounter = rep; /* * write the file(s), getting timing between I/O calls */ - if (test->writeFile + if (params->writeFile #if USE_UNDOC_OPT /* multiReRead */ - && (!test->multiReRead || !rep) + && (!params->multiReRead || !rep) #endif /* USE_UNDOC_OPT - multiReRead */ && (maxTimeDuration ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { - GetTestFileName(testFileName, test); + GetTestFileName(testFileName, params); if (verbose >= VERBOSE_3) { fprintf(stdout, "task %d writing %s\n", rank, testFileName); } - DelaySecs(test->interTestDelay); - if (test->useExistingTestFile == FALSE) { - RemoveFile(testFileName, test->filePerProc, - test); + DelaySecs(params->interTestDelay); + if (params->useExistingTestFile == FALSE) { + RemoveFile(testFileName, params->filePerProc, + params); } MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - test->open = WRITE; + params->open = WRITE; timer[0][rep] = GetTimeStamp(); - fd = backend->create(testFileName, test); + fd = backend->create(testFileName, params); timer[1][rep] = GetTimeStamp(); - if (test->intraTestBarriers) + if (params->intraTestBarriers) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); if (rank == 0 && verbose >= VERBOSE_1) { @@ -1962,24 +2046,24 @@ static void TestIoSys(IOR_param_t * test) fprintf(stdout, "%s\n", CurrentTimeString()); } timer[2][rep] = GetTimeStamp(); - dataMoved = WriteOrRead(test, fd, WRITE); + dataMoved = WriteOrRead(params, fd, WRITE); timer[3][rep] = GetTimeStamp(); - if (test->intraTestBarriers) + if (params->intraTestBarriers) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); timer[4][rep] = GetTimeStamp(); - backend->close(fd, test); + backend->close(fd, params); #if USE_UNDOC_OPT /* includeDeleteTime */ - if (test->includeDeleteTime) { + if (params->includeDeleteTime) { if (rank == 0 && verbose >= VERBOSE_1) { fprintf(stdout, "** including delete time **\n"); } MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - RemoveFile(testFileName, test->filePerProc, - test); + RemoveFile(testFileName, params->filePerProc, + params); } #endif /* USE_UNDOC_OPT - includeDeleteTime */ @@ -1987,20 +2071,20 @@ static void TestIoSys(IOR_param_t * test) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); #if USE_UNDOC_OPT /* includeDeleteTime */ - if (test->includeDeleteTime) { + if (params->includeDeleteTime) { /* not accurate, but no longer a test file to examine */ - test->aggFileSizeFromStat[rep] = - test->aggFileSizeFromCalc[rep]; - test->aggFileSizeFromXfer[rep] = - test->aggFileSizeFromCalc[rep]; - test->aggFileSizeForBW[rep] = - test->aggFileSizeFromCalc[rep]; + results->aggFileSizeFromStat[rep] = + params->expectedAggFileSize; + results->aggFileSizeFromXfer[rep] = + params->expectedAggFileSize; + results->aggFileSizeForBW[rep] = + params->expectedAggFileSize; } else { #endif /* USE_UNDOC_OPT - includeDeleteTime */ /* get the size of the file just written */ - test->aggFileSizeFromStat[rep] - = backend->get_file_size(test, testComm, + results->aggFileSizeFromStat[rep] + = backend->get_file_size(params, testComm, testFileName); /* check if stat() of file doesn't equal expected file size, @@ -2012,10 +2096,10 @@ static void TestIoSys(IOR_param_t * test) #endif /* USE_UNDOC_OPT - includeDeleteTime */ if (verbose >= VERBOSE_3) - WriteTimes(test, timer, rep, WRITE); + WriteTimes(params, timer, rep, WRITE); ReduceIterResults(test, timer, rep, WRITE); - if (test->outlierThreshold) { - CheckForOutliers(test, timer, rep, WRITE); + if (params->outlierThreshold) { + CheckForOutliers(params, timer, rep, WRITE); } } @@ -2023,17 +2107,17 @@ static void TestIoSys(IOR_param_t * test) * perform a check of data, reading back data and comparing * against what was expected to be written */ - if (test->checkWrite + if (params->checkWrite #if USE_UNDOC_OPT /* multiReRead */ - && (!test->multiReRead || rep) + && (!params->multiReRead || rep) #endif /* USE_UNDOC_OPT - multiReRead */ && (maxTimeDuration ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { #if USE_UNDOC_OPT /* corruptFile */ MPI_CHECK(MPI_Barrier(testComm), "barrier error"); /* intentionally corrupt file to determine if check works */ - if (test->corruptFile) { - CorruptFile(testFileName, test, rep, + if (params->corruptFile) { + CorruptFile(testFileName, params, rep, WRITECHECK); } #endif /* USE_UNDOC_OPT - corruptFile */ @@ -2043,69 +2127,69 @@ static void TestIoSys(IOR_param_t * test) "Verifying contents of the file(s) just written.\n"); fprintf(stdout, "%s\n", CurrentTimeString()); } - if (test->reorderTasks) { + if (params->reorderTasks) { /* move two nodes away from writing node */ rankOffset = - (2 * test->tasksPerNode) % test->numTasks; + (2 * params->tasksPerNode) % params->numTasks; } - GetTestFileName(testFileName, test); - test->open = WRITECHECK; - fd = backend->open(testFileName, test); - dataMoved = WriteOrRead(test, fd, WRITECHECK); - backend->close(fd, test); + GetTestFileName(testFileName, params); + params->open = WRITECHECK; + fd = backend->open(testFileName, params); + dataMoved = WriteOrRead(params, fd, WRITECHECK); + backend->close(fd, params); rankOffset = 0; } /* * read the file(s), getting timing between I/O calls */ - if (test->readFile + if (params->readFile && (maxTimeDuration ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { /* Get rankOffset [file offset] for this process to read, based on -C,-Z,-Q,-X options */ /* Constant process offset reading */ - if (test->reorderTasks) { + if (params->reorderTasks) { /* move taskPerNodeOffset nodes[1==default] away from writing node */ rankOffset = - (test->taskPerNodeOffset * - test->tasksPerNode) % test->numTasks; + (params->taskPerNodeOffset * + params->tasksPerNode) % params->numTasks; } /* random process offset reading */ - if (test->reorderTasksRandom) { + if (params->reorderTasksRandom) { /* this should not intefere with randomOffset within a file because GetOffsetArrayRandom */ /* seeds every random() call */ int *rankoffs, *filecont, *filehits, ifile, jfile, nodeoffset; unsigned int iseed0; - nodeoffset = test->taskPerNodeOffset; + nodeoffset = params->taskPerNodeOffset; nodeoffset = (nodeoffset < - test->nodes) ? nodeoffset : test->nodes - + params->nodes) ? nodeoffset : params->nodes - 1; iseed0 = - (test->reorderTasksRandomSeed < - 0) ? (-1 * test->reorderTasksRandomSeed + - rep) : test->reorderTasksRandomSeed; + (params->reorderTasksRandomSeed < + 0) ? (-1 * params->reorderTasksRandomSeed + + rep) : params->reorderTasksRandomSeed; srand(rank + iseed0); { - rankOffset = rand() % test->numTasks; + rankOffset = rand() % params->numTasks; } while (rankOffset < - (nodeoffset * test->tasksPerNode)) { - rankOffset = rand() % test->numTasks; + (nodeoffset * params->tasksPerNode)) { + rankOffset = rand() % params->numTasks; } /* Get more detailed stats if requested by verbose level */ if (verbose >= VERBOSE_2) { if (rank == 0) { rankoffs = - (int *)malloc(test->numTasks + (int *)malloc(params->numTasks * sizeof(int)); filecont = - (int *)malloc(test->numTasks + (int *)malloc(params->numTasks * sizeof(int)); filehits = - (int *)malloc(test->numTasks + (int *)malloc(params->numTasks * sizeof(int)); } @@ -2117,26 +2201,26 @@ static void TestIoSys(IOR_param_t * test) /*file hits histogram */ if (rank == 0) { memset((void *)filecont, 0, - test->numTasks * + params->numTasks * sizeof(int)); for (ifile = 0; - ifile < test->numTasks; + ifile < params->numTasks; ifile++) { filecont[(ifile + rankoffs [ifile]) % - test-> + params-> numTasks]++; } memset((void *)filehits, 0, - test->numTasks * + params->numTasks * sizeof(int)); for (ifile = 0; - ifile < test->numTasks; + ifile < params->numTasks; ifile++) for (jfile = 0; jfile < - test->numTasks; + params->numTasks; jfile++) { if (ifile == filecont @@ -2145,14 +2229,14 @@ static void TestIoSys(IOR_param_t * test) [ifile]++; } /* fprintf(stdout, "File Contention Dist:"); - for (ifile=0; ifilenumTasks; ifile++) { fprintf(stdout," %d",filecont[ifile]); } + for (ifile=0; ifilenumTasks; ifile++) { fprintf(stdout," %d",filecont[ifile]); } fprintf(stdout,"\n"); */ fprintf(stdout, "#File Hits Dist:"); jfile = 0; ifile = 0; - while (jfile < test->numTasks && - ifile < test->numTasks) { + while (jfile < params->numTasks && + ifile < params->numTasks) { fprintf(stdout, " %d", filehits [ifile]); @@ -2168,24 +2252,24 @@ static void TestIoSys(IOR_param_t * test) } } /* Using globally passed rankOffset, following function generates testFileName to read */ - GetTestFileName(testFileName, test); + GetTestFileName(testFileName, params); if (verbose >= VERBOSE_3) { fprintf(stdout, "task %d reading %s\n", rank, testFileName); } - DelaySecs(test->interTestDelay); + DelaySecs(params->interTestDelay); MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - test->open = READ; + params->open = READ; timer[6][rep] = GetTimeStamp(); - fd = backend->open(testFileName, test); + fd = backend->open(testFileName, params); if (rank == 0 && verbose >= VERBOSE_2) { fprintf(stdout, "[RANK %03d] open for reading file %s\n", rank, testFileName); } timer[7][rep] = GetTimeStamp(); - if (test->intraTestBarriers) + if (params->intraTestBarriers) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); if (rank == 0 && verbose >= VERBOSE_1) { @@ -2194,18 +2278,18 @@ static void TestIoSys(IOR_param_t * test) fprintf(stdout, "%s\n", CurrentTimeString()); } timer[8][rep] = GetTimeStamp(); - dataMoved = WriteOrRead(test, fd, READ); + dataMoved = WriteOrRead(params, fd, READ); timer[9][rep] = GetTimeStamp(); - if (test->intraTestBarriers) + if (params->intraTestBarriers) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); timer[10][rep] = GetTimeStamp(); - backend->close(fd, test); + backend->close(fd, params); timer[11][rep] = GetTimeStamp(); /* get the size of the file just read */ - test->aggFileSizeFromStat[rep] = - backend->get_file_size(test, testComm, + results->aggFileSizeFromStat[rep] = + backend->get_file_size(params, testComm, testFileName); /* check if stat() of file doesn't equal expected file size, @@ -2213,10 +2297,10 @@ static void TestIoSys(IOR_param_t * test) CheckFileSize(test, dataMoved, rep); if (verbose >= VERBOSE_3) - WriteTimes(test, timer, rep, READ); + WriteTimes(params, timer, rep, READ); ReduceIterResults(test, timer, rep, READ); - if (test->outlierThreshold) { - CheckForOutliers(test, timer, rep, READ); + if (params->outlierThreshold) { + CheckForOutliers(params, timer, rep, READ); } } @@ -2225,7 +2309,7 @@ static void TestIoSys(IOR_param_t * test) * perform a check of data, reading back data twice and * comparing against what was expected to be read */ - if (test->checkRead + if (params->checkRead && (maxTimeDuration ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { MPI_CHECK(MPI_Barrier(testComm), "barrier error"); @@ -2236,39 +2320,39 @@ static void TestIoSys(IOR_param_t * test) "verify that reads are consistent.\n"); fprintf(stdout, "%s\n", CurrentTimeString()); } - if (test->reorderTasks) { + if (params->reorderTasks) { /* move three nodes away from reading node */ rankOffset = - (3 * test->tasksPerNode) % test->numTasks; + (3 * params->tasksPerNode) % params->numTasks; } - GetTestFileName(testFileName, test); + GetTestFileName(testFileName, params); MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - test->open = READCHECK; - fd = backend->open(testFileName, test); - if (test->filePerProc) { + params->open = READCHECK; + fd = backend->open(testFileName, params); + if (params->filePerProc) { int tmpRankOffset; tmpRankOffset = rankOffset; /* increment rankOffset to open comparison file on other node */ - if (test->reorderTasks) { + if (params->reorderTasks) { /* move four nodes away from reading node */ rankOffset = - (4 * test->tasksPerNode) % - test->numTasks; + (4 * params->tasksPerNode) % + params->numTasks; } - GetTestFileName(test->testFileName_fppReadCheck, - test); + GetTestFileName(params->testFileName_fppReadCheck, + params); rankOffset = tmpRankOffset; - test->fd_fppReadCheck = - backend->open(test-> + params->fd_fppReadCheck = + backend->open(params-> testFileName_fppReadCheck, - test); + params); } - dataMoved = WriteOrRead(test, fd, READCHECK); - if (test->filePerProc) { - backend->close(test->fd_fppReadCheck, test); - test->fd_fppReadCheck = NULL; + dataMoved = WriteOrRead(params, fd, READCHECK); + if (params->filePerProc) { + backend->close(params->fd_fppReadCheck, params); + params->fd_fppReadCheck = NULL; } - backend->close(fd, test); + backend->close(fd, params); } /* * this final barrier may not be necessary as backend->close should @@ -2277,30 +2361,25 @@ static void TestIoSys(IOR_param_t * test) * the MPI_Barrier() call has been included. */ MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (!test->keepFile - && !(test->keepFileWithError && test->errorFound)) { - RemoveFile(testFileName, test->filePerProc, test); + if (!params->keepFile + && !(params->keepFileWithError && params->errorFound)) { + RemoveFile(testFileName, params->filePerProc, params); } - test->errorFound = FALSE; + params->errorFound = FALSE; MPI_CHECK(MPI_Barrier(testComm), "barrier error"); rankOffset = 0; } #if USE_UNDOC_OPT /* fillTheFileSystem */ - if (rank == 0 && test->fillTheFileSystem && verbose >= VERBOSE_0) { + if (rank == 0 && params->fillTheFileSystem && verbose >= VERBOSE_0) { fprintf(stdout, "Run ended: %s", CurrentTimeString()); } #endif /* USE_UNDOC_OPT - fillTheFileSystem */ - SummarizeResults(test); - MPI_CHECK(MPI_Comm_free(&testComm), "MPI_Comm_free() error"); - free(test->writeTime); - free(test->readTime); - free(test->aggFileSizeFromCalc); - free(test->aggFileSizeFromStat); - free(test->aggFileSizeFromXfer); - free(test->aggFileSizeForBW); + + PrintShortSummary(test); + for (i = 0; i < 12; i++) { free(timer[i]); } diff --git a/src/ior.h b/src/ior.h index f8c3141..325a25f 100644 --- a/src/ior.h +++ b/src/ior.h @@ -55,8 +55,6 @@ typedef struct int repCounter; /* rep counter */ int multiFile; /* multiple files */ int interTestDelay; /* delay between reps in seconds */ - double *writeTime; /* array of write time results for each rep */ - double *readTime; /* array to read time results for each rep */ int open; /* flag for writing or reading */ int readFile; /* read of existing file */ int writeFile; /* write of file */ @@ -76,10 +74,7 @@ typedef struct IOR_offset_t blockSize; /* contiguous bytes to write per task */ IOR_offset_t transferSize; /* size of transfer in bytes */ IOR_offset_t offset; /* offset for read/write */ - IOR_offset_t * aggFileSizeFromCalc; /* calculated aggregate file size */ - IOR_offset_t * aggFileSizeFromStat; /* stat() aggregate file size */ - IOR_offset_t * aggFileSizeFromXfer; /* transfered aggregate file size */ - IOR_offset_t * aggFileSizeForBW; /* aggregate file size used for b/w */ + IOR_offset_t expectedAggFileSize; /* calculated aggregate file size */ int preallocate; /* preallocate file size */ int useFileView; /* use MPI_File_set_view */ int useSharedFilePointer; /* use shared file pointer */ @@ -141,13 +136,25 @@ typedef struct int intraTestBarriers; /* barriers between open/op and op/close */ } IOR_param_t; -/* define the queuing structure for the test parameters */ -typedef struct IOR_queue_t { - IOR_param_t testParameters; - struct IOR_queue_t *nextTest; -} IOR_queue_t; +/* each pointer is to an array, each of length equal to the number of + repetitions in the test */ +typedef struct { + double *writeTime; + double *readTime; + IOR_offset_t *aggFileSizeFromStat; + IOR_offset_t *aggFileSizeFromXfer; + IOR_offset_t *aggFileSizeForBW; +} IOR_results_t; -IOR_queue_t *CreateNewTest(int); +/* define the queuing structure for the test parameters */ +typedef struct IOR_test_t { + IOR_param_t params; + IOR_results_t *results; + struct IOR_test_t *next; +} IOR_test_t; + +IOR_test_t *CreateTest(IOR_param_t *init_params, int test_num); +void AllocResults(IOR_test_t *test); void GetPlatformName(char *); void init_IOR_Param_t(IOR_param_t *p); diff --git a/src/parse_options.c b/src/parse_options.c index fcfc1fb..099cf7a 100644 --- a/src/parse_options.c +++ b/src/parse_options.c @@ -24,35 +24,44 @@ IOR_param_t initialTestParams; +static void RecalculateExpectedFileSize(IOR_param_t *params) +{ + params->expectedAggFileSize = + params->blockSize * params->segmentCount * params->numTasks; +} + /* * Check and correct all settings of each test in queue for correctness. */ -static void CheckRunSettings(IOR_queue_t * tests) +static void CheckRunSettings(IOR_test_t *tests) { - while (tests != NULL) { + IOR_test_t *ptr; + IOR_param_t *params; + + for (ptr = tests; ptr != NULL; ptr = ptr->next) { + params = &ptr->params; /* If no write/read/check action requested, set both write and read */ - if (tests->testParameters.writeFile == FALSE - && tests->testParameters.readFile == FALSE - && tests->testParameters.checkWrite == FALSE - && tests->testParameters.checkRead == FALSE) { - tests->testParameters.readFile = TRUE; - tests->testParameters.writeFile = TRUE; + if (params->writeFile == FALSE + && params->readFile == FALSE + && params->checkWrite == FALSE + && params->checkRead == FALSE) { + params->readFile = TRUE; + params->writeFile = TRUE; } /* If numTasks set to 0, use all tasks */ - if (tests->testParameters.numTasks == 0) { + if (params->numTasks == 0) { MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD, - &tests-> - testParameters.numTasks), + ¶ms->numTasks), "MPI_Comm_size() error"); + RecalculateExpectedFileSize(params); } - tests = tests->nextTest; } } /* * Set flags from commandline string/value pairs. */ -void DecodeDirective(char *line, IOR_param_t * test) +void DecodeDirective(char *line, IOR_param_t *params) { char option[MAX_STR]; char value[MAX_STR]; @@ -65,144 +74,147 @@ void DecodeDirective(char *line, IOR_param_t * test) MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); } if (strcasecmp(option, "api") == 0) { - strcpy(test->api, value); + strcpy(params->api, value); } else if (strcasecmp(option, "testnum") == 0) { - test->TestNum = atoi(value); + params->TestNum = atoi(value); } else if (strcasecmp(option, "debug") == 0) { - strcpy(test->debug, value); + strcpy(params->debug, value); } else if (strcasecmp(option, "platform") == 0) { - strcpy(test->platform, value); + strcpy(params->platform, value); } else if (strcasecmp(option, "testfile") == 0) { - strcpy(test->testFileName, value); + strcpy(params->testFileName, value); } else if (strcasecmp(option, "hintsfilename") == 0) { - strcpy(test->hintsFileName, value); + strcpy(params->hintsFileName, value); } else if (strcasecmp(option, "deadlineforstonewalling") == 0) { - test->deadlineForStonewalling = atoi(value); + params->deadlineForStonewalling = atoi(value); } else if (strcasecmp(option, "maxtimeduration") == 0) { - test->maxTimeDuration = atoi(value); + params->maxTimeDuration = atoi(value); } else if (strcasecmp(option, "outlierthreshold") == 0) { - test->outlierThreshold = atoi(value); + params->outlierThreshold = atoi(value); } else if (strcasecmp(option, "nodes") == 0) { - test->nodes = atoi(value); + params->nodes = atoi(value); } else if (strcasecmp(option, "repetitions") == 0) { - test->repetitions = atoi(value); + params->repetitions = atoi(value); } else if (strcasecmp(option, "intertestdelay") == 0) { - test->interTestDelay = atoi(value); + params->interTestDelay = atoi(value); } else if (strcasecmp(option, "readfile") == 0) { - test->readFile = atoi(value); + params->readFile = atoi(value); } else if (strcasecmp(option, "writefile") == 0) { - test->writeFile = atoi(value); + params->writeFile = atoi(value); } else if (strcasecmp(option, "fileperproc") == 0) { - test->filePerProc = atoi(value); + params->filePerProc = atoi(value); } else if (strcasecmp(option, "reordertasksconstant") == 0) { - test->reorderTasks = atoi(value); + params->reorderTasks = atoi(value); } else if (strcasecmp(option, "taskpernodeoffset") == 0) { - test->taskPerNodeOffset = atoi(value); + params->taskPerNodeOffset = atoi(value); } else if (strcasecmp(option, "reordertasksrandom") == 0) { - test->reorderTasksRandom = atoi(value); + params->reorderTasksRandom = atoi(value); } else if (strcasecmp(option, "reordertasksrandomSeed") == 0) { - test->reorderTasksRandomSeed = atoi(value); + params->reorderTasksRandomSeed = atoi(value); } else if (strcasecmp(option, "checkwrite") == 0) { - test->checkWrite = atoi(value); + params->checkWrite = atoi(value); } else if (strcasecmp(option, "checkread") == 0) { - test->checkRead = atoi(value); + params->checkRead = atoi(value); } else if (strcasecmp(option, "keepfile") == 0) { - test->keepFile = atoi(value); + params->keepFile = atoi(value); } else if (strcasecmp(option, "keepfilewitherror") == 0) { - test->keepFileWithError = atoi(value); + params->keepFileWithError = atoi(value); } else if (strcasecmp(option, "multiFile") == 0) { - test->multiFile = atoi(value); + params->multiFile = atoi(value); } else if (strcasecmp(option, "quitonerror") == 0) { - test->quitOnError = atoi(value); + params->quitOnError = atoi(value); } else if (strcasecmp(option, "segmentcount") == 0) { - test->segmentCount = StringToBytes(value); + params->segmentCount = StringToBytes(value); + RecalculateExpectedFileSize(params); } else if (strcasecmp(option, "blocksize") == 0) { - test->blockSize = StringToBytes(value); + params->blockSize = StringToBytes(value); + RecalculateExpectedFileSize(params); } else if (strcasecmp(option, "transfersize") == 0) { - test->transferSize = StringToBytes(value); + params->transferSize = StringToBytes(value); } else if (strcasecmp(option, "setalignment") == 0) { - test->setAlignment = StringToBytes(value); + params->setAlignment = StringToBytes(value); } else if (strcasecmp(option, "singlexferattempt") == 0) { - test->singleXferAttempt = atoi(value); + params->singleXferAttempt = atoi(value); } else if (strcasecmp(option, "individualdatasets") == 0) { - test->individualDataSets = atoi(value); + params->individualDataSets = atoi(value); } else if (strcasecmp(option, "intraTestBarriers") == 0) { - test->intraTestBarriers = atoi(value); + params->intraTestBarriers = atoi(value); } else if (strcasecmp(option, "nofill") == 0) { - test->noFill = atoi(value); + params->noFill = atoi(value); } else if (strcasecmp(option, "verbose") == 0) { - test->verbose = atoi(value); + params->verbose = atoi(value); } else if (strcasecmp(option, "settimestampsignature") == 0) { - test->setTimeStampSignature = atoi(value); + params->setTimeStampSignature = atoi(value); } else if (strcasecmp(option, "collective") == 0) { - test->collective = atoi(value); + params->collective = atoi(value); } else if (strcasecmp(option, "preallocate") == 0) { - test->preallocate = atoi(value); + params->preallocate = atoi(value); } else if (strcasecmp(option, "storefileoffset") == 0) { - test->storeFileOffset = atoi(value); + params->storeFileOffset = atoi(value); } else if (strcasecmp(option, "usefileview") == 0) { - test->useFileView = atoi(value); + params->useFileView = atoi(value); } else if (strcasecmp(option, "usesharedfilepointer") == 0) { - test->useSharedFilePointer = atoi(value); + params->useSharedFilePointer = atoi(value); } else if (strcasecmp(option, "useo_direct") == 0) { - test->useO_DIRECT = atoi(value); + params->useO_DIRECT = atoi(value); } else if (strcasecmp(option, "usestrideddatatype") == 0) { - test->useStridedDatatype = atoi(value); + params->useStridedDatatype = atoi(value); } else if (strcasecmp(option, "showhints") == 0) { - test->showHints = atoi(value); + params->showHints = atoi(value); } else if (strcasecmp(option, "showhelp") == 0) { - test->showHelp = atoi(value); + params->showHelp = atoi(value); } else if (strcasecmp(option, "uniqueDir") == 0) { - test->uniqueDir = atoi(value); + params->uniqueDir = atoi(value); } else if (strcasecmp(option, "useexistingtestfile") == 0) { - test->useExistingTestFile = atoi(value); + params->useExistingTestFile = atoi(value); } else if (strcasecmp(option, "fsyncperwrite") == 0) { - test->fsyncPerWrite = atoi(value); + params->fsyncPerWrite = atoi(value); } else if (strcasecmp(option, "fsync") == 0) { - test->fsync = atoi(value); + params->fsync = atoi(value); } else if (strcasecmp(option, "randomoffset") == 0) { - test->randomOffset = atoi(value); + params->randomOffset = atoi(value); } else if (strcasecmp(option, "lustrestripecount") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H ERR("ior was not compiled with Lustre support"); #endif - test->lustre_stripe_count = atoi(value); - test->lustre_set_striping = 1; + params->lustre_stripe_count = atoi(value); + params->lustre_set_striping = 1; } else if (strcasecmp(option, "lustrestripesize") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H ERR("ior was not compiled with Lustre support"); #endif - test->lustre_stripe_size = StringToBytes(value); - test->lustre_set_striping = 1; + params->lustre_stripe_size = StringToBytes(value); + params->lustre_set_striping = 1; } else if (strcasecmp(option, "lustrestartost") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H ERR("ior was not compiled with Lustre support"); #endif - test->lustre_start_ost = atoi(value); - test->lustre_set_striping = 1; + params->lustre_start_ost = atoi(value); + params->lustre_set_striping = 1; } else if (strcasecmp(option, "lustreignorelocks") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H ERR("ior was not compiled with Lustre support"); #endif - test->lustre_ignore_locks = atoi(value); + params->lustre_ignore_locks = atoi(value); #if USE_UNDOC_OPT } else if (strcasecmp(option, "corruptFile") == 0) { - test->corruptFile = atoi(value); + params->corruptFile = atoi(value); } else if (strcasecmp(option, "fillTheFileSystem") == 0) { - test->fillTheFileSystem = atoi(value); + params->fillTheFileSystem = atoi(value); } else if (strcasecmp(option, "includeDeleteTime") == 0) { - test->includeDeleteTime = atoi(value); + params->includeDeleteTime = atoi(value); } else if (strcasecmp(option, "multiReRead") == 0) { - test->multiReRead = atoi(value); + params->multiReRead = atoi(value); } else if (strcasecmp(option, "nfs_rootpath") == 0) { - strcpy(test->NFS_rootPath, value); + strcpy(params->NFS_rootPath, value); } else if (strcasecmp(option, "nfs_servername") == 0) { - strcpy(test->NFS_serverName, value); + strcpy(params->NFS_serverName, value); } else if (strcasecmp(option, "nfs_servercount") == 0) { - test->NFS_serverCount = atoi(value); + params->NFS_serverCount = atoi(value); #endif /* USE_UNDOC_OPT */ } else if (strcasecmp(option, "numtasks") == 0) { - test->numTasks = atoi(value); + params->numTasks = atoi(value); + RecalculateExpectedFileSize(params); } else { if (rank == 0) fprintf(stdout, "Unrecognized parameter \"%s\"\n", @@ -259,19 +271,19 @@ int contains_only(char *haystack, char *needle) * Read the configuration script, allocating and filling in the structure of * global parameters. */ -IOR_queue_t *ReadConfigScript(char *scriptName) +IOR_test_t *ReadConfigScript(char *scriptName) { int test_num = 0; int runflag = 0; char linebuf[MAX_STR]; char empty[MAX_STR]; FILE *file; - IOR_queue_t *head = NULL; - IOR_queue_t *tail = NULL; - IOR_queue_t *newTest = NULL; + IOR_test_t *head = NULL; + IOR_test_t *tail = NULL; + IOR_test_t *newTest = NULL; /* Initialize the first test */ - head = CreateNewTest(test_num++); + head = CreateTest(&initialTestParams, test_num++); tail = head; /* open the script */ @@ -295,25 +307,20 @@ IOR_queue_t *ReadConfigScript(char *scriptName) if (sscanf(linebuf, " #%s", empty) == 1) continue; if (contains_only(linebuf, "ior stop")) { + AllocResults(tail); break; } else if (contains_only(linebuf, "run")) { + AllocResults(tail); runflag = 1; - } else { + } else if (runflag) { /* If this directive was preceded by a "run" line, then create and initialize a new test structure */ - if (runflag) { - newTest = - (IOR_queue_t *) malloc(sizeof(IOR_queue_t)); - if (newTest == NULL) - ERR("malloc() failed"); - newTest->testParameters = tail->testParameters; - newTest->testParameters.id = test_num++; - tail->nextTest = newTest; - tail = newTest; - tail->nextTest = NULL; - runflag = 0; - } - ParseLine(linebuf, &tail->testParameters); + runflag = 0; + tail->next = CreateTest(&tail->params, test_num++); + tail = tail->next; + ParseLine(linebuf, &tail->params); + } else { + ParseLine(linebuf, &tail->params); } } @@ -321,18 +328,18 @@ IOR_queue_t *ReadConfigScript(char *scriptName) if (fclose(file) != 0) ERR("fclose() of script file failed"); - return (head); + return head; } /* * Parse Commandline. */ -IOR_queue_t *ParseCommandLine(int argc, char **argv) +IOR_test_t *ParseCommandLine(int argc, char **argv) { static const char *opts = "A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmnN:o:O:pPqrRs:St:T:uU:vVwWxz"; int c, i; - static IOR_queue_t *tests = NULL; + static IOR_test_t *tests = NULL; /* suppress getopt() error message when a character is unrecognized */ opterr = 0; @@ -352,6 +359,7 @@ IOR_queue_t *ParseCommandLine(int argc, char **argv) break; case 'b': initialTestParams.blockSize = StringToBytes(optarg); + RecalculateExpectedFileSize(&initialTestParams); break; case 'B': initialTestParams.useO_DIRECT = TRUE; @@ -434,6 +442,7 @@ IOR_queue_t *ParseCommandLine(int argc, char **argv) break; case 'N': initialTestParams.numTasks = atoi(optarg); + RecalculateExpectedFileSize(&initialTestParams); break; case 'o': strcpy(initialTestParams.testFileName, optarg); @@ -458,6 +467,7 @@ IOR_queue_t *ParseCommandLine(int argc, char **argv) break; case 's': initialTestParams.segmentCount = atoi(optarg); + RecalculateExpectedFileSize(&initialTestParams); break; case 'S': initialTestParams.useStridedDatatype = TRUE; @@ -504,11 +514,8 @@ IOR_queue_t *ParseCommandLine(int argc, char **argv) /* If an IOR script was not used, initialize test queue to the defaults */ if (tests == NULL) { - tests = (IOR_queue_t *) malloc(sizeof(IOR_queue_t)); - if (!tests) - ERR("malloc() failed"); - tests->testParameters = initialTestParams; - tests->nextTest = NULL; + tests = CreateTest(&initialTestParams, 0); + AllocResults(tests); } CheckRunSettings(tests); diff --git a/src/parse_options.h b/src/parse_options.h index 325855b..a7485da 100644 --- a/src/parse_options.h +++ b/src/parse_options.h @@ -12,6 +12,6 @@ extern IOR_param_t initialTestParams; -IOR_queue_t *ParseCommandLine(int argc, char **argv); +IOR_test_t *ParseCommandLine(int argc, char **argv); #endif /* !_PARSE_OPTIONS_H */ diff --git a/src/utilities.c b/src/utilities.c index 12e65e6..944dac0 100644 --- a/src/utilities.c +++ b/src/utilities.c @@ -421,37 +421,38 @@ static void ModifyByteInFile(char *fileName, IOR_offset_t offset, int byteValue) close(fd); return; } + /* * Corrupt file to testing data checking options. */ -void CorruptFile(char *testFileName, IOR_param_t * test, int rep, int access) +void CorruptFile(char *testFileName, IOR_param_t *params, int rep, int access) { IOR_offset_t tmpOff, range, eof; char fileName[MAX_STR]; /* determine file name */ strcpy(fileName, testFileName); - if (access == READCHECK && test->filePerProc) { - strcpy(fileName, test->testFileName_fppReadCheck); + if (access == READCHECK && params->filePerProc) { + strcpy(fileName, params->testFileName_fppReadCheck); } /* determine offset to modify */ - SeedRandGen(test->testComm); - eof = test->aggFileSizeFromCalc[rep] - / (test->filePerProc ? test->numTasks : 1); + SeedRandGen(params->testComm); + eof = params->expectedAggFileSize + / (params->filePerProc ? params->numTasks : 1); if (access == WRITECHECK) { - range = eof - test->offset; + range = eof - params->offset; } else { /* READCHECK */ - range = test->transferSize; + range = params->transferSize; } tmpOff = - (IOR_offset_t) ((rand() / (float)RAND_MAX) * range) + test->offset; + (IOR_offset_t) ((rand() / (float)RAND_MAX) * range) + params->offset; if (tmpOff >= eof) tmpOff = tmpOff / 2; /* corrupt at with */ - if (rank == 0 || test->filePerProc) { + if (rank == 0 || params->filePerProc) { ModifyByteInFile(fileName, tmpOff, 121); }