diff --git a/runtime/include/chpllaunch.h b/runtime/include/chpllaunch.h index 43c1926c6b29..01b04e08926b 100644 --- a/runtime/include/chpllaunch.h +++ b/runtime/include/chpllaunch.h @@ -45,6 +45,7 @@ typedef struct { int chpl_doDryRun(void); void chpl_append_to_largv(int* largc, const char*** largv, int* largv_len, const char* arg); +char* chpl_append_to_cmd(char* cmdBuf, const char* format, ...); int chpl_run_utility1K(const char *command, char *const argv[], char *outbuf, int outbuflen); int chpl_run_cmdstr(const char *commandStr, char *outbuf, int outbuflen); diff --git a/runtime/src/chpl-launcher-common.c b/runtime/src/chpl-launcher-common.c index c5abe13877ba..2045ac922d3b 100644 --- a/runtime/src/chpl-launcher-common.c +++ b/runtime/src/chpl-launcher-common.c @@ -102,6 +102,39 @@ void chpl_append_to_largv(int* largc, const char*** largv, int* largv_len, (*largv)[(*largc)++] = (arg); } +// Helper for appending arguments to a variable-size command buffer. +// - Requires the buffer pointer is uninitialized on first call. +// - After exceeding an initial allocated size estimate, each call will allocate +// additional memory as needed. +char* chpl_append_to_cmd(char* cmdBuf, const char* format, ...) { + static const int initialSize = 2048; + static int charsWritten = 0; + + if (charsWritten == 0) { + assert(cmdBuf == NULL); + cmdBuf = (char*)chpl_mem_allocMany(initialSize, sizeof(char), + CHPL_RT_MD_COMMAND_BUFFER, -1, 0); + } + + va_list argsForLen, argsForPrint; + va_start(argsForLen, format); + va_copy(argsForPrint, argsForLen); + + const int addedLen = vsnprintf(NULL, 0, format, argsForLen); + va_end(argsForLen); + int newLen = charsWritten + addedLen; + + if (newLen >= initialSize) { + cmdBuf = (char*)chpl_mem_realloc(cmdBuf, newLen * sizeof(char), + CHPL_RT_MD_COMMAND_BUFFER, -1, 0); + } + + vsnprintf(cmdBuf + charsWritten, addedLen + 1, format, argsForPrint); + va_end(argsForPrint); + + charsWritten = newLen; +} + // // Use this function to run short utility programs that will return less // than 1024 characters of output. The program must not expect any input. diff --git a/runtime/src/launch/slurm-gasnetrun_common/slurm-gasnetrun_common.h b/runtime/src/launch/slurm-gasnetrun_common/slurm-gasnetrun_common.h index df8415440eda..650864d1fcd5 100644 --- a/runtime/src/launch/slurm-gasnetrun_common/slurm-gasnetrun_common.h +++ b/runtime/src/launch/slurm-gasnetrun_common/slurm-gasnetrun_common.h @@ -179,41 +179,9 @@ static void propagate_environment(char* buf, size_t size) // We could do this more selectively, but we would be likely // to leave out something important. char *enviro_keys = chpl_get_enviro_keys(','); - if (enviro_keys) appendToCmdBuf(buf, " -E '%s'", enviro_keys); + if (enviro_keys) chpl_append_to_cmd(buf, " -E '%s'", enviro_keys); } -// Helper for appending arguments to a variable-size command buffer. -// - Requires the buffer pointer is uninitialized on first call. -// - After exceeding an initial allocated size estimate, each call will allocate -// additional memory as needed. -static char* appendToCmdBuf(char* com, const char* format, ...) { - static const int initialSize = 2048; - static int charsWritten = 0; - - if (charsWritten == 0) { - assert(com == NULL); - com = (char*)chpl_mem_allocMany(initialSize, sizeof(char), - CHPL_RT_MD_COMMAND_BUFFER, -1, 0); - } - - va_list argsForLen, argsForPrint; - va_start(argsForLen, format); - va_copy(argsForPrint, argsForLen); - - const int addedLen = vsnprintf(NULL, 0, format, argsForLen); - va_end(argsForLen); - int newLen = charsWritten + addedLen; - - if (newLen >= initialSize) { - com = (char*)chpl_mem_realloc(com, newLen * sizeof(char), - CHPL_RT_MD_COMMAND_BUFFER, -1, 0); - } - - vsnprintf(com + charsWritten, addedLen + 1, format, argsForPrint); - va_end(argsForPrint); - - charsWritten = newLen; -} static char* chpl_launch_create_command(int argc, char* argv[], int32_t numLocales, @@ -352,28 +320,28 @@ static char* chpl_launch_create_command(int argc, char* argv[], char* iCom = NULL; if (!getSlurmDebug()) { - appendToCmdBuf(iCom, "--quiet "); + chpl_append_to_cmd(iCom, "--quiet "); } - appendToCmdBuf(iCom, "-J %s ", jobName); - appendToCmdBuf(iCom, "-N %d ", numNodes); - appendToCmdBuf(iCom, "--ntasks=%d ", numLocales); - if (nodeAccessStr != NULL) appendToCmdBuf(iCom, "--%s ", nodeAccessStr); - if (walltime) appendToCmdBuf(iCom, "--time=%s ", walltime); - if (nodelist) appendToCmdBuf(iCom, "--nodelist=%s ", nodelist); - if (partition) appendToCmdBuf(iCom, "--partition=%s ", partition); - if (exclude) appendToCmdBuf(iCom, "--exclude=%s ", exclude); - if (gpusPerNode) appendToCmdBuf(iCom, "--gpus-per-node=%s ", gpusPerNode); + chpl_append_to_cmd(iCom, "-J %s ", jobName); + chpl_append_to_cmd(iCom, "-N %d ", numNodes); + chpl_append_to_cmd(iCom, "--ntasks=%d ", numLocales); + if (nodeAccessStr != NULL) chpl_append_to_cmd(iCom, "--%s ", nodeAccessStr); + if (walltime) chpl_append_to_cmd(iCom, "--time=%s ", walltime); + if (nodelist) chpl_append_to_cmd(iCom, "--nodelist=%s ", nodelist); + if (partition) chpl_append_to_cmd(iCom, "--partition=%s ", partition); + if (exclude) chpl_append_to_cmd(iCom, "--exclude=%s ", exclude); + if (gpusPerNode) chpl_append_to_cmd(iCom, "--gpus-per-node=%s ", gpusPerNode); if (projectString && strlen(projectString) > 0) - appendToCmdBuf(iCom, "--account=%s ", projectString); - if (constraint) appendToCmdBuf(iCom, "-C %s", constraint); - appendToCmdBuf(iCom, " %s/%s/%s -n %d -N %d -c 0", + chpl_append_to_cmd(iCom, "--account=%s ", projectString); + if (constraint) chpl_append_to_cmd(iCom, "-C %s", constraint); + chpl_append_to_cmd(iCom, " %s/%s/%s -n %d -N %d -c 0", CHPL_THIRD_PARTY, WRAP_TO_STR(LAUNCH_PATH), GASNETRUN_LAUNCHER, numLocales, numNodes); propagate_environment(iCom); - appendToCmdBuf(iCom, " %s %s", chpl_get_real_binary_wrapper(), + chpl_append_to_cmd(iCom, " %s %s", chpl_get_real_binary_wrapper(), chpl_get_real_binary_name()); for (i=1; i 1) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--cpu-bind=none "); + chpl_append_to_cmd(iCom, "--cpu-bind=none "); } // request specified node access if (nodeAccessStr != NULL) - len += snprintf(iCom+len, sizeof(iCom)-len, "--%s ", nodeAccessStr); + chpl_append_to_cmd(iCom, "--%s ", nodeAccessStr); // request specified amount of memory if (memStr != NULL) - len += snprintf(iCom+len, sizeof(iCom)-len, "--mem=%s ", memStr); + chpl_append_to_cmd(iCom, "--mem=%s ", memStr); // kill the job if any program instance halts with non-zero exit status - len += snprintf(iCom+len, sizeof(iCom)-len, "--kill-on-bad-exit "); + chpl_append_to_cmd(iCom, "--kill-on-bad-exit "); // Set the walltime if it was specified if (walltime) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--time=%s ",walltime); + chpl_append_to_cmd(iCom, "--time=%s ", walltime); } // Set the nodelist if it was specified if (nodelist) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--nodelist=%s ", nodelist); + chpl_append_to_cmd(iCom, "--nodelist=%s ", nodelist); } // Set the partition if it was specified if (partition) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--partition=%s ", - partition); + chpl_append_to_cmd(iCom, "--partition=%s ", partition); } // Set the exclude list if it was specified if (exclude) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--exclude=%s ", exclude); + chpl_append_to_cmd(iCom, "--exclude=%s ", exclude); } // Set the gpus per node if it was specified if (gpusPerNode) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--gpus-per-node=%s ", - gpusPerNode); + chpl_append_to_cmd(iCom, "--gpus-per-node=%s ", gpusPerNode); } // set any constraints if (constraint) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--constraint=%s ", constraint); + chpl_append_to_cmd(iCom, "--constraint=%s ", constraint); } // set the account name if one was provided if (account && strlen(account) > 0) { - len += snprintf(iCom+len, sizeof(iCom)-len, "--account=%s ", account); + chpl_append_to_cmd(iCom, "--account=%s ", account); } // add the (possibly wrapped) binary name - len += snprintf(iCom+len, sizeof(iCom)-len, "%s %s", + chpl_append_to_cmd(iCom, "%s %s ", chpl_get_real_binary_wrapper(), chpl_get_real_binary_name()); // add any arguments passed to the launcher to the binary for (i=1; i