From: Berk Hess Date: Fri, 30 May 2014 15:18:07 +0000 (+0200) Subject: Replaced gmx_hostname_num by gmx_physicalnode_id_hash X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=d682f2f3e31f5b4074b06b4393b59fd7b4bdb2b0;p=alexxy%2Fgromacs.git Replaced gmx_hostname_num by gmx_physicalnode_id_hash gmx_hostname_num was only used to distinguish physical nodes. Since it only worked for hostnames with numbers, we replaced it by a hash of the hostname. Fixes #1513 Change-Id: I8e60757707386f43269afe0bb38e8500decefcd6 --- diff --git a/src/gromacs/gmxlib/gmx_thread_affinity.c b/src/gromacs/gmxlib/gmx_thread_affinity.c index 9752fb0295..03bf0db93f 100644 --- a/src/gromacs/gmxlib/gmx_thread_affinity.c +++ b/src/gromacs/gmxlib/gmx_thread_affinity.c @@ -236,7 +236,8 @@ gmx_set_thread_affinity(FILE *fplog, */ MPI_Comm comm_intra; - MPI_Comm_split(MPI_COMM_WORLD, gmx_hostname_num(), cr->rank_intranode, + MPI_Comm_split(MPI_COMM_WORLD, + gmx_physicalnode_id_hash(), cr->rank_intranode, &comm_intra); MPI_Scan(&nthread_local, &thread0_id_node, 1, MPI_INT, MPI_SUM, comm_intra); /* MPI_Scan is inclusive, but here we need exclusive */ diff --git a/src/gromacs/gmxlib/network.c b/src/gromacs/gmxlib/network.c index 346f8cff30..a5b7828a1d 100644 --- a/src/gromacs/gmxlib/network.c +++ b/src/gromacs/gmxlib/network.c @@ -166,11 +166,7 @@ int gmx_node_rank(void) #endif } -#if defined GMX_LIB_MPI && defined GMX_TARGET_BGQ -#include -#endif - -int gmx_physicalnode_id_hash(void) +static int mpi_hostname_hash(void) { int hash_int; @@ -204,24 +200,12 @@ int gmx_physicalnode_id_hash(void) return hash_int; } -/* TODO: this function should be fully replaced by gmx_physicalnode_id_hash */ -int gmx_hostname_num() -{ -#ifndef GMX_MPI - return 0; -#else -#ifdef GMX_THREAD_MPI - /* thread-MPI currently puts the thread number in the process name, - * we might want to change this, as this is inconsistent with what - * most MPI implementations would do when running on a single node. - */ - return 0; -#else - int resultlen, hostnum, i, j; - char mpi_hostname[MPI_MAX_PROCESSOR_NAME], hostnum_str[MPI_MAX_PROCESSOR_NAME]; +#if defined GMX_LIB_MPI && defined GMX_TARGET_BGQ +#include - MPI_Get_processor_name(mpi_hostname, &resultlen); -#ifdef GMX_TARGET_BGQ +static int bgq_nodenum(void) +{ + int hostnum; Personality_t personality; Kernel_GetPersonality(&personality, sizeof(personality)); /* Each MPI rank has a unique coordinate in a 6-dimensional space @@ -242,38 +226,9 @@ int gmx_hostname_num() hostnum += personality.Network_Config.Dcoord; hostnum *= personality.Network_Config.Enodes; hostnum += personality.Network_Config.Ecoord; -#else - /* This procedure can only differentiate nodes with host names - * that end on unique numbers. - */ - i = 0; - j = 0; - /* Only parse the host name up to the first dot */ - while (i < resultlen && mpi_hostname[i] != '.') - { - if (isdigit(mpi_hostname[i])) - { - hostnum_str[j++] = mpi_hostname[i]; - } - i++; - } - hostnum_str[j] = '\0'; - if (j == 0) - { - hostnum = 0; - } - else - { - /* Use only the last 9 decimals, so we don't overflow an int */ - hostnum = strtol(hostnum_str + max(0, j-9), NULL, 10); - } -#endif if (debug) { - fprintf(debug, "In gmx_hostname_num: hostname '%s', hostnum %d\n", - mpi_hostname, hostnum); -#ifdef GMX_TARGET_BGQ fprintf(debug, "Torus ID A: %d / %d B: %d / %d C: %d / %d D: %d / %d E: %d / %d\nNode ID T: %d / %d core: %d / %d hardware thread: %d / %d\n", personality.Network_Config.Acoord, @@ -292,17 +247,45 @@ int gmx_hostname_num() 64, Kernel_ProcessorThreadID(), 4); -#endif } return hostnum; +} +#endif + +int gmx_physicalnode_id_hash(void) +{ + int hash; + +#ifndef GMX_MPI + hash = 0; +#else +#ifdef GMX_THREAD_MPI + /* thread-MPI currently puts the thread number in the process name, + * we might want to change this, as this is inconsistent with what + * most MPI implementations would do when running on a single node. + */ + hash = 0; +#else +#ifdef GMX_TARGET_BGQ + hash = bgq_nodenum(); +#else + hash = mpi_hostname_hash(); +#endif #endif #endif + + if (debug) + { + fprintf(debug, "In gmx_physicalnode_id_hash: hash %d\n", hash); + } + + return hash; } void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) { gmx_nodecomm_t *nc; - int n, rank, hostnum, ng, ni; + int n, rank, nodehash, ng, ni; /* Many MPI implementations do not optimize MPI_Allreduce * (and probably also other global communication calls) @@ -323,7 +306,7 @@ void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) MPI_Comm_size(cr->mpi_comm_mygroup, &n); MPI_Comm_rank(cr->mpi_comm_mygroup, &rank); - hostnum = gmx_hostname_num(); + nodehash = gmx_physicalnode_id_hash(); if (debug) { @@ -332,7 +315,7 @@ void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) /* The intra-node communicator, split on node number */ - MPI_Comm_split(cr->mpi_comm_mygroup, hostnum, rank, &nc->comm_intra); + MPI_Comm_split(cr->mpi_comm_mygroup, nodehash, rank, &nc->comm_intra); MPI_Comm_rank(nc->comm_intra, &nc->rank_intra); if (debug) { @@ -392,25 +375,25 @@ void gmx_init_intranode_counters(t_commrec *cr) /* thread-MPI is not initialized when not running in parallel */ #if defined GMX_MPI && !defined GMX_THREAD_MPI int nrank_world, rank_world; - int i, mynum, *num, *num_s, *num_pp, *num_pp_s; + int i, myhash, *hash, *hash_s, *hash_pp, *hash_pp_s; MPI_Comm_size(MPI_COMM_WORLD, &nrank_world); MPI_Comm_rank(MPI_COMM_WORLD, &rank_world); - /* Get the node number from the hostname to identify the nodes */ - mynum = gmx_hostname_num(); + /* Get a (hopefully unique) hash that identifies our physical node */ + myhash = gmx_physicalnode_id_hash(); /* We can't rely on MPI_IN_PLACE, so we need send and receive buffers */ - snew(num, nrank_world); - snew(num_s, nrank_world); - snew(num_pp, nrank_world); - snew(num_pp_s, nrank_world); + snew(hash, nrank_world); + snew(hash_s, nrank_world); + snew(hash_pp, nrank_world); + snew(hash_pp_s, nrank_world); - num_s[rank_world] = mynum; - num_pp_s[rank_world] = (cr->duty & DUTY_PP) ? mynum : -1; + hash_s[rank_world] = myhash; + hash_pp_s[rank_world] = (cr->duty & DUTY_PP) ? myhash : -1; - MPI_Allreduce(num_s, num, nrank_world, MPI_INT, MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(num_pp_s, num_pp, nrank_world, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(hash_s, hash, nrank_world, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(hash_pp_s, hash_pp, nrank_world, MPI_INT, MPI_SUM, MPI_COMM_WORLD); nrank_intranode = 0; rank_intranode = 0; @@ -418,7 +401,7 @@ void gmx_init_intranode_counters(t_commrec *cr) rank_pp_intranode = 0; for (i = 0; i < nrank_world; i++) { - if (num[i] == mynum) + if (hash[i] == myhash) { nrank_intranode++; if (i < rank_world) @@ -426,7 +409,7 @@ void gmx_init_intranode_counters(t_commrec *cr) rank_intranode++; } } - if (num_pp[i] == mynum) + if (hash_pp[i] == myhash) { nrank_pp_intranode++; if ((cr->duty & DUTY_PP) && i < rank_world) @@ -435,10 +418,10 @@ void gmx_init_intranode_counters(t_commrec *cr) } } } - sfree(num); - sfree(num_s); - sfree(num_pp); - sfree(num_pp_s); + sfree(hash); + sfree(hash_s); + sfree(hash_pp); + sfree(hash_pp_s); #else /* Serial or thread-MPI code: we run within a single physical node */ nrank_intranode = cr->nnodes; diff --git a/src/gromacs/legacyheaders/network.h b/src/gromacs/legacyheaders/network.h index 8d4d4f17a3..1e5cbdf60f 100644 --- a/src/gromacs/legacyheaders/network.h +++ b/src/gromacs/legacyheaders/network.h @@ -78,14 +78,6 @@ int gmx_physicalnode_id_hash(void); * This hash is useful for determining hardware locality. */ -int gmx_hostname_num(void); -/* Ostensibly, returns a integer characteristic of and unique to each - physical node in the MPI system. If the first part of the MPI - hostname (up to the first dot) ends with a number, returns this - number. If the first part of the MPI hostname does not ends in a - number (0-9 characters), returns 0. - */ - void gmx_setup_nodecomm(FILE *fplog, t_commrec *cr); /* Sets up fast global communication for clusters with multi-core nodes */