From 95bbad7d33e141f3e14ab4626165e796a7ef1b25 Mon Sep 17 00:00:00 2001 From: Mark Abraham Date: Mon, 31 Mar 2014 17:19:14 +0200 Subject: [PATCH] Move string-parsing code to where it can be reused Change-Id: Ie043e403828237ee3a58baaa1521df2ea58d2f6d --- src/gromacs/gmxlib/gmx_detect_hardware.c | 37 +++++------------------- src/gromacs/utility/cstringutil.c | 33 +++++++++++++++++++++ src/gromacs/utility/cstringutil.h | 15 ++++++++++ 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/gromacs/gmxlib/gmx_detect_hardware.c b/src/gromacs/gmxlib/gmx_detect_hardware.c index f262dcc584..9aa1105bb3 100644 --- a/src/gromacs/gmxlib/gmx_detect_hardware.c +++ b/src/gromacs/gmxlib/gmx_detect_hardware.c @@ -59,6 +59,7 @@ #include "main.h" #include "md_logging.h" #include "gromacs/utility/gmxomp.h" +#include "gromacs/utility/cstringutil.h" #include "thread_mpi/threads.h" @@ -190,33 +191,6 @@ static void print_gpu_use_stats(FILE *fplog, md_print_info(cr, fplog, "%s\n\n", sbuf); } -/* Parse a "plain" GPU ID string which contains a sequence of digits corresponding - * to GPU IDs; the order will indicate the process/tMPI thread - GPU assignment. */ -static void parse_gpu_id_plain_string(const char *idstr, int *nid, int **idlist) -{ - int i; - - *nid = strlen(idstr); - - snew(*idlist, *nid); - - for (i = 0; i < *nid; i++) - { - if (idstr[i] < '0' || idstr[i] > '9') - { - gmx_fatal(FARGS, "Invalid character in GPU ID string: '%c'\n%s\n", - idstr[i], invalid_gpuid_hint); - } - (*idlist)[i] = idstr[i] - '0'; - } -} - -static void parse_gpu_id_csv_string(const char gmx_unused *idstr, int gmx_unused *nid, int gmx_unused *idlist) -{ - /* XXX implement cvs format to support more than 10 different GPUs in a box. */ - gmx_incons("Not implemented yet"); -} - /* Give a suitable fatal error or warning if the build configuration and runtime CPU do not match. */ static void @@ -724,9 +698,12 @@ void gmx_parse_gpu_ids(gmx_gpu_opt_t *gpu_opt) /* parse GPU IDs if the user passed any */ if (env != NULL) { - parse_gpu_id_plain_string(env, - &gpu_opt->ncuda_dev_use, - &gpu_opt->cuda_dev_use); + /* Parse a "plain" GPU ID string which contains a sequence of + * digits corresponding to GPU IDs; the order will indicate + * the process/tMPI thread - GPU assignment. */ + parse_digits_from_plain_string(env, + &gpu_opt->ncuda_dev_use, + &gpu_opt->cuda_dev_use); if (gpu_opt->ncuda_dev_use == 0) { diff --git a/src/gromacs/utility/cstringutil.c b/src/gromacs/utility/cstringutil.c index 92c6eb4542..71c22d3838 100644 --- a/src/gromacs/utility/cstringutil.c +++ b/src/gromacs/utility/cstringutil.c @@ -586,3 +586,36 @@ str_to_int64_t(const char *str, char **endptr) return _strtoi64(str, endptr, 10); #endif } + +void parse_digits_from_plain_string(const char *digitstring, int *ndigits, int **digitlist) +{ + int i; + + if (NULL == digitstring) + { + *ndigits = 0; + *digitlist = NULL; + return; + } + + *ndigits = strlen(digitstring); + + snew(*digitlist, *ndigits); + + for (i = 0; i < *ndigits; i++) + { + if (digitstring[i] < '0' || digitstring[i] > '9') + { + gmx_fatal(FARGS, "Invalid character in digit-only string: '%c'\n", + digitstring[i]); + } + (*digitlist)[i] = digitstring[i] - '0'; + } +} + +static void parse_digits_from_csv_string(const char gmx_unused *digitstring, int gmx_unused *ndigits, int gmx_unused *digitlist) +{ + /* TODO Implement csv format to support (e.g.) more than 10 + different GPUs in a node. */ + gmx_incons("Not implemented yet"); +} diff --git a/src/gromacs/utility/cstringutil.h b/src/gromacs/utility/cstringutil.h index eaa8bd97df..6d8f94b4e7 100644 --- a/src/gromacs/utility/cstringutil.h +++ b/src/gromacs/utility/cstringutil.h @@ -205,6 +205,21 @@ gmx_int64_t str_to_int64_t(const char *str, char **endptr); #define snprintf _snprintf #endif +/*! \brief Construct an array of digits found in the input string + * + * \param[in] digitstring String that must contain only digits + * \param[out] ndigits Size of return array with the values of the digits + * \param[out] digitlist Array of digits found in + * digitstring. Allocated by this function + * with size *ndigits. Calling code is + * responsible for deallocation. + * + * If digitstring is NULL, then ndigits is set to zero and digitlist + * to NULL. If digitstring contains a non-digit character, a fatal + * error results. + */ +void parse_digits_from_plain_string(const char *digitstring, int *ndigits, int **digitlist); + #ifdef __cplusplus } #endif -- 2.22.0