From c9a68862b525b4dc77933a42e40487a2f14579cf Mon Sep 17 00:00:00 2001 From: Philip Davis Date: Thu, 25 Jun 2020 09:08:58 -0400 Subject: [PATCH 1/6] Add rank decomposition by dimensional ratio to iotestx --- source/utils/adios_iotest/settings.cpp | 77 ++++++++++++++++++++++++-- source/utils/adios_iotest/settings.h | 3 + 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/source/utils/adios_iotest/settings.cpp b/source/utils/adios_iotest/settings.cpp index bab37393a8..24e06391db 100644 --- a/source/utils/adios_iotest/settings.cpp +++ b/source/utils/adios_iotest/settings.cpp @@ -10,6 +10,8 @@ #include "settings.h" +#include +#include #include #include #include @@ -42,7 +44,8 @@ size_t Settings::ndigits(size_t n) const void Settings::displayHelp() { std::cout - << "Usage: adios_iotest -a appid -c config {-s | -w} -d d1 [d2 .. dN] " + << "Usage: adios_iotest -a appid -c config {-s | -w} -d {d1 [d2 .. dN] " + "| r1,[r2,..,rN]}" "[-x " "file]\n" << " -a appID: unique number for each application in the workflow\n" @@ -51,6 +54,12 @@ void Settings::displayHelp() << " d1: number of processes in 1st (slowest) dimension\n" << " dN: number of processes in Nth dimension\n" << " d1*d2*..*dN must equal the number of processes\n" + << " r1: ratio of process decomposition in the 1st " + "(slowest) dimension\n" + << " rN: ratio of process decomposition in the Nth " + "dimension\n" + << " r1xr2x..xrN must scale up to process count" + "count without remainder\n" << " -s OR -w: strong or weak scaling. \n" << " Dimensions in config are treated accordingly\n" << " -x file ADIOS configuration XML file\n" @@ -77,6 +86,54 @@ size_t Settings::stringToNumber(const std::string &varName, return retval; } +int Settings::parseRatios(const char *arg) +{ + char *argCopy = strdup(arg); + char *ratio; + + ratio = strtok(argCopy, ","); + while (ratio) + { + processDecomp[nDecomp++] = stringToNumber("decomposition ratio", ratio); + ratio = strtok(NULL, ","); + } + + free(argCopy); + + isRatioDecomp = true; + + return (0); +} + +int Settings::rescaleDecomp() +{ + size_t ratioProd = 1; + size_t scaleFactor; + + for (size_t i = 0; i < nDecomp; i++) + { + ratioProd *= processDecomp[i]; + } + + for (scaleFactor = 1; ratioProd * pow(scaleFactor, nDecomp) <= nProc; + scaleFactor++) + { + if (ratioProd * pow(scaleFactor, nDecomp) == nProc) + { + for (size_t i = 0; i < nDecomp; i++) + { + processDecomp[i] *= scaleFactor; + } + return (0); + } + } + + throw std::invalid_argument( + "decomposition ratios must scale up to process count"); + + return (0); +} + int Settings::processArgs(int argc, char *argv[]) { bool appIdDefined = false; @@ -97,9 +154,16 @@ int Settings::processArgs(int argc, char *argv[]) configFileName = optarg; break; case 'd': - processDecomp[nDecomp] = - stringToNumber("decomposition in dimension 1", optarg); - ++nDecomp; + if (strchr(optarg, ',')) + { + parseRatios(optarg); + } + else + { + processDecomp[nDecomp] = + stringToNumber("decomposition in dimension 1", optarg); + ++nDecomp; + } break; case 'F': fixedPattern = true; @@ -220,6 +284,11 @@ int Settings::processArguments(int argc, char *argv[], MPI_Comm worldComm) MPI_Comm_size(appComm, &nproc); myRank = static_cast(rank); nProc = static_cast(nproc); + + if (isRatioDecomp) + { + rescaleDecomp(); + } } catch (std::exception &e) // command-line argument errors { diff --git a/source/utils/adios_iotest/settings.h b/source/utils/adios_iotest/settings.h index 647dd7aa11..fca6738041 100644 --- a/source/utils/adios_iotest/settings.h +++ b/source/utils/adios_iotest/settings.h @@ -40,6 +40,7 @@ class Settings bool isStrongScaling = true; // strong or weak scaling bool ioTimer = false; // used to measure io time bool fixedPattern = false; // should Lock definitions? + bool isRatioDecomp = false; IOLib iolib = IOLib::ADIOS; // process decomposition std::vector processDecomp = {1, 1, 1, 1, 1, 1, 1, 1, @@ -57,6 +58,8 @@ class Settings int processArguments(int argc, char *argv[], MPI_Comm worldComm); int extraArgumentChecks(); size_t stringToNumber(const std::string &varName, const char *arg) const; + int parseRatios(const char *arg); + int rescaleDecomp(); size_t ndigits(size_t n) const; private: From 646b43650004c9025f7529cfebec24eb7dce61a2 Mon Sep 17 00:00:00 2001 From: Philip Davis Date: Thu, 25 Jun 2020 11:07:15 -0400 Subject: [PATCH 2/6] Removed unreachable return statement --- source/utils/adios_iotest/settings.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/utils/adios_iotest/settings.cpp b/source/utils/adios_iotest/settings.cpp index 24e06391db..41a50508ad 100644 --- a/source/utils/adios_iotest/settings.cpp +++ b/source/utils/adios_iotest/settings.cpp @@ -130,8 +130,6 @@ int Settings::rescaleDecomp() throw std::invalid_argument( "decomposition ratios must scale up to process count"); - - return (0); } int Settings::processArgs(int argc, char *argv[]) From 4c0e38bf643e692e847527f0a0421950991b956a Mon Sep 17 00:00:00 2001 From: Philip Davis Date: Thu, 25 Jun 2020 13:51:31 -0400 Subject: [PATCH 3/6] Remove non-ISO standard strdup usagex --- source/utils/adios_iotest/settings.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/utils/adios_iotest/settings.cpp b/source/utils/adios_iotest/settings.cpp index 41a50508ad..266c0f5139 100644 --- a/source/utils/adios_iotest/settings.cpp +++ b/source/utils/adios_iotest/settings.cpp @@ -88,9 +88,10 @@ size_t Settings::stringToNumber(const std::string &varName, int Settings::parseRatios(const char *arg) { - char *argCopy = strdup(arg); + char *argCopy = malloc(strlen(arg) * sizeof(*argCopy)); char *ratio; + strcpy(argCopy, arg); ratio = strtok(argCopy, ","); while (ratio) { From 8867faa70a65508967b16ba3918ba8d3eb1dbad6 Mon Sep 17 00:00:00 2001 From: Philip Davis Date: Thu, 25 Jun 2020 14:51:53 -0400 Subject: [PATCH 4/6] Added explicit pointer conversion --- source/utils/adios_iotest/settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utils/adios_iotest/settings.cpp b/source/utils/adios_iotest/settings.cpp index 266c0f5139..22b834a74b 100644 --- a/source/utils/adios_iotest/settings.cpp +++ b/source/utils/adios_iotest/settings.cpp @@ -88,7 +88,7 @@ size_t Settings::stringToNumber(const std::string &varName, int Settings::parseRatios(const char *arg) { - char *argCopy = malloc(strlen(arg) * sizeof(*argCopy)); + char *argCopy = (char *)malloc(strlen(arg) * sizeof(*argCopy)); char *ratio; strcpy(argCopy, arg); From d099b9063efdb4d2f82da46c93cbd5e6d6b7d124 Mon Sep 17 00:00:00 2001 From: Philip Davis Date: Thu, 25 Jun 2020 15:51:39 -0400 Subject: [PATCH 5/6] Added -D option to iotest for decomp ratios, ending the overload of -d. Both now accept comma-seperated arguments --- source/utils/adios_iotest/settings.cpp | 42 +++++++++++++++++++++----- source/utils/adios_iotest/settings.h | 2 +- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/source/utils/adios_iotest/settings.cpp b/source/utils/adios_iotest/settings.cpp index 22b834a74b..77dccb606d 100644 --- a/source/utils/adios_iotest/settings.cpp +++ b/source/utils/adios_iotest/settings.cpp @@ -22,6 +22,7 @@ struct option options[] = {{"help", no_argument, NULL, 'h'}, {"appid", required_argument, NULL, 'a'}, {"config", required_argument, NULL, 'c'}, {"decomp", required_argument, NULL, 'd'}, + {"decomp-ratio", required_argument, NULL, 'D'}, {"xml", required_argument, NULL, 'x'}, {"strong-scaling", no_argument, NULL, 's'}, {"weak-scaling", no_argument, NULL, 'w'}, @@ -32,7 +33,7 @@ struct option options[] = {{"help", no_argument, NULL, 'h'}, #endif {NULL, 0, NULL, 0}}; -static const char *optstring = "-hvswtFHa:c:d:x:"; +static const char *optstring = "-hvswtFHa:c:d:D:x:"; size_t Settings::ndigits(size_t n) const { @@ -44,8 +45,8 @@ size_t Settings::ndigits(size_t n) const void Settings::displayHelp() { std::cout - << "Usage: adios_iotest -a appid -c config {-s | -w} -d {d1 [d2 .. dN] " - "| r1,[r2,..,rN]}" + << "Usage: adios_iotest -a appid -c config {-s | -w} {-d d1[,d2,..,dN] " + "| -D r1[,r2,..,rN]}" "[-x " "file]\n" << " -a appID: unique number for each application in the workflow\n" @@ -54,6 +55,7 @@ void Settings::displayHelp() << " d1: number of processes in 1st (slowest) dimension\n" << " dN: number of processes in Nth dimension\n" << " d1*d2*..*dN must equal the number of processes\n" + << " -D ... define process decomposition ratio:\n" << " r1: ratio of process decomposition in the 1st " "(slowest) dimension\n" << " rN: ratio of process decomposition in the Nth " @@ -86,7 +88,7 @@ size_t Settings::stringToNumber(const std::string &varName, return retval; } -int Settings::parseRatios(const char *arg) +int Settings::parseCSDecomp(const char *arg) { char *argCopy = (char *)malloc(strlen(arg) * sizeof(*argCopy)); char *ratio; @@ -101,8 +103,6 @@ int Settings::parseRatios(const char *arg) free(argCopy); - isRatioDecomp = true; - return (0); } @@ -137,6 +137,7 @@ int Settings::processArgs(int argc, char *argv[]) { bool appIdDefined = false; bool scalingDefined = false; + bool decompDefined = false; int c; int last_c = '_'; @@ -153,9 +154,32 @@ int Settings::processArgs(int argc, char *argv[]) configFileName = optarg; break; case 'd': + if (decompDefined && isRatioDecomp) + { + throw std::invalid_argument( + "Cannot have -D and -d used at the same time "); + } + if (strchr(optarg, ',')) + { + parseCSDecomp(optarg); + } + else + { + processDecomp[nDecomp] = + stringToNumber("decomposition in dimension 1", optarg); + ++nDecomp; + } + decompDefined = true; + break; + case 'D': + if (decompDefined && !isRatioDecomp) + { + throw std::invalid_argument( + "Cannot have -D and -d used at the same time "); + } if (strchr(optarg, ',')) { - parseRatios(optarg); + parseCSDecomp(optarg); } else { @@ -163,6 +187,8 @@ int Settings::processArgs(int argc, char *argv[]) stringToNumber("decomposition in dimension 1", optarg); ++nDecomp; } + decompDefined = true; + isRatioDecomp = true; break; case 'F': fixedPattern = true; @@ -209,7 +235,7 @@ int Settings::processArgs(int argc, char *argv[]) /* This means a field is unknown, or could be multiple arg or bad * arg*/ - if (last_c == 'd') + if (last_c == 'd' || last_c == 'D') { // --decomp extra arg (or not if not a number) processDecomp[nDecomp] = stringToNumber( "decomposition in dimension " + std::to_string(nDecomp + 1), diff --git a/source/utils/adios_iotest/settings.h b/source/utils/adios_iotest/settings.h index fca6738041..c3b2a4775c 100644 --- a/source/utils/adios_iotest/settings.h +++ b/source/utils/adios_iotest/settings.h @@ -58,7 +58,7 @@ class Settings int processArguments(int argc, char *argv[], MPI_Comm worldComm); int extraArgumentChecks(); size_t stringToNumber(const std::string &varName, const char *arg) const; - int parseRatios(const char *arg); + int parseCSDecomp(const char *arg); int rescaleDecomp(); size_t ndigits(size_t n) const; From 5501fffd83eaa8005004b1b672ce4e9ab4e1bfcb Mon Sep 17 00:00:00 2001 From: Philip Davis Date: Fri, 26 Jun 2020 11:40:48 -0400 Subject: [PATCH 6/6] Empty commit to rerun CI