commits
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
July 2016
- 1 participants
- 16 discussions
[mpich] MPICH primary repository branch, master, updated. v3.2-373-g26fbb71
by noreply@mpich.org 27 Jul '16
by noreply@mpich.org 27 Jul '16
27 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via 26fbb71011da8e90b25ebdcb66d78abec8dcb7af (commit)
from 679bd676e9dbdc8926f20ecc9f4bd45d1d41f4f6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/26fbb71011da8e90b25ebdcb66d78abec…
commit 26fbb71011da8e90b25ebdcb66d78abec8dcb7af
Author: Rob Latham <robl(a)mcs.anl.gov>
Date: Mon Jul 25 16:25:44 2016 -0500
remove unused variable
No Reviewer
diff --git a/src/mpi/romio/adio/common/ad_tuning.c b/src/mpi/romio/adio/common/ad_tuning.c
index dc89bd6..fd39213 100644
--- a/src/mpi/romio/adio/common/ad_tuning.c
+++ b/src/mpi/romio/adio/common/ad_tuning.c
@@ -81,7 +81,7 @@ int romio_tunegather;
*/
void ad_get_env_vars() {
- char *x, *dummy;
+ char *x;
romio_write_aggmethod = 0;
x = getenv( "ROMIO_WRITE_AGGMETHOD" );
-----------------------------------------------------------------------
Summary of changes:
src/mpi/romio/adio/common/ad_tuning.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-372-g679bd67
by noreply@mpich.org 27 Jul '16
by noreply@mpich.org 27 Jul '16
27 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via 679bd676e9dbdc8926f20ecc9f4bd45d1d41f4f6 (commit)
via 355a3e01c52f914d235a6a387dd0e13a6fcc6f8f (commit)
from 0d6412303488428c461986655a56639cbbdbf705 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/679bd676e9dbdc8926f20ecc9f4bd45d1…
commit 679bd676e9dbdc8926f20ecc9f4bd45d1d41f4f6
Author: Yanfei Guo <yguo(a)anl.gov>
Date: Thu Apr 21 22:00:28 2016 -0500
util: Put nodemap code in util layer
Hoist generic nodemap code out of CH3 and into the util layer for use
by other devices.
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/ch3/src/mpid_vc.c b/src/mpid/ch3/src/mpid_vc.c
index aa70c6a..02417bc 100644
--- a/src/mpid/ch3/src/mpid_vc.c
+++ b/src/mpid/ch3/src/mpid_vc.c
@@ -22,36 +22,11 @@
#endif
#include <ctype.h>
+#include "build_nodemap.h"
/*
=== BEGIN_MPI_T_CVAR_INFO_BLOCK ===
cvars:
- - name : MPIR_CVAR_CH3_NOLOCAL
- category : CH3
- alt-env : MPIR_CVAR_CH3_NO_LOCAL
- type : boolean
- default : false
- class : none
- verbosity : MPI_T_VERBOSITY_USER_BASIC
- scope : MPI_T_SCOPE_ALL_EQ
- description : >-
- If true, force all processes to operate as though all processes
- are located on another node. For example, this disables shared
- memory communication hierarchical collectives.
-
- - name : MPIR_CVAR_CH3_ODD_EVEN_CLIQUES
- category : CH3
- alt-env : MPIR_CVAR_CH3_EVEN_ODD_CLIQUES
- type : boolean
- default : false
- class : none
- verbosity : MPI_T_VERBOSITY_USER_BASIC
- scope : MPI_T_SCOPE_ALL_EQ
- description : >-
- If true, odd procs on a node are seen as local to each other, and even
- procs on a node are seen as local to each other. Used for debugging on
- a single machine.
-
- name : MPIR_CVAR_CH3_EAGER_MAX_MSG_SIZE
category : CH3
type : int
@@ -683,333 +658,6 @@ int MPID_Get_max_node_id(MPIR_Comm *comm, MPID_Node_id_t *max_id_p)
return MPI_SUCCESS;
}
-#if !defined(USE_PMI2_API)
-/* this function is not used in pmi2 */
-static int publish_node_id(MPIDI_PG_t *pg, int our_pg_rank)
-{
- int mpi_errno = MPI_SUCCESS;
- int pmi_errno;
- int ret;
- char *key;
- int key_max_sz;
- char *kvs_name;
- MPIR_CHKLMEM_DECL(1);
-
- /* set MPIU_hostname */
- ret = gethostname(MPIU_hostname, MAX_HOSTNAME_LEN);
- MPIR_ERR_CHKANDJUMP2(ret == -1, mpi_errno, MPI_ERR_OTHER, "**sock_gethost", "**sock_gethost %s %d", MPIR_Strerror(errno), errno);
- MPIU_hostname[MAX_HOSTNAME_LEN-1] = '\0';
-
- /* Allocate space for pmi key */
- pmi_errno = PMI_KVS_Get_key_length_max(&key_max_sz);
- MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
-
- MPIR_CHKLMEM_MALLOC(key, char *, key_max_sz, mpi_errno, "key");
-
- mpi_errno = MPIDI_PG_GetConnKVSname(&kvs_name);
- if (mpi_errno) MPIR_ERR_POP(mpi_errno);
-
- /* Put my hostname id */
- if (pg->size > 1)
- {
- memset(key, 0, key_max_sz);
- MPL_snprintf(key, key_max_sz, "hostname[%d]", our_pg_rank);
-
- pmi_errno = PMI_KVS_Put(kvs_name, key, MPIU_hostname);
- MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_put", "**pmi_kvs_put %d", pmi_errno);
-
- pmi_errno = PMI_KVS_Commit(kvs_name);
- MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_commit", "**pmi_kvs_commit %d", pmi_errno);
-
- pmi_errno = PMI_Barrier();
- MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_barrier", "**pmi_barrier %d", pmi_errno);
- }
-
-fn_exit:
- MPIR_CHKLMEM_FREEALL();
- return mpi_errno;
-fn_fail:
- goto fn_exit;
-}
-#endif
-
-
-#define parse_error() MPIR_ERR_INTERNALANDJUMP(mpi_errno, "parse error")
-/* advance _c until we find a non whitespace character */
-#define skip_space(_c) while (isspace(*(_c))) ++(_c)
-/* return true iff _c points to a character valid as an indentifier, i.e., [-_a-zA-Z0-9] */
-#define isident(_c) (isalnum(_c) || (_c) == '-' || (_c) == '_')
-
-/* give an error iff *_c != _e */
-#define expect_c(_c, _e) do { if (*(_c) != _e) parse_error(); } while (0)
-#define expect_and_skip_c(_c, _e) do { expect_c(_c, _e); ++c; } while (0)
-/* give an error iff the first |_m| characters of the string _s are equal to _e */
-#define expect_s(_s, _e) (strncmp(_s, _e, strlen(_e)) == 0 && !isident((_s)[strlen(_e)]))
-
-typedef enum {
- UNKNOWN_MAPPING = -1,
- NULL_MAPPING = 0,
- VECTOR_MAPPING
-} mapping_type_t;
-
-#define VECTOR "vector"
-
-typedef struct map_block
-{
- int start_id;
- int count;
- int size;
-} map_block_t;
-
-#undef FUNCNAME
-#define FUNCNAME parse_mapping
-#undef FCNAME
-#define FCNAME MPL_QUOTE(FUNCNAME)
-static int parse_mapping(char *map_str, mapping_type_t *type, map_block_t **map, int *nblocks)
-{
- int mpi_errno = MPI_SUCCESS;
- char *c = map_str, *d;
- int num_blocks = 0;
- int i;
- MPIR_CHKPMEM_DECL(1);
- MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_PARSE_MAPPING);
-
- MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_PARSE_MAPPING);
-
- /* parse string of the form:
- '(' <format> ',' '(' <num> ',' <num> ',' <num> ')' {',' '(' <num> ',' <num> ',' <num> ')'} ')'
-
- the values of each 3-tuple have the following meaning (X,Y,Z):
- X - node id start value
- Y - number of nodes with size Z
- Z - number of processes assigned to each node
- */
- MPL_DBG_MSG_S(MPIDI_CH3_DBG_OTHER,VERBOSE,"parsing mapping string '%s'", map_str);
-
- if (!strlen(map_str)) {
- /* An empty-string indicates an inability to determine or express the
- * process layout on the part of the process manager. Consider this a
- * non-fatal error case. */
- *type = NULL_MAPPING;
- *map = NULL;
- *nblocks = 0;
- goto fn_exit;
- }
-
- skip_space(c);
- expect_and_skip_c(c, '(');
- skip_space(c);
-
- d = c;
- if (expect_s(d, VECTOR))
- *type = VECTOR_MAPPING;
- else
- parse_error();
- c += strlen(VECTOR);
- skip_space(c);
-
- /* first count the number of block descriptors */
- d = c;
- while (*d) {
- if (*d == '(')
- ++num_blocks;
- ++d;
- }
-
- MPIR_CHKPMEM_MALLOC(*map, map_block_t *, sizeof(map_block_t) * num_blocks, mpi_errno, "map");
-
- /* parse block descriptors */
- for (i = 0; i < num_blocks; ++i) {
- expect_and_skip_c(c, ',');
- skip_space(c);
-
- expect_and_skip_c(c, '(');
- skip_space(c);
-
- if (!isdigit(*c))
- parse_error();
- (*map)[i].start_id = (int)strtol(c, &c, 0);
- skip_space(c);
-
- expect_and_skip_c(c, ',');
- skip_space(c);
-
- if (!isdigit(*c))
- parse_error();
- (*map)[i].count = (int)strtol(c, &c, 0);
- skip_space(c);
-
- expect_and_skip_c(c, ',');
- skip_space(c);
-
- if (!isdigit(*c))
- parse_error();
- (*map)[i].size = (int)strtol(c, &c, 0);
-
- expect_and_skip_c(c, ')');
- skip_space(c);
- }
-
- expect_and_skip_c(c, ')');
-
- *nblocks = num_blocks;
- MPIR_CHKPMEM_COMMIT();
-fn_exit:
- MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_PARSE_MAPPING);
- return mpi_errno;
-fn_fail:
- /* --BEGIN ERROR HANDLING-- */
- MPIR_CHKPMEM_REAP();
- goto fn_exit;
- /* --END ERROR HANDLING-- */
-}
-
-#if 0
-static void t(const char *s, int nprocs)
-{
- int ret;
- map_block_t *mb;
- int nblocks=0;
- int i;
- mapping_type_t mt = UNKNOWN_MAPPING;
- int rank;
- int block, block_node, node_proc;
-
- ret = parse_mapping(strdup(s), &mt, &mb, &nblocks);
- printf("str=\"%s\" type=%d ret=%d\n", s, mt, ret);
- if (ret) return;
- for (i = 0; i < nblocks; ++i)
- printf(" %d: start=%d size=%d count=%d\n", i, mb[i].start_id, mb[i].size, mb[i].count);
- printf("\n");
-
-
- rank = 0;
- while (rank < nprocs) {
- int node_id;
- for (block = 0; block < nblocks; ++block) {
- node_id = mb[block].start_id;
- for (block_node = 0; block_node < mb[block].count; ++block_node) {
- for (node_proc = 0; node_proc < mb[block].size; ++node_proc) {
- printf(" %d %d\n", rank, node_id);
- ++rank;
- if (rank == nprocs)
- goto done;
- }
- ++node_id;
- }
- }
- }
-done:
- return;
-
-}
-
-
- void test_parse_mapping(void)
-{
- t("(vector, (0,1,1))", 5);
- t("(vector, (0,1,1), (1,5,3), (6,2, 5))", 100);
- t("(vector, (1,1,1), (0,2,2))", 5);
-
- t("(vector, (1,1,1), (0,2,2),)", 5);
- t("XXX, (1,1))", 1);
- t("vector, (1,1))", 1);
- t("(vector, (1.11, 2,2))", 1);
- t("", 1);
-
-}
-
-
-#endif
-
-#undef FUNCNAME
-#define FUNCNAME populate_ids_from_mapping
-#undef FCNAME
-#define FCNAME MPL_QUOTE(FUNCNAME)
-static int populate_ids_from_mapping(char *mapping, MPID_Node_id_t *max_node_id, MPIDI_PG_t *pg, int *did_map)
-{
- int mpi_errno = MPI_SUCCESS;
- /* PMI_process_mapping is available */
- mapping_type_t mt = UNKNOWN_MAPPING;
- map_block_t *mb = NULL;
- int nblocks = 0;
- int rank;
- int block, block_node, node_proc;
- int i;
- int found_wrap;
-
- *did_map = 1; /* reset upon failure */
-
- mpi_errno = parse_mapping(mapping, &mt, &mb, &nblocks);
- if (mpi_errno) MPIR_ERR_POP(mpi_errno);
-
- if (NULL_MAPPING == mt) goto fn_fail;
- MPIR_ERR_CHKINTERNAL(mt != VECTOR_MAPPING, mpi_errno, "unsupported mapping type");
-
- /* allocate nodes to ranks */
- found_wrap = 0;
- for (rank = 0;;) {
- /* FIXME: The patch is hacky because it assumes that seeing a
- * start node ID of 0 means a wrap around. This is not
- * necessarily true. A user-defined node list can, in theory,
- * use the node ID 0 without actually creating a wrap around.
- * The reason this patch still works in this case is because
- * Hydra creates a new node list starting from node ID 0 for
- * user-specified nodes during MPI_Comm_spawn{_multiple}. If
- * a different process manager searches for allocated nodes in
- * the user-specified list, this patch will break. */
-
- /* If we found that the blocks wrap around, repeat loops
- * should only start at node id 0 */
- for (block = 0; found_wrap && mb[block].start_id; block++);
-
- for (; block < nblocks; block++) {
- if (mb[block].start_id == 0)
- found_wrap = 1;
- for (block_node = 0; block_node < mb[block].count; block_node++) {
- for (node_proc = 0; node_proc < mb[block].size; node_proc++) {
- pg->vct[rank].node_id = mb[block].start_id + block_node;
- if (++rank == pg->size)
- goto break_out;
- }
- }
- }
- }
-
- break_out:
- /* identify maximum node id */
- *max_node_id = -1;
- for (i = 0; i < pg->size; i++)
- if (pg->vct[i].node_id + 1 > *max_node_id)
- *max_node_id = pg->vct[i].node_id;
-
-fn_exit:
- MPL_free(mb);
- return mpi_errno;
-fn_fail:
- /* --BEGIN ERROR HANDLING-- */
- *did_map = 0;
- goto fn_exit;
- /* --END ERROR HANDLING-- */
-}
-
-/* Fills in the node_id info from PMI info. Adapted from MPIU_Get_local_procs.
- This function is collective over the entire PG because PMI_Barrier is called.
-
- our_pg_rank should be set to -1 if this is not the current process' PG. This
- is currently not supported due to PMI limitations.
-
- Fallback Algorithm:
-
- Each process kvs_puts its hostname and stores the total number of
- processes (g_num_global). Each process determines maximum node id
- (g_max_node_id) and assigns a node id to each process (g_node_ids[]):
-
- For each hostname the process seaches the list of unique nodes
- names (node_names[]) for a match. If a match is found, the node id
- is recorded for that matching process. Otherwise, the hostname is
- added to the list of node names.
-*/
#undef FUNCNAME
#define FUNCNAME MPIDI_Populate_vc_node_ids
#undef FCNAME
@@ -1017,178 +665,20 @@ fn_fail:
int MPIDI_Populate_vc_node_ids(MPIDI_PG_t *pg, int our_pg_rank)
{
int mpi_errno = MPI_SUCCESS;
- int pmi_errno;
- int i, j;
- char *key;
- char *value;
- int key_max_sz;
- int val_max_sz;
- char *kvs_name;
- char **node_names;
- char *node_name_buf;
- int no_local = 0;
- int odd_even_cliques = 0;
- int pmi_version = MPIDI_CH3I_DEFAULT_PMI_VERSION;
- int pmi_subversion = MPIDI_CH3I_DEFAULT_PMI_SUBVERSION;
- MPIR_CHKLMEM_DECL(4);
-
- /* See if the user wants to override our default values */
- MPL_env2int("PMI_VERSION", &pmi_version);
- MPL_env2int("PMI_SUBVERSION", &pmi_subversion);
-
- if (pg->size == 1) {
- pg->vct[0].node_id = ++g_max_node_id;
- goto fn_exit;
- }
-
- /* Used for debugging only. This disables communication over shared memory */
-#ifdef ENABLED_NO_LOCAL
- no_local = 1;
-#else
- no_local = MPIR_CVAR_CH3_NOLOCAL;
-#endif
-
- /* Used for debugging on a single machine: Odd procs on a node are
- seen as local to each other, and even procs on a node are seen
- as local to each other. */
-#ifdef ENABLED_ODD_EVEN_CLIQUES
- odd_even_cliques = 1;
-#else
- odd_even_cliques = MPIR_CVAR_CH3_ODD_EVEN_CLIQUES;
-#endif
-
- if (no_local) {
- /* just assign 0 to n-1 as node ids and bail */
- for (i = 0; i < pg->size; ++i) {
- pg->vct[i].node_id = ++g_max_node_id;
- }
- goto fn_exit;
- }
-
-#ifdef USE_PMI2_API
- {
- char process_mapping[PMI2_MAX_VALLEN];
- int outlen;
- int found = FALSE;
- int i;
- map_block_t *mb;
- int nblocks;
- int rank;
- int block, block_node, node_proc;
- int did_map = 0;
-
- mpi_errno = PMI2_Info_GetJobAttr("PMI_process_mapping", process_mapping, sizeof(process_mapping), &found);
- if (mpi_errno) MPIR_ERR_POP(mpi_errno);
- MPIR_ERR_CHKINTERNAL(!found, mpi_errno, "PMI_process_mapping attribute not found");
- /* this code currently assumes pg is comm_world */
- mpi_errno = populate_ids_from_mapping(process_mapping, &g_max_node_id, pg, &did_map);
- if (mpi_errno) MPIR_ERR_POP(mpi_errno);
- MPIR_ERR_CHKINTERNAL(!did_map, mpi_errno, "unable to populate node ids from PMI_process_mapping");
- }
-#else /* USE_PMI2_API */
- if (our_pg_rank == -1) {
- /* FIXME this routine can't handle the dynamic process case at this
- time. This will require more support from the process manager. */
- MPIR_Assert(0);
- }
-
- /* Allocate space for pmi key and value */
- pmi_errno = PMI_KVS_Get_key_length_max(&key_max_sz);
- MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
- MPIR_CHKLMEM_MALLOC(key, char *, key_max_sz, mpi_errno, "key");
-
- pmi_errno = PMI_KVS_Get_value_length_max(&val_max_sz);
- MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
- MPIR_CHKLMEM_MALLOC(value, char *, val_max_sz, mpi_errno, "value");
-
- mpi_errno = MPIDI_PG_GetConnKVSname(&kvs_name);
- if (mpi_errno) MPIR_ERR_POP(mpi_errno);
-
- /* See if process manager supports PMI_process_mapping keyval */
-
- if (pmi_version == 1 && pmi_subversion == 1) {
- pmi_errno = PMI_KVS_Get(kvs_name, "PMI_process_mapping", value, val_max_sz);
- if (pmi_errno == 0) {
- int did_map = 0;
- /* this code currently assumes pg is comm_world */
- mpi_errno = populate_ids_from_mapping(value, &g_max_node_id, pg, &did_map);
- if (mpi_errno) MPIR_ERR_POP(mpi_errno);
- if (did_map) {
- goto odd_even_cliques;
- }
- else {
- MPL_DBG_MSG_S(MPIDI_CH3_DBG_OTHER,TERSE,"did_map==0, unable to populate node ids from mapping=%s",value);
- }
- /* else fall through to O(N^2) PMI_KVS_Gets version */
- }
- else {
- MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,TERSE,"unable to obtain the 'PMI_process_mapping' PMI key");
- }
- }
+ int i;
+ MPID_Node_id_t *out_nodemap;
+ out_nodemap = (MPID_Node_id_t *) MPL_malloc(pg->size * sizeof(MPID_Node_id_t));
- mpi_errno = publish_node_id(pg, our_pg_rank);
+ mpi_errno = MPIR_NODEMAP_build_nodemap(pg->size, our_pg_rank, out_nodemap, &g_max_node_id);
if (mpi_errno) MPIR_ERR_POP(mpi_errno);
+ MPIR_Assert(g_max_node_id >= 0);
- /* Allocate temporary structures. These would need to be persistent if
- we somehow were able to support dynamic processes via this method. */
- MPIR_CHKLMEM_MALLOC(node_names, char **, pg->size * sizeof(char*), mpi_errno, "node_names");
- MPIR_CHKLMEM_MALLOC(node_name_buf, char *, pg->size * key_max_sz * sizeof(char), mpi_errno, "node_name_buf");
-
- /* Gather hostnames */
- for (i = 0; i < pg->size; ++i)
- {
- node_names[i] = &node_name_buf[i * key_max_sz];
- node_names[i][0] = '\0';
- }
-
- g_max_node_id = -1; /* defensive */
-
- for (i = 0; i < pg->size; ++i)
- {
- MPIR_Assert(g_max_node_id < pg->size);
- if (i == our_pg_rank)
- {
- /* This is us, no need to perform a get */
- MPL_snprintf(node_names[g_max_node_id+1], key_max_sz, "%s", MPIU_hostname);
- }
- else
- {
- memset(key, 0, key_max_sz);
- MPL_snprintf(key, key_max_sz, "hostname[%d]", i);
-
- pmi_errno = PMI_KVS_Get(kvs_name, key, node_names[g_max_node_id+1], key_max_sz);
- MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_get", "**pmi_kvs_get %d", pmi_errno);
- }
-
- /* Find the node_id for this process, or create a new one */
- /* FIXME:need a better algorithm -- this one does O(N^2) strncmp()s! */
- /* The right fix is to get all this information from the process
- manager, rather than bother with this hostname hack at all. */
- for (j = 0; j < g_max_node_id + 1; ++j)
- if (!strncmp(node_names[j], node_names[g_max_node_id+1], key_max_sz))
- break;
- if (j == g_max_node_id + 1)
- ++g_max_node_id;
- else
- node_names[g_max_node_id+1][0] = '\0';
- pg->vct[i].node_id = j;
+ for (i = 0; i < pg->size; i++) {
+ pg->vct[i].node_id = out_nodemap[i];
}
-odd_even_cliques:
- if (odd_even_cliques)
- {
- /* Create new processes for all odd numbered processes. This
- may leave nodes ids with no processes assigned to them, but
- I think this is OK */
- for (i = 0; i < pg->size; ++i)
- if (i & 0x1)
- pg->vct[i].node_id += g_max_node_id + 1;
- g_max_node_id = (g_max_node_id + 1) * 2;
- }
-#endif
-
fn_exit:
- MPIR_CHKLMEM_FREEALL();
+ MPL_free(out_nodemap);
return mpi_errno;
fn_fail:
goto fn_exit;
diff --git a/src/util/Makefile.mk b/src/util/Makefile.mk
index f97cc63..b98fc67 100644
--- a/src/util/Makefile.mk
+++ b/src/util/Makefile.mk
@@ -9,5 +9,6 @@ include $(top_srcdir)/src/util/logging/Makefile.mk
include $(top_srcdir)/src/util/mem/Makefile.mk
include $(top_srcdir)/src/util/cvar/Makefile.mk
include $(top_srcdir)/src/util/procmap/Makefile.mk
+include $(top_srcdir)/src/util/nodemap/Makefile.mk
include $(top_srcdir)/src/util/wrappers/Makefile.mk
include $(top_srcdir)/src/util/assert/Makefile.mk
diff --git a/src/util/nodemap/Makefile.mk b/src/util/nodemap/Makefile.mk
new file mode 100644
index 0000000..e7756df
--- /dev/null
+++ b/src/util/nodemap/Makefile.mk
@@ -0,0 +1,12 @@
+## -*- Mode: Makefile; -*-
+## vim: set ft=automake :
+##
+## (C) 2016 by Argonne National Laboratory.
+## See COPYRIGHT in top-level directory.
+##
+
+## FIXME check that this is the right way to do VPATH
+AM_CPPFLAGS += -I$(top_srcdir)/src/util/nodemap
+
+noinst_HEADERS += \
+ src/util/nodemap/build_nodemap.h
diff --git a/src/util/nodemap/build_nodemap.h b/src/util/nodemap/build_nodemap.h
new file mode 100644
index 0000000..1c0dd82
--- /dev/null
+++ b/src/util/nodemap/build_nodemap.h
@@ -0,0 +1,515 @@
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2016 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+#ifndef BUILD_NODEMAP_H_INCLUDED
+#define BUILD_NODEMAP_H_INCLUDED
+
+#include "mpl.h"
+
+/*
+=== BEGIN_MPI_T_CVAR_INFO_BLOCK ===
+
+cvars:
+ - name : MPIR_CVAR_NOLOCAL
+ category : NODEMAP
+ alt-env : MPIR_CVAR_NO_LOCAL
+ type : boolean
+ default : false
+ class : none
+ verbosity : MPI_T_VERBOSITY_USER_BASIC
+ scope : MPI_T_SCOPE_ALL_EQ
+ description : >-
+ If true, force all processes to operate as though all processes
+ are located on another node. For example, this disables shared
+ memory communication hierarchical collectives.
+
+ - name : MPIR_CVAR_ODD_EVEN_CLIQUES
+ category : NODEMAP
+ alt-env : MPIR_CVAR_EVEN_ODD_CLIQUES
+ type : boolean
+ default : false
+ class : none
+ verbosity : MPI_T_VERBOSITY_USER_BASIC
+ scope : MPI_T_SCOPE_ALL_EQ
+ description : >-
+ If true, odd procs on a node are seen as local to each other, and even
+ procs on a node are seen as local to each other. Used for debugging on
+ a single machine.
+
+=== END_MPI_T_CVAR_INFO_BLOCK ===
+*/
+
+#if !defined(USE_PMI2_API)
+/* this function is not used in pmi2 */
+#undef FUNCNAME
+#define FUNCNAME MPIR_NODEMAP_publish_node_id
+#undef FCNAME
+#define FCNAME MPL_QUOTE(FUNCNAME)
+static inline int MPIR_NODEMAP_publish_node_id(int sz, int myrank)
+{
+ int mpi_errno = MPI_SUCCESS;
+ int pmi_errno;
+ int ret;
+ char *key;
+ int key_max_sz;
+ char *kvs_name;
+ char hostname[MAX_HOSTNAME_LEN];
+ MPIR_CHKLMEM_DECL(2);
+
+ /* set hostname */
+
+ ret = gethostname(hostname, MAX_HOSTNAME_LEN);
+ MPIR_ERR_CHKANDJUMP2(ret == -1, mpi_errno, MPI_ERR_OTHER, "**sock_gethost", "**sock_gethost %s %d", MPIR_Strerror(errno), errno);
+ hostname[MAX_HOSTNAME_LEN-1] = '\0';
+
+ /* Allocate space for pmi key */
+ pmi_errno = PMI_KVS_Get_key_length_max(&key_max_sz);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
+
+ MPIR_CHKLMEM_MALLOC(key, char *, key_max_sz, mpi_errno, "key");
+
+ MPIR_CHKLMEM_MALLOC(kvs_name, char *, 256, mpi_errno, "kvs_name");
+ pmi_errno = PMI_KVS_Get_my_name(kvs_name, 256);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
+ /* Put my hostname id */
+ if (sz > 1)
+ {
+ memset(key, 0, key_max_sz);
+ MPL_snprintf(key, key_max_sz, "hostname[%d]", myrank);
+
+ pmi_errno = PMI_KVS_Put(kvs_name, key, hostname);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_put", "**pmi_kvs_put %d", pmi_errno);
+
+ pmi_errno = PMI_KVS_Commit(kvs_name);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_commit", "**pmi_kvs_commit %d", pmi_errno);
+
+ pmi_errno = PMI_Barrier();
+ MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_barrier", "**pmi_barrier %d", pmi_errno);
+ }
+
+fn_exit:
+ MPIR_CHKLMEM_FREEALL();
+ return mpi_errno;
+fn_fail:
+ goto fn_exit;
+}
+#endif
+
+
+#define MPIR_NODEMAP_PARSE_ERROR() MPIR_ERR_INTERNALANDJUMP(mpi_errno, "parse error")
+/* advance _c until we find a non whitespace character */
+#define MPIR_NODEMAP_SKIP_SPACE(_c) while (isspace(*(_c))) ++(_c)
+/* return true iff _c points to a character valid as an indentifier, i.e., [-_a-zA-Z0-9] */
+#define MPIR_NODEMAP_ISIDENT(_c) (isalnum(_c) || (_c) == '-' || (_c) == '_')
+
+/* give an error iff *_c != _e */
+#define MPIR_NODEMAP_EXPECT_C(_c, _e) do { if (*(_c) != _e) MPIR_NODEMAP_PARSE_ERROR(); } while (0)
+#define MPIR_NODEMAP_EXPECT_AND_SKIP_C(_c, _e) do { MPIR_NODEMAP_EXPECT_C(_c, _e); ++c; } while (0)
+/* give an error iff the first |_m| characters of the string _s are equal to _e */
+#define MPIR_NODEMAP_EXPECT_S(_s, _e) (MPL_strncmp(_s, _e, strlen(_e)) == 0 && !MPIR_NODEMAP_ISIDENT((_s)[strlen(_e)]))
+
+typedef enum {
+ MPIR_NODEMAP_UNKNOWN_MAPPING = -1,
+ MPIR_NODEMAP_NULL_MAPPING = 0,
+ MPIR_NODEMAP_VECTOR_MAPPING
+} MPIR_NODEMAP_mapping_type_t;
+
+#define MPIR_NODEMAP_VECTOR "vector"
+
+typedef struct map_block
+{
+ int start_id;
+ int count;
+ int size;
+} MPIR_NODEMAP_map_block_t;
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_NODEMAP_parse_mapping
+#undef FCNAME
+#define FCNAME MPL_QUOTE(FUNCNAME)
+static inline int MPIR_NODEMAP_parse_mapping(char *map_str,
+ MPIR_NODEMAP_mapping_type_t *type,
+ MPIR_NODEMAP_map_block_t **map,
+ int *nblocks)
+{
+ int mpi_errno = MPI_SUCCESS;
+ char *c = map_str, *d;
+ int num_blocks = 0;
+ int i;
+ MPIR_CHKPMEM_DECL(1);
+
+ /* parse string of the form:
+ '(' <format> ',' '(' <num> ',' <num> ',' <num> ')' {',' '(' <num> ',' <num> ',' <num> ')'} ')'
+
+ the values of each 3-tuple have the following meaning (X,Y,Z):
+ X - node id start value
+ Y - number of nodes with size Z
+ Z - number of processes assigned to each node
+ */
+
+ if (!strlen(map_str)) {
+ /* An empty-string indicates an inability to determine or express the
+ * process layout on the part of the process manager. Consider this a
+ * non-fatal error case. */
+ *type = MPIR_NODEMAP_NULL_MAPPING;
+ *map = NULL;
+ *nblocks = 0;
+ goto fn_exit;
+ }
+
+ MPIR_NODEMAP_SKIP_SPACE(c);
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, '(');
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ d = c;
+ if (MPIR_NODEMAP_EXPECT_S(d, MPIR_NODEMAP_VECTOR))
+ *type = MPIR_NODEMAP_VECTOR_MAPPING;
+ else
+ MPIR_NODEMAP_PARSE_ERROR();
+ c += strlen(MPIR_NODEMAP_VECTOR);
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ /* first count the number of block descriptors */
+ d = c;
+ while (*d) {
+ if (*d == '(')
+ ++num_blocks;
+ ++d;
+ }
+
+ MPIR_CHKPMEM_MALLOC(*map, MPIR_NODEMAP_map_block_t *, sizeof(MPIR_NODEMAP_map_block_t) * num_blocks, mpi_errno, "map");
+
+ /* parse block descriptors */
+ for (i = 0; i < num_blocks; ++i) {
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, ',');
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, '(');
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ if (!isdigit(*c))
+ MPIR_NODEMAP_PARSE_ERROR();
+ (*map)[i].start_id = (int)strtol(c, &c, 0);
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, ',');
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ if (!isdigit(*c))
+ MPIR_NODEMAP_PARSE_ERROR();
+ (*map)[i].count = (int)strtol(c, &c, 0);
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, ',');
+ MPIR_NODEMAP_SKIP_SPACE(c);
+
+ if (!isdigit(*c))
+ MPIR_NODEMAP_PARSE_ERROR();
+ (*map)[i].size = (int)strtol(c, &c, 0);
+
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, ')');
+ MPIR_NODEMAP_SKIP_SPACE(c);
+ }
+
+ MPIR_NODEMAP_EXPECT_AND_SKIP_C(c, ')');
+
+ *nblocks = num_blocks;
+ MPIR_CHKPMEM_COMMIT();
+fn_exit:
+ return mpi_errno;
+fn_fail:
+ /* --BEGIN ERROR HANDLING-- */
+ MPIR_CHKPMEM_REAP();
+ goto fn_exit;
+ /* --END ERROR HANDLING-- */
+}
+
+#undef FUNCNAME
+#define FUNCNAME MPIR_NODEMAP_populate_ids_from_mapping
+#undef FCNAME
+#define FCNAME MPL_QUOTE(FUNCNAME)
+static inline int MPIR_NODEMAP_populate_ids_from_mapping(char *mapping,
+ int sz,
+ MPID_Node_id_t *out_nodemap,
+ MPID_Node_id_t *max_node_id,
+ int *did_map)
+{
+ int mpi_errno = MPI_SUCCESS;
+ /* PMI_process_mapping is available */
+ MPIR_NODEMAP_mapping_type_t mt = MPIR_NODEMAP_UNKNOWN_MAPPING;
+ MPIR_NODEMAP_map_block_t *mb = NULL;
+ int nblocks = 0;
+ int rank;
+ int block, block_node, node_proc;
+ int i;
+ int found_wrap;
+
+ *did_map = 1; /* reset upon failure */
+
+ mpi_errno = MPIR_NODEMAP_parse_mapping(mapping, &mt, &mb, &nblocks);
+ if (mpi_errno) MPIR_ERR_POP(mpi_errno);
+
+ if (MPIR_NODEMAP_NULL_MAPPING == mt) goto fn_fail;
+ MPIR_ERR_CHKINTERNAL(mt != MPIR_NODEMAP_VECTOR_MAPPING, mpi_errno, "unsupported mapping type");
+
+ /* allocate nodes to ranks */
+ found_wrap = 0;
+ for (rank = 0;;) {
+ /* FIXME: The patch is hacky because it assumes that seeing a
+ * start node ID of 0 means a wrap around. This is not
+ * necessarily true. A user-defined node list can, in theory,
+ * use the node ID 0 without actually creating a wrap around.
+ * The reason this patch still works in this case is because
+ * Hydra creates a new node list starting from node ID 0 for
+ * user-specified nodes during MPI_Comm_spawn{_multiple}. If
+ * a different process manager searches for allocated nodes in
+ * the user-specified list, this patch will break. */
+
+ /* If we found that the blocks wrap around, repeat loops
+ * should only start at node id 0 */
+ for (block = 0; found_wrap && mb[block].start_id; block++);
+
+ for (; block < nblocks; block++) {
+ if (mb[block].start_id == 0)
+ found_wrap = 1;
+ for (block_node = 0; block_node < mb[block].count; block_node++) {
+ for (node_proc = 0; node_proc < mb[block].size; node_proc++) {
+ out_nodemap[rank]= mb[block].start_id + block_node;
+ if (++rank == sz)
+ goto break_out;
+ }
+ }
+ }
+ }
+
+ break_out:
+ /* identify maximum node id */
+ *max_node_id = -1;
+ for (i = 0; i < sz; i++)
+ if (out_nodemap[i] + 1 > *max_node_id)
+ *max_node_id = out_nodemap[i];
+
+fn_exit:
+ MPL_free(mb);
+ return mpi_errno;
+fn_fail:
+ /* --BEGIN ERROR HANDLING-- */
+ *did_map = 0;
+ goto fn_exit;
+ /* --END ERROR HANDLING-- */
+}
+
+/* Fills in the node_id info from PMI info. Adapted from MPIU_Get_local_procs.
+ This function is collective over the entire PG because PMI_Barrier is called.
+
+ myrank should be set to -1 if this is not the current process' PG. This
+ is currently not supported due to PMI limitations.
+
+ Fallback Algorithm:
+
+ Each process kvs_puts its hostname and stores the total number of
+ processes (g_num_global). Each process determines maximum node id
+ (g_max_node_id) and assigns a node id to each process (g_node_ids[]):
+
+ For each hostname the process seaches the list of unique nodes
+ names (node_names[]) for a match. If a match is found, the node id
+ is recorded for that matching process. Otherwise, the hostname is
+ added to the list of node names.
+*/
+#undef FUNCNAME
+#define FUNCNAME MPIR_NODEMAP_build_nodemap
+#undef FCNAME
+#define FCNAME MPL_QUOTE(FUNCNAME)
+static inline int MPIR_NODEMAP_build_nodemap(int sz,
+ int myrank,
+ MPID_Node_id_t *out_nodemap,
+ MPID_Node_id_t *out_sz)
+{
+ static int g_max_node_id = -1;
+ int mpi_errno = MPI_SUCCESS;
+ int pmi_errno;
+ int i, j;
+ char *key;
+ char *value;
+ int key_max_sz;
+ int val_max_sz;
+ char *kvs_name;
+ char **node_names;
+ char *node_name_buf;
+ int no_local = 0;
+ int odd_even_cliques = 0;
+ int pmi_version = 1;
+ int pmi_subversion = 1;
+ MPIR_CHKLMEM_DECL(5);
+
+ /* See if the user wants to override our default values */
+ MPL_env2int("PMI_VERSION", &pmi_version);
+ MPL_env2int("PMI_SUBVERSION", &pmi_subversion);
+
+ if (sz == 1) {
+ out_nodemap[0] = ++g_max_node_id;
+ *out_sz = g_max_node_id;
+ goto fn_exit;
+ }
+
+ /* Used for debugging only. This disables communication over shared memory */
+#ifdef ENABLED_NO_LOCAL
+ no_local = 1;
+#else
+ no_local = MPIR_CVAR_NOLOCAL;
+#endif
+
+ /* Used for debugging on a single machine: Odd procs on a node are
+ seen as local to each other, and even procs on a node are seen
+ as local to each other. */
+#ifdef ENABLED_ODD_EVEN_CLIQUES
+ odd_even_cliques = 1;
+#else
+ odd_even_cliques = MPIR_CVAR_ODD_EVEN_CLIQUES;
+#endif
+
+ if (no_local) {
+ /* just assign 0 to n-1 as node ids and bail */
+ for (i = 0; i < sz; ++i) {
+ out_nodemap[i] = ++g_max_node_id;
+ }
+ *out_sz = g_max_node_id;
+ goto fn_exit;
+ }
+
+#ifdef USE_PMI2_API
+ {
+ char process_mapping[PMI2_MAX_VALLEN];
+ int outlen;
+ int found = FALSE;
+ int i;
+ MPIR_NODEMAP_map_block_t *mb;
+ int nblocks;
+ int rank;
+ int block, block_node, node_proc;
+ int did_map = 0;
+
+ mpi_errno = PMI2_Info_GetJobAttr("PMI_process_mapping", process_mapping, sizeof(process_mapping), &found);
+ if (mpi_errno) MPIR_ERR_POP(mpi_errno);
+ MPIR_ERR_CHKINTERNAL(!found, mpi_errno, "PMI_process_mapping attribute not found");
+ /* this code currently assumes pg is comm_world */
+ mpi_errno = MPIR_NODEMAP_populate_ids_from_mapping(process_mapping, sz, out_nodemap, out_sz, &did_map);
+ if (mpi_errno) MPIR_ERR_POP(mpi_errno);
+ MPIR_ERR_CHKINTERNAL(!did_map, mpi_errno, "unable to populate node ids from PMI_process_mapping");
+ }
+#else /* USE_PMI2_API */
+ if (myrank == -1) {
+ /* fixme this routine can't handle the dynamic process case at this
+ time. this will require more support from the process manager. */
+ MPIR_Assert(0);
+ }
+
+ /* Allocate space for pmi key and value */
+ pmi_errno = PMI_KVS_Get_key_length_max(&key_max_sz);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
+ MPIR_CHKLMEM_MALLOC(key, char *, key_max_sz, mpi_errno, "key");
+
+ pmi_errno = PMI_KVS_Get_value_length_max(&val_max_sz);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
+ MPIR_CHKLMEM_MALLOC(value, char *, val_max_sz, mpi_errno, "value");
+
+ MPIR_CHKLMEM_MALLOC(kvs_name, char *, 256, mpi_errno, "kvs_name");
+ pmi_errno = PMI_KVS_Get_my_name(kvs_name, 256);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %d", pmi_errno);
+ /* See if process manager supports PMI_process_mapping keyval */
+
+ if (pmi_version == 1 && pmi_subversion == 1) {
+ pmi_errno = PMI_KVS_Get(kvs_name, "PMI_process_mapping", value, val_max_sz);
+ if (pmi_errno == 0) {
+ int did_map = 0;
+ /* this code currently assumes pg is comm_world */
+ mpi_errno = MPIR_NODEMAP_populate_ids_from_mapping(value, sz, out_nodemap, out_sz, &did_map);
+ g_max_node_id = *out_sz;
+ if (mpi_errno) MPIR_ERR_POP(mpi_errno);
+ if (did_map) {
+ goto odd_even_cliques;
+ }
+ /* else fall through to O(N^2) PMI_KVS_Gets version */
+ }
+ }
+
+ /* fallback algorithm */
+ mpi_errno = MPIR_NODEMAP_publish_node_id(sz, myrank);
+ if (mpi_errno) MPIR_ERR_POP(mpi_errno);
+
+ /* Allocate temporary structures. These would need to be persistent if
+ we somehow were able to support dynamic processes via this method. */
+ MPIR_CHKLMEM_MALLOC(node_names, char **, sz * sizeof(char*), mpi_errno, "node_names");
+ MPIR_CHKLMEM_MALLOC(node_name_buf, char *, sz * key_max_sz * sizeof(char), mpi_errno, "node_name_buf");
+
+ /* Gather hostnames */
+ for (i = 0; i < sz; ++i)
+ {
+ node_names[i] = &node_name_buf[i * key_max_sz];
+ node_names[i][0] = '\0';
+ }
+
+ g_max_node_id = -1; /* defensive */
+
+ for (i = 0; i < sz; ++i)
+ {
+ MPIR_Assert(g_max_node_id < sz);
+ if (i == myrank)
+ {
+ /* This is us, no need to perform a get */
+ int ret;
+ char *hostname = (char*) MPL_malloc(sizeof(char) * MAX_HOSTNAME_LEN);
+ ret = gethostname(hostname, MAX_HOSTNAME_LEN);
+ MPIR_ERR_CHKANDJUMP2(ret == -1, mpi_errno, MPI_ERR_OTHER, "**sock_gethost", "**sock_gethost %s %d", MPIR_Strerror(errno), errno);
+ hostname[MAX_HOSTNAME_LEN-1] = '\0';
+ MPL_snprintf(node_names[g_max_node_id+1], key_max_sz, "%s", hostname);
+ MPL_free(hostname);
+ }
+ else
+ {
+ memset(key, 0, key_max_sz);
+ MPL_snprintf(key, key_max_sz, "hostname[%d]", i);
+
+ pmi_errno = PMI_KVS_Get(kvs_name, key, node_names[g_max_node_id+1], key_max_sz);
+ MPIR_ERR_CHKANDJUMP1(pmi_errno != PMI_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**pmi_kvs_get", "**pmi_kvs_get %d", pmi_errno);
+ }
+
+ /* Find the node_id for this process, or create a new one */
+ /* FIXME:need a better algorithm -- this one does O(N^2) strncmp()s! */
+ /* The right fix is to get all this information from the process
+ manager, rather than bother with this hostname hack at all. */
+ for (j = 0; j < g_max_node_id + 1; ++j)
+ if (!MPL_strncmp(node_names[j], node_names[g_max_node_id+1], key_max_sz))
+ break;
+ if (j == g_max_node_id + 1)
+ ++g_max_node_id;
+ else
+ node_names[g_max_node_id+1][0] = '\0';
+ out_nodemap[i] = j;
+ }
+
+odd_even_cliques:
+ if (odd_even_cliques)
+ {
+ /* Create new processes for all odd numbered processes. This
+ may leave nodes ids with no processes assigned to them, but
+ I think this is OK */
+ for (i = 0; i < sz; ++i)
+ if (i & 0x1)
+ out_nodemap[i] += g_max_node_id + 1;
+ g_max_node_id = (g_max_node_id + 1) * 2;
+ }
+ *out_sz = g_max_node_id;
+#endif
+
+fn_exit:
+ MPIR_CHKLMEM_FREEALL();
+ return mpi_errno;
+fn_fail:
+ goto fn_exit;
+}
+
+#endif /* ifndef BUILD_NODEMAP_H_INCLUDED */
http://git.mpich.org/mpich.git/commitdiff/355a3e01c52f914d235a6a387dd0e13a6…
commit 355a3e01c52f914d235a6a387dd0e13a6fcc6f8f
Author: Ken Raffenetti <raffenet(a)mcs.anl.gov>
Date: Mon Apr 11 13:12:41 2016 -0500
Guard datatype macro definitions
These macros have a tendency to show up in other parts of the code
that deal with MPI_Datatype (i.e. not MPIR_Datatype). Guard their
definition to avoid duplicate warnings at compile time.
Signed-off-by: Charles J Archer <charles.j.archer(a)intel.com>
diff --git a/src/mpid/common/sched/mpidu_sched.c b/src/mpid/common/sched/mpidu_sched.c
index bc72332..5225feb 100644
--- a/src/mpid/common/sched/mpidu_sched.c
+++ b/src/mpid/common/sched/mpidu_sched.c
@@ -21,6 +21,7 @@
/* helper macros to improve code readability */
/* we pessimistically assume that MPI_DATATYPE_NULL may be passed as a "valid" type
* for send/recv when MPI_PROC_NULL is the destination/src */
+#ifndef dtype_add_ref_if_not_builtin
#define dtype_add_ref_if_not_builtin(datatype_) \
do { \
if ((datatype_) != MPI_DATATYPE_NULL && \
@@ -31,6 +32,8 @@
MPID_Datatype_add_ref(dtp_); \
} \
} while (0)
+#endif
+#ifndef dtype_release_if_not_builtin
#define dtype_release_if_not_builtin(datatype_) \
do { \
if ((datatype_) != MPI_DATATYPE_NULL && \
@@ -41,6 +44,7 @@
MPID_Datatype_release(dtp_); \
} \
} while (0)
+#endif
/* TODO move to a header somewhere? */
void MPIDU_Sched_dump(struct MPIDU_Sched *s);
-----------------------------------------------------------------------
Summary of changes:
src/mpid/ch3/src/mpid_vc.c | 528 +----------------------------------
src/mpid/common/sched/mpidu_sched.c | 4 +
src/util/Makefile.mk | 1 +
src/util/nodemap/Makefile.mk | 12 +
src/util/nodemap/build_nodemap.h | 515 ++++++++++++++++++++++++++++++++++
5 files changed, 541 insertions(+), 519 deletions(-)
create mode 100644 src/util/nodemap/Makefile.mk
create mode 100644 src/util/nodemap/build_nodemap.h
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-370-g0d64123
by noreply@mpich.org 26 Jul '16
by noreply@mpich.org 26 Jul '16
26 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via 0d6412303488428c461986655a56639cbbdbf705 (commit)
from f43c017cea598e37088d75a58a87b714ce4e8921 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/0d6412303488428c461986655a56639cb…
commit 0d6412303488428c461986655a56639cbbdbf705
Author: Sayantan Sur <sayantan.sur(a)intel.com>
Date: Thu Jan 7 18:24:53 2016 -0800
MPL: Provide uthash implementation
Provide a single, prefixed version of uthash in MPL. This way it can
easily be used by other components in the future, such as Hydra.
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/include/Makefile.mk b/src/include/Makefile.mk
index 7da2717..7e685fe 100644
--- a/src/include/Makefile.mk
+++ b/src/include/Makefile.mk
@@ -63,7 +63,6 @@ noinst_HEADERS += \
src/include/mpir_op.h \
src/include/mpir_process.h \
src/include/mpir_utarray.h \
- src/include/mpir_uthash.h \
src/include/mpir_misc.h \
src/include/mpir_tags.h \
src/include/mpir_datatype.h \
diff --git a/src/include/mpit.h b/src/include/mpit.h
index d2e2986..a8e7a08 100644
--- a/src/include/mpit.h
+++ b/src/include/mpit.h
@@ -44,7 +44,7 @@ static inline cvar_table_entry_t * LOOKUP_CVAR_BY_NAME(const char* cvar_name)
{
unsigned cvar_idx;
name2index_hash_t *hash_entry;
- HASH_FIND_STR(cvar_hash, cvar_name, hash_entry);
+ MPL_HASH_FIND_STR(cvar_hash, cvar_name, hash_entry);
MPIR_Assert(hash_entry != NULL);
cvar_idx = hash_entry->idx;
return (cvar_table_entry_t *)utarray_eltptr(cvar_table, cvar_idx);
diff --git a/src/include/mpitimpl.h b/src/include/mpitimpl.h
index c3a9d03..bacf7c0 100644
--- a/src/include/mpitimpl.h
+++ b/src/include/mpitimpl.h
@@ -16,7 +16,7 @@
#include "mpir_assert.h"
#include "mpir_pointers.h"
#include "mpir_utarray.h"
-#include "mpir_uthash.h"
+#include "mpl_uthash.h"
#include "mpir_objects.h"
#ifdef HAVE_ERROR_CHECKING
@@ -58,7 +58,7 @@ typedef struct {
typedef struct {
const char *name;
unsigned idx;
- UT_hash_handle hh; /* Makes this structure hashable */
+ MPL_UT_hash_handle hh; /* Makes this structure hashable */
} name2index_hash_t;
/* MPI_T control variable (cvar)
diff --git a/src/mpi/comm/commutil.c b/src/mpi/comm/commutil.c
index 3129d6a..c365612 100644
--- a/src/mpi/comm/commutil.c
+++ b/src/mpi/comm/commutil.c
@@ -9,7 +9,7 @@
#include "mpir_info.h" /* MPIR_Info_free */
#include "mpl_utlist.h"
-#include "mpir_uthash.h"
+#include "mpl_uthash.h"
/* This is the utility file for comm that contains the basic comm items
and storage management */
@@ -39,7 +39,7 @@ struct MPIR_Comm_hint_fn_elt {
char name[MPI_MAX_INFO_KEY];
MPIR_Comm_hint_fn_t fn;
void *state;
- UT_hash_handle hh;
+ MPL_UT_hash_handle hh;
};
static struct MPIR_Comm_hint_fn_elt *MPID_hint_fns = NULL;
@@ -1091,7 +1091,7 @@ int MPII_Comm_apply_hints(MPIR_Comm * comm_ptr, MPIR_Info * info_ptr)
strncpy(hint_name, hint->key, MPI_MAX_INFO_KEY);
- HASH_FIND_STR(MPID_hint_fns, hint_name, hint_fn);
+ MPL_HASH_FIND_STR(MPID_hint_fns, hint_name, hint_fn);
/* Skip hints that MPICH doesn't recognize. */
if (hint_fn) {
@@ -1121,8 +1121,8 @@ static int free_hint_handles(void *ignore)
MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPIR_COMM_FREE_HINT_HANDLES);
if (MPID_hint_fns) {
- HASH_ITER(hh, MPID_hint_fns, curr_hint, tmp) {
- HASH_DEL(MPID_hint_fns, curr_hint);
+ MPL_HASH_ITER(hh, MPID_hint_fns, curr_hint, tmp) {
+ MPL_HASH_DEL(MPID_hint_fns, curr_hint);
MPL_free(curr_hint);
}
}
@@ -1154,7 +1154,7 @@ int MPIR_Comm_register_hint(const char *hint_key, MPIR_Comm_hint_fn_t fn, void *
hint_elt->state = state;
hint_elt->fn = fn;
- HASH_ADD_STR(MPID_hint_fns, name, hint_elt);
+ MPL_HASH_ADD_STR(MPID_hint_fns, name, hint_elt);
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_COMM_REGISTER_HINT);
return mpi_errno;
diff --git a/src/mpi/comm/contextid.c b/src/mpi/comm/contextid.c
index bffb158..d43d677 100644
--- a/src/mpi/comm/contextid.c
+++ b/src/mpi/comm/contextid.c
@@ -9,7 +9,6 @@
#include "mpir_info.h" /* MPIR_Info_free */
#include "mpl_utlist.h"
-#include "mpir_uthash.h"
/*
=== BEGIN_MPI_T_CVAR_INFO_BLOCK ===
diff --git a/src/mpi_t/cat_get_index.c b/src/mpi_t/cat_get_index.c
index e50ced8..a9f3254 100644
--- a/src/mpi_t/cat_get_index.c
+++ b/src/mpi_t/cat_get_index.c
@@ -71,7 +71,7 @@ int MPI_T_category_get_index(const char *name, int *cat_index)
name2index_hash_t *hash_entry;
/* Do hash lookup by the name */
- HASH_FIND_STR(cat_hash, name, hash_entry);
+ MPL_HASH_FIND_STR(cat_hash, name, hash_entry);
if (hash_entry != NULL) {
*cat_index = hash_entry->idx;
} else {
diff --git a/src/mpi_t/cvar_get_index.c b/src/mpi_t/cvar_get_index.c
index f49cbc4..050b20c 100644
--- a/src/mpi_t/cvar_get_index.c
+++ b/src/mpi_t/cvar_get_index.c
@@ -71,7 +71,7 @@ int MPI_T_cvar_get_index(const char *name, int *cvar_index)
name2index_hash_t *hash_entry;
/* Do hash lookup by the name */
- HASH_FIND_STR(cvar_hash, name, hash_entry);
+ MPL_HASH_FIND_STR(cvar_hash, name, hash_entry);
if (hash_entry != NULL) {
*cvar_index = hash_entry->idx;
} else {
diff --git a/src/mpi_t/mpit.c b/src/mpi_t/mpit.c
index cb8c2dc..588d5be 100644
--- a/src/mpi_t/mpit.c
+++ b/src/mpi_t/mpit.c
@@ -94,7 +94,7 @@ static cat_table_entry_t *MPIR_T_cat_create(const char *cat_name)
/* Need not to Strdup cat_name, since cat_table and cat_hash co-exist */
hash_entry->name = cat_name;
hash_entry->idx = cat_idx;
- HASH_ADD_KEYPTR(hh, cat_hash, hash_entry->name,
+ MPL_HASH_ADD_KEYPTR(hh, cat_hash, hash_entry->name,
strlen(hash_entry->name), hash_entry);
return cat;
@@ -115,7 +115,7 @@ int MPIR_T_cat_add_pvar(const char *cat_name, int pvar_index)
if (cat_name == NULL || *cat_name == '\0')
goto fn_exit;
- HASH_FIND_STR(cat_hash, cat_name, hash_entry);
+ MPL_HASH_FIND_STR(cat_hash, cat_name, hash_entry);
if (hash_entry != NULL) {
/* Found it, i.e., category already exists */
@@ -149,7 +149,7 @@ int MPIR_T_cat_add_cvar(const char *cat_name, int cvar_index)
if (cat_name == NULL || *cat_name == '\0')
goto fn_exit;
- HASH_FIND_STR(cat_hash, cat_name, hash_entry);
+ MPL_HASH_FIND_STR(cat_hash, cat_name, hash_entry);
if (hash_entry != NULL) {
/* Found it, i.e., category already exists */
@@ -188,7 +188,7 @@ int MPIR_T_cat_add_subcat(const char *parent_name, const char *child_name)
}
/* Find or create parent */
- HASH_FIND_STR(cat_hash, parent_name, hash_entry);
+ MPL_HASH_FIND_STR(cat_hash, parent_name, hash_entry);
if (hash_entry != NULL) {
/* Found parent in cat_table */
parent_index = hash_entry->idx;
@@ -199,7 +199,7 @@ int MPIR_T_cat_add_subcat(const char *parent_name, const char *child_name)
}
/* Find or create child */
- HASH_FIND_STR(cat_hash, child_name, hash_entry);
+ MPL_HASH_FIND_STR(cat_hash, child_name, hash_entry);
if (hash_entry != NULL) {
/* Found child in cat_table */
child_index = hash_entry->idx;
@@ -235,7 +235,7 @@ int MPIR_T_cat_add_desc(const char *cat_name, const char *cat_desc)
MPIR_Assert(cat_name);
MPIR_Assert(cat_desc);
- HASH_FIND_STR(cat_hash, cat_name, hash_entry);
+ MPL_HASH_FIND_STR(cat_hash, cat_name, hash_entry);
if (hash_entry != NULL) {
/* Found it, i.e., category already exists */
@@ -284,7 +284,7 @@ void MPIR_T_CVAR_REGISTER_impl(
int cvar_idx;
/* Check whether this is a replicated cvar, whose name is unique. */
- HASH_FIND_STR(cvar_hash, name, hash_entry);
+ MPL_HASH_FIND_STR(cvar_hash, name, hash_entry);
if (hash_entry != NULL) {
/* Found it, the cvar already exists */
@@ -332,7 +332,7 @@ void MPIR_T_CVAR_REGISTER_impl(
/* Need not to Strdup name, since cvar_table and cvar_hash co-exist */
hash_entry->name =name;
hash_entry->idx = cvar_idx;
- HASH_ADD_KEYPTR(hh, cvar_hash, hash_entry->name,
+ MPL_HASH_ADD_KEYPTR(hh, cvar_hash, hash_entry->name,
strlen(hash_entry->name), hash_entry);
/* Add the cvar to a category */
@@ -370,7 +370,7 @@ void MPIR_T_PVAR_REGISTER_impl(
int seq = varclass - MPIR_T_PVAR_CLASS_FIRST;
/* Check whether this is a replicated pvar, whose name is unique per class */
- HASH_FIND_STR(pvar_hashs[seq], name, hash_entry);
+ MPL_HASH_FIND_STR(pvar_hashs[seq], name, hash_entry);
if (hash_entry != NULL) {
/* Found it, the pvar already exists */
@@ -407,7 +407,7 @@ void MPIR_T_PVAR_REGISTER_impl(
/* Need not to Strdup name, since pvar_table and pvar_hashs co-exist */
hash_entry->name = name;
hash_entry->idx = pvar_idx;
- HASH_ADD_KEYPTR(hh, pvar_hashs[seq], hash_entry->name,
+ MPL_HASH_ADD_KEYPTR(hh, pvar_hashs[seq], hash_entry->name,
strlen(hash_entry->name), hash_entry);
/* Add the pvar to a category */
diff --git a/src/mpi_t/mpit_finalize.c b/src/mpi_t/mpit_finalize.c
index 04da543..fb19042 100644
--- a/src/mpi_t/mpit_finalize.c
+++ b/src/mpi_t/mpit_finalize.c
@@ -77,13 +77,13 @@ static void MPIR_T_cat_env_finalize(void)
if (cat_hash) {
name2index_hash_t *current, *tmp;
/* Free all entries */
- HASH_ITER(hh, cat_hash, current, tmp) {
- HASH_DEL(cat_hash, current);
+ MPL_HASH_ITER(hh, cat_hash, current, tmp) {
+ MPL_HASH_DEL(cat_hash, current);
MPL_free(current);
}
/* Free cat_hash itself */
- HASH_CLEAR(hh, cat_hash);
+ MPL_HASH_CLEAR(hh, cat_hash);
cat_hash = NULL;
}
}
@@ -113,13 +113,13 @@ static void MPIR_T_cvar_env_finalize(void)
if (cvar_hash) {
name2index_hash_t *current, *tmp;
/* Free all entries */
- HASH_ITER(hh, cvar_hash, current, tmp) {
- HASH_DEL(cvar_hash, current);
+ MPL_HASH_ITER(hh, cvar_hash, current, tmp) {
+ MPL_HASH_DEL(cvar_hash, current);
MPL_free(current);
}
/* Free cvar_hash itself */
- HASH_CLEAR(hh, cvar_hash);
+ MPL_HASH_CLEAR(hh, cvar_hash);
cvar_hash = NULL;
}
}
@@ -146,13 +146,13 @@ static void MPIR_T_pvar_env_finalize(void)
if (pvar_hashs[i]) {
name2index_hash_t *current, *tmp;
/* Free all entries */
- HASH_ITER(hh, pvar_hashs[i], current, tmp) {
- HASH_DEL(pvar_hashs[i], current);
+ MPL_HASH_ITER(hh, pvar_hashs[i], current, tmp) {
+ MPL_HASH_DEL(pvar_hashs[i], current);
MPL_free(current);
}
/* Free pvar_hashs[i] itself */
- HASH_CLEAR(hh, pvar_hashs[i]);
+ MPL_HASH_CLEAR(hh, pvar_hashs[i]);
pvar_hashs[i] = NULL;
}
}
diff --git a/src/mpi_t/pvar_get_index.c b/src/mpi_t/pvar_get_index.c
index 6ca9e59..d528814 100644
--- a/src/mpi_t/pvar_get_index.c
+++ b/src/mpi_t/pvar_get_index.c
@@ -79,7 +79,7 @@ int MPI_T_pvar_get_index(const char *name, int var_class, int *pvar_index)
name2index_hash_t *hash_entry;
/* Do hash lookup by the name */
- HASH_FIND_STR(pvar_hashs[seq], name, hash_entry);
+ MPL_HASH_FIND_STR(pvar_hashs[seq], name, hash_entry);
if (hash_entry != NULL) {
*pvar_index = hash_entry->idx;
} else {
diff --git a/src/include/mpir_uthash.h b/src/mpl/include/mpl_uthash.h
old mode 100644
new mode 100755
similarity index 57%
rename from src/include/mpir_uthash.h
rename to src/mpl/include/mpl_uthash.h
index 8efbff9..ba46af1
--- a/src/include/mpir_uthash.h
+++ b/src/mpl/include/mpl_uthash.h
@@ -1,16 +1,13 @@
-/* MPICH-local modifications:
+/* MPICH changes:
*
- * 1) Rename header from "uthash.h" to "mpir_uthash.h" to avoid accidentally
- * pulling in a system-installed version of the header.
- *
- * 2) Use MPL_malloc/MPL_free instead of malloc/free
- *
- * The actual macros themselves have not been namespaced, so if a plain
- * "uthash.h" is included anywhere in the tree then there could be a conflict.
+ * - The file name has been changed to avoid conflicts with any system-installed
+ * "uthash.h" header files.
+ * - some configure-time checking for __typeof() support was added
+ * - intentionally omitted from "mpl.h" in order to require using code to opt-in
+ * - override malloc/free/realloc to call MPL routines
*/
-
/*
-Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/
+Copyright (c) 2003-2014, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -32,183 +29,201 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MPIR_UTHASH_H_INCLUDED
-#define MPIR_UTHASH_H_INCLUDED
+#ifndef MPL_UTHASH_H
+#define MPL_UTHASH_H
#include <string.h> /* memcmp,strlen */
#include <stddef.h> /* ptrdiff_t */
#include <stdlib.h> /* exit() */
+#ifdef MPL_HAVE___TYPEOF /* MPICH modification */
/* These macros use decltype or the earlier __typeof GNU extension.
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
when compiling c++ source) this code uses whatever method is needed
or, for VS2008 where neither is available, uses casting workarounds. */
-#ifdef _MSC_VER /* MS compiler */
+#if defined(_MSC_VER) /* MS compiler */
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
-#define DECLTYPE(x) (decltype(x))
+#define MPL_DECLTYPE(x) (decltype(x))
#else /* VS2008 or older (or VS2010 in C mode) */
-#define NO_DECLTYPE
-#define DECLTYPE(x)
+#define MPL_NO_DECLTYPE
+#define MPL_DECLTYPE(x)
#endif
+#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__)
+#define MPL_NO_DECLTYPE
+#define MPL_DECLTYPE(x)
#else /* GNU, Sun and other compilers */
-#define DECLTYPE(x) (__typeof(x))
+#define MPL_DECLTYPE(x) (__typeof(x))
#endif
+#else /* !MPL_HAVE___TYPEOF */
+#define MPL_NO_DECLTYPE
+#define MPL_DECLTYPE(x)
+#endif /* !MPL_HAVE__TYPEOF */
-#ifdef NO_DECLTYPE
-#define DECLTYPE_ASSIGN(dst,src) \
+
+#ifdef MPL_NO_DECLTYPE
+#define MPL_DECLTYPE_ASSIGN(dst,src) \
do { \
char **_da_dst = (char**)(&(dst)); \
*_da_dst = (char*)(src); \
} while(0)
#else
-#define DECLTYPE_ASSIGN(dst,src) \
+#define MPL_DECLTYPE_ASSIGN(dst,src) \
do { \
- (dst) = DECLTYPE(dst)(src); \
+ (dst) = MPL_DECLTYPE(dst)(src); \
} while(0)
#endif
-/* a number of the hash function use uint32_t which isn't defined on win32 */
-#ifdef _MSC_VER
+/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */
+#if defined(_WIN32)
+#if defined(_MSC_VER) && _MSC_VER >= 1600
+#include <stdint.h>
+#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__)
+#include <stdint.h>
+#else
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
+#endif
+#elif defined(__GNUC__) && !defined(__VXWORKS__)
+#include <stdint.h>
#else
-#include <inttypes.h> /* uint32_t */
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
#endif
-#define UTHASH_VERSION 1.9.8
+#define MPL_UTHASH_VERSION 1.9.9
-#ifndef uthash_fatal
-#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
+#ifndef MPL_uthash_fatal
+#define MPL_uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
#endif
-#ifndef uthash_malloc
-#define uthash_malloc(sz) MPL_malloc(sz) /* malloc fcn */
+#ifndef MPL_uthash_malloc
+#define MPL_uthash_malloc(sz) MPL_malloc(sz) /* malloc fcn */
#endif
-#ifndef uthash_free
-#define uthash_free(ptr,sz) MPL_free(ptr) /* free fcn */
+#ifndef MPL_uthash_free
+#define MPL_uthash_free(ptr,sz) MPL_free(ptr) /* free fcn */
#endif
-#ifndef uthash_noexpand_fyi
-#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
+#ifndef MPL_uthash_noexpand_fyi
+#define MPL_uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
#endif
-#ifndef uthash_expand_fyi
-#define uthash_expand_fyi(tbl) /* can be defined to log expands */
+#ifndef MPL_uthash_expand_fyi
+#define MPL_uthash_expand_fyi(tbl) /* can be defined to log expands */
#endif
/* initial number of buckets */
-#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
-#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
-#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
+#define MPL_HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */
+#define MPL_HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */
+#define MPL_HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */
/* calculate the element whose hash handle address is hhe */
-#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
+#define MPL_ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
-#define HASH_FIND(hh,head,keyptr,keylen,out) \
+#define MPL_HASH_FIND(hh,head,keyptr,keylen,out) \
do { \
- unsigned _hf_bkt,_hf_hashv; \
out=NULL; \
- if (head) { \
- HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
- if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
- HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
+ if (head != NULL) { \
+ unsigned _hf_bkt,_hf_hashv; \
+ MPL_HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
+ if (MPL_HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv) != 0) { \
+ MPL_HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
keyptr,keylen,out); \
} \
} \
} while (0)
-#ifdef HASH_BLOOM
-#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
-#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
-#define HASH_BLOOM_MAKE(tbl) \
+#ifdef MPL_HASH_BLOOM
+#define MPL_HASH_BLOOM_BITLEN (1UL << MPL_HASH_BLOOM)
+#define MPL_HASH_BLOOM_BYTELEN (MPL_HASH_BLOOM_BITLEN/8UL) + (((MPL_HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL)
+#define MPL_HASH_BLOOM_MAKE(tbl) \
do { \
- (tbl)->bloom_nbits = HASH_BLOOM; \
- (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
- if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
- memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
- (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
+ (tbl)->bloom_nbits = MPL_HASH_BLOOM; \
+ (tbl)->bloom_bv = (uint8_t*)MPL_uthash_malloc(MPL_HASH_BLOOM_BYTELEN); \
+ if (!((tbl)->bloom_bv)) { MPL_uthash_fatal( "out of memory"); } \
+ memset((tbl)->bloom_bv, 0, MPL_HASH_BLOOM_BYTELEN); \
+ (tbl)->bloom_sig = MPL_HASH_BLOOM_SIGNATURE; \
} while (0)
-#define HASH_BLOOM_FREE(tbl) \
+#define MPL_HASH_BLOOM_FREE(tbl) \
do { \
- uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
+ MPL_uthash_free((tbl)->bloom_bv, MPL_HASH_BLOOM_BYTELEN); \
} while (0)
-#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
-#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
+#define MPL_HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U)))
+#define MPL_HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U)))
-#define HASH_BLOOM_ADD(tbl,hashv) \
- HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
+#define MPL_HASH_BLOOM_ADD(tbl,hashv) \
+ MPL_HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U)))
-#define HASH_BLOOM_TEST(tbl,hashv) \
- HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
+#define MPL_HASH_BLOOM_TEST(tbl,hashv) \
+ MPL_HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U)))
#else
-#define HASH_BLOOM_MAKE(tbl)
-#define HASH_BLOOM_FREE(tbl)
-#define HASH_BLOOM_ADD(tbl,hashv)
-#define HASH_BLOOM_TEST(tbl,hashv) (1)
-#define HASH_BLOOM_BYTELEN 0
+#define MPL_HASH_BLOOM_MAKE(tbl)
+#define MPL_HASH_BLOOM_FREE(tbl)
+#define MPL_HASH_BLOOM_ADD(tbl,hashv)
+#define MPL_HASH_BLOOM_TEST(tbl,hashv) (1)
+#define MPL_HASH_BLOOM_BYTELEN 0U
#endif
-#define HASH_MAKE_TABLE(hh,head) \
+#define MPL_HASH_MAKE_TABLE(hh,head) \
do { \
- (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
- sizeof(UT_hash_table)); \
- if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
- memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
+ (head)->hh.tbl = (MPL_UT_hash_table*)MPL_uthash_malloc( \
+ sizeof(MPL_UT_hash_table)); \
+ if (!((head)->hh.tbl)) { MPL_uthash_fatal( "out of memory"); } \
+ memset((head)->hh.tbl, 0, sizeof(MPL_UT_hash_table)); \
(head)->hh.tbl->tail = &((head)->hh); \
- (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
- (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
+ (head)->hh.tbl->num_buckets = MPL_HASH_INITIAL_NUM_BUCKETS; \
+ (head)->hh.tbl->log2_num_buckets = MPL_HASH_INITIAL_NUM_BUCKETS_LOG2; \
(head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
- (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
- HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
- if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
+ (head)->hh.tbl->buckets = (MPL_UT_hash_bucket*)MPL_uthash_malloc( \
+ MPL_HASH_INITIAL_NUM_BUCKETS*sizeof(struct MPL_UT_hash_bucket)); \
+ if (! (head)->hh.tbl->buckets) { MPL_uthash_fatal( "out of memory"); } \
memset((head)->hh.tbl->buckets, 0, \
- HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
- HASH_BLOOM_MAKE((head)->hh.tbl); \
- (head)->hh.tbl->signature = HASH_SIGNATURE; \
+ MPL_HASH_INITIAL_NUM_BUCKETS*sizeof(struct MPL_UT_hash_bucket)); \
+ MPL_HASH_BLOOM_MAKE((head)->hh.tbl); \
+ (head)->hh.tbl->signature = MPL_HASH_SIGNATURE; \
} while(0)
-#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
- HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
+#define MPL_HASH_ADD(hh,head,fieldname,keylen_in,add) \
+ MPL_HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
-#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
+#define MPL_HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
do { \
replaced=NULL; \
- HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \
+ MPL_HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \
if (replaced!=NULL) { \
- HASH_DELETE(hh,head,replaced); \
- }; \
- HASH_ADD(hh,head,fieldname,keylen_in,add); \
+ MPL_HASH_DELETE(hh,head,replaced); \
+ } \
+ MPL_HASH_ADD(hh,head,fieldname,keylen_in,add); \
} while(0)
-#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
+#define MPL_HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
do { \
unsigned _ha_bkt; \
(add)->hh.next = NULL; \
- (add)->hh.key = (char*)keyptr; \
- (add)->hh.keylen = (unsigned)keylen_in; \
+ (add)->hh.key = (char*)(keyptr); \
+ (add)->hh.keylen = (unsigned)(keylen_in); \
if (!(head)) { \
head = (add); \
(head)->hh.prev = NULL; \
- HASH_MAKE_TABLE(hh,head); \
+ MPL_HASH_MAKE_TABLE(hh,head); \
} else { \
(head)->hh.tbl->tail->next = (add); \
- (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
+ (add)->hh.prev = MPL_ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
(head)->hh.tbl->tail = &((add)->hh); \
} \
(head)->hh.tbl->num_items++; \
(add)->hh.tbl = (head)->hh.tbl; \
- HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
+ MPL_HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
(add)->hh.hashv, _ha_bkt); \
- HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
- HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
- HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
- HASH_FSCK(hh,head); \
+ MPL_HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
+ MPL_HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
+ MPL_HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
+ MPL_HASH_FSCK(hh,head); \
} while(0)
-#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
+#define MPL_HASH_TO_BKT( hashv, num_bkts, bkt ) \
do { \
- bkt = ((hashv) & ((num_bkts) - 1)); \
+ bkt = ((hashv) & ((num_bkts) - 1U)); \
} while(0)
/* delete "delptr" from the hash table.
@@ -223,84 +238,84 @@ do {
* copy the deletee pointer, then the latter references are via that
* scratch pointer rather than through the repointed (users) symbol.
*/
-#define HASH_DELETE(hh,head,delptr) \
+#define MPL_HASH_DELETE(hh,head,delptr) \
do { \
- unsigned _hd_bkt; \
- struct UT_hash_handle *_hd_hh_del; \
+ struct MPL_UT_hash_handle *_hd_hh_del; \
if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
- uthash_free((head)->hh.tbl->buckets, \
- (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
- HASH_BLOOM_FREE((head)->hh.tbl); \
- uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
+ MPL_uthash_free((head)->hh.tbl->buckets, \
+ (head)->hh.tbl->num_buckets*sizeof(struct MPL_UT_hash_bucket) ); \
+ MPL_HASH_BLOOM_FREE((head)->hh.tbl); \
+ MPL_uthash_free((head)->hh.tbl, sizeof(MPL_UT_hash_table)); \
head = NULL; \
} else { \
- _hd_hh_del = &((delptr)->hh); \
- if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
+ unsigned _hd_bkt; \
+ _hd_hh_del = (MPL_UT_hash_handle*)&((delptr)->hh); \
+ if ((delptr) == MPL_ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
(head)->hh.tbl->tail = \
- (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
+ (MPL_UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
(head)->hh.tbl->hho); \
} \
- if ((delptr)->hh.prev) { \
- ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
+ if ((delptr)->hh.prev != NULL) { \
+ ((MPL_UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
(head)->hh.tbl->hho))->next = (delptr)->hh.next; \
} else { \
- DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
+ MPL_DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
} \
- if (_hd_hh_del->next) { \
- ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \
+ if (_hd_hh_del->next != NULL) { \
+ ((MPL_UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \
(head)->hh.tbl->hho))->prev = \
_hd_hh_del->prev; \
} \
- HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
- HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
+ MPL_HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
+ MPL_HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
(head)->hh.tbl->num_items--; \
} \
- HASH_FSCK(hh,head); \
+ MPL_HASH_FSCK(hh,head); \
} while (0)
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
-#define HASH_FIND_STR(head,findstr,out) \
- HASH_FIND(hh,head,findstr,strlen(findstr),out)
-#define HASH_ADD_STR(head,strfield,add) \
- HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
-#define HASH_REPLACE_STR(head,strfield,add,replaced) \
- HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced)
-#define HASH_FIND_INT(head,findint,out) \
- HASH_FIND(hh,head,findint,sizeof(int),out)
-#define HASH_ADD_INT(head,intfield,add) \
- HASH_ADD(hh,head,intfield,sizeof(int),add)
-#define HASH_REPLACE_INT(head,intfield,add,replaced) \
- HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
-#define HASH_FIND_PTR(head,findptr,out) \
- HASH_FIND(hh,head,findptr,sizeof(void *),out)
-#define HASH_ADD_PTR(head,ptrfield,add) \
- HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
-#define HASH_REPLACE_PTR(head,ptrfield,add) \
- HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
-#define HASH_DEL(head,delptr) \
- HASH_DELETE(hh,head,delptr)
+#define MPL_HASH_FIND_STR(head,findstr,out) \
+ MPL_HASH_FIND(hh,head,findstr,(unsigned)strlen(findstr),out)
+#define MPL_HASH_ADD_STR(head,strfield,add) \
+ MPL_HASH_ADD(hh,head,strfield[0],(unsigned int)strlen(add->strfield),add)
+#define MPL_HASH_REPLACE_STR(head,strfield,add,replaced) \
+ MPL_HASH_REPLACE(hh,head,strfield[0],(unsigned)strlen(add->strfield),add,replaced)
+#define MPL_HASH_FIND_INT(head,findint,out) \
+ MPL_HASH_FIND(hh,head,findint,sizeof(int),out)
+#define MPL_HASH_ADD_INT(head,intfield,add) \
+ MPL_HASH_ADD(hh,head,intfield,sizeof(int),add)
+#define MPL_HASH_REPLACE_INT(head,intfield,add,replaced) \
+ MPL_HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
+#define MPL_HASH_FIND_PTR(head,findptr,out) \
+ MPL_HASH_FIND(hh,head,findptr,sizeof(void *),out)
+#define MPL_HASH_ADD_PTR(head,ptrfield,add) \
+ MPL_HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
+#define MPL_HASH_REPLACE_PTR(head,ptrfield,add,replaced) \
+ MPL_HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
+#define MPL_HASH_DEL(head,delptr) \
+ MPL_HASH_DELETE(hh,head,delptr)
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
*/
-#ifdef HASH_DEBUG
-#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
-#define HASH_FSCK(hh,head) \
+#ifdef MPL_HASH_DEBUG
+#define MPL_HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
+#define MPL_HASH_FSCK(hh,head) \
do { \
- unsigned _bkt_i; \
- unsigned _count, _bkt_count; \
- char *_prev; \
- struct UT_hash_handle *_thh; \
+ struct MPL_UT_hash_handle *_thh; \
if (head) { \
+ unsigned _bkt_i; \
+ unsigned _count; \
+ char *_prev; \
_count = 0; \
for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
- _bkt_count = 0; \
+ unsigned _bkt_count = 0; \
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
_prev = NULL; \
while (_thh) { \
if (_prev != (char*)(_thh->hh_prev)) { \
- HASH_OOPS("invalid hh_prev %p, actual %p\n", \
+ MPL_HASH_OOPS("invalid hh_prev %p, actual %p\n", \
_thh->hh_prev, _prev ); \
} \
_bkt_count++; \
@@ -309,12 +324,12 @@ do {
} \
_count += _bkt_count; \
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
- HASH_OOPS("invalid bucket count %d, actual %d\n", \
+ MPL_HASH_OOPS("invalid bucket count %u, actual %u\n", \
(head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
} \
} \
if (_count != (head)->hh.tbl->num_items) { \
- HASH_OOPS("invalid hh item count %d, actual %d\n", \
+ MPL_HASH_OOPS("invalid hh item count %u, actual %u\n", \
(head)->hh.tbl->num_items, _count ); \
} \
/* traverse hh in app order; check next/prev integrity, count */ \
@@ -324,81 +339,86 @@ do {
while (_thh) { \
_count++; \
if (_prev !=(char*)(_thh->prev)) { \
- HASH_OOPS("invalid prev %p, actual %p\n", \
+ MPL_HASH_OOPS("invalid prev %p, actual %p\n", \
_thh->prev, _prev ); \
} \
- _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
- _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
+ _prev = (char*)MPL_ELMT_FROM_HH((head)->hh.tbl, _thh); \
+ _thh = ( _thh->next ? (MPL_UT_hash_handle*)((char*)(_thh->next) + \
(head)->hh.tbl->hho) : NULL ); \
} \
if (_count != (head)->hh.tbl->num_items) { \
- HASH_OOPS("invalid app item count %d, actual %d\n", \
+ MPL_HASH_OOPS("invalid app item count %u, actual %u\n", \
(head)->hh.tbl->num_items, _count ); \
} \
} \
} while (0)
#else
-#define HASH_FSCK(hh,head)
+#define MPL_HASH_FSCK(hh,head)
#endif
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
* the descriptor to which this macro is defined for tuning the hash function.
* The app can #include <unistd.h> to get the prototype for write(2). */
-#ifdef HASH_EMIT_KEYS
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
+#ifdef MPL_HASH_EMIT_KEYS
+#define MPL_HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
do { \
unsigned _klen = fieldlen; \
- write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
- write(HASH_EMIT_KEYS, keyptr, fieldlen); \
+ write(MPL_HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
+ write(MPL_HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \
} while (0)
#else
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
+#define MPL_HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
#endif
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
-#ifdef HASH_FUNCTION
-#define HASH_FCN HASH_FUNCTION
+#ifdef MPL_HASH_FUNCTION
+#define MPL_HASH_FCN MPL_HASH_FUNCTION
#else
-#define HASH_FCN HASH_JEN
+#define MPL_HASH_FCN MPL_HASH_JEN
#endif
-/* The Bernstein hash function, used in Perl prior to v5.6 */
-#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
+/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
+#define MPL_HASH_BER(key,keylen,num_bkts,hashv,bkt) \
do { \
- unsigned _hb_keylen=keylen; \
- char *_hb_key=(char*)(key); \
+ unsigned _hb_keylen=(unsigned)keylen; \
+ const unsigned char *_hb_key=(const unsigned char*)(key); \
(hashv) = 0; \
- while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
- bkt = (hashv) & (num_bkts-1); \
+ while (_hb_keylen-- != 0U) { \
+ (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \
+ } \
+ bkt = (hashv) & (num_bkts-1U); \
} while (0)
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
-#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
+#define MPL_HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _sx_i; \
- char *_hs_key=(char*)(key); \
+ const unsigned char *_hs_key=(const unsigned char*)(key); \
hashv = 0; \
- for(_sx_i=0; _sx_i < keylen; _sx_i++) \
+ for(_sx_i=0; _sx_i < keylen; _sx_i++) { \
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
- bkt = hashv & (num_bkts-1); \
+ } \
+ bkt = hashv & (num_bkts-1U); \
} while (0)
-
-#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
+/* FNV-1a variation */
+#define MPL_HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _fn_i; \
- char *_hf_key=(char*)(key); \
- hashv = 2166136261UL; \
- for(_fn_i=0; _fn_i < keylen; _fn_i++) \
- hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
- bkt = hashv & (num_bkts-1); \
+ const unsigned char *_hf_key=(const unsigned char*)(key); \
+ hashv = 2166136261U; \
+ for(_fn_i=0; _fn_i < keylen; _fn_i++) { \
+ hashv = hashv ^ _hf_key[_fn_i]; \
+ hashv = hashv * 16777619U; \
+ } \
+ bkt = hashv & (num_bkts-1U); \
} while(0)
-#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
+#define MPL_HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _ho_i; \
- char *_ho_key=(char*)(key); \
+ const unsigned char *_ho_key=(const unsigned char*)(key); \
hashv = 0; \
for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
hashv += _ho_key[_ho_i]; \
@@ -408,10 +428,10 @@ do {
hashv += (hashv << 3); \
hashv ^= (hashv >> 11); \
hashv += (hashv << 15); \
- bkt = hashv & (num_bkts-1); \
+ bkt = hashv & (num_bkts-1U); \
} while(0)
-#define HASH_JEN_MIX(a,b,c) \
+#define MPL_HASH_JEN_MIX(a,b,c) \
do { \
a -= b; a -= c; a ^= ( c >> 13 ); \
b -= c; b -= a; b ^= ( a << 8 ); \
@@ -424,14 +444,14 @@ do {
c -= a; c -= b; c ^= ( b >> 15 ); \
} while (0)
-#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
+#define MPL_HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _hj_i,_hj_j,_hj_k; \
- unsigned char *_hj_key=(unsigned char*)(key); \
- hashv = 0xfeedbeef; \
- _hj_i = _hj_j = 0x9e3779b9; \
- _hj_k = (unsigned)keylen; \
- while (_hj_k >= 12) { \
+ unsigned const char *_hj_key=(unsigned const char*)(key); \
+ hashv = 0xfeedbeefu; \
+ _hj_i = _hj_j = 0x9e3779b9u; \
+ _hj_k = (unsigned)(keylen); \
+ while (_hj_k >= 12U) { \
_hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
+ ( (unsigned)_hj_key[2] << 16 ) \
+ ( (unsigned)_hj_key[3] << 24 ) ); \
@@ -442,27 +462,27 @@ do {
+ ( (unsigned)_hj_key[10] << 16 ) \
+ ( (unsigned)_hj_key[11] << 24 ) ); \
\
- HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
+ MPL_HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
\
_hj_key += 12; \
- _hj_k -= 12; \
+ _hj_k -= 12U; \
} \
- hashv += keylen; \
+ hashv += (unsigned)(keylen); \
switch ( _hj_k ) { \
- case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
- case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
- case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
- case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
- case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
- case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
- case 5: _hj_j += _hj_key[4]; \
- case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
- case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
- case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
+ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \
+ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \
+ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \
+ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \
+ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \
+ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \
+ case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \
+ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \
+ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \
+ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \
case 1: _hj_i += _hj_key[0]; \
} \
- HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
- bkt = hashv & (num_bkts-1); \
+ MPL_HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
+ bkt = hashv & (num_bkts-1U); \
} while(0)
/* The Paul Hsieh hash function */
@@ -476,21 +496,21 @@ do {
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
+(uint32_t)(((const uint8_t *)(d))[0]) )
#endif
-#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
+#define MPL_HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
do { \
- unsigned char *_sfh_key=(unsigned char*)(key); \
- uint32_t _sfh_tmp, _sfh_len = keylen; \
+ unsigned const char *_sfh_key=(unsigned const char*)(key); \
+ uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \
\
- int _sfh_rem = _sfh_len & 3; \
+ unsigned _sfh_rem = _sfh_len & 3U; \
_sfh_len >>= 2; \
- hashv = 0xcafebabe; \
+ hashv = 0xcafebabeu; \
\
/* Main loop */ \
- for (;_sfh_len > 0; _sfh_len--) { \
+ for (;_sfh_len > 0U; _sfh_len--) { \
hashv += get16bits (_sfh_key); \
- _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \
+ _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \
hashv = (hashv << 16) ^ _sfh_tmp; \
- _sfh_key += 2*sizeof (uint16_t); \
+ _sfh_key += 2U*sizeof (uint16_t); \
hashv += hashv >> 11; \
} \
\
@@ -498,7 +518,7 @@ do {
switch (_sfh_rem) { \
case 3: hashv += get16bits (_sfh_key); \
hashv ^= hashv << 16; \
- hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \
+ hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \
hashv += hashv >> 11; \
break; \
case 2: hashv += get16bits (_sfh_key); \
@@ -517,10 +537,10 @@ do {
hashv += hashv >> 17; \
hashv ^= hashv << 25; \
hashv += hashv >> 6; \
- bkt = hashv & (num_bkts-1); \
+ bkt = hashv & (num_bkts-1U); \
} while(0)
-#ifdef HASH_USING_NO_STRICT_ALIASING
+#ifdef MPL_HASH_USING_NO_STRICT_ALIASING
/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
* MurmurHash uses the faster approach only on CPU's where we know it's safe.
@@ -531,118 +551,118 @@ do {
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
*/
#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86))
-#define MUR_GETBLOCK(p,i) p[i]
+#define MPL_MUR_GETBLOCK(p,i) p[i]
#else /* non intel */
-#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
-#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
-#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
-#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
-#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
+#define MPL_MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL)
+#define MPL_MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL)
+#define MPL_MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL)
+#define MPL_MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL)
+#define MPL_WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
-#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
-#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
-#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
+#define MPL_MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
+#define MPL_MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
+#define MPL_MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
#else /* assume little endian non-intel */
-#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
-#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
-#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
+#define MPL_MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
+#define MPL_MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
+#define MPL_MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
#endif
-#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
- (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
- (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
- MUR_ONE_THREE(p))))
+#define MPL_MUR_GETBLOCK(p,i) (MPL_MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
+ (MPL_MUR_PLUS1_ALIGNED(p) ? MPL_MUR_THREE_ONE(p) : \
+ (MPL_MUR_PLUS2_ALIGNED(p) ? MPL_MUR_TWO_TWO(p) : \
+ MPL_MUR_ONE_THREE(p))))
#endif
-#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
-#define MUR_FMIX(_h) \
+#define MPL_MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
+#define MPL_MUR_FMIX(_h) \
do { \
_h ^= _h >> 16; \
- _h *= 0x85ebca6b; \
+ _h *= 0x85ebca6bu; \
_h ^= _h >> 13; \
- _h *= 0xc2b2ae35l; \
+ _h *= 0xc2b2ae35u; \
_h ^= _h >> 16; \
} while(0)
-#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
+#define MPL_HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
do { \
const uint8_t *_mur_data = (const uint8_t*)(key); \
- const int _mur_nblocks = (keylen) / 4; \
- uint32_t _mur_h1 = 0xf88D5353; \
- uint32_t _mur_c1 = 0xcc9e2d51; \
- uint32_t _mur_c2 = 0x1b873593; \
+ const int _mur_nblocks = (int)(keylen) / 4; \
+ uint32_t _mur_h1 = 0xf88D5353u; \
+ uint32_t _mur_c1 = 0xcc9e2d51u; \
+ uint32_t _mur_c2 = 0x1b873593u; \
uint32_t _mur_k1 = 0; \
const uint8_t *_mur_tail; \
- const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
+ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \
int _mur_i; \
- for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
- _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
+ for(_mur_i = -_mur_nblocks; _mur_i!=0; _mur_i++) { \
+ _mur_k1 = MPL_MUR_GETBLOCK(_mur_blocks,_mur_i); \
_mur_k1 *= _mur_c1; \
- _mur_k1 = MUR_ROTL32(_mur_k1,15); \
+ _mur_k1 = MPL_MUR_ROTL32(_mur_k1,15); \
_mur_k1 *= _mur_c2; \
\
_mur_h1 ^= _mur_k1; \
- _mur_h1 = MUR_ROTL32(_mur_h1,13); \
- _mur_h1 = _mur_h1*5+0xe6546b64; \
+ _mur_h1 = MPL_MUR_ROTL32(_mur_h1,13); \
+ _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \
} \
- _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \
+ _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \
_mur_k1=0; \
- switch((keylen) & 3) { \
- case 3: _mur_k1 ^= _mur_tail[2] << 16; \
- case 2: _mur_k1 ^= _mur_tail[1] << 8; \
- case 1: _mur_k1 ^= _mur_tail[0]; \
+ switch((keylen) & 3U) { \
+ case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \
+ case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \
+ case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \
_mur_k1 *= _mur_c1; \
- _mur_k1 = MUR_ROTL32(_mur_k1,15); \
+ _mur_k1 = MPL_MUR_ROTL32(_mur_k1,15); \
_mur_k1 *= _mur_c2; \
_mur_h1 ^= _mur_k1; \
} \
- _mur_h1 ^= (keylen); \
- MUR_FMIX(_mur_h1); \
+ _mur_h1 ^= (uint32_t)(keylen); \
+ MPL_MUR_FMIX(_mur_h1); \
hashv = _mur_h1; \
- bkt = hashv & (num_bkts-1); \
+ bkt = hashv & (num_bkts-1U); \
} while(0)
#endif /* HASH_USING_NO_STRICT_ALIASING */
/* key comparison function; return 0 if keys equal */
-#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
+#define MPL_HASH_KEYCMP(a,b,len) memcmp(a,b,(unsigned long)(len))
/* iterate over items in a known bucket to find desired item */
-#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
+#define MPL_HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
do { \
- if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
- else out=NULL; \
- while (out) { \
- if ((out)->hh.keylen == keylen_in) { \
- if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \
+ if (head.hh_head != NULL) { MPL_DECLTYPE_ASSIGN(out,MPL_ELMT_FROM_HH(tbl,head.hh_head)); } \
+ else { out=NULL; } \
+ while (out != NULL) { \
+ if ((out)->hh.keylen == (keylen_in)) { \
+ if ((MPL_HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) { break; } \
} \
- if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \
- else out = NULL; \
+ if ((out)->hh.hh_next != NULL) { MPL_DECLTYPE_ASSIGN(out,MPL_ELMT_FROM_HH(tbl,(out)->hh.hh_next)); } \
+ else { out = NULL; } \
} \
} while(0)
/* add an item to a bucket */
-#define HASH_ADD_TO_BKT(head,addhh) \
+#define MPL_HASH_ADD_TO_BKT(head,addhh) \
do { \
head.count++; \
(addhh)->hh_next = head.hh_head; \
(addhh)->hh_prev = NULL; \
- if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
+ if (head.hh_head != NULL) { (head).hh_head->hh_prev = (addhh); } \
(head).hh_head=addhh; \
- if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
- && (addhh)->tbl->noexpand != 1) { \
- HASH_EXPAND_BUCKETS((addhh)->tbl); \
+ if ((head.count >= ((head.expand_mult+1U) * MPL_HASH_BKT_CAPACITY_THRESH)) \
+ && ((addhh)->tbl->noexpand != 1U)) { \
+ MPL_HASH_EXPAND_BUCKETS((addhh)->tbl); \
} \
} while(0)
/* remove an item from a given bucket */
-#define HASH_DEL_IN_BKT(hh,head,hh_del) \
+#define MPL_HASH_DEL_IN_BKT(hh,head,hh_del) \
(head).count--; \
- if ((head).hh_head == hh_del) { \
- (head).hh_head = hh_del->hh_next; \
+ if ((head).hh_head == (MPL_UT_hash_handle*)hh_del) { \
+ (head).hh_head = (MPL_UT_hash_handle*)hh_del->hh_next; \
} \
if (hh_del->hh_prev) { \
- hh_del->hh_prev->hh_next = hh_del->hh_next; \
+ hh_del->hh_prev->hh_next = hh_del->hh_next; \
} \
if (hh_del->hh_next) { \
- hh_del->hh_next->hh_prev = hh_del->hh_prev; \
+ hh_del->hh_next->hh_prev = hh_del->hh_prev; \
}
/* Bucket expansion has the effect of doubling the number of buckets
@@ -674,27 +694,27 @@ do {
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
*
*/
-#define HASH_EXPAND_BUCKETS(tbl) \
+#define MPL_HASH_EXPAND_BUCKETS(tbl) \
do { \
unsigned _he_bkt; \
unsigned _he_bkt_i; \
- struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
- UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
- _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
- 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
- if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
+ struct MPL_UT_hash_handle *_he_thh, *_he_hh_nxt; \
+ MPL_UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
+ _he_new_buckets = (MPL_UT_hash_bucket*)MPL_uthash_malloc( \
+ 2UL * tbl->num_buckets * sizeof(struct MPL_UT_hash_bucket)); \
+ if (!_he_new_buckets) { MPL_uthash_fatal( "out of memory"); } \
memset(_he_new_buckets, 0, \
- 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
+ 2UL * tbl->num_buckets * sizeof(struct MPL_UT_hash_bucket)); \
tbl->ideal_chain_maxlen = \
- (tbl->num_items >> (tbl->log2_num_buckets+1)) + \
- ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
+ (tbl->num_items >> (tbl->log2_num_buckets+1U)) + \
+ (((tbl->num_items & ((tbl->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \
tbl->nonideal_items = 0; \
for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
{ \
_he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
- while (_he_thh) { \
+ while (_he_thh != NULL) { \
_he_hh_nxt = _he_thh->hh_next; \
- HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
+ MPL_HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2U, _he_bkt); \
_he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
tbl->nonideal_items++; \
@@ -703,106 +723,114 @@ do {
} \
_he_thh->hh_prev = NULL; \
_he_thh->hh_next = _he_newbkt->hh_head; \
- if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
- _he_thh; \
+ if (_he_newbkt->hh_head != NULL) { _he_newbkt->hh_head->hh_prev = \
+ _he_thh; } \
_he_newbkt->hh_head = _he_thh; \
_he_thh = _he_hh_nxt; \
} \
} \
- uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
- tbl->num_buckets *= 2; \
+ MPL_uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct MPL_UT_hash_bucket) ); \
+ tbl->num_buckets *= 2U; \
tbl->log2_num_buckets++; \
tbl->buckets = _he_new_buckets; \
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
- (tbl->ineff_expands+1) : 0; \
- if (tbl->ineff_expands > 1) { \
+ (tbl->ineff_expands+1U) : 0U; \
+ if (tbl->ineff_expands > 1U) { \
tbl->noexpand=1; \
- uthash_noexpand_fyi(tbl); \
+ MPL_uthash_noexpand_fyi(tbl); \
} \
- uthash_expand_fyi(tbl); \
+ MPL_uthash_expand_fyi(tbl); \
} while(0)
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
/* Note that HASH_SORT assumes the hash handle name to be hh.
* HASH_SRT was added to allow the hash handle name to be passed in. */
-#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
-#define HASH_SRT(hh,head,cmpfcn) \
+#define MPL_HASH_SORT(head,cmpfcn) MPL_HASH_SRT(hh,head,cmpfcn)
+#define MPL_HASH_SRT(hh,head,cmpfcn) \
do { \
unsigned _hs_i; \
unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
- struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
- if (head) { \
+ struct MPL_UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
+ if (head != NULL) { \
_hs_insize = 1; \
_hs_looping = 1; \
_hs_list = &((head)->hh); \
- while (_hs_looping) { \
+ while (_hs_looping != 0U) { \
_hs_p = _hs_list; \
_hs_list = NULL; \
_hs_tail = NULL; \
_hs_nmerges = 0; \
- while (_hs_p) { \
+ while (_hs_p != NULL) { \
_hs_nmerges++; \
_hs_q = _hs_p; \
_hs_psize = 0; \
for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
_hs_psize++; \
- _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ _hs_q = (MPL_UT_hash_handle*)((_hs_q->next != NULL) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
- if (! (_hs_q) ) break; \
+ if (! (_hs_q) ) { break; } \
} \
_hs_qsize = _hs_insize; \
- while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
- if (_hs_psize == 0) { \
+ while ((_hs_psize > 0U) || ((_hs_qsize > 0U) && (_hs_q != NULL))) {\
+ if (_hs_psize == 0U) { \
_hs_e = _hs_q; \
- _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ _hs_q = (MPL_UT_hash_handle*)((_hs_q->next != NULL) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
- } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
+ } else if ( (_hs_qsize == 0U) || (_hs_q == NULL) ) { \
_hs_e = _hs_p; \
- _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
- ((void*)((char*)(_hs_p->next) + \
- (head)->hh.tbl->hho)) : NULL); \
+ if (_hs_p != NULL){ \
+ _hs_p = (MPL_UT_hash_handle*)((_hs_p->next != NULL) ? \
+ ((void*)((char*)(_hs_p->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ } \
_hs_psize--; \
} else if (( \
- cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
- DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
+ cmpfcn(MPL_DECLTYPE(head)(MPL_ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
+ MPL_DECLTYPE(head)(MPL_ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
) <= 0) { \
_hs_e = _hs_p; \
- _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
- ((void*)((char*)(_hs_p->next) + \
- (head)->hh.tbl->hho)) : NULL); \
+ if (_hs_p != NULL){ \
+ _hs_p = (MPL_UT_hash_handle*)((_hs_p->next != NULL) ? \
+ ((void*)((char*)(_hs_p->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ } \
_hs_psize--; \
} else { \
_hs_e = _hs_q; \
- _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ _hs_q = (MPL_UT_hash_handle*)((_hs_q->next != NULL) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} \
- if ( _hs_tail ) { \
- _hs_tail->next = ((_hs_e) ? \
- ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
+ if ( _hs_tail != NULL ) { \
+ _hs_tail->next = ((_hs_e != NULL) ? \
+ MPL_ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
} else { \
_hs_list = _hs_e; \
} \
- _hs_e->prev = ((_hs_tail) ? \
- ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
+ if (_hs_e != NULL) { \
+ _hs_e->prev = ((_hs_tail != NULL) ? \
+ MPL_ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
+ } \
_hs_tail = _hs_e; \
} \
_hs_p = _hs_q; \
} \
- _hs_tail->next = NULL; \
- if ( _hs_nmerges <= 1 ) { \
+ if (_hs_tail != NULL){ \
+ _hs_tail->next = NULL; \
+ } \
+ if ( _hs_nmerges <= 1U ) { \
_hs_looping=0; \
(head)->hh.tbl->tail = _hs_tail; \
- DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
+ MPL_DECLTYPE_ASSIGN(head,MPL_ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
} \
- _hs_insize *= 2; \
+ _hs_insize *= 2U; \
} \
- HASH_FSCK(hh,head); \
+ MPL_HASH_FSCK(hh,head); \
} \
} while (0)
@@ -811,34 +839,34 @@ do {
* in both hashes. There is no copy of the items made; rather
* they are added into the new hash through a secondary hash
* hash handle that must be present in the structure. */
-#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
+#define MPL_HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
do { \
unsigned _src_bkt, _dst_bkt; \
void *_last_elt=NULL, *_elt; \
- UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
+ MPL_UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
- if (src) { \
+ if (src != NULL) { \
for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
- _src_hh; \
+ _src_hh != NULL; \
_src_hh = _src_hh->hh_next) { \
- _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
+ _elt = MPL_ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
if (cond(_elt)) { \
- _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
+ _dst_hh = (MPL_UT_hash_handle*)(((char*)_elt) + _dst_hho); \
_dst_hh->key = _src_hh->key; \
_dst_hh->keylen = _src_hh->keylen; \
_dst_hh->hashv = _src_hh->hashv; \
_dst_hh->prev = _last_elt; \
_dst_hh->next = NULL; \
- if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
- if (!dst) { \
- DECLTYPE_ASSIGN(dst,_elt); \
- HASH_MAKE_TABLE(hh_dst,dst); \
+ if (_last_elt_hh != NULL) { _last_elt_hh->next = _elt; } \
+ if (dst == NULL) { \
+ MPL_DECLTYPE_ASSIGN(dst,_elt); \
+ MPL_HASH_MAKE_TABLE(hh_dst,dst); \
} else { \
_dst_hh->tbl = (dst)->hh_dst.tbl; \
} \
- HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
- HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
+ MPL_HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
+ MPL_HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
(dst)->hh_dst.tbl->num_items++; \
_last_elt = _elt; \
_last_elt_hh = _dst_hh; \
@@ -846,42 +874,43 @@ do {
} \
} \
} \
- HASH_FSCK(hh_dst,dst); \
+ MPL_HASH_FSCK(hh_dst,dst); \
} while (0)
-#define HASH_CLEAR(hh,head) \
+#define MPL_HASH_CLEAR(hh,head) \
do { \
- if (head) { \
- uthash_free((head)->hh.tbl->buckets, \
- (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
- HASH_BLOOM_FREE((head)->hh.tbl); \
- uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
+ if (head != NULL) { \
+ MPL_uthash_free((head)->hh.tbl->buckets, \
+ (head)->hh.tbl->num_buckets*sizeof(struct MPL_UT_hash_bucket)); \
+ MPL_HASH_BLOOM_FREE((head)->hh.tbl); \
+ MPL_uthash_free((head)->hh.tbl, sizeof(MPL_UT_hash_table)); \
(head)=NULL; \
} \
} while(0)
-#define HASH_OVERHEAD(hh,head) \
- (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \
- ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \
- (sizeof(UT_hash_table)) + \
- (HASH_BLOOM_BYTELEN)))
-
-#ifdef NO_DECLTYPE
-#define HASH_ITER(hh,head,el,tmp) \
-for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
- el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
+#define MPL_HASH_OVERHEAD(hh,head) \
+ ((head != NULL) ? ( \
+ (size_t)(((head)->hh.tbl->num_items * sizeof(MPL_UT_hash_handle)) + \
+ ((head)->hh.tbl->num_buckets * sizeof(MPL_UT_hash_bucket)) + \
+ sizeof(MPL_UT_hash_table) + \
+ (MPL_HASH_BLOOM_BYTELEN))) : 0U)
+
+#ifdef MPL_NO_DECLTYPE
+#define MPL_HASH_ITER(hh,head,el,tmp) \
+for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \
+ (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL)))
#else
-#define HASH_ITER(hh,head,el,tmp) \
-for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
- el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
+#define MPL_HASH_ITER(hh,head,el,tmp) \
+for(((el)=(head)), ((tmp)=MPL_DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \
+ (el) != NULL; ((el)=(tmp)), ((tmp)=MPL_DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL)))
#endif
/* obtain a count of items in the hash */
-#define HASH_COUNT(head) HASH_CNT(hh,head)
-#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
+#define MPL_HASH_COUNT(head) MPL_HASH_CNT(hh,head)
+#define MPL_HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U)
-typedef struct UT_hash_bucket {
- struct UT_hash_handle *hh_head;
+typedef struct MPL_UT_hash_bucket {
+ struct MPL_UT_hash_handle *hh_head;
unsigned count;
/* expand_mult is normally set to 0. In this situation, the max chain length
@@ -898,17 +927,17 @@ typedef struct UT_hash_bucket {
*/
unsigned expand_mult;
-} UT_hash_bucket;
+} MPL_UT_hash_bucket;
/* random signature used only to find hash tables in external analysis */
-#define HASH_SIGNATURE 0xa0111fe1
-#define HASH_BLOOM_SIGNATURE 0xb12220f2
+#define MPL_HASH_SIGNATURE 0xa0111fe1u
+#define MPL_HASH_BLOOM_SIGNATURE 0xb12220f2u
-typedef struct UT_hash_table {
- UT_hash_bucket *buckets;
+typedef struct MPL_UT_hash_table {
+ MPL_UT_hash_bucket *buckets;
unsigned num_buckets, log2_num_buckets;
unsigned num_items;
- struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
+ struct MPL_UT_hash_handle *tail; /* tail hh in app order, for fast append */
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
/* in an ideal situation (all buckets used equally), no bucket would have
@@ -929,23 +958,23 @@ typedef struct UT_hash_table {
unsigned ineff_expands, noexpand;
uint32_t signature; /* used only to find hash tables in external analysis */
-#ifdef HASH_BLOOM
+#ifdef MPL_HASH_BLOOM
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
uint8_t *bloom_bv;
- char bloom_nbits;
+ uint8_t bloom_nbits;
#endif
-} UT_hash_table;
+} MPL_UT_hash_table;
-typedef struct UT_hash_handle {
- struct UT_hash_table *tbl;
+typedef struct MPL_UT_hash_handle {
+ struct MPL_UT_hash_table *tbl;
void *prev; /* prev element in app order */
void *next; /* next element in app order */
- struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
- struct UT_hash_handle *hh_next; /* next hh in bucket order */
+ struct MPL_UT_hash_handle *hh_prev; /* previous hh in bucket order */
+ struct MPL_UT_hash_handle *hh_next; /* next hh in bucket order */
void *key; /* ptr to enclosing struct's key */
unsigned keylen; /* enclosing struct's key len */
unsigned hashv; /* result of hash-fcn(key) */
-} UT_hash_handle;
+} MPL_UT_hash_handle;
-#endif /* MPIR_UTHASH_H_INCLUDED */
+#endif /* MPL_UTHASH_H */
-----------------------------------------------------------------------
Summary of changes:
src/include/Makefile.mk | 1 -
src/include/mpit.h | 2 +-
src/include/mpitimpl.h | 4 +-
src/mpi/comm/commutil.c | 12 +-
src/mpi/comm/contextid.c | 1 -
src/mpi_t/cat_get_index.c | 2 +-
src/mpi_t/cvar_get_index.c | 2 +-
src/mpi_t/mpit.c | 20 +-
src/mpi_t/mpit_finalize.c | 18 +-
src/mpi_t/pvar_get_index.c | 2 +-
.../mpir_uthash.h => mpl/include/mpl_uthash.h} | 777 ++++++++++----------
11 files changed, 434 insertions(+), 407 deletions(-)
rename src/{include/mpir_uthash.h => mpl/include/mpl_uthash.h} (57%)
mode change 100644 => 100755
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-369-gf43c017
by noreply@mpich.org 26 Jul '16
by noreply@mpich.org 26 Jul '16
26 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via f43c017cea598e37088d75a58a87b714ce4e8921 (commit)
from ec30eb3ed2538801ceac2763ba0f81c400462063 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/f43c017cea598e37088d75a58a87b714c…
commit f43c017cea598e37088d75a58a87b714ce4e8921
Author: Ken Raffenetti <raffenet(a)mcs.anl.gov>
Date: Tue Jul 26 10:39:56 2016 -0500
mpir_object.h: Add missing macro prefix
No reviewer.
diff --git a/src/include/mpir_objects.h b/src/include/mpir_objects.h
index e92cf79..34b2342 100644
--- a/src/include/mpir_objects.h
+++ b/src/include/mpir_objects.h
@@ -263,7 +263,7 @@ typedef int Handle_ref_count;
#define MPIR_Object_get_ref(objptr_) \
((objptr_)->ref_count)
-#define Object_add_ref_always(objptr_) \
+#define MPIR_Object_add_ref_always(objptr_) \
do { \
(objptr_)->ref_count++; \
HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "incr"); \
@@ -291,7 +291,7 @@ typedef OPA_int_t Handle_ref_count;
#define MPIR_Object_get_ref(objptr_) \
(OPA_load_int(&(objptr_)->ref_count))
-#define Object_add_ref_always(objptr_) \
+#define MPIR_Object_add_ref_always(objptr_) \
do { \
OPA_incr_int(&((objptr_)->ref_count)); \
HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "incr"); \
@@ -327,7 +327,7 @@ typedef OPA_int_t Handle_ref_count;
do { \
int handle_kind_ = HANDLE_GET_KIND((objptr_)->handle); \
if (unlikely(handle_kind_ != HANDLE_KIND_BUILTIN)) { \
- Object_add_ref_always((objptr_)); \
+ MPIR_Object_add_ref_always((objptr_)); \
} \
else { \
MPL_DBG_MSG_FMT(MPIR_DBG_HANDLE,TYPICAL,(MPL_DBG_FDEST, \
@@ -359,7 +359,7 @@ typedef OPA_int_t Handle_ref_count;
/* the base case, where we just always manipulate the reference counts */
#define MPIR_Object_add_ref(objptr_) \
- Object_add_ref_always((objptr_))
+ MPIR_Object_add_ref_always((objptr_))
#define MPIR_Object_release_ref(objptr_,inuse_ptr_) \
MPIR_Object_release_ref_always((objptr_),(inuse_ptr_))
-----------------------------------------------------------------------
Summary of changes:
src/include/mpir_objects.h | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-368-gec30eb3
by noreply@mpich.org 25 Jul '16
by noreply@mpich.org 25 Jul '16
25 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via ec30eb3ed2538801ceac2763ba0f81c400462063 (commit)
via 36a128747962564b0499fbe5db18de880152f47c (commit)
via cab988ed5e523f92814c7223f38a472a7f1ea770 (commit)
via a83721f6da89c1c05fb786da6020f790d7d0cfc4 (commit)
via 7df6a4a8474e71299bbd257ef4ef48f80ccba549 (commit)
via d803c979eba80b8a0705c718719e5b8035d44cf2 (commit)
via d9d88286385f2df24bb7832aa6ce2e544f0d0672 (commit)
via 08c588602b12fc0abf9ecf2667c5ba28cd60e55f (commit)
via 1227b993ca8664d3331157e87fb68bfd17ee9fea (commit)
from a9c78f27dd8d49a5a6ec05d563e965c8b8e141b8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/ec30eb3ed2538801ceac2763ba0f81c40…
commit ec30eb3ed2538801ceac2763ba0f81c400462063
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 12:41:17 2016 -0700
Remove unnecessary include
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/common/shm/mpidu_shm.h b/src/mpid/common/shm/mpidu_shm.h
index 2ce5a40..0f42f06 100644
--- a/src/mpid/common/shm/mpidu_shm.h
+++ b/src/mpid/common/shm/mpidu_shm.h
@@ -8,8 +8,6 @@
#ifndef MPIDU_SHM_H
#define MPIDU_SHM_H
-#include "mpiimpl.h"
-
#define MPIDU_SHM_MAX_FNAME_LEN 256
#define MPIDU_SHM_CACHE_LINE_LEN 64
http://git.mpich.org/mpich.git/commitdiff/36a128747962564b0499fbe5db18de880…
commit 36a128747962564b0499fbe5db18de880152f47c
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 12:40:42 2016 -0700
Add missing MPICH header
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/common/shm/mpidu_shm.h b/src/mpid/common/shm/mpidu_shm.h
index 2060cd6..2ce5a40 100644
--- a/src/mpid/common/shm/mpidu_shm.h
+++ b/src/mpid/common/shm/mpidu_shm.h
@@ -1,3 +1,9 @@
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/* vim: set ft=c.mpich : */
+/*
+ * (C) 2016 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
#ifndef MPIDU_SHM_H
#define MPIDU_SHM_H
@@ -42,4 +48,3 @@ int MPIDU_shm_barrier_init(MPIDU_shm_barrier_t *barrier_region,
int MPIDU_shm_barrier(MPIDU_shm_barrier_t *barrier, int num_local);
#endif /* MPIDU_SHM_H */
-/* vim: ft=c */
http://git.mpich.org/mpich.git/commitdiff/cab988ed5e523f92814c7223f38a472a7…
commit cab988ed5e523f92814c7223f38a472a7f1ea770
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Fri Jan 29 13:16:34 2016 -0800
Bug-fix: Protect multi-threading defines
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/common/thread/mpidu_thread_fallback.h b/src/mpid/common/thread/mpidu_thread_fallback.h
index fec107f..b89c242 100644
--- a/src/mpid/common/thread/mpidu_thread_fallback.h
+++ b/src/mpid/common/thread/mpidu_thread_fallback.h
@@ -524,6 +524,7 @@ M*/
("tls_get failed, err=%d (%s)", *((int *) err_ptr_), strerror(*((int *) err_ptr_)))); \
} while (0)
+#if defined(MPICH_IS_THREADED)
#define MPIDU_THREADPRIV_KEY_CREATE \
do { \
@@ -533,12 +534,17 @@ M*/
} while (0)
#define MPIDU_THREADPRIV_KEY_GET_ADDR MPL_THREADPRIV_KEY_GET_ADDR
-
#define MPIDU_THREADPRIV_KEY_DESTROY \
do { \
int err_ = 0; \
MPL_THREADPRIV_KEY_DESTROY(MPIR_Per_thread_key, &err_); \
MPIR_Assert(err_ == 0); \
} while (0)
+#else /* !defined(MPICH_IS_THREADED) */
+#define MPIDU_THREADPRIV_KEY_CREATE(key, var, err_ptr_)
+#define MPIDU_THREADPRIV_KEY_GET_ADDR(is_threaded, key, var, addr, err_ptr_) \
+ MPL_THREADPRIV_KEY_GET_ADDR(0, key, var, addr, err_ptr_)
+#define MPIDU_THREADPRIV_KEY_DESTROY(key, err_ptr_)
+#endif /* MPICH_IS_THREADED */
#endif /* !defined(MPIDU_THREAD_H_INCLUDED) */
http://git.mpich.org/mpich.git/commitdiff/a83721f6da89c1c05fb786da6020f790d…
commit a83721f6da89c1c05fb786da6020f790d7d0cfc4
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 12:26:30 2016 -0700
Fix some circular dependency issues
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/common/datatype/mpidu_dataloop.h b/src/mpid/common/datatype/mpidu_dataloop.h
index 1fa82d2..b9dddd1 100644
--- a/src/mpid/common/datatype/mpidu_dataloop.h
+++ b/src/mpid/common/datatype/mpidu_dataloop.h
@@ -9,6 +9,7 @@
#define MPIDU_DATALOOP_H
#include <mpi.h>
+#include <mpl.h>
/* Note: this is where you define the prefix that will be prepended on
* all externally visible generic dataloop and segment functions.
@@ -110,6 +111,4 @@
#define MPIDU_DATALOOP_HOMOGENEOUS DLOOP_DATALOOP_HOMOGENEOUS
#define MPIDU_DATALOOP_ALL_BYTES DLOOP_DATALOOP_ALL_BYTES
-#include <mpiimpl.h>
-
#endif
diff --git a/src/mpid/common/datatype/mpidu_datatype.h b/src/mpid/common/datatype/mpidu_datatype.h
index 73cd35d..350515f 100644
--- a/src/mpid/common/datatype/mpidu_datatype.h
+++ b/src/mpid/common/datatype/mpidu_datatype.h
@@ -6,7 +6,6 @@
#ifndef MPIDU_DATATYPE_H
#define MPIDU_DATATYPE_H
-#include "mpiimpl.h"
#include "mpidu_dataloop.h"
#include "mpir_objects.h"
diff --git a/src/mpid/common/datatype/mpidu_type_commit.c b/src/mpid/common/datatype/mpidu_type_commit.c
index 407ecd7..a847ebf 100644
--- a/src/mpid/common/datatype/mpidu_type_commit.c
+++ b/src/mpid/common/datatype/mpidu_type_commit.c
@@ -5,6 +5,7 @@
* See COPYRIGHT in top-level directory.
*/
+#include <mpiimpl.h>
#include <mpidu_dataloop.h>
#include <stdlib.h>
http://git.mpich.org/mpich.git/commitdiff/7df6a4a8474e71299bbd257ef4ef48f80…
commit 7df6a4a8474e71299bbd257ef4ef48f80ccba549
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Thu Jan 21 10:59:53 2016 -0800
Cleanup unused label warnings
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpi/coll/alltoall.c b/src/mpi/coll/alltoall.c
index 309a6c3..b686562 100644
--- a/src/mpi/coll/alltoall.c
+++ b/src/mpi/coll/alltoall.c
@@ -527,16 +527,13 @@ int MPIR_Alltoall_inter(
}
}
- fn_exit:
if (mpi_errno_ret)
mpi_errno = mpi_errno_ret;
else if (*errflag != MPIR_ERR_NONE)
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
return mpi_errno;
- fn_fail:
- goto fn_exit;
-}
+ }
#undef FUNCNAME
diff --git a/src/mpi/coll/alltoallv.c b/src/mpi/coll/alltoallv.c
index 46f1809..d7c6b0c 100644
--- a/src/mpi/coll/alltoallv.c
+++ b/src/mpi/coll/alltoallv.c
@@ -303,14 +303,11 @@ int MPIR_Alltoallv_inter(const void *sendbuf, const int *sendcounts, const int *
}
}
- fn_exit:
if (mpi_errno_ret)
mpi_errno = mpi_errno_ret;
else if (*errflag != MPIR_ERR_NONE)
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
diff --git a/src/mpi/coll/alltoallw.c b/src/mpi/coll/alltoallw.c
index 02eba11..6b5f925 100644
--- a/src/mpi/coll/alltoallw.c
+++ b/src/mpi/coll/alltoallw.c
@@ -297,15 +297,11 @@ int MPIR_Alltoallw_inter(const void *sendbuf, const int sendcounts[], const int
MPIR_ERR_ADD(mpi_errno_ret, mpi_errno);
}
}
-
- fn_exit:
if (mpi_errno_ret)
mpi_errno = mpi_errno_ret;
else if (*errflag != MPIR_ERR_NONE)
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
#undef FUNCNAME
diff --git a/src/mpi/coll/barrier.c b/src/mpi/coll/barrier.c
index 54347c5..ef6590c 100644
--- a/src/mpi/coll/barrier.c
+++ b/src/mpi/coll/barrier.c
@@ -113,14 +113,11 @@ static int barrier_smp_intra(MPIR_Comm *comm_ptr, MPIR_Errflag_t *errflag)
}
}
- fn_exit:
if (mpi_errno_ret)
mpi_errno = mpi_errno_ret;
else if (*errflag != MPIR_ERR_NONE)
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
/* not declared static because it is called in ch3_comm_connect/accept */
@@ -174,8 +171,6 @@ int MPIR_Barrier_intra( MPIR_Comm *comm_ptr, MPIR_Errflag_t *errflag )
else if (*errflag != MPIR_ERR_NONE)
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
/* not declared static because a machine-specific function may call this one
diff --git a/src/mpi/coll/barrier_group.c b/src/mpi/coll/barrier_group.c
index cd629bf..1c68132 100644
--- a/src/mpi/coll/barrier_group.c
+++ b/src/mpi/coll/barrier_group.c
@@ -27,9 +27,7 @@ int MPIR_Barrier_group( MPIR_Comm *comm_ptr, MPIR_Group *group_ptr, int tag, MPI
if (mpi_errno != MPI_SUCCESS || *errflag != MPIR_ERR_NONE)
*errflag = MPIR_ERR_GET_CLASS(mpi_errno);
- fn_exit:
+ fn_exit:
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
diff --git a/src/mpi/coll/bcast.c b/src/mpi/coll/bcast.c
index b024d5e..49149ff 100644
--- a/src/mpi/coll/bcast.c
+++ b/src/mpi/coll/bcast.c
@@ -438,7 +438,6 @@ static int scatter_for_bcast(
mask >>= 1;
}
-fn_exit:
/* --BEGIN ERROR HANDLING-- */
if (mpi_errno_ret)
mpi_errno = mpi_errno_ret;
@@ -446,8 +445,6 @@ fn_exit:
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
/* --END ERROR HANDLING-- */
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
/*
@@ -1163,8 +1160,6 @@ fn_exit:
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
/* --END ERROR HANDLING-- */
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
@@ -1322,8 +1317,6 @@ fn_exit:
MPIR_ERR_SET(mpi_errno, *errflag, "**coll_fail");
/* --END ERROR HANDLING-- */
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
@@ -1406,7 +1399,6 @@ int MPIR_Bcast_inter (
}
}
-fn_fail:
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_BCAST_INTER);
/* --BEGIN ERROR HANDLING-- */
if (mpi_errno_ret)
diff --git a/src/mpi/coll/reduce_local.c b/src/mpi/coll/reduce_local.c
index 547ad56..c97126f 100644
--- a/src/mpi/coll/reduce_local.c
+++ b/src/mpi/coll/reduce_local.c
@@ -123,8 +123,6 @@ int MPIR_Reduce_local_impl(const void *inbuf, void *inoutbuf, int count, MPI_Dat
fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif
diff --git a/src/mpi/comm/comm_create.c b/src/mpi/comm/comm_create.c
index d75f825..7540e65 100644
--- a/src/mpi/comm/comm_create.c
+++ b/src/mpi/comm/comm_create.c
@@ -173,11 +173,7 @@ int MPII_Comm_create_map(int local_n,
MPIR_Comm_map_irregular(newcomm, mapping_comm, remote_mapping,
remote_n, MPIR_COMM_MAP_DIR__R2R, NULL);
}
-
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
diff --git a/src/mpi/comm/commutil.c b/src/mpi/comm/commutil.c
index 53190ec..3129d6a 100644
--- a/src/mpi/comm/commutil.c
+++ b/src/mpi/comm/commutil.c
@@ -111,7 +111,6 @@ int MPII_Comm_init(MPIR_Comm * comm_p)
/* Fields not set include context_id, remote and local size, and
* kind, since different communicator construction routines need
* different values */
- fn_fail:
return mpi_errno;
}
@@ -510,11 +509,8 @@ int MPIR_Comm_map_free(MPIR_Comm * comm)
}
comm->mapper_head = NULL;
- fn_exit:
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_COMM_MAP_FREE);
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
/* Provides a hook for the top level functions to perform some manipulation on a
@@ -906,7 +902,6 @@ int MPII_Comm_copy_data(MPIR_Comm * comm_ptr, MPIR_Comm ** outcomm_ptr)
*outcomm_ptr = newcomm_ptr;
fn_fail:
- fn_exit:
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_COMM_COPY_DATA);
return mpi_errno;
}
@@ -1132,11 +1127,8 @@ static int free_hint_handles(void *ignore)
}
}
- fn_exit:
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_COMM_FREE_HINT_HANDLES);
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
/* The hint logic is stored in a uthash, with hint name as key and
@@ -1164,9 +1156,6 @@ int MPIR_Comm_register_hint(const char *hint_key, MPIR_Comm_hint_fn_t fn, void *
HASH_ADD_STR(MPID_hint_fns, name, hint_elt);
- fn_exit:
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_COMM_REGISTER_HINT);
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
diff --git a/src/mpi/comm/intercomm_merge.c b/src/mpi/comm/intercomm_merge.c
index c7283f3..52c55ff 100644
--- a/src/mpi/comm/intercomm_merge.c
+++ b/src/mpi/comm/intercomm_merge.c
@@ -61,7 +61,6 @@ static int create_and_map(MPIR_Comm *comm_ptr, int local_high, MPIR_Comm *new_in
MPIR_Comm_map_dup(new_intracomm_ptr, comm_ptr, MPIR_COMM_MAP_DIR__R2L);
}
-fn_fail:
return mpi_errno;
}
diff --git a/src/mpi/datatype/get_elements_x.c b/src/mpi/datatype/get_elements_x.c
index 2f6351b..d83bd21 100644
--- a/src/mpi/datatype/get_elements_x.c
+++ b/src/mpi/datatype/get_elements_x.c
@@ -349,10 +349,7 @@ int MPIR_Get_elements_x_impl(const MPI_Status *status, MPI_Datatype datatype, MP
*elements = MPIR_Type_get_elements(&byte_count, -1, datatype);
}
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi/datatype/status_set_elements_x.c b/src/mpi/datatype/status_set_elements_x.c
index 007e00e..c08a97d 100644
--- a/src/mpi/datatype/status_set_elements_x.c
+++ b/src/mpi/datatype/status_set_elements_x.c
@@ -45,10 +45,7 @@ int MPIR_Status_set_elements_x_impl(MPI_Status *status, MPI_Datatype datatype, M
MPIR_STATUS_SET_COUNT(*status, size_x * count);
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi/datatype/type_size_x.c b/src/mpi/datatype/type_size_x.c
index 4cfd973..25ab1b5 100644
--- a/src/mpi/datatype/type_size_x.c
+++ b/src/mpi/datatype/type_size_x.c
@@ -36,10 +36,7 @@ int MPIR_Type_size_x_impl(MPI_Datatype datatype, MPI_Count *size)
MPID_Datatype_get_size_macro(datatype, *size);
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi/group/group_compare.c b/src/mpi/group/group_compare.c
index dd92714..7c15e97 100644
--- a/src/mpi/group/group_compare.c
+++ b/src/mpi/group/group_compare.c
@@ -75,8 +75,6 @@ int MPIR_Group_compare_impl(MPIR_Group *group_ptr1, MPIR_Group *group_ptr2, int
fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif
diff --git a/src/mpi/group/group_translate_ranks.c b/src/mpi/group/group_translate_ranks.c
index dad9886..3cd24b0 100644
--- a/src/mpi/group/group_translate_ranks.c
+++ b/src/mpi/group/group_translate_ranks.c
@@ -100,10 +100,7 @@ int MPIR_Group_translate_ranks_impl(MPIR_Group *gp1, int n, const int ranks1[],
}
}
}
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
diff --git a/src/mpi/init/initthread.c b/src/mpi/init/initthread.c
index a784f42..9e20e9b 100644
--- a/src/mpi/init/initthread.c
+++ b/src/mpi/init/initthread.c
@@ -594,7 +594,6 @@ int MPIR_Init_thread(int * argc, char ***argv, int required, int * provided)
if (mpi_errno == MPI_SUCCESS)
mpi_errno = MPID_InitCompleted();
-fn_exit:
MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
/* Make fields of MPIR_Process global visible and set mpich_state
atomically so that MPI_Initialized() etc. are thread safe */
diff --git a/src/mpi/pt2pt/bsendutil.c b/src/mpi/pt2pt/bsendutil.c
index 32e71c6..e10ae28 100644
--- a/src/mpi/pt2pt/bsendutil.c
+++ b/src/mpi/pt2pt/bsendutil.c
@@ -344,10 +344,7 @@ int MPIR_Bsend_free_req_seg( MPIR_Request* req )
MPL_DBG_MSG_P(MPIR_DBG_BSEND,TYPICAL,"Next active is %p",active);
}
- fn_exit:
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
/*
diff --git a/src/mpi/pt2pt/mpir_request.c b/src/mpi/pt2pt/mpir_request.c
index d61cd1c..9453e58 100644
--- a/src/mpi/pt2pt/mpir_request.c
+++ b/src/mpi/pt2pt/mpir_request.c
@@ -46,8 +46,8 @@ int MPIR_Progress_wait_request(MPIR_Request *req)
}
MPID_Progress_end(&progress_state);
}
-fn_fail: /* no special err handling at this level */
-fn_exit:
+
+ fn_fail:
return mpi_errno;
}
diff --git a/src/mpi_t/cat_get_categories.c b/src/mpi_t/cat_get_categories.c
index a17dc89..c3ccc0c 100644
--- a/src/mpi_t/cat_get_categories.c
+++ b/src/mpi_t/cat_get_categories.c
@@ -44,10 +44,7 @@ int MPIR_T_category_get_categories_impl(int cat_index, int len, int indices[])
indices[i] = *(int *)utarray_eltptr(cat->subcat_indices, i);
}
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi_t/cat_get_cvars.c b/src/mpi_t/cat_get_cvars.c
index 3f9ed53..e23071f 100644
--- a/src/mpi_t/cat_get_cvars.c
+++ b/src/mpi_t/cat_get_cvars.c
@@ -44,10 +44,7 @@ int MPIR_T_category_get_cvars_impl(int cat_index, int len, int indices[])
indices[i] = *(int *)utarray_eltptr(cat->cvar_indices, i);
}
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi_t/cat_get_pvars.c b/src/mpi_t/cat_get_pvars.c
index 10c3b1d..984f024 100644
--- a/src/mpi_t/cat_get_pvars.c
+++ b/src/mpi_t/cat_get_pvars.c
@@ -44,10 +44,7 @@ int MPIR_T_category_get_pvars_impl(int cat_index, int len, int indices[])
indices[i] = *(int *)utarray_eltptr(cat->pvar_indices, i);
}
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi_t/mpit.c b/src/mpi_t/mpit.c
index 5107124..cb8c2dc 100644
--- a/src/mpi_t/mpit.c
+++ b/src/mpi_t/mpit.c
@@ -130,12 +130,8 @@ int MPIR_T_cat_add_pvar(const char *cat_name, int pvar_index)
/* Notify categories have been changed */
cat_stamp++;
}
-
fn_exit:
return mpi_errno;
-
-fn_fail:
- goto fn_exit;
}
/* Add a cvar to an existing or new category
@@ -171,9 +167,6 @@ int MPIR_T_cat_add_cvar(const char *cat_name, int cvar_index)
fn_exit:
return mpi_errno;
-
-fn_fail:
- goto fn_exit;
}
/* Add a sub-category to an existing or new category
@@ -226,8 +219,6 @@ int MPIR_T_cat_add_subcat(const char *parent_name, const char *child_name)
fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
/* Add description to an existing or new category
@@ -262,11 +253,7 @@ int MPIR_T_cat_add_desc(const char *cat_name, const char *cat_desc)
cat_stamp++;
}
-fn_exit:
return mpi_errno;
-
-fn_fail:
- goto fn_exit;
}
/* A low level, generic and internally used interface to register
diff --git a/src/mpi_t/mpit_initthread.c b/src/mpi_t/mpit_initthread.c
index d177384..0c92342 100644
--- a/src/mpi_t/mpit_initthread.c
+++ b/src/mpi_t/mpit_initthread.c
@@ -139,20 +139,6 @@ int MPI_T_init_thread(int required, int *provided)
/* ... end of body of routine ... */
-fn_exit:
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_T_INIT_THREAD);
return mpi_errno;
-
-fn_fail:
- /* --BEGIN ERROR HANDLING-- */
-# ifdef HAVE_ERROR_CHECKING
- {
- mpi_errno = MPIR_Err_create_code(
- mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
- "**mpi_t_init_thread", "**mpi_t_init_thread %d %p", required, provided);
- }
-# endif
- mpi_errno = MPIR_Err_return_comm(NULL, FCNAME, mpi_errno);
- goto fn_exit;
- /* --END ERROR HANDLING-- */
}
diff --git a/src/mpi_t/pvar_handle_free.c b/src/mpi_t/pvar_handle_free.c
index ca571ea..7570961 100644
--- a/src/mpi_t/pvar_handle_free.c
+++ b/src/mpi_t/pvar_handle_free.c
@@ -62,10 +62,7 @@ int MPIR_T_pvar_handle_free_impl(MPI_T_pvar_session session, MPI_T_pvar_handle *
MPL_free(hnd);
*handle = MPI_T_PVAR_HANDLE_NULL;
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi_t/pvar_reset.c b/src/mpi_t/pvar_reset.c
index a96a488..c5d8c49 100644
--- a/src/mpi_t/pvar_reset.c
+++ b/src/mpi_t/pvar_reset.c
@@ -67,10 +67,7 @@ int MPIR_T_pvar_reset_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle)
}
}
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi_t/pvar_session_free.c b/src/mpi_t/pvar_session_free.c
index edb9468..6988792 100644
--- a/src/mpi_t/pvar_session_free.c
+++ b/src/mpi_t/pvar_session_free.c
@@ -49,10 +49,7 @@ int MPIR_T_pvar_session_free_impl(MPI_T_pvar_session *session)
MPL_free(*session);
*session = MPI_T_PVAR_SESSION_NULL;
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpi_t/pvar_start.c b/src/mpi_t/pvar_start.c
index 85995d6..25139e9 100644
--- a/src/mpi_t/pvar_start.c
+++ b/src/mpi_t/pvar_start.c
@@ -67,10 +67,7 @@ int MPIR_T_pvar_start_impl(MPI_T_pvar_session session, MPI_T_pvar_handle handle)
/* OK, let's get started */
MPIR_T_pvar_set_started(handle);
-fn_exit:
return mpi_errno;
-fn_fail:
- goto fn_exit;
}
#endif /* MPICH_MPI_FROM_PMPI */
diff --git a/src/mpid/common/sched/mpidu_sched.c b/src/mpid/common/sched/mpidu_sched.c
index 3640f0c..bc72332 100644
--- a/src/mpid/common/sched/mpidu_sched.c
+++ b/src/mpid/common/sched/mpidu_sched.c
@@ -795,10 +795,7 @@ int MPIDU_Sched_barrier(MPIR_Sched_t s)
s->entries[s->num_entries - 1].is_barrier = TRUE;
}
- fn_exit:
return mpi_errno;
- fn_fail:
- goto fn_exit;
}
#undef FUNCNAME
http://git.mpich.org/mpich.git/commitdiff/d803c979eba80b8a0705c718719e5b803…
commit d803c979eba80b8a0705c718719e5b8035d44cf2
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 11:40:31 2016 -0700
Fix warning with unsigned to signed conversion
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/include/mpit.h b/src/include/mpit.h
index 6757358..d2e2986 100644
--- a/src/include/mpit.h
+++ b/src/include/mpit.h
@@ -42,7 +42,7 @@ extern int MPIR_T_cat_add_desc(const char *cat_name, const char *cat_desc);
static inline cvar_table_entry_t * LOOKUP_CVAR_BY_NAME(const char* cvar_name)
{
- int cvar_idx;
+ unsigned cvar_idx;
name2index_hash_t *hash_entry;
HASH_FIND_STR(cvar_hash, cvar_name, hash_entry);
MPIR_Assert(hash_entry != NULL);
diff --git a/src/include/mpitimpl.h b/src/include/mpitimpl.h
index a3af890..c3a9d03 100644
--- a/src/include/mpitimpl.h
+++ b/src/include/mpitimpl.h
@@ -57,7 +57,7 @@ typedef struct {
/* Hash names to indices in a table */
typedef struct {
const char *name;
- int idx;
+ unsigned idx;
UT_hash_handle hh; /* Makes this structure hashable */
} name2index_hash_t;
http://git.mpich.org/mpich.git/commitdiff/d9d88286385f2df24bb7832aa6ce2e544…
commit d9d88286385f2df24bb7832aa6ce2e544f0d0672
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 11:08:11 2016 -0700
Add assert to check for negative refcounts
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/include/mpir_refcount_global.h b/src/include/mpir_refcount_global.h
index 9f01da2..0803404 100644
--- a/src/include/mpir_refcount_global.h
+++ b/src/include/mpir_refcount_global.h
@@ -23,6 +23,7 @@ typedef volatile int MPIR_cc_t;
#define MPIR_cc_decr(cc_ptr_, incomplete_) \
do { \
*(incomplete_) = --(*(cc_ptr_)); \
+ MPIR_Assert(*(incomplete_) >= 0); \
} while (0)
diff --git a/src/include/mpir_refcount_pobj.h b/src/include/mpir_refcount_pobj.h
index a9d500a..6a98ed6 100644
--- a/src/include/mpir_refcount_pobj.h
+++ b/src/include/mpir_refcount_pobj.h
@@ -58,9 +58,12 @@ static inline int MPIR_cc_is_complete(MPIR_cc_t * cc_ptr)
/* incomplete_==TRUE iff the cc > 0 after the decr */
#define MPIR_cc_decr(cc_ptr_, incomplete_) \
do { \
+ int ctr_; \
OPA_write_barrier(); \
MPL_VG_ANNOTATE_HAPPENS_BEFORE(cc_ptr_); \
- *(incomplete_) = !OPA_decr_and_test_int(cc_ptr_); \
+ ctr_ = OPA_fetch_and_decr_int(cc_ptr_); \
+ MPIR_Assert(ctr_ >= 1); \
+ *(incomplete_) = (ctr_ != 1); \
/* TODO check if this HA is actually necessary */ \
if (!*(incomplete_)) { \
MPL_VG_ANNOTATE_HAPPENS_AFTER(cc_ptr_); \
diff --git a/src/include/mpir_refcount_single.h b/src/include/mpir_refcount_single.h
index 3ae7758..c5116db 100644
--- a/src/include/mpir_refcount_single.h
+++ b/src/include/mpir_refcount_single.h
@@ -22,6 +22,7 @@ typedef int MPIR_cc_t;
#define MPIR_cc_decr(cc_ptr_, incomplete_) \
do { \
*(incomplete_) = --(*(cc_ptr_)); \
+ MPIR_Assert(*(incomplete_) >= 0); \
} while (0)
http://git.mpich.org/mpich.git/commitdiff/08c588602b12fc0abf9ecf2667c5ba28c…
commit 08c588602b12fc0abf9ecf2667c5ba28cd60e55f
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 10:59:22 2016 -0700
Add configuration to control tag error bits
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/configure.ac b/configure.ac
index 2a3f25e..942f780 100644
--- a/configure.ac
+++ b/configure.ac
@@ -342,6 +342,12 @@ AC_ARG_ENABLE(error-messages,
none - No messages
],,enable_error_messages=all)
+AC_ARG_ENABLE(tag-error-bits,
+[ --enable-tag-error-bits=yes|no - Control whether bits are taken from the user tag for error handling.
+ yes - Two bits are taken from the user tag to support error propagation.
+ no - No bits are taken from the user tag (this could cause deadlock if an error is detected during a collective).
+],,enable_tag_error_bits=yes)
+
AC_ARG_ENABLE(timing,
[ --enable-timing=level - Control the amount of timing information
collected by the MPICH implementation.
@@ -955,6 +961,11 @@ case "$enable_error_messages" in
esac
AC_DEFINE_UNQUOTED(MPICH_ERROR_MSG_LEVEL,$error_message_kind,[define to enable error messages])
+#error-tags
+if test "$enable_tag_error_bits" = "yes" ; then
+ AC_DEFINE([HAVE_TAG_ERROR_BITS],[1],[Define to enable tag error bits])
+fi
+
# ----------------------------------------------------------------------------
#
# enable-timing and with-logging
diff --git a/src/include/mpir_tags.h b/src/include/mpir_tags.h
index 7bd0c26..da14044 100644
--- a/src/include/mpir_tags.h
+++ b/src/include/mpir_tags.h
@@ -50,30 +50,62 @@
/* This bitmask can be used to manually mask the tag space wherever it might
* be necessary to do so (for instance in the receive queue */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_ERROR_BIT (1 << 30)
+#else
+#define MPIR_TAG_ERROR_BIT
+#endif
/* This bitmask is used to differentiate between a process failure
* (MPIX_ERR_PROC_FAILED) and any other kind of failure (MPI_ERR_OTHER). */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_PROC_FAILURE_BIT (1 << 29)
+#else
+#define MPIR_TAG_PROC_FAILURE_BIT
+#endif
/* This macro checks the value of the error bit in the MPI tag and returns 1
* if the tag is set and 0 if it is not. */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_CHECK_ERROR_BIT(tag) ((MPIR_TAG_ERROR_BIT & (tag)) == MPIR_TAG_ERROR_BIT ? 1 : 0)
+#else
+#define MPIR_TAG_CHECK_ERROR_BIT(tag) 0
+#endif
/* This macro checks the value of the process failure bit in the MPI tag and
* returns 1 if the tag is set and 0 if it is not. */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_CHECK_PROC_FAILURE_BIT(tag) ((MPIR_TAG_PROC_FAILURE_BIT & (tag)) == MPIR_TAG_PROC_FAILURE_BIT ? 1 : 0)
+#else
+#define MPIR_TAG_CHECK_PROC_FAILURE_BIT(tag) 0
+#endif
/* This macro sets the value of the error bit in the MPI tag to 1 */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_SET_ERROR_BIT(tag) ((tag) |= MPIR_TAG_ERROR_BIT)
+#else
+#define MPIR_TAG_SET_ERROR_BIT(tag) (tag)
+#endif
/* This macro sets the value of the process failure bit in the MPI tag to 1 */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_SET_PROC_FAILURE_BIT(tag) ((tag) |= (MPIR_TAG_ERROR_BIT | MPIR_TAG_PROC_FAILURE_BIT))
+#else
+#define MPIR_TAG_SET_PROC_FAILURE_BIT(tag) (tag)
+#endif
/* This macro clears the value of the error bits in the MPI tag */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_CLEAR_ERROR_BITS(tag) ((tag) &= ~(MPIR_TAG_ERROR_BIT ^ MPIR_TAG_PROC_FAILURE_BIT))
+#else
+#define MPIR_TAG_CLEAR_ERROR_BITS(tag) (tag)
+#endif
/* This macro masks the value of the error bits in the MPI tag */
+#ifdef HAVE_TAG_ERROR_BITS
#define MPIR_TAG_MASK_ERROR_BITS(tag) ((tag) & ~(MPIR_TAG_ERROR_BIT ^ MPIR_TAG_PROC_FAILURE_BIT))
+#else
+#define MPIR_TAG_MASK_ERROR_BITS(tag) (tag)
+#endif
#endif /* MPIR_TAGS_H_INCLUDED */
diff --git a/src/mpi/init/initthread.c b/src/mpi/init/initthread.c
index b93ebae..a784f42 100644
--- a/src/mpi/init/initthread.c
+++ b/src/mpi/init/initthread.c
@@ -509,7 +509,11 @@ int MPIR_Init_thread(int * argc, char ***argv, int required, int * provided)
MPIR_Assert(((unsigned)MPIR_Process.attrs.tag_ub & ((unsigned)MPIR_Process.attrs.tag_ub + 1)) == 0);
/* Set aside tag space for tagged collectives and failure notification */
+#ifdef HAVE_TAG_ERROR_BITS
MPIR_Process.attrs.tag_ub >>= 3;
+#else
+ MPIR_Process.attrs.tag_ub >>= 1;
+#endif
/* The bit for error checking is set in a macro in mpiimpl.h for
* performance reasons. */
MPIR_Process.tagged_coll_mask = MPIR_Process.attrs.tag_ub + 1;
http://git.mpich.org/mpich.git/commitdiff/1227b993ca8664d3331157e87fb68bfd1…
commit 1227b993ca8664d3331157e87fb68bfd17ee9fea
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Wed Jul 20 10:50:23 2016 -0700
Fix function name in comment
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/common/shm/mpidu_shm_alloc.c b/src/mpid/common/shm/mpidu_shm_alloc.c
index c938fab..f7bed7a 100644
--- a/src/mpid/common/shm/mpidu_shm_alloc.c
+++ b/src/mpid/common/shm/mpidu_shm_alloc.c
@@ -152,7 +152,7 @@ int MPIDU_shm_seg_commit(MPIDU_shm_seg_ptr_t memory, MPIDU_shm_barrier_ptr_t *ba
MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDU_SHM_SEG_COMMIT);
- /* MPIDU_SHM_Seg_alloc() needs to have been called before this function */
+ /* MPIDU_shm_seg_alloc() needs to have been called before this function */
MPIR_Assert(!ALLOCQ_EMPTY());
MPIR_Assert(segment_len > 0);
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 11 ++++++++
src/include/mpir_refcount_global.h | 1 +
src/include/mpir_refcount_pobj.h | 5 +++-
src/include/mpir_refcount_single.h | 1 +
src/include/mpir_tags.h | 32 ++++++++++++++++++++++++
src/include/mpit.h | 2 +-
src/include/mpitimpl.h | 2 +-
src/mpi/coll/alltoall.c | 5 +---
src/mpi/coll/alltoallv.c | 3 --
src/mpi/coll/alltoallw.c | 4 ---
src/mpi/coll/barrier.c | 5 ---
src/mpi/coll/barrier_group.c | 4 +--
src/mpi/coll/bcast.c | 8 ------
src/mpi/coll/reduce_local.c | 2 -
src/mpi/comm/comm_create.c | 4 ---
src/mpi/comm/commutil.c | 11 --------
src/mpi/comm/intercomm_merge.c | 1 -
src/mpi/datatype/get_elements_x.c | 3 --
src/mpi/datatype/status_set_elements_x.c | 3 --
src/mpi/datatype/type_size_x.c | 3 --
src/mpi/group/group_compare.c | 2 -
src/mpi/group/group_translate_ranks.c | 3 --
src/mpi/init/initthread.c | 5 +++-
src/mpi/pt2pt/bsendutil.c | 3 --
src/mpi/pt2pt/mpir_request.c | 4 +-
src/mpi_t/cat_get_categories.c | 3 --
src/mpi_t/cat_get_cvars.c | 3 --
src/mpi_t/cat_get_pvars.c | 3 --
src/mpi_t/mpit.c | 13 ---------
src/mpi_t/mpit_initthread.c | 14 ----------
src/mpi_t/pvar_handle_free.c | 3 --
src/mpi_t/pvar_reset.c | 3 --
src/mpi_t/pvar_session_free.c | 3 --
src/mpi_t/pvar_start.c | 3 --
src/mpid/common/datatype/mpidu_dataloop.h | 3 +-
src/mpid/common/datatype/mpidu_datatype.h | 1 -
src/mpid/common/datatype/mpidu_type_commit.c | 1 +
src/mpid/common/sched/mpidu_sched.c | 3 --
src/mpid/common/shm/mpidu_shm.h | 9 ++++--
src/mpid/common/shm/mpidu_shm_alloc.c | 2 +-
src/mpid/common/thread/mpidu_thread_fallback.h | 8 +++++-
41 files changed, 75 insertions(+), 127 deletions(-)
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-359-ga9c78f2
by noreply@mpich.org 25 Jul '16
by noreply@mpich.org 25 Jul '16
25 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via a9c78f27dd8d49a5a6ec05d563e965c8b8e141b8 (commit)
via a78e899047778329e4f87416ab89aebb005cd8c1 (commit)
via 8fe8cc157c8330d0e940ba67895c7a3604b3c6c3 (commit)
via 28d1b074f135173c79244c2ce92e8b5197af00da (commit)
via e474997fd5e859fe363d3b2ce116ca63868ad3e2 (commit)
via 598aa493dcef472ac32498fa0100976df15c2b26 (commit)
via ccd815498267d6cc342d25fce7ce3107f3e18294 (commit)
via b95b4e4ef0ed1b6ea4b47b56859eef18487d5eb8 (commit)
from ea008be1976a301092ccb7a35b3ee1f9a4ec4d07 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/a9c78f27dd8d49a5a6ec05d563e965c8b…
commit a9c78f27dd8d49a5a6ec05d563e965c8b8e141b8
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Fri Mar 25 13:59:49 2016 -0700
ROMIO apply TUNEGATHER to ADIOI_LUSTRE_WriteStridedColl
Implement ROMIO_TUNEGATHER within ADIOI_LUSTRE_WriteStridedColl
to use one MPI_Allreduce instead of 2 (or 3 in the case of onesided aggregation)
MPI_Allgathers to communication all starting and ending file offsets
(and onesided count sizes)
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c b/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c
index 0e47e5e..cf6787c 100644
--- a/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c
+++ b/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c
@@ -96,7 +96,7 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
int *striping_info = NULL;
ADIO_Offset **buf_idx = NULL;
int old_error, tmp_error;
- ADIO_Offset *count_sizes;
+ ADIO_Offset *lustre_offsets0, *lustre_offsets, *count_sizes;
MPI_Comm_size(fd->comm, &nprocs);
MPI_Comm_rank(fd->comm, &myrank);
@@ -133,6 +133,46 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
MPI_Type_size_x(datatype, &buftype_size);
my_count_size = (ADIO_Offset) count * (ADIO_Offset)buftype_size;
}
+ if (romio_tunegather) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
+ lustre_offsets0 = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
+ lustre_offsets = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
+ for (i=0; i<nprocs; i++) {
+ lustre_offsets0[i*3] = 0;
+ lustre_offsets0[i*3+1] = 0;
+ lustre_offsets0[i*3+2] = 0;
+ }
+ lustre_offsets0[myrank*3] = start_offset;
+ lustre_offsets0[myrank*3+1] = end_offset;
+ lustre_offsets0[myrank*3+2] = my_count_size;
+ MPI_Allreduce( lustre_offsets0, lustre_offsets, nprocs*3, ADIO_OFFSET, MPI_MAX, fd->comm );
+ for (i=0; i<nprocs; i++) {
+ st_offsets [i] = lustre_offsets[i*3] ;
+ end_offsets[i] = lustre_offsets[i*3+1];
+ count_sizes[i] = lustre_offsets[i*3+2];
+ }
+ }
+ else {
+ lustre_offsets0 = (ADIO_Offset *) ADIOI_Malloc(2*nprocs*sizeof(ADIO_Offset));
+ lustre_offsets = (ADIO_Offset *) ADIOI_Malloc(2*nprocs*sizeof(ADIO_Offset));
+ for (i=0; i<nprocs; i++) {
+ lustre_offsets0[i*2] = 0;
+ lustre_offsets0[i*2+1] = 0;
+ }
+ lustre_offsets0[myrank*2] = start_offset;
+ lustre_offsets0[myrank*2+1] = end_offset;
+
+ MPI_Allreduce( lustre_offsets0, lustre_offsets, nprocs*2, ADIO_OFFSET, MPI_MAX, fd->comm );
+
+ for (i=0; i<nprocs; i++) {
+ st_offsets [i] = lustre_offsets[i*2] ;
+ end_offsets[i] = lustre_offsets[i*2+1];
+ }
+ }
+ ADIOI_Free( lustre_offsets0 );
+ ADIOI_Free( lustre_offsets );
+ }
+ else {
MPI_Allgather(&start_offset, 1, ADIO_OFFSET, st_offsets, 1,
ADIO_OFFSET, fd->comm);
MPI_Allgather(&end_offset, 1, ADIO_OFFSET, end_offsets, 1,
@@ -141,6 +181,7 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
MPI_Allgather(&my_count_size, 1, ADIO_OFFSET, count_sizes, 1,
ADIO_OFFSET, fd->comm);
}
+ }
/* are the accesses of different processes interleaved? */
for (i = 1; i < nprocs; i++)
if ((st_offsets[i] < end_offsets[i-1]) &&
http://git.mpich.org/mpich.git/commitdiff/a78e899047778329e4f87416ab89aebb0…
commit a78e899047778329e4f87416ab89aebb005cd8c1
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Fri Mar 25 13:57:47 2016 -0700
Generalize ROMIO collective aggregation tuning
Use the TUNEGATHER environment variable to select different collective
tuning approaches. The current implementation for GPFS allows the user
to use one MPI_Allreduce instead of 2 (or 3 in the case of onesided
aggregation) MPI_Allgathers to communication all starting and ending
file offsets (and onesided count sizes) if the GPFSMPIO_TUNEGATHER
environment variable is set. Generalize to other file systems as
ROMIO_TUNEGATHER.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c
index bcbd2a4..68df849 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c
@@ -185,7 +185,7 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
MPI_Type_size_x(datatype, &buftype_size);
my_count_size = (ADIO_Offset) count * (ADIO_Offset)buftype_size;
}
- if (gpfsmpio_tunegather) {
+ if (romio_tunegather) {
if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
gpfs_offsets0 = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
gpfs_offsets = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c
index 8b4d06d..548ae67 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c
@@ -31,7 +31,6 @@ int gpfsmpio_timing;
int gpfsmpio_timing2;
int gpfsmpio_timing_cw_level;
int gpfsmpio_comm;
-int gpfsmpio_tunegather;
int gpfsmpio_tuneblocking;
long bglocklessmpio_f_type;
int gpfsmpio_bg_nagg_pset;
@@ -59,12 +58,6 @@ double gpfsmpio_prof_cr [GPFSMPIO_CIO_LAST+1];
* - 1 - Collect/report timing.
* - Default is 0.
*
- * - GPFSMPIO_TUNEGATHER - Tune how starting and ending offsets are communicated
- * for aggregator collective i/o. Possible values:
- * - 0 - Use two MPI_Allgather's to collect starting and ending offsets.
- * - 1 - Use MPI_Allreduce(MPI_MAX) to collect starting and ending offsets.
- * - Default is 1.
- *
* - GPFSMPIO_TUNEBLOCKING - Tune how aggregate file domains are
* calculated (block size). Possible values:
* - 0 - Evenly calculate file domains across aggregators. Also use
@@ -139,9 +132,6 @@ void ad_gpfs_get_env_vars() {
gpfsmpio_timing = 0;
x = getenv( "GPFSMPIO_TIMING" );
if (x) gpfsmpio_timing = atoi(x);
- gpfsmpio_tunegather = 1;
- x = getenv( "GPFSMPIO_TUNEGATHER" );
- if (x) gpfsmpio_tunegather = atoi(x);
gpfsmpio_tuneblocking = 1;
x = getenv( "GPFSMPIO_TUNEBLOCKING" );
if (x) gpfsmpio_tuneblocking = atoi(x);
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h
index 21f98f6..df0139d 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h
@@ -61,7 +61,6 @@ extern double gpfsmpio_prof_cr [GPFSMPIO_CIO_LAST+1];
extern int gpfsmpio_timing;
extern int gpfsmpio_timing_cw_level;
extern int gpfsmpio_comm;
-extern int gpfsmpio_tunegather;
extern int gpfsmpio_tuneblocking;
extern long bglocklessmpio_f_type;
extern int gpfsmpio_pthreadio;
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
index bf9707e..f52f2d7 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
@@ -187,7 +187,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
MPI_Type_size_x(datatype, &buftype_size);
my_count_size = (ADIO_Offset) count * (ADIO_Offset)buftype_size;
}
- if (gpfsmpio_tunegather) {
+ if (romio_tunegather) {
if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
gpfs_offsets0 = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
gpfs_offsets = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
diff --git a/src/mpi/romio/adio/common/ad_tuning.c b/src/mpi/romio/adio/common/ad_tuning.c
index ee9c318..dc89bd6 100644
--- a/src/mpi/romio/adio/common/ad_tuning.c
+++ b/src/mpi/romio/adio/common/ad_tuning.c
@@ -26,6 +26,7 @@ int romio_read_aggmethod;
int romio_onesided_no_rmw;
int romio_onesided_always_rmw;
int romio_onesided_inform_rmw;
+int romio_tunegather;
/* set internal variables for tuning environment variables */
/** \page mpiio_vars MPIIO Configuration
@@ -71,6 +72,12 @@ int romio_onesided_inform_rmw;
* - 0 (disabled) or 1 (enabled)
* - Default is 0
*
+ * - ROMIO_TUNEGATHER - Tune how starting and ending offsets are communicated
+ * for aggregator collective i/o. Possible values:
+ * - 0 - Use two or three MPI_Allgather's to collect starting and ending offsets.
+ * - 1 - Use MPI_Allreduce(MPI_MAX) to collect starting and ending offsets.
+ * - Default is 1.
+ *
*/
void ad_get_env_vars() {
@@ -97,4 +104,8 @@ void ad_get_env_vars() {
romio_onesided_inform_rmw = 0;
x = getenv( "ROMIO_ONESIDED_INFORM_RMW" );
if (x) romio_onesided_inform_rmw = atoi(x);
+
+ romio_tunegather = 1;
+ x = getenv( "ROMIO_TUNEGATHER" );
+ if (x) romio_tunegather = atoi(x);
}
diff --git a/src/mpi/romio/adio/include/ad_tuning.h b/src/mpi/romio/adio/include/ad_tuning.h
index 51fc926..f481ccc 100644
--- a/src/mpi/romio/adio/include/ad_tuning.h
+++ b/src/mpi/romio/adio/include/ad_tuning.h
@@ -10,7 +10,6 @@
* ad_tuning.h
*
* declares common global variables and functions for performance tuning
- * and functional debugging.
*---------------------------------------------------------------------*/
#ifndef AD_TUNING_H_
@@ -23,14 +22,13 @@
* Global variables for the control of performance tuning.
*-----------------------------------------*/
-/* corresponds to environment variables to select optimizations and timing level */
-extern int romio_pthreadio;
-extern int romio_p2pcontig;
+/* corresponds to environment variables to select optimizations */
extern int romio_write_aggmethod;
extern int romio_read_aggmethod;
extern int romio_onesided_no_rmw;
extern int romio_onesided_always_rmw;
extern int romio_onesided_inform_rmw;
+extern int romio_tunegather;
/* set internal variables for tuning environment variables */
void ad_get_env_vars(void);
http://git.mpich.org/mpich.git/commitdiff/8fe8cc157c8330d0e940ba67895c7a360…
commit 8fe8cc157c8330d0e940ba67895c7a3604b3c6c3
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Fri Mar 25 13:43:47 2016 -0700
ROMIO Onesided write aggregation fixes to ADIOI_GPFS_WriteStridedColl
Fix count_sizes allgather and pass correct parms for the starting and ending file offset
to ADIOI_OneSidedWriteAggregation when re-running for RMW.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
index 9a48a4f..bf9707e 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
@@ -231,7 +231,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
MPI_Allgather(&end_offset, 1, ADIO_OFFSET, end_offsets, 1,
ADIO_OFFSET, fd->comm);
if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
- MPI_Allgather(&count_sizes, 1, ADIO_OFFSET, count_sizes, 1,
+ MPI_Allgather(&my_count_size, 1, ADIO_OFFSET, count_sizes, 1,
ADIO_OFFSET, fd->comm);
}
}
@@ -389,7 +389,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
romio_onesided_always_rmw = 1;
int prev_romio_onesided_no_rmw = romio_onesided_no_rmw;
romio_onesided_no_rmw = 1;
- ADIOI_OneSidedWriteAggregation(fd, offset_list, len_list, contig_access_count, buf, datatype, error_code, st_offsets, end_offsets, currentValidDataIndex, fd_start, fd_end, &holeFound, noStripeParms);
+ ADIOI_OneSidedWriteAggregation(fd, offset_list, len_list, contig_access_count, buf, datatype, error_code, firstFileOffset, lastFileOffset, currentValidDataIndex, fd_start, fd_end, &holeFound, noStripeParms);
romio_onesided_no_rmw = prev_romio_onesided_no_rmw;
GPFSMPIO_T_CIO_REPORT( 1, fd, myrank, nprocs)
ADIOI_Free(offset_list);
http://git.mpich.org/mpich.git/commitdiff/28d1b074f135173c79244c2ce92e8b519…
commit 28d1b074f135173c79244c2ce92e8b5197af00da
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Thu Mar 24 21:20:14 2016 -0700
ROMIO Onesided write aggregation enhancements to support file striping
The algorithm has been extended to support multiple calls for a single
one-sided collective write operation for a file system utilizing
striping. The algorithm can now be called once for each segment of
data, a segment being defined as a contiguous region of the file which
has up to one occurrence of each stripe - the data for each stripe
being written out by a particular aggregator. The parameters for
ADIOI_OneSidedWriteAggregation have changed slightly - pushing the
computation of the first and last file offsets to the caller to avoid
re-computation of this based on the offset list and an extra parm for
a striping parameters data structure. The call from GPFS therefore
needed to change to support this new definition, but indicating that
no striping was enabled via the striping parameter. Each call for a
striping file system effectively packs one striping unit of data into
the collective buffer on each agg, with additional parameters which
govern flushing the collective buffer to the file. In practice the
collective write for a file system such as lustre on a dataset
composed of multiple segments would call the algorithm several times
without a flush parameter to fill the collective buffers with multiple
stripes of data, before calling it again to flush the collective buffer
to the file system. In this fashion the synchronization can be
minimized as that only needs to occur around the actual read from or
write to the file system.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
index 0e1d6b6..9a48a4f 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
@@ -286,6 +286,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
done by (logically) dividing the file into file domains (FDs); each
process may directly access only its own file domain. */
+ ADIO_Offset lastFileOffset = 0, firstFileOffset = -1;
int currentValidDataIndex = 0;
if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
/* Take out the 0-data offsets by shifting the indexes with data to the front
@@ -295,6 +296,12 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
if (count_sizes[i] > 0) {
st_offsets[currentValidDataIndex] = st_offsets[i];
end_offsets[currentValidDataIndex] = end_offsets[i];
+ lastFileOffset = MPL_MAX(lastFileOffset,end_offsets[currentValidDataIndex]);
+ if (firstFileOffset == -1)
+ firstFileOffset = st_offsets[currentValidDataIndex];
+ else
+ firstFileOffset = MPL_MIN(firstFileOffset,st_offsets[currentValidDataIndex]);
+
currentValidDataIndex++;
}
}
@@ -337,10 +344,22 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
/* If the user has specified to use a one-sided aggregation method then do that at
* this point instead of the two-phase I/O.
*/
+ /* pass this datastructure to indicate we are a non-striping filesystem
+ * to the onesided algorithm by setting stripe size to 0.
+ */
+ ADIOI_OneSidedStripeParms noStripeParms;
+ noStripeParms.stripeSize = 0;
+ noStripeParms.segmentLen = 0;
+ noStripeParms.stripesPerAgg = 0;
+ noStripeParms.segmentIter = 0;
+ noStripeParms.flushCB = 1;
+ noStripeParms.stripedLastFileOffset = 0;
+ noStripeParms.firstStripedWriteCall = 0;
+ noStripeParms.lastStripedWriteCall = 0;
int holeFound = 0;
ADIOI_OneSidedWriteAggregation(fd, offset_list, len_list, contig_access_count,
- buf, datatype, error_code, st_offsets, end_offsets,
- currentValidDataIndex, fd_start, fd_end, &holeFound);
+ buf, datatype, error_code, firstFileOffset, lastFileOffset,
+ currentValidDataIndex, fd_start, fd_end, &holeFound, noStripeParms);
int anyHolesFound = 0;
if (!romio_onesided_no_rmw)
MPI_Allreduce(&holeFound, &anyHolesFound, 1, MPI_INT, MPI_MAX, fd->comm);
@@ -366,11 +385,11 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
if (romio_onesided_inform_rmw && (myrank ==0))
FPRINTF(stderr,"Information: Holes found during one-sided "
"write aggregation algorithm --- re-running one-sided "
- "write aggregation with GPFSMPIO_ONESIDED_ALWAYS_RMW set to 1.\n");
+ "write aggregation with ROMIO_ONESIDED_ALWAYS_RMW set to 1.\n");
romio_onesided_always_rmw = 1;
int prev_romio_onesided_no_rmw = romio_onesided_no_rmw;
romio_onesided_no_rmw = 1;
- ADIOI_OneSidedWriteAggregation(fd, offset_list, len_list, contig_access_count, buf, datatype, error_code, st_offsets, end_offsets, currentValidDataIndex, fd_start, fd_end, &holeFound);
+ ADIOI_OneSidedWriteAggregation(fd, offset_list, len_list, contig_access_count, buf, datatype, error_code, st_offsets, end_offsets, currentValidDataIndex, fd_start, fd_end, &holeFound, noStripeParms);
romio_onesided_no_rmw = prev_romio_onesided_no_rmw;
GPFSMPIO_T_CIO_REPORT( 1, fd, myrank, nprocs)
ADIOI_Free(offset_list);
diff --git a/src/mpi/romio/adio/common/onesided_aggregation.c b/src/mpi/romio/adio/common/onesided_aggregation.c
index c96b8bf..1445000 100644
--- a/src/mpi/romio/adio/common/onesided_aggregation.c
+++ b/src/mpi/romio/adio/common/onesided_aggregation.c
@@ -16,7 +16,30 @@
// #define onesidedtrace 1
-
+/* Data that needs to persist throughout multiple calls to ADIOI_OneSidedWriteAggregation
+ * to support file systems that stripe data -- the algorithm can now be called once
+ * for each segment of data, a segment being defined as a contiguous region of the file which
+ * is the size of one striping unit times the number of aggregators. Each call effectively packs one
+ * striping unit of data into the collective buffer on each agg, with additional parameters which govern when to flush
+ * the collective buffer to the file. Therefore in practice the collective write call for a file system such as
+ * lustre on a dataset composed of multiple segments would call the algorithm several times without a
+ * flush parameter to fill the collective buffers with multiple stripes of data, before calling it again to flush
+ * the collective buffer to the file system. In this fashion the synchronization can be minimized as that
+ * only needs to occur during the actual read from or write to the file system.
+ */
+int iWasUsedStripingAgg; /* whether this rank was ever a used agg for this striping segement */
+int numStripesUsed; /* the number of stripes packed into an aggregator */
+/* These 2 variables are the offset and lengths in the file corresponding to the actual stripes */
+ADIO_Offset *stripeWriteOffsets, *stripeWriteLens;
+int amountOfStripedDataExpected; /* used to determine holes in this segment thereby requiring a rmw */
+/* Since ADIOI_OneSidedWriteAggregation can be called multiple times now only flatten the buffer once */
+/* for optimal performance so persist these two variables through multiple calls */
+MPI_Aint bufTypeExtent;
+ADIOI_Flatlist_node *flatBuf;
+/* These three variables track the state of the source buffer advancement through multiple calls */
+int lastDataTypeExtent;
+int lastFlatBufIndice;
+ADIO_Offset lastIndiceOffset;
/* This data structure holds the number of extents, the index into the flattened buffer and the remnant length
* beyond the flattened buffer index corresponding to the base buffer offset for non-contiguous source data
* for the range to be written coresponding to the round and target agg.
@@ -49,7 +72,6 @@ typedef struct FDSourceBufferState {
} FDSourceBufferState;
-
static int ADIOI_OneSidedSetup(ADIO_File fd, int procs) {
int ret = MPI_SUCCESS;
@@ -59,6 +81,7 @@ static int ADIOI_OneSidedSetup(ADIO_File fd, int procs) {
fd->io_buf_put_amounts = 0;
ret =MPI_Win_create(&(fd->io_buf_put_amounts),sizeof(int),sizeof(int),
MPI_INFO_NULL,fd->comm, &fd->io_buf_put_amounts_window);
+
fn_exit:
return ret;
}
@@ -182,16 +205,19 @@ void ADIOI_OneSidedWriteAggregation(ADIO_File fd,
const void *buf,
MPI_Datatype datatype,
int *error_code,
- ADIO_Offset *st_offsets,
- ADIO_Offset *end_offsets,
+ ADIO_Offset firstFileOffset,
+ ADIO_Offset lastFileOffset,
int numNonZeroDataOffsets,
ADIO_Offset *fd_start,
ADIO_Offset* fd_end,
- int *hole_found)
+ int *hole_found,
+ ADIOI_OneSidedStripeParms stripe_parms)
{
int i,j; /* generic iterators */
+ if ((stripe_parms.stripeSize > 0) && stripe_parms.firstStripedWriteCall)
+ iWasUsedStripingAgg = 0;
#ifdef onesidedtrace
if (buf == NULL) {
printf("ADIOI_OneSidedWriteAggregation - buf is NULL contig_access_count is %d\n",contig_access_count);
@@ -244,14 +270,15 @@ printf("ADIOI_OneSidedWriteAggregation started on rank %d\n",myrank);
*/
int bufTypeIsContig;
- MPI_Aint bufTypeExtent;
- ADIOI_Flatlist_node *flatBuf=NULL;
ADIOI_Datatype_iscontig(datatype, &bufTypeIsContig);
if (!bufTypeIsContig) {
/* Flatten the non-contiguous source datatype and set the extent. */
- flatBuf = ADIOI_Flatten_and_find(datatype);
- MPI_Type_extent(datatype, &bufTypeExtent);
+ if ((stripe_parms.stripeSize == 0) || stripe_parms.firstStripedWriteCall) {
+ flatBuf = ADIOI_Flatten_and_find(datatype);
+ MPI_Type_extent(datatype, &bufTypeExtent);
+ }
+
#ifdef onesidedtrace
printf("flatBuf->count is %d bufTypeExtent is %d\n", flatBuf->count,bufTypeExtent);
for (i=0;i<flatBuf->count;i++)
@@ -272,9 +299,9 @@ printf("ADIOI_OneSidedWriteAggregation started on rank %d\n",myrank);
#ifdef onesidedtrace
printf("sizeof(FDSourceBufferState) is %d - make sure is 32 for 32-byte memalign optimal\n",sizeof(FDSourceBufferState));
#endif
- FDSourceBufferState *currentFDSourceBufferState;
- currentFDSourceBufferState = (FDSourceBufferState *) ADIOI_Malloc(naggs * sizeof(FDSourceBufferState));
+ FDSourceBufferState *currentFDSourceBufferState = (FDSourceBufferState *) ADIOI_Malloc(naggs * sizeof(FDSourceBufferState));
+
for (i=0;i<naggs;i++) {
/* initialize based on the bufType to indicate that it is unset.
*/
@@ -295,27 +322,17 @@ printf("ADIOI_OneSidedWriteAggregation started on rank %d\n",myrank);
*/
int maxNumContigOperations = contig_access_count;
- ADIO_Offset lastFileOffset = 0, firstFileOffset = -1;
- /* Get the total range being written - in the case of just 1 byte the starting and ending offsets
- * will match the same as they would for 0 bytes so to distinguish we need the actual data count.
- */
- for (j=0;j<numNonZeroDataOffsets;j++) {
-#ifdef onesidedtrace
-printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_offsets[j]);
-#endif
- lastFileOffset = MPL_MAX(lastFileOffset,end_offsets[j]);
- if (firstFileOffset == -1)
- firstFileOffset = st_offsets[j];
- else
- firstFileOffset = MPL_MIN(firstFileOffset,st_offsets[j]);
- }
-
int myAggRank = -1; /* if I am an aggregor this is my index into fd->hints->ranklist */
int iAmUsedAgg = 0; /* whether or not this rank is used as an aggregator. */
/* Make coll_bufsize an ADIO_Offset since it is used in calculations with offsets.
*/
- ADIO_Offset coll_bufsize = (ADIO_Offset)(fd->hints->cb_buffer_size);
+ ADIO_Offset coll_bufsize = 0;
+ if (stripe_parms.stripeSize == 0)
+ coll_bufsize = (ADIO_Offset)(fd->hints->cb_buffer_size);
+ else
+ coll_bufsize = stripe_parms.stripeSize;
+
#ifdef ROMIO_GPFS
if (gpfsmpio_pthreadio == 1) {
/* split buffer in half for a kind of double buffering with the threads*/
@@ -342,6 +359,7 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
myAggRank = j;
if (fd_end[j] > fd_start[j]) {
iAmUsedAgg = 1;
+ iWasUsedStripingAgg = 1;
}
}
}
@@ -406,6 +424,16 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
int currentFlatBufIndice=0;
ADIO_Offset currentIndiceOffset = 0;
+ /* Remember where we left off in the source buffer when packing stripes. */
+ if ((stripe_parms.stripeSize > 0) && !stripe_parms.firstStripedWriteCall) {
+ currentDataTypeExtent = lastDataTypeExtent;
+ currentFlatBufIndice = lastFlatBufIndice;
+ currentIndiceOffset = lastIndiceOffset;
+#ifdef onesidedtrace
+ printf("using lastDataTypeExtent %d lastFlatBufIndice %d lastIndiceOffset %ld\n",lastDataTypeExtent,lastFlatBufIndice,lastIndiceOffset);
+#endif
+ }
+
/* This denotes the coll_bufsize boundaries within the source buffer for writing for the same round.
*/
ADIO_Offset intraRoundCollBufsizeOffset = 0;
@@ -592,8 +620,7 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
ADIO_Offset amountToAdvanceSBOffsetForFD = 0;
int additionalFDCounter = 0;
- while (blockEnd >= fd_end[currentAggRankListIndex]) {
- ADIO_Offset thisAggBlockEnd = fd_end[currentAggRankListIndex];
+ while (blockEnd > fd_end[currentAggRankListIndex]) { ADIO_Offset thisAggBlockEnd = fd_end[currentAggRankListIndex];
if (thisAggBlockEnd >= intraRoundCollBufsizeOffset) {
while (thisAggBlockEnd >= intraRoundCollBufsizeOffset) {
targetAggsForMyDataCurrentRoundIter[numTargetAggs]++;
@@ -706,10 +733,11 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
additionalFDCounter++;
#ifdef onesidedtrace
- printf("block extended beyond fd init settings numTargetAggs %d offset_list[%d] with value %ld past fd border %ld with len %ld\n",numTargetAggs,i,offset_list[blockIter],fd_start[currentAggRankListIndex],len_list[blockIter]);
+ printf("block extended beyond fd init settings numTargetAggs %d offset_list[%d] with value %ld past fd border %ld with len %ld\n",numTargetAggs,blockIter,offset_list[blockIter],fd_start[currentAggRankListIndex],len_list[blockIter]);
#endif
intraRoundCollBufsizeOffset = fd_start[currentAggRankListIndex] + coll_bufsize;
targetAggsForMyDataLastOffLenIndex[targetAggsForMyDataCurrentRoundIter[numTargetAggs]][numTargetAggs] = blockIter;
+
} // if (blockEnd >= fd_start[currentAggRankListIndex])
} // while (blockEnd >= fd_end[currentAggRankListIndex])
} // if (blockEnd > fd_end[currentAggRankListIndex])
@@ -780,6 +808,7 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
if (iAmUsedAgg) {
currentRoundFDStart = fd_start[myAggRank];
+ currentRoundFDEnd = fd_end[myAggRank];
if (myAggRank == smallestFileDomainAggRank) {
if (currentRoundFDStart < firstFileOffset)
currentRoundFDStart = firstFileOffset;
@@ -791,7 +820,49 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
#ifdef onesidedtrace
printf("iAmUsedAgg - currentRoundFDStart initialized to %ld currentRoundFDEnd to %ld\n",currentRoundFDStart,currentRoundFDEnd);
#endif
- if (romio_onesided_always_rmw) { // read in the first buffer
+
+ if ((stripe_parms.stripeSize > 0) && (stripe_parms.segmentIter == 0)) {
+ numStripesUsed = 0;
+ stripeWriteOffsets = (ADIO_Offset *) ADIOI_Malloc(stripe_parms.stripesPerAgg*sizeof(ADIO_Offset));
+ stripeWriteLens = (ADIO_Offset *) ADIOI_Malloc(stripe_parms.stripesPerAgg*sizeof(ADIO_Offset));
+ amountOfStripedDataExpected = 0;
+ int stripeIter = 0;
+ for (stripeIter=0;stripeIter<stripe_parms.stripesPerAgg;stripeIter++) {
+ if (stripeIter == 0) {
+ stripeWriteOffsets[stripeIter] = currentRoundFDStart;
+ stripeWriteLens[stripeIter] = (int)(currentRoundFDEnd - currentRoundFDStart)+1;
+ amountOfStripedDataExpected += (int)(currentRoundFDEnd - currentRoundFDStart)+1;
+ numStripesUsed++;
+ }
+ else {
+ if (((currentRoundFDEnd + (ADIO_Offset)1 + ((ADIO_Offset)stripeIter * stripe_parms.segmentLen))) > stripe_parms.stripedLastFileOffset) {
+ if (((currentRoundFDEnd + (ADIO_Offset)1 - (ADIO_Offset)(stripe_parms.stripeSize) + ((ADIO_Offset)stripeIter * stripe_parms.segmentLen))) <= stripe_parms.stripedLastFileOffset) {
+ stripeWriteOffsets[stripeIter] = (currentRoundFDEnd + (ADIO_Offset)1) - (ADIO_Offset)(stripe_parms.stripeSize) + ((ADIO_Offset)stripeIter * stripe_parms.segmentLen);
+ stripeWriteLens[stripeIter] = (int)(stripe_parms.stripedLastFileOffset - (currentRoundFDEnd + (ADIO_Offset)1 - (ADIO_Offset)(stripe_parms.stripeSize) + ((ADIO_Offset)stripeIter * stripe_parms.segmentLen)) + (ADIO_Offset)1);
+ amountOfStripedDataExpected += (int)(stripe_parms.stripedLastFileOffset - (currentRoundFDEnd + (ADIO_Offset)1 - (ADIO_Offset)(stripe_parms.stripeSize) + ((ADIO_Offset)stripeIter * stripe_parms.segmentLen)) + (ADIO_Offset)1);
+ numStripesUsed++;
+ }
+ }
+ else {
+ stripeWriteOffsets[stripeIter] = (currentRoundFDEnd + (ADIO_Offset)1) - (ADIO_Offset)(stripe_parms.stripeSize) + ((ADIO_Offset)stripeIter * stripe_parms.segmentLen);
+ stripeWriteLens[stripeIter] = stripe_parms.stripeSize;
+ amountOfStripedDataExpected += stripe_parms.stripeSize;
+ numStripesUsed++;
+ }
+ }
+ } // for-loop
+
+#ifdef onesidedtrace
+ printf("amountOfStripedDataExpected is %d numStripesUsed is %d offsets and lengths are ",amountOfStripedDataExpected,numStripesUsed);
+ for (i=0;i<numStripesUsed;i++) {
+ printf("%ld %ld --",stripeWriteOffsets[i],stripeWriteLens[i]);
+ }
+ printf("\n");
+#endif
+ } // if ((stripe_parms.stripeSize>0) && (stripe_parms.segmentIter==0))
+
+
+ if (romio_onesided_always_rmw && ((stripe_parms.stripeSize==0) || (stripe_parms.segmentIter==0))) { // read in the first buffer
ADIO_Offset tmpCurrentRoundFDEnd = 0;
if ((fd_end[myAggRank] - currentRoundFDStart) < coll_bufsize) {
if (myAggRank == greatestFileDomainAggRank) {
@@ -808,12 +879,21 @@ printf("iAmUsedAgg - currentRoundFDStart initialized to %ld currentRoundFDEnd to
#ifdef onesidedtrace
printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld to %ld total is %d\n",currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
#endif
- ADIO_ReadContig(fd, write_buf, (int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1,
- MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
+ if (stripe_parms.stripeSize==0) {
+ ADIO_ReadContig(fd, write_buf, (int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1,
+ MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
+ }
+ else {
+ // pre-read the entire batch of stripes we will do before writing
+ int stripeIter = 0;
+ for (stripeIter=0;stripeIter<numStripesUsed;stripeIter++)
+ ADIO_ReadContig(fd, (char*)write_buf + ((ADIO_Offset)stripeIter * (ADIO_Offset)stripe_parms.stripeSize), stripeWriteLens[stripeIter],
+ MPI_BYTE, ADIO_EXPLICIT_OFFSET,stripeWriteOffsets[stripeIter], &status, error_code);
+ }
}
- }
- if (romio_onesided_always_rmw) // wait until the first buffer is read
+ } // if iAmUsedAgg
+ if (romio_onesided_always_rmw && ((stripe_parms.stripeSize == 0) || (stripe_parms.segmentIter == 0))) // wait until the first buffer is read
MPI_Barrier(fd->comm);
#ifdef ROMIO_GPFS
@@ -822,6 +902,7 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
startTimeBase = MPI_Wtime();
#endif
+
/* This is the second main loop of the algorithm, actually nested loop of target aggs within rounds. There are 2 flavors of this.
* For romio_write_aggmethod of 1 each nested iteration for the target
* agg does an mpi_put on a contiguous chunk using a primative datatype
@@ -938,7 +1019,7 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
/* Determine the offset into the target window.
*/
- MPI_Aint targetDisplacementToUseThisRound = (MPI_Aint) (offsetStart - currentRoundFDStartForMyTargetAgg);
+ MPI_Aint targetDisplacementToUseThisRound = (MPI_Aint) (offsetStart - currentRoundFDStartForMyTargetAgg) + ((MPI_Aint)(stripe_parms.segmentIter)*(MPI_Aint)(stripe_parms.stripeSize));
/* If using the thread writer select the appropriate side of the split window.
*/
@@ -961,6 +1042,7 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
putSourceData = (char *) ADIOI_Malloc(bufferAmountToSend*sizeof(char));
nonContigSourceDataBufferAdvance(((char*)buf), flatBuf, bufferAmountToSend, 1, ¤tFDSourceBufferState[aggIter], putSourceData);
MPI_Put(putSourceData,bufferAmountToSend, MPI_BYTE,targetAggsForMyData[aggIter],targetDisplacementToUseThisRound, bufferAmountToSend,MPI_BYTE,write_buf_window);
+
}
MPI_Win_unlock(targetAggsForMyData[aggIter], write_buf_window);
if (!bufTypeIsContig)
@@ -992,7 +1074,7 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
}
}
#ifdef onesidedtrace
- printf("roundIter %d bufferAmountToSend is %d offsetStart is %ld currentRoundFDStartForMyTargetAgg is %ld targetDisplacementToUseThisRound is %ld targetAggsForMyDataFDStart[aggIter] is %ld\n",roundIter, bufferAmountToSend, offsetStart,currentRoundFDStartForMyTargetAgg,targetDisplacementToUseThisRound,targetAggsForMyDataFDStart[aggIter]);
+ printf("roundIter %d bufferAmountToSend is %d offsetStart is %ld currentRoundFDStartForMyTargetAgg is %ld currentRoundFDEndForMyTargetAgg is %ld targetDisplacementToUseThisRound is %ld targetAggsForMyDataFDStart[aggIter] is %ld\n",roundIter, bufferAmountToSend, offsetStart,currentRoundFDStartForMyTargetAgg,currentRoundFDEndForMyTargetAgg,targetDisplacementToUseThisRound,targetAggsForMyDataFDStart[aggIter]);
#endif
} // bufferAmountToSend > 0
@@ -1045,16 +1127,33 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
}
} // baseoffset != -1
} // target aggs
- } /// contig_access_count > 0
+
+ if (stripe_parms.stripeSize > 0) {
+ lastDataTypeExtent = currentFDSourceBufferState[numTargetAggs-1].dataTypeExtent;
+ lastFlatBufIndice = currentFDSourceBufferState[numTargetAggs-1].flatBufIndice;
+ lastIndiceOffset = currentFDSourceBufferState[numTargetAggs-1].indiceOffset;
#ifdef onesidedtrace
-printf("first barrier roundIter %d\n",roundIter);
+printf("setting lastDataTypeExtent %d lastFlatBufIndice %d lastIndiceOffset %ld\n",lastDataTypeExtent,lastFlatBufIndice,lastIndiceOffset);
#endif
- MPI_Barrier(fd->comm);
- if (iAmUsedAgg) {
+ }
+
+ } /// contig_access_count > 0
+
+ /* Synchronize all procs before the file write */
+ if ((stripe_parms.stripeSize == 0) || (stripe_parms.flushCB)) {
+#ifdef onesidedtrace
+ printf("first barrier roundIter %d\n",roundIter);
+#endif
+ MPI_Barrier(fd->comm);
+ }
+
+ if ((iAmUsedAgg || iWasUsedStripingAgg) && ((stripe_parms.stripeSize == 0) || (stripe_parms.flushCB))) {
+ iWasUsedStripingAgg = 0;
/* Determine what offsets define the portion of the file domain the agg is writing this round.
*/
+ if (iAmUsedAgg) {
if ((fd_end[myAggRank] - currentRoundFDStart) < coll_bufsize) {
if (myAggRank == greatestFileDomainAggRank) {
if (fd_end[myAggRank] > lastFileOffset)
@@ -1069,23 +1168,59 @@ printf("first barrier roundIter %d\n",roundIter);
currentRoundFDEnd = currentRoundFDStart + coll_bufsize - (ADIO_Offset)1;
#ifdef onesidedtrace
- printf("used agg about to writecontig - currentRoundFDStart is %ld currentRoundFDEnd is %ld within file domeain %ld to %ld\n",currentRoundFDStart,currentRoundFDEnd,fd_start[myAggRank],fd_end[myAggRank]);
+ printf("current used agg about to writecontig - currentRoundFDStart is %ld currentRoundFDEnd is %ld within file domeain %ld to %ld\n",currentRoundFDStart,currentRoundFDEnd,fd_start[myAggRank],fd_end[myAggRank]);
+#endif
+ }
+#ifdef onesidedtrace
+ else {
+ printf("former used agg about to writecontig\n");
+ }
#endif
-
int doWriteContig = 1;
if (!romio_onesided_no_rmw) {
- if (fd->io_buf_put_amounts != ((int)(currentRoundFDEnd - currentRoundFDStart)+1)) {
- doWriteContig = 0;
- *hole_found = 1;
+ if (stripe_parms.stripeSize == 0) {
+ if (fd->io_buf_put_amounts != ((int)(currentRoundFDEnd - currentRoundFDStart)+1)) {
+ doWriteContig = 0;
+ *hole_found = 1;
+#ifdef onesidedtrace
+ printf("hole found --- fd->io_buf_put_amounts is %d currentRoundFDEnd is %ld currentRoundFDStart is %ld on roundIter %d\n",fd->io_buf_put_amounts,currentRoundFDEnd,currentRoundFDStart,roundIter);
+#endif
+ }
+ }
+ else { // file striping
+ if (fd->io_buf_put_amounts != amountOfStripedDataExpected) {
+ doWriteContig = 0;
+ *hole_found = 1;
+#ifdef onesidedtrace
+ printf("striping hole found --- fd->io_buf_put_amounts is %d amountOfStripedDataExpected is %d on roundIter %d\n",fd->io_buf_put_amounts,amountOfStripedDataExpected,roundIter);
+#endif
+ }
}
fd->io_buf_put_amounts = 0;
}
if (!useIOBuffer) {
- if (doWriteContig)
- ADIO_WriteContig(fd, write_buf, (int)(currentRoundFDEnd - currentRoundFDStart)+1,
- MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
-
+ if (doWriteContig) {
+ if (stripe_parms.stripeSize > 0) {
+#ifdef onesidedtrace
+ printf("about to write out %d stripes\n",numStripesUsed);
+#endif
+ int stripeIter = 0;
+ for (stripeIter=0;stripeIter<numStripesUsed;stripeIter++) {
+#ifdef onesidedtrace
+ printf("writing write_buf offset %ld len %ld file offset %ld\n",((ADIO_Offset)stripeIter * (ADIO_Offset)(stripe_parms.stripeSize)),stripeWriteLens[stripeIter],stripeWriteOffsets[stripeIter]);
+#endif
+ ADIO_WriteContig(fd, (char*)write_buf + ((ADIO_Offset)stripeIter * (ADIO_Offset)(stripe_parms.stripeSize)), stripeWriteLens[stripeIter],
+ MPI_BYTE, ADIO_EXPLICIT_OFFSET,stripeWriteOffsets[stripeIter], &status, error_code);
+ }
+ ADIOI_Free(stripeWriteLens);
+ ADIOI_Free(stripeWriteOffsets);
+ }
+ else {
+ ADIO_WriteContig(fd, write_buf, (int)(currentRoundFDEnd - currentRoundFDStart)+1,
+ MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
+ }
+ }
} else { /* use the thread writer */
if(!pthread_equal(io_thread, pthread_self())) {
@@ -1113,7 +1248,8 @@ printf("first barrier roundIter %d\n",roundIter);
io_thread_args.io_kind = ADIOI_WRITE;
io_thread_args.size = (currentRoundFDEnd-currentRoundFDStart) + 1;
io_thread_args.offset = currentRoundFDStart;
- io_thread_args.status = &status;
+ ADIO_Status adio_status;
+ io_thread_args.status = &adio_status;
io_thread_args.error_code = *error_code;
if ( (pthread_create(&io_thread, NULL,
@@ -1124,7 +1260,7 @@ printf("first barrier roundIter %d\n",roundIter);
} // iAmUsedAgg
- if (!iAmUsedAgg && useIOBuffer) {
+ if (!iAmUsedAgg && useIOBuffer && ((stripe_parms.stripeSize == 0) || (stripe_parms.flushCB))) {
if (currentWriteBuf == 0) {
currentWriteBuf = 1;
write_buf = write_buf1;
@@ -1135,7 +1271,7 @@ printf("first barrier roundIter %d\n",roundIter);
}
}
- if (iAmUsedAgg) {
+ if (iAmUsedAgg && stripe_parms.stripeSize == 0) {
currentRoundFDStart += coll_bufsize;
if (romio_onesided_always_rmw && (roundIter<(numberOfRounds-1))) { // read in the buffer for the next round unless this is the last round
@@ -1153,7 +1289,7 @@ printf("first barrier roundIter %d\n",roundIter);
else
tmpCurrentRoundFDEnd = currentRoundFDStart + coll_bufsize - (ADIO_Offset)1;
#ifdef onesidedtrace
-printf("romio_onesided_always_rmw - round %d buffer pre-read for file offsets %ld to %ld total is %d\n",roundIter, currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
+ printf("romio_onesided_always_rmw - round %d buffer pre-read for file offsets %ld to %ld total is %d\n",roundIter, currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
#endif
ADIO_ReadContig(fd, write_buf, (int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1,
MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
@@ -1163,7 +1299,7 @@ printf("romio_onesided_always_rmw - round %d buffer pre-read for file offsets %l
if (roundIter<(numberOfRounds-1)) {
#ifdef onesidedtrace
-printf("second barrier roundIter %d\n",roundIter);
+printf("second barrier roundIter %d --- waiting in loop this time\n",roundIter);
#endif
MPI_Barrier(fd->comm);
}
diff --git a/src/mpi/romio/adio/include/adioi.h b/src/mpi/romio/adio/include/adioi.h
index e6a80b6..bea225d 100644
--- a/src/mpi/romio/adio/include/adioi.h
+++ b/src/mpi/romio/adio/include/adioi.h
@@ -692,6 +692,28 @@ void ADIOI_P2PContigReadAggregation(ADIO_File fd,
ADIO_Offset *fd_start,
ADIO_Offset *fd_end);
+/* This data structure holds parameters releated to file */
+/* striping needed by the one-sided aggregation algorithm. */
+/* A stripeSize of 0 indicates there is no striping. */
+typedef struct ADIOI_OneSidedStripeParms {
+ int stripeSize; /* size in bytes of the striping unit - a size of 0 indicates to the */
+ /* onesided algorithm that we are a non-striping file system */
+ ADIO_Offset segmentLen; /* size in bytes of the segment (stripeSize*number of aggs) */
+ /* up to the size of the file) */
+ int stripesPerAgg; /* the number of stripes to be packed into an agg cb for this segment */
+ int segmentIter; /* segment number for the group of stripes currently being packed into */
+ /* the agg cb - resets to 0 for each cb flush to the file system */
+ int flushCB; /* once we have fully packed the cb on an agg this flags */
+ /* tells us to now write to the file */
+ ADIO_Offset stripedLastFileOffset; /* since we are now just calling the onesided algorithm */
+ /* with the offset range of segment, we still need to */
+ /* know the actual last offset of the file. */
+ int firstStripedWriteCall; /* whether this is the first call in the first segement of the */
+ /* onesided algorithm. */
+ int lastStripedWriteCall; /* whether this is the last call in the last segement of the */
+ /* onesided algorithm. */
+} ADIOI_OneSidedStripeParms;
+
int ADIOI_OneSidedCleanup(ADIO_File fd);
void ADIOI_OneSidedWriteAggregation(ADIO_File fd,
ADIO_Offset *offset_list,
@@ -700,12 +722,13 @@ void ADIOI_OneSidedWriteAggregation(ADIO_File fd,
const void *buf,
MPI_Datatype datatype,
int *error_code,
- ADIO_Offset *st_offsets,
- ADIO_Offset *end_offsets,
+ ADIO_Offset firstFileOffset,
+ ADIO_Offset lastFileOffset,
int numNonZeroDataOffsets,
ADIO_Offset *fd_start,
ADIO_Offset* fd_end,
- int *hole_found);
+ int *hole_found,
+ ADIOI_OneSidedStripeParms stripe_parms);
void ADIOI_OneSidedReadAggregation(ADIO_File fd,
ADIO_Offset *offset_list,
ADIO_Offset *len_list,
http://git.mpich.org/mpich.git/commitdiff/e474997fd5e859fe363d3b2ce116ca638…
commit e474997fd5e859fe363d3b2ce116ca63868ad3e2
Author: Rob Latham <robl(a)mcs.anl.gov>
Date: Thu Jul 14 13:24:18 2016 -0500
ROMIO Onesided write aggregation utilization for Lustre
The collective write aggregation call for Lustre
(ADIOI_LUSTRE_WriteStridedColl) has been enhanced to utilize
ADIOI_OneSidedWriteAggregation if the one-sided environment
variables are set. The general algorithm is to divide the file up into
segements, a segment being defined as a contiguous region of the file
which has up to one occurrence of each stripe - the data for each
stripe being written out by a particular aggregator. Iteratively call
ADIOI_OneSidedWriteAggregation for each segment to aggregate
the data to the collective buffers, but only do the actual write
once the appropriate number of stripes have been packed (based
on the size of the collective buffer) or the aggregation for all the
data is complete, minimizing synchronization.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/ad_lustre/ad_lustre.h b/src/mpi/romio/adio/ad_lustre/ad_lustre.h
index 5e8f017..27f13e7 100644
--- a/src/mpi/romio/adio/ad_lustre/ad_lustre.h
+++ b/src/mpi/romio/adio/ad_lustre/ad_lustre.h
@@ -29,6 +29,7 @@
#include <sys/ioctl.h>
#include <lustre/lustre_user.h>
#include "adio.h"
+#include "ad_tuning.h"
/*#include "adioi.h"*/
#ifdef HAVE_SIGNAL_H
diff --git a/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c b/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c
index e87f927..0e47e5e 100644
--- a/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c
+++ b/src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c
@@ -42,7 +42,7 @@ static void ADIOI_LUSTRE_W_Exchange_data(ADIO_File fd, const void *buf,
ADIO_Offset *len_list, int *send_size,
int *recv_size, ADIO_Offset off,
int size, int *count,
- int *start_pos,
+ int *start_pos,
int *sent_to_proc, int nprocs,
int myrank, int buftype_is_contig,
int contig_access_count,
@@ -59,6 +59,14 @@ void ADIOI_Heap_merge(ADIOI_Access *others_req, int *count,
ADIO_Offset *srt_off, int *srt_len, int *start_pos,
int nprocs, int nprocs_recv, int total_elements);
+static void ADIOI_LUSTRE_IterateOneSided(ADIO_File fd, const void *buf, int *striping_info,
+ ADIO_Offset *offset_list, ADIO_Offset *len_list,
+ int contig_access_count, int currentValidDataIndex,
+ int count, int file_ptr_type, ADIO_Offset offset,
+ ADIO_Offset start_offset, ADIO_Offset end_offset,
+ ADIO_Offset firstFileOffset, ADIO_Offset lastFileOffset,
+ MPI_Datatype datatype, int myrank, int *error_code);
+
void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
MPI_Datatype datatype,
int file_ptr_type, ADIO_Offset offset,
@@ -88,6 +96,7 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
int *striping_info = NULL;
ADIO_Offset **buf_idx = NULL;
int old_error, tmp_error;
+ ADIO_Offset *count_sizes;
MPI_Comm_size(fd->comm, &nprocs);
MPI_Comm_rank(fd->comm, &myrank);
@@ -113,10 +122,25 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
*/
st_offsets = (ADIO_Offset *) ADIOI_Malloc(nprocs * sizeof(ADIO_Offset));
end_offsets = (ADIO_Offset *) ADIOI_Malloc(nprocs * sizeof(ADIO_Offset));
+ ADIO_Offset my_count_size=0;
+ /* One-sided aggregation needs the amount of data per rank as well because
+ * the difference in starting and ending offsets for 1 byte is 0 the same
+ * as 0 bytes so it cannot be distiguished.
+ */
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
+ count_sizes = (ADIO_Offset *) ADIOI_Malloc(nprocs*sizeof(ADIO_Offset));
+ MPI_Count buftype_size;
+ MPI_Type_size_x(datatype, &buftype_size);
+ my_count_size = (ADIO_Offset) count * (ADIO_Offset)buftype_size;
+ }
MPI_Allgather(&start_offset, 1, ADIO_OFFSET, st_offsets, 1,
ADIO_OFFSET, fd->comm);
MPI_Allgather(&end_offset, 1, ADIO_OFFSET, end_offsets, 1,
ADIO_OFFSET, fd->comm);
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
+ MPI_Allgather(&my_count_size, 1, ADIO_OFFSET, count_sizes, 1,
+ ADIO_OFFSET, fd->comm);
+ }
/* are the accesses of different processes interleaved? */
for (i = 1; i < nprocs; i++)
if ((st_offsets[i] < end_offsets[i-1]) &&
@@ -148,6 +172,8 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
ADIOI_Free(len_list);
ADIOI_Free(st_offsets);
ADIOI_Free(end_offsets);
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2))
+ ADIOI_Free(count_sizes);
}
fd->fp_ind = orig_fp;
@@ -168,8 +194,47 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
return;
}
+ ADIO_Offset lastFileOffset = 0, firstFileOffset = -1;
+ int currentValidDataIndex = 0;
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
+ /* Take out the 0-data offsets by shifting the indexes with data to the front
+ * and keeping track of the valid data index for use as the length.
+ */
+ for (i=0; i<nprocs; i++) {
+ if (count_sizes[i] > 0) {
+ st_offsets[currentValidDataIndex] = st_offsets[i];
+ end_offsets[currentValidDataIndex] = end_offsets[i];
+
+ lastFileOffset = MPL_MAX(lastFileOffset,end_offsets[currentValidDataIndex]);
+ if (firstFileOffset == -1)
+ firstFileOffset = st_offsets[currentValidDataIndex];
+ else
+ firstFileOffset = MPL_MIN(firstFileOffset,st_offsets[currentValidDataIndex]);
+
+ currentValidDataIndex++;
+ }
+ }
+ }
+
/* Get Lustre hints information */
ADIOI_LUSTRE_Get_striping_info(fd, &striping_info, 1);
+ /* If the user has specified to use a one-sided aggregation method then do that at
+ * this point instead of the two-phase I/O.
+ */
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
+
+ ADIOI_LUSTRE_IterateOneSided(fd, buf, striping_info, offset_list, len_list, contig_access_count, currentValidDataIndex, count, file_ptr_type, offset, start_offset, end_offset, firstFileOffset, lastFileOffset, datatype, myrank, error_code);
+
+ ADIOI_Free(offset_list);
+ ADIOI_Free(len_list);
+ ADIOI_Free(st_offsets);
+ ADIOI_Free(end_offsets);
+ ADIOI_Free(count_sizes);
+ ADIOI_Free(striping_info);
+
+ goto fn_exit;
+
+ } // onesided aggregation
/* calculate what portions of the access requests of this process are
* located in which process
@@ -262,6 +327,7 @@ void ADIOI_LUSTRE_WriteStridedColl(ADIO_File fd, const void *buf, int count,
ADIOI_Free(end_offsets);
ADIOI_Free(striping_info);
+fn_exit:
#ifdef HAVE_STATUS_SET_BYTES
if (status) {
MPI_Count bufsize, size;
@@ -982,3 +1048,337 @@ static void ADIOI_LUSTRE_Fill_send_buffer(ADIO_File fd, const void *buf,
if (send_size[i])
sent_to_proc[i] = curr_to_proc[i];
}
+
+/* This function calls ADIOI_OneSidedWriteAggregation iteratively to
+ * essentially pack stripes of data into the collective buffer and then
+ * flush the collective buffer to the file when fully packed, repeating this
+ * process until all the data is written to the file.
+ */
+static void ADIOI_LUSTRE_IterateOneSided(ADIO_File fd, const void *buf, int *striping_info,
+ ADIO_Offset *offset_list, ADIO_Offset *len_list,
+ int contig_access_count, int currentValidDataIndex,
+ int count, int file_ptr_type, ADIO_Offset offset,
+ ADIO_Offset start_offset, ADIO_Offset end_offset,
+ ADIO_Offset firstFileOffset, ADIO_Offset lastFileOffset,
+ MPI_Datatype datatype, int myrank, int *error_code)
+{
+ int i;
+ int stripesPerAgg = fd->hints->cb_buffer_size/striping_info[0];
+ if (stripesPerAgg == 0) {
+ /* The striping unit is larger than the collective buffer size
+ * therefore we must abort since the buffer has already been
+ * allocated during the open.
+ */
+ FPRINTF(stderr,"Error: The collective buffer size %d is less "
+ "than the striping unit size %d - the ROMIO "
+ "Lustre one-sided write aggregation algorithm "
+ "cannot continue.\n",fd->hints->cb_buffer_size,striping_info[0]);
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ /* The maximum number of aggregators we can use is the number of
+ * stripes used in the file - each agg writes exactly 1 stripe.
+ */
+ int numStripedAggs = striping_info[2];
+
+ int orig_cb_nodes = fd->hints->cb_nodes;
+ if (fd->hints->cb_nodes > numStripedAggs)
+ fd->hints->cb_nodes = numStripedAggs;
+ else if (fd->hints->cb_nodes < numStripedAggs)
+ numStripedAggs = fd->hints->cb_nodes;
+
+ /* Declare ADIOI_OneSidedStripeParms here as some fields will not change.
+ */
+ ADIOI_OneSidedStripeParms stripeParms;
+ stripeParms.stripeSize = striping_info[0];
+ stripeParms.stripedLastFileOffset = lastFileOffset;
+
+ /* The general algorithm here is to divide the file up into segements, a segment
+ * being defined as a contiguous region of the file which has up to one occurrence
+ * of each stripe - the data for each stripe being written out by a particular
+ * aggregator. The segmentLen is the maximum size in bytes of each segment
+ * (stripeSize*number of aggs). Iteratively call ADIOI_OneSidedWriteAggregation
+ * for each segment to aggregate the data to the collective buffers, but only do
+ * the actual write (via flushCB stripe parm) once stripesPerAgg stripes
+ * have been packed or the aggregation for all the data is complete, minimizing
+ * synchronization.
+ */
+ stripeParms.segmentLen = ((ADIO_Offset)numStripedAggs)*((ADIO_Offset)(striping_info[0]));
+ ADIO_Offset totalFileSize = (lastFileOffset-firstFileOffset)+(ADIO_Offset)1;
+
+ /* These arrays define the file offsets for the stripes for a given segment - similar
+ * to the concept of file domains in GPFS, essentially file domeains for the segment.
+ */
+ ADIO_Offset *segment_stripe_start = (ADIO_Offset *) ADIOI_Malloc(numStripedAggs*sizeof(ADIO_Offset));
+ ADIO_Offset *segment_stripe_end = (ADIO_Offset *) ADIOI_Malloc(numStripedAggs*sizeof(ADIO_Offset));
+
+ /* Find the actual range of stripes in the file that have data in the offset
+ * ranges being written -- skip holes at the front and back of the file.
+ */
+ int currentOffsetListIndex = 0;
+ int fileSegmentIter = 0;
+ int startingStripeWithData = 0;
+ int foundStartingStripeWithData = 0;
+ while (!foundStartingStripeWithData) {
+ if ( ((startingStripeWithData+1) * (ADIO_Offset)(striping_info[0])) > firstFileOffset)
+ foundStartingStripeWithData = 1;
+ else
+ startingStripeWithData++;
+ }
+
+ ADIO_Offset currentSegementOffset = (ADIO_Offset)startingStripeWithData * (ADIO_Offset)(striping_info[0]);
+
+ int numSegments = (int) ((lastFileOffset+(ADIO_Offset)1 - currentSegementOffset)/stripeParms.segmentLen);
+ if ((lastFileOffset+(ADIO_Offset)1 - currentSegementOffset)%stripeParms.segmentLen > 0)
+ numSegments++;
+
+ /* To support read-modify-write use a while-loop to redo the aggregation if necessary
+ * to fill in the holes.
+ */
+ int doAggregation = 1;
+ int holeFound = 0;
+
+ /* Remember romio_onesided_no_rmw setting if we have to re-do
+ * the aggregation if holes are found.
+ */
+ int prev_romio_onesided_no_rmw = romio_onesided_no_rmw;
+
+ while (doAggregation) {
+
+ int totalDataWrittenLastRound = 0;
+
+ /* This variable tracks how many segment stripes we have packed into the agg
+ * buffers so we know when to flush to the file system.
+ */
+ stripeParms.segmentIter = 0;
+
+ /* stripeParms.stripesPerAgg is the number of stripes to aggregate before doing a flush.
+ */
+ stripeParms.stripesPerAgg = stripesPerAgg;
+ if (stripeParms.stripesPerAgg > numSegments)
+ stripeParms.stripesPerAgg = numSegments;
+
+ for (fileSegmentIter=0;fileSegmentIter < numSegments;fileSegmentIter++) {
+
+ int dataWrittenThisRound = 0;
+
+ /* Define the segment range in terms of file offsets.
+ */
+ ADIO_Offset segmentFirstFileOffset = currentSegementOffset;
+ if ((currentSegementOffset+stripeParms.segmentLen-(ADIO_Offset)1) > lastFileOffset)
+ currentSegementOffset = lastFileOffset;
+ else
+ currentSegementOffset += (stripeParms.segmentLen-(ADIO_Offset)1);
+ ADIO_Offset segmentLastFileOffset = currentSegementOffset;
+ currentSegementOffset++;
+
+ ADIO_Offset segment_stripe_offset = segmentFirstFileOffset;
+ for (i=0;i<numStripedAggs;i++) {
+ if (firstFileOffset > segmentFirstFileOffset)
+ segment_stripe_start[i] = firstFileOffset;
+ else
+ segment_stripe_start[i] = segment_stripe_offset;
+ if ((segment_stripe_offset + (ADIO_Offset)(striping_info[0])) > lastFileOffset)
+ segment_stripe_end[i] = lastFileOffset;
+ else
+ segment_stripe_end[i] = segment_stripe_offset + (ADIO_Offset)(striping_info[0]) - (ADIO_Offset)1;
+ segment_stripe_offset += (ADIO_Offset)(striping_info[0]);
+ }
+
+ /* In the interest of performance for non-contiguous data with large offset lists
+ * essentially modify the given offset and length list appropriately for this segment
+ * and then pass pointers to the sections of the lists being used for this segment
+ * to ADIOI_OneSidedWriteAggregation. Remember how we have modified the list for this
+ * segment, and then restore it appropriately after processing for this segment has
+ * concluded, so it is ready for the next segment.
+ */
+ int segmentContigAccessCount = 0;
+ int startingOffsetListIndex = -1;
+ int endingOffsetListIndex = -1;
+ ADIO_Offset startingOffsetAdvancement = 0;
+ ADIO_Offset startingLenTrim = 0;
+ ADIO_Offset endingLenTrim = 0;
+
+ while ( ((offset_list[currentOffsetListIndex] + ((ADIO_Offset)(len_list[currentOffsetListIndex]))-(ADIO_Offset)1) < segmentFirstFileOffset) && (currentOffsetListIndex < (contig_access_count-1)))
+ currentOffsetListIndex++;
+ startingOffsetListIndex = currentOffsetListIndex;
+ endingOffsetListIndex = currentOffsetListIndex;
+ int offsetInSegment = 0;
+ ADIO_Offset offsetStart = offset_list[currentOffsetListIndex];
+ ADIO_Offset offsetEnd = (offset_list[currentOffsetListIndex] + ((ADIO_Offset)(len_list[currentOffsetListIndex]))-(ADIO_Offset)1);
+
+ if (len_list[currentOffsetListIndex] == 0)
+ offsetInSegment = 0;
+ else if ((offsetStart >= segmentFirstFileOffset) && (offsetStart <= segmentLastFileOffset)) {
+ offsetInSegment = 1;
+ }
+ else if ((offsetEnd >= segmentFirstFileOffset) && (offsetEnd <= segmentLastFileOffset)) {
+ offsetInSegment = 1;
+ }
+ else if ((offsetStart <= segmentFirstFileOffset) && (offsetEnd >= segmentLastFileOffset)) {
+ offsetInSegment = 1;
+ }
+
+ if (!offsetInSegment) {
+ segmentContigAccessCount = 0;
+ }
+ else {
+ /* We are in the segment, advance currentOffsetListIndex until we are out of segment.
+ */
+ segmentContigAccessCount = 1;
+
+ while ((offset_list[currentOffsetListIndex] <= segmentLastFileOffset) && (currentOffsetListIndex < contig_access_count)) {
+ dataWrittenThisRound += (int) len_list[currentOffsetListIndex];
+ currentOffsetListIndex++;
+ }
+
+ if (currentOffsetListIndex > startingOffsetListIndex) {
+ /* If we did advance, if we are at the end need to check if we are still in segment.
+ */
+ if (currentOffsetListIndex == contig_access_count) {
+ currentOffsetListIndex--;
+ }
+ else if (offset_list[currentOffsetListIndex] > segmentLastFileOffset) {
+ /* We advanced into the last one and it still in the segment.
+ */
+ currentOffsetListIndex--;
+ }
+ else {
+ dataWrittenThisRound += (int) len_list[currentOffsetListIndex];
+ }
+ segmentContigAccessCount += (currentOffsetListIndex-startingOffsetListIndex);
+ endingOffsetListIndex = currentOffsetListIndex;
+ }
+ }
+
+ if (segmentContigAccessCount > 0) {
+ /* Trim edges here so all data in the offset list range fits exactly in the segment.
+ */
+ if (offset_list[startingOffsetListIndex] < segmentFirstFileOffset) {
+ startingOffsetAdvancement = segmentFirstFileOffset-offset_list[startingOffsetListIndex];
+ offset_list[startingOffsetListIndex] += startingOffsetAdvancement;
+ dataWrittenThisRound -= (int) startingOffsetAdvancement;
+ startingLenTrim = startingOffsetAdvancement;
+ len_list[startingOffsetListIndex] -= startingLenTrim;
+ }
+
+ if ((offset_list[endingOffsetListIndex] + ((ADIO_Offset)(len_list[endingOffsetListIndex]))-(ADIO_Offset)1) > segmentLastFileOffset) {
+ endingLenTrim = offset_list[endingOffsetListIndex]+ ((ADIO_Offset)(len_list[endingOffsetListIndex]))-(ADIO_Offset)1 - segmentLastFileOffset;
+ len_list[endingOffsetListIndex] -= endingLenTrim;
+ dataWrittenThisRound -= (int) endingLenTrim;
+ }
+ }
+
+ int holeFoundThisRound = 0;
+
+ /* Once we have packed the collective buffers do the actual write.
+ */
+ if ((stripeParms.segmentIter == (stripeParms.stripesPerAgg-1)) || (fileSegmentIter == (numSegments-1))) {
+ stripeParms.flushCB = 1;
+ }
+ else
+ stripeParms.flushCB = 0;
+
+ stripeParms.firstStripedWriteCall = 0;
+ stripeParms.lastStripedWriteCall = 0;
+ if (fileSegmentIter == 0) {
+ stripeParms.firstStripedWriteCall = 1;
+ }
+ else if (fileSegmentIter == (numSegments-1))
+ stripeParms.lastStripedWriteCall = 1;
+
+ /* The difference in calls to ADIOI_OneSidedWriteAggregation is based on the whether the buftype is
+ * contiguous. The algorithm tracks the position in the source buffer when called
+ * multiple times -- in the case of contiguous data this is simple and can be externalized with
+ * a buffer offset, in the case of non-contiguous data this is complex and the state must be tracked
+ * internally, therefore no external buffer offset. Care was taken to minimize
+ * ADIOI_OneSidedWriteAggregation changes at the expense of some added complexity to the caller.
+ */
+ int bufTypeIsContig;
+ ADIOI_Datatype_iscontig(datatype, &bufTypeIsContig);
+ if (bufTypeIsContig) {
+ ADIOI_OneSidedWriteAggregation(fd,(ADIO_Offset*)&(offset_list[startingOffsetListIndex]), (ADIO_Offset*)&(len_list[startingOffsetListIndex]), segmentContigAccessCount, buf+totalDataWrittenLastRound, datatype, error_code, segmentFirstFileOffset, segmentLastFileOffset, currentValidDataIndex, segment_stripe_start, segment_stripe_end, &holeFoundThisRound,stripeParms);
+ }
+ else {
+ ADIOI_OneSidedWriteAggregation(fd,(ADIO_Offset*)&(offset_list[startingOffsetListIndex]), (ADIO_Offset*)&(len_list[startingOffsetListIndex]), segmentContigAccessCount, buf, datatype, error_code, segmentFirstFileOffset, segmentLastFileOffset, currentValidDataIndex, segment_stripe_start, segment_stripe_end, &holeFoundThisRound,stripeParms);
+ }
+
+ if (stripeParms.flushCB) {
+ stripeParms.segmentIter = 0;
+ if (stripesPerAgg > (numSegments-fileSegmentIter-1))
+ stripeParms.stripesPerAgg = numSegments-fileSegmentIter-1;
+ else
+ stripeParms.stripesPerAgg = stripesPerAgg;
+ }
+ else
+ stripeParms.segmentIter++;
+
+ if (holeFoundThisRound)
+ holeFound = 1;
+
+ /* If we know we won't be doing a pre-read in a subsequent call to
+ * ADIOI_OneSidedWriteAggregation which will have a barrier to keep
+ * feeder ranks from doing rma to the collective buffer before the
+ * write completes that we told it do with the stripeParms.flushCB
+ * flag then we need to do a barrier here.
+ */
+ if (!romio_onesided_always_rmw && stripeParms.flushCB) {
+ if (fileSegmentIter < (numSegments-1)) {
+ MPI_Barrier(fd->comm);
+ }
+ }
+
+ /* Restore the offset_list and len_list to values that are ready for the
+ * next iteration.
+ */
+ if (segmentContigAccessCount > 0) {
+ offset_list[endingOffsetListIndex] += len_list[endingOffsetListIndex];
+ len_list[endingOffsetListIndex] = endingLenTrim;
+ }
+ totalDataWrittenLastRound += dataWrittenThisRound;
+ } // fileSegmentIter for-loop
+
+ /* Check for holes in the data unless romio_onesided_no_rmw is set.
+ * If a hole is found redo the entire aggregation and write.
+ */
+ if (!romio_onesided_no_rmw) {
+ int anyHolesFound = 0;
+ MPI_Allreduce(&holeFound, &anyHolesFound, 1, MPI_INT, MPI_MAX, fd->comm);
+
+ if (anyHolesFound) {
+ ADIOI_Free(offset_list);
+ ADIOI_Free(len_list);
+ ADIOI_Calc_my_off_len(fd, count, datatype, file_ptr_type, offset,
+ &offset_list, &len_list, &start_offset,
+ &end_offset, &contig_access_count);
+
+ currentSegementOffset = (ADIO_Offset)startingStripeWithData * (ADIO_Offset)(striping_info[0]);
+ romio_onesided_always_rmw = 1;
+ romio_onesided_no_rmw = 1;
+
+ /* Holes are found in the data and the user has not set
+ * romio_onesided_no_rmw --- set romio_onesided_always_rmw to 1
+ * and redo the entire aggregation and write and if the user has
+ * romio_onesided_inform_rmw set then inform him of this condition
+ * and behavior.
+ */
+ if (romio_onesided_inform_rmw && (myrank ==0)) {
+ FPRINTF(stderr,"Information: Holes found during one-sided "
+ "write aggregation algorithm --- re-running one-sided "
+ "write aggregation with ROMIO_ONESIDED_ALWAYS_RMW set to 1.\n");
+ }
+ }
+ else
+ doAggregation = 0;
+ }
+ else
+ doAggregation = 0;
+ } // while doAggregation
+ romio_onesided_no_rmw = prev_romio_onesided_no_rmw;
+
+ ADIOI_Free(segment_stripe_start);
+ ADIOI_Free(segment_stripe_end);
+
+ fd->hints->cb_nodes = orig_cb_nodes;
+
+}
http://git.mpich.org/mpich.git/commitdiff/598aa493dcef472ac32498fa0100976df…
commit 598aa493dcef472ac32498fa0100976df15c2b26
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Tue Mar 22 21:27:18 2016 -0700
ROMIO Onesided write fix hole checking
change implementation of hole checking to use MPI_Accumulate
The current implementation to check for holes to determine if rmw is necessary uses an
nproc-size array of ints and MPI_Put. With MPI3 the atomic MPI_Accumulate can be used
instead with a single integer to track this.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/common/onesided_aggregation.c b/src/mpi/romio/adio/common/onesided_aggregation.c
index f7aca5f..c96b8bf 100644
--- a/src/mpi/romio/adio/common/onesided_aggregation.c
+++ b/src/mpi/romio/adio/common/onesided_aggregation.c
@@ -56,8 +56,8 @@ static int ADIOI_OneSidedSetup(ADIO_File fd, int procs) {
ret = MPI_Win_create(fd->io_buf,fd->hints->cb_buffer_size,1,
MPI_INFO_NULL,fd->comm, &fd->io_buf_window);
if (ret != MPI_SUCCESS) goto fn_exit;
- fd->io_buf_put_amounts = (int *) ADIOI_Malloc(procs*sizeof(int));
- ret =MPI_Win_create(fd->io_buf_put_amounts,procs*sizeof(int),sizeof(int),
+ fd->io_buf_put_amounts = 0;
+ ret =MPI_Win_create(&(fd->io_buf_put_amounts),sizeof(int),sizeof(int),
MPI_INFO_NULL,fd->comm, &fd->io_buf_put_amounts_window);
fn_exit:
return ret;
@@ -70,8 +70,6 @@ int ADIOI_OneSidedCleanup(ADIO_File fd)
ret = MPI_Win_free(&fd->io_buf_window);
if (fd->io_buf_put_amounts_window != MPI_WIN_NULL)
ret = MPI_Win_free(&fd->io_buf_put_amounts_window);
- if (fd->io_buf_put_amounts != NULL)
- ADIOI_Free(fd->io_buf_put_amounts);
return ret;
}
@@ -771,11 +769,8 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
char *write_buf = write_buf0;
MPI_Win write_buf_window = fd->io_buf_window;
- int *write_buf_put_amounts = fd->io_buf_put_amounts;
if(!romio_onesided_no_rmw) {
*hole_found = 0;
- for (i=0;i<nprocs;i++)
- write_buf_put_amounts[i] = 0;
}
/* Counters to track the offset range being written by the used aggs.
@@ -1045,7 +1040,7 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
}
if (!romio_onesided_no_rmw) {
MPI_Win_lock(MPI_LOCK_SHARED, targetAggsForMyData[aggIter], 0, fd->io_buf_put_amounts_window);
- MPI_Put(&numBytesPutThisAggRound,1, MPI_INT,targetAggsForMyData[aggIter],myrank, 1,MPI_INT,fd->io_buf_put_amounts_window);
+ MPI_Accumulate(&numBytesPutThisAggRound,1, MPI_INT,targetAggsForMyData[aggIter],0, 1, MPI_INT, MPI_SUM, fd->io_buf_put_amounts_window);
MPI_Win_unlock(targetAggsForMyData[aggIter], fd->io_buf_put_amounts_window);
}
} // baseoffset != -1
@@ -1079,15 +1074,11 @@ printf("first barrier roundIter %d\n",roundIter);
int doWriteContig = 1;
if (!romio_onesided_no_rmw) {
- int numBytesPutIntoBuf = 0;
- for (i=0;i<nprocs;i++) {
- numBytesPutIntoBuf += write_buf_put_amounts[i];
- write_buf_put_amounts[i] = 0;
- }
- if (numBytesPutIntoBuf != ((int)(currentRoundFDEnd - currentRoundFDStart)+1)) {
+ if (fd->io_buf_put_amounts != ((int)(currentRoundFDEnd - currentRoundFDStart)+1)) {
doWriteContig = 0;
*hole_found = 1;
}
+ fd->io_buf_put_amounts = 0;
}
if (!useIOBuffer) {
diff --git a/src/mpi/romio/adio/include/adio.h b/src/mpi/romio/adio/include/adio.h
index 34e1914..d29a01f 100644
--- a/src/mpi/romio/adio/include/adio.h
+++ b/src/mpi/romio/adio/include/adio.h
@@ -230,7 +230,7 @@ typedef struct ADIOI_FileD {
int my_cb_nodes_index; /* my index into cb_config_list. -1 if N/A */
char *io_buf; /* two-phase buffer allocated out of i/o path */
MPI_Win io_buf_window; /* Window over the io_buf to support one-sided aggregation */
- int *io_buf_put_amounts; /* array tracking the amount of data mpi_put into the io_buf
+ int io_buf_put_amounts; /* the amount of data mpi_put into the io_buf
during the same round of one-sided write aggregation */
MPI_Win io_buf_put_amounts_window; /* Window over the io_buf_put_amounts */
/* External32 */
http://git.mpich.org/mpich.git/commitdiff/ccd815498267d6cc342d25fce7ce3107f…
commit ccd815498267d6cc342d25fce7ce3107f3e18294
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Tue Mar 22 20:43:19 2016 -0700
ROMIO Onesided write fix improper buffer free
Code was calling MPI_Put buffer after MPI_Win_unlock The current
implementation errantly frees a buffer used by MPI_Put for aggmethod 1
(the put-at-a-time approach) BEFORE the call to MPI_Win_unlock - this
must be done AFTER.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/common/onesided_aggregation.c b/src/mpi/romio/adio/common/onesided_aggregation.c
index ec68f5b..f7aca5f 100644
--- a/src/mpi/romio/adio/common/onesided_aggregation.c
+++ b/src/mpi/romio/adio/common/onesided_aggregation.c
@@ -957,17 +957,19 @@ printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld t
if (romio_write_aggmethod == 1) {
MPI_Win_lock(MPI_LOCK_SHARED, targetAggsForMyData[aggIter], 0, write_buf_window);
+ char *putSourceData;
if (bufTypeIsContig) {
MPI_Put(((char*)buf) + currentFDSourceBufferState[aggIter].sourceBufferOffset,bufferAmountToSend, MPI_BYTE,targetAggsForMyData[aggIter],targetDisplacementToUseThisRound, bufferAmountToSend,MPI_BYTE,write_buf_window);
currentFDSourceBufferState[aggIter].sourceBufferOffset += (ADIO_Offset)bufferAmountToSend;
}
else {
- char *putSourceData = (char *) ADIOI_Malloc(bufferAmountToSend*sizeof(char));
+ putSourceData = (char *) ADIOI_Malloc(bufferAmountToSend*sizeof(char));
nonContigSourceDataBufferAdvance(((char*)buf), flatBuf, bufferAmountToSend, 1, ¤tFDSourceBufferState[aggIter], putSourceData);
MPI_Put(putSourceData,bufferAmountToSend, MPI_BYTE,targetAggsForMyData[aggIter],targetDisplacementToUseThisRound, bufferAmountToSend,MPI_BYTE,write_buf_window);
- ADIOI_Free(putSourceData);
}
MPI_Win_unlock(targetAggsForMyData[aggIter], write_buf_window);
+ if (!bufTypeIsContig)
+ ADIOI_Free(putSourceData);
}
/* For romio_write_aggmethod of 2 populate the data structures for this round/agg for this offset iter
http://git.mpich.org/mpich.git/commitdiff/b95b4e4ef0ed1b6ea4b47b56859eef184…
commit b95b4e4ef0ed1b6ea4b47b56859eef18487d5eb8
Author: Paul Coffman <pcoffman(a)anl.gov>
Date: Mon Mar 21 09:08:42 2016 -0700
Generalize ROMIO collective aggregation tuning environment variables
Several ROMIO optimizations including a one-sided aggregation method
were done only for GPFS which were enabled via GPFS-specific
environment variables, now we need to enable them for other file
systems such as Lustre. The names and utilization functions must be
generalized - ad_gpfs_get_env var has been reduced to gpfs-only env
vars and a new function ad_get_env has been created and called
appropriately.
Signed-off-by: Rob Latham <robl(a)mcs.anl.gov>
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs.h b/src/mpi/romio/adio/ad_gpfs/ad_gpfs.h
index d64dcae..9f1e0e0 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs.h
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs.h
@@ -67,6 +67,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
void ADIOI_GPFS_Flush(ADIO_File fd, int *error_code);
+#include "ad_tuning.h"
#include "ad_gpfs_tuning.h"
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c
index fd6cdbc..c561ec9 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c
@@ -87,6 +87,7 @@ void ADIOI_GPFS_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code)
*/
if (!fd->hints->initialized) {
+ ad_get_env_vars();
ad_gpfs_get_env_vars();
did_anything = 1;
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c
index d504836..bcbd2a4 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c
@@ -179,14 +179,14 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
/* One-sided aggregation needs the amount of data per rank as well because the difference in
* starting and ending offsets for 1 byte is 0 the same as 0 bytes so it cannot be distiguished.
*/
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
count_sizes = (ADIO_Offset *) ADIOI_Malloc(nprocs*sizeof(ADIO_Offset));
MPI_Count buftype_size;
MPI_Type_size_x(datatype, &buftype_size);
my_count_size = (ADIO_Offset) count * (ADIO_Offset)buftype_size;
}
if (gpfsmpio_tunegather) {
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
gpfs_offsets0 = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
gpfs_offsets = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
for (ii=0; ii<nprocs; ii++) {
@@ -228,7 +228,7 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
ADIO_OFFSET, fd->comm);
MPI_Allgather(&end_offset, 1, ADIO_OFFSET, end_offsets, 1,
ADIO_OFFSET, fd->comm);
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
MPI_Allgather(&count_sizes, 1, ADIO_OFFSET, count_sizes, 1,
ADIO_OFFSET, fd->comm);
}
@@ -295,7 +295,7 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
*
*/
int currentNonZeroDataIndex = 0;
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
/* Take out the 0-data offsets by shifting the indexes with data to the
* front and keeping track of the non-zero data index for use as the
* length. By doing this we will optimally use all available aggs
@@ -312,7 +312,7 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
}
}
if (gpfsmpio_tuneblocking) {
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
ADIOI_GPFS_Calc_file_domains(fd, st_offsets, end_offsets, currentNonZeroDataIndex,
nprocs_for_coll, &min_st_offset,
&fd_start, &fd_end, &fd_size, fd->fs_ptr);
@@ -324,7 +324,7 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
}
}
else {
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
ADIOI_Calc_file_domains(st_offsets, end_offsets, currentNonZeroDataIndex,
nprocs_for_coll, &min_st_offset,
&fd_start, &fd_end,
@@ -341,7 +341,7 @@ void ADIOI_GPFS_ReadStridedColl(ADIO_File fd, void *buf, int count,
}
GPFSMPIO_T_CIO_SET_GET( r, 1, 1, GPFSMPIO_CIO_T_MYREQ, GPFSMPIO_CIO_T_FD_PART );
- if ((gpfsmpio_read_aggmethod == 1) || (gpfsmpio_read_aggmethod == 2)) {
+ if ((romio_read_aggmethod == 1) || (romio_read_aggmethod == 2)) {
/* If the user has specified to use a one-sided aggregation method then do that at
* this point instead of the two-phase I/O.
*/
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c
index 333612b..8b4d06d 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c
@@ -37,14 +37,9 @@ long bglocklessmpio_f_type;
int gpfsmpio_bg_nagg_pset;
int gpfsmpio_pthreadio;
int gpfsmpio_p2pcontig;
-int gpfsmpio_write_aggmethod;
-int gpfsmpio_read_aggmethod;
int gpfsmpio_balancecontig;
int gpfsmpio_devnullio;
int gpfsmpio_bridgeringagg;
-int gpfsmpio_onesided_no_rmw;
-int gpfsmpio_onesided_always_rmw;
-int gpfsmpio_onesided_inform_rmw;
double gpfsmpio_prof_cw [GPFSMPIO_CIO_LAST+1];
double gpfsmpio_prof_cr [GPFSMPIO_CIO_LAST+1];
@@ -110,40 +105,6 @@ double gpfsmpio_prof_cr [GPFSMPIO_CIO_LAST+1];
* 3.) There are no gaps between the offsets.
* 4.) No single rank has a data size which spans multiple file domains.
*
- * - GPFSMPIO_WRITE_AGGMETHOD/GPFSMPIO_READ_AGGMETHOD - Replaces the two-phase
- * collective IO aggregation
- * with a one-sided algorithm, significantly reducing communication and
- * memory overhead. Fully
- * supports all datasets and datatypes, the only caveat is that any holes in the data
- * when writing to a pre-existing file are ignored -- there is no read-modify-write
- * support to maintain the correctness of regions of pre-existing data so every byte
- * must be explicitly written to maintain correctness. Users must beware of middle-ware
- * libraries like PNETCDF which may count on read-modify-write functionality for certain
- * features (like fill values). Possible values:
- * - 0 - Normal two-phase collective IO is used.
- * - 1 - A separate one-sided MPI_Put or MPI_Get is used for each contigous chunk of data
- * for a compute to write to or read from the collective buffer on the aggregator.
- * - 2 - An MPI derived datatype is created using all the contigous chunks and just one
- * call to MPI_Put or MPI_Get is done with the derived datatype. On Blue Gene /Q
- * optimal performance for this is achieved when paired with PAMID_TYPED_ONESIDED=1.
- * - Default is 0
- *
- * - GPFSMPIO_ONESIDED_NO_RMW - For one-sided aggregation (GPFSMPIO_WRITE_AGGMETHOD = 1 or 2)
- * disable the detection of holes in the data when writing to a pre-existing
- * file requiring a read-modify-write, thereby avoiding the communication
- * overhead for this detection.
- * - 0 (hole detection enabled) or 1 (hole detection disabled)
- * - Default is 0
- *
- * - GPFSMPIO_ONESIDED_INFORM_RMW - For one-sided aggregation
- * (GPFSMPIO_AGGMETHOD = 1 or 2) generate an informational message informing
- * the user whether holes exist in the data when writing to a pre-existing
- * file requiring a read-modify-write, thereby educating the user to set
- * GPFSMPIO_ONESIDED_NO_RMW=1 on a future run to avoid the communication
- * overhead for this detection.
- * - 0 (disabled) or 1 (enabled)
- * - Default is 0
- *
* - GPFSMPIO_BALANCECONTIG - Relevant only to BGQ. File domain blocks are assigned
* to aggregators in a breadth-first fashion relative to the ions - additionally,
* file domains on the aggregators sharing the same bridgeset and ion have contiguous
@@ -196,22 +157,10 @@ void ad_gpfs_get_env_vars() {
x = getenv("GPFSMPIO_NAGG_PSET");
if (x) gpfsmpio_bg_nagg_pset = atoi(x);
- gpfsmpio_pthreadio = 0;
- x = getenv( "GPFSMPIO_PTHREADIO" );
- if (x) gpfsmpio_pthreadio = atoi(x);
-
gpfsmpio_p2pcontig = 0;
x = getenv( "GPFSMPIO_P2PCONTIG" );
if (x) gpfsmpio_p2pcontig = atoi(x);
- gpfsmpio_write_aggmethod = 0;
- x = getenv( "GPFSMPIO_WRITE_AGGMETHOD" );
- if (x) gpfsmpio_write_aggmethod = atoi(x);
-
- gpfsmpio_read_aggmethod = 0;
- x = getenv( "GPFSMPIO_READ_AGGMETHOD" );
- if (x) gpfsmpio_read_aggmethod = atoi(x);
-
gpfsmpio_balancecontig = 0;
x = getenv( "GPFSMPIO_BALANCECONTIG" );
if (x) gpfsmpio_balancecontig = atoi(x);
@@ -224,19 +173,6 @@ void ad_gpfs_get_env_vars() {
x = getenv( "GPFSMPIO_BRIDGERINGAGG" );
if (x) gpfsmpio_bridgeringagg = atoi(x);
- gpfsmpio_onesided_no_rmw = 0;
- x = getenv( "GPFSMPIO_ONESIDED_NO_RMW" );
- if (x) gpfsmpio_onesided_no_rmw = atoi(x);
-
- gpfsmpio_onesided_always_rmw = 0;
- x = getenv( "GPFSMPIO_ONESIDED_ALWAYS_RMW" );
- if (x) gpfsmpio_onesided_always_rmw = atoi(x);
- if (gpfsmpio_onesided_always_rmw)
- gpfsmpio_onesided_no_rmw = 1;
-
- gpfsmpio_onesided_inform_rmw = 0;
- x = getenv( "GPFSMPIO_ONESIDED_INFORM_RMW" );
- if (x) gpfsmpio_onesided_inform_rmw = atoi(x);
}
/* report timing breakdown for MPI I/O collective call */
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h
index 35fdc8d..21f98f6 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h
@@ -66,14 +66,9 @@ extern int gpfsmpio_tuneblocking;
extern long bglocklessmpio_f_type;
extern int gpfsmpio_pthreadio;
extern int gpfsmpio_p2pcontig;
-extern int gpfsmpio_write_aggmethod;
-extern int gpfsmpio_read_aggmethod;
extern int gpfsmpio_balancecontig;
extern int gpfsmpio_devnullio;
extern int gpfsmpio_bridgeringagg;
-extern int gpfsmpio_onesided_no_rmw;
-extern int gpfsmpio_onesided_always_rmw;
-extern int gpfsmpio_onesided_inform_rmw;
/* Default is, well, kind of complicated. Blue Gene /L and /P had "psets": one
* i/o node and all compute nodes wired to it. On Blue Gene /Q that
diff --git a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
index 036aad2..0e1d6b6 100644
--- a/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
+++ b/src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c
@@ -181,14 +181,14 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
* the difference in starting and ending offsets for 1 byte is 0 the same
* as 0 bytes so it cannot be distiguished.
*/
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
count_sizes = (ADIO_Offset *) ADIOI_Malloc(nprocs*sizeof(ADIO_Offset));
MPI_Count buftype_size;
MPI_Type_size_x(datatype, &buftype_size);
my_count_size = (ADIO_Offset) count * (ADIO_Offset)buftype_size;
}
if (gpfsmpio_tunegather) {
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
gpfs_offsets0 = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
gpfs_offsets = (ADIO_Offset *) ADIOI_Malloc(3*nprocs*sizeof(ADIO_Offset));
for (ii=0; ii<nprocs; ii++) {
@@ -230,7 +230,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
ADIO_OFFSET, fd->comm);
MPI_Allgather(&end_offset, 1, ADIO_OFFSET, end_offsets, 1,
ADIO_OFFSET, fd->comm);
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
MPI_Allgather(&count_sizes, 1, ADIO_OFFSET, count_sizes, 1,
ADIO_OFFSET, fd->comm);
}
@@ -287,7 +287,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
process may directly access only its own file domain. */
int currentValidDataIndex = 0;
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
/* Take out the 0-data offsets by shifting the indexes with data to the front
* and keeping track of the valid data index for use as the length.
*/
@@ -301,7 +301,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
}
if (gpfsmpio_tuneblocking) {
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
ADIOI_GPFS_Calc_file_domains(fd, st_offsets, end_offsets,
currentValidDataIndex,
nprocs_for_coll, &min_st_offset,
@@ -315,7 +315,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
}
}
else {
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
ADIOI_Calc_file_domains(st_offsets, end_offsets, currentValidDataIndex,
nprocs_for_coll, &min_st_offset,
&fd_start, &fd_end,
@@ -333,7 +333,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
GPFSMPIO_T_CIO_SET_GET( w, 1, 1, GPFSMPIO_CIO_T_MYREQ, GPFSMPIO_CIO_T_FD_PART );
- if ((gpfsmpio_write_aggmethod == 1) || (gpfsmpio_write_aggmethod == 2)) {
+ if ((romio_write_aggmethod == 1) || (romio_write_aggmethod == 2)) {
/* If the user has specified to use a one-sided aggregation method then do that at
* this point instead of the two-phase I/O.
*/
@@ -342,7 +342,7 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
buf, datatype, error_code, st_offsets, end_offsets,
currentValidDataIndex, fd_start, fd_end, &holeFound);
int anyHolesFound = 0;
- if (!gpfsmpio_onesided_no_rmw)
+ if (!romio_onesided_no_rmw)
MPI_Allreduce(&holeFound, &anyHolesFound, 1, MPI_INT, MPI_MAX, fd->comm);
if (anyHolesFound == 0) {
GPFSMPIO_T_CIO_REPORT( 1, fd, myrank, nprocs)
@@ -357,21 +357,21 @@ void ADIOI_GPFS_WriteStridedColl(ADIO_File fd, const void *buf, int count,
}
else {
/* Holes are found in the data and the user has not set
- * gpfsmpio_onesided_no_rmw --- set gpfsmpio_onesided_always_rmw to 1
+ * romio_onesided_no_rmw --- set romio_onesided_always_rmw to 1
* and re-call ADIOI_OneSidedWriteAggregation and if the user has
- * gpfsmpio_onesided_inform_rmw set then inform him of this condition
+ * romio_onesided_inform_rmw set then inform him of this condition
* and behavior.
*/
- if (gpfsmpio_onesided_inform_rmw && (myrank ==0))
+ if (romio_onesided_inform_rmw && (myrank ==0))
FPRINTF(stderr,"Information: Holes found during one-sided "
"write aggregation algorithm --- re-running one-sided "
"write aggregation with GPFSMPIO_ONESIDED_ALWAYS_RMW set to 1.\n");
- gpfsmpio_onesided_always_rmw = 1;
- int prev_gpfsmpio_onesided_no_rmw = gpfsmpio_onesided_no_rmw;
- gpfsmpio_onesided_no_rmw = 1;
+ romio_onesided_always_rmw = 1;
+ int prev_romio_onesided_no_rmw = romio_onesided_no_rmw;
+ romio_onesided_no_rmw = 1;
ADIOI_OneSidedWriteAggregation(fd, offset_list, len_list, contig_access_count, buf, datatype, error_code, st_offsets, end_offsets, currentValidDataIndex, fd_start, fd_end, &holeFound);
- gpfsmpio_onesided_no_rmw = prev_gpfsmpio_onesided_no_rmw;
+ romio_onesided_no_rmw = prev_romio_onesided_no_rmw;
GPFSMPIO_T_CIO_REPORT( 1, fd, myrank, nprocs)
ADIOI_Free(offset_list);
ADIOI_Free(len_list);
diff --git a/src/mpi/romio/adio/common/Makefile.mk b/src/mpi/romio/adio/common/Makefile.mk
index 80194ef..a06f059 100644
--- a/src/mpi/romio/adio/common/Makefile.mk
+++ b/src/mpi/romio/adio/common/Makefile.mk
@@ -72,5 +72,6 @@ romio_other_sources += \
adio/common/ad_threaded_io.c \
adio/common/p2p_aggregation.c \
adio/common/onesided_aggregation.c \
+ adio/common/ad_tuning.c \
adio/common/utils.c
diff --git a/src/mpi/romio/adio/common/ad_hints.c b/src/mpi/romio/adio/common/ad_hints.c
index 83f0533..dcad549 100644
--- a/src/mpi/romio/adio/common/ad_hints.c
+++ b/src/mpi/romio/adio/common/ad_hints.c
@@ -8,6 +8,7 @@
#include "adio.h"
#include "adio_extern.h"
#include "hint_fns.h"
+#include "ad_tuning.h"
void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code)
{
@@ -31,6 +32,7 @@ void ADIOI_GEN_SetInfo(ADIO_File fd, MPI_Info users_info, int *error_code)
*error_code = MPI_SUCCESS;
return;
}
+ ad_get_env_vars();
if (fd->info == MPI_INFO_NULL) MPI_Info_create(&(fd->info));
info = fd->info;
diff --git a/src/mpi/romio/adio/common/ad_tuning.c b/src/mpi/romio/adio/common/ad_tuning.c
new file mode 100644
index 0000000..ee9c318
--- /dev/null
+++ b/src/mpi/romio/adio/common/ad_tuning.c
@@ -0,0 +1,100 @@
+/* ---------------------------------------------------------------- */
+/* (C)Copyright IBM Corp. 2007, 2008 */
+/* ---------------------------------------------------------------- */
+/**
+ * \file ad_tuning.c
+ * \brief Defines common performance tuning env var options
+ */
+
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ * Copyright (C) 2008 University of Chicago.
+ * See COPYRIGHT notice in top-level directory.
+ */
+
+/*---------------------------------------------------------------------
+ * ad_tuning.c
+ *
+ * defines common global variables and functions for performance tuning
+ * and functional debugging.
+ *---------------------------------------------------------------------*/
+
+#include "ad_tuning.h"
+
+int romio_write_aggmethod;
+int romio_read_aggmethod;
+int romio_onesided_no_rmw;
+int romio_onesided_always_rmw;
+int romio_onesided_inform_rmw;
+
+/* set internal variables for tuning environment variables */
+/** \page mpiio_vars MPIIO Configuration
+ \section env_sec Environment Variables
+ *
+ * - ROMIO_WRITE_AGGMETHOD/ROMIO_READ_AGGMETHOD - Replaces the two-phase
+ * collective IO aggregation
+ * with a one-sided algorithm, significantly reducing communication and
+ * memory overhead. Fully
+ * supports all datasets and datatypes, the only caveat is that any holes in the data
+ * when writing to a pre-existing file are ignored -- there is no read-modify-write
+ * support to maintain the correctness of regions of pre-existing data so every byte
+ * must be explicitly written to maintain correctness. Users must beware of middle-ware
+ * libraries like PNETCDF which may count on read-modify-write functionality for certain
+ * features (like fill values). Possible values:
+ * - 0 - Normal two-phase collective IO is used.
+ * - 1 - A separate one-sided MPI_Put or MPI_Get is used for each contigous chunk of data
+ * for a compute to write to or read from the collective buffer on the aggregator.
+ * - 2 - An MPI derived datatype is created using all the contigous chunks and just one
+ * call to MPI_Put or MPI_Get is done with the derived datatype. On Blue Gene /Q
+ * optimal performance for this is achieved when paired with PAMID_TYPED_ONESIDED=1.
+ * - Default is 0
+ *
+ * - ROMIO_ONESIDED_NO_RMW - For one-sided write aggregation (ROMIO_WRITE_AGGMETHOD = 1 or 2)
+ * disable the detection of holes in the data when writing to a pre-existing
+ * file requiring a read-modify-write, thereby avoiding the communication
+ * overhead for this detection.
+ * - 0 (hole detection enabled) or 1 (hole detection disabled)
+ * - Default is 0
+ *
+ * - ROMIO_ONESIDED_ALWAYS_RMW - For one-sided write aggregation (ROMIO_WRITE_AGGMETHOD = 1 or 2)
+ * always pre-read the offset range being written to a pre-existing file thereby filling
+ * any holes that may exist in the data before being written.
+ * - 0 (do not pre-read file offset range) or 1 (pre-read file offset range)
+ * - Default is 0
+ *
+ * - ROMIO_ONESIDED_INFORM_RMW - For one-sided aggregation
+ * (ROMIO_WRITE_AGGMETHOD = 1 or 2) generate an informational message informing
+ * the user whether holes exist in the data when writing to a pre-existing
+ * file requiring a read-modify-write, thereby educating the user to set
+ * ROMIO_ONESIDED_NO_RMW=1 on a future run to avoid the communication
+ * overhead for this detection.
+ * - 0 (disabled) or 1 (enabled)
+ * - Default is 0
+ *
+ */
+
+void ad_get_env_vars() {
+ char *x, *dummy;
+
+ romio_write_aggmethod = 0;
+ x = getenv( "ROMIO_WRITE_AGGMETHOD" );
+ if (x) romio_write_aggmethod = atoi(x);
+
+ romio_read_aggmethod = 0;
+ x = getenv( "ROMIO_READ_AGGMETHOD" );
+ if (x) romio_read_aggmethod = atoi(x);
+
+ romio_onesided_no_rmw = 0;
+ x = getenv( "ROMIO_ONESIDED_NO_RMW" );
+ if (x) romio_onesided_no_rmw = atoi(x);
+
+ romio_onesided_always_rmw = 0;
+ x = getenv( "ROMIO_ONESIDED_ALWAYS_RMW" );
+ if (x) romio_onesided_always_rmw = atoi(x);
+ if (romio_onesided_always_rmw)
+ romio_onesided_no_rmw = 1;
+
+ romio_onesided_inform_rmw = 0;
+ x = getenv( "ROMIO_ONESIDED_INFORM_RMW" );
+ if (x) romio_onesided_inform_rmw = atoi(x);
+}
diff --git a/src/mpi/romio/adio/common/onesided_aggregation.c b/src/mpi/romio/adio/common/onesided_aggregation.c
index c627570..ec68f5b 100644
--- a/src/mpi/romio/adio/common/onesided_aggregation.c
+++ b/src/mpi/romio/adio/common/onesided_aggregation.c
@@ -6,16 +6,12 @@
#include "adio.h"
#include "adio_extern.h"
+#include "ad_tuning.h"
#ifdef ROMIO_GPFS
-/* right now this is GPFS only but TODO: extend this to all file systems */
#include "../ad_gpfs/ad_gpfs_tuning.h"
-#else
-int gpfsmpio_onesided_no_rmw = 0;
-int gpfsmpio_write_aggmethod = 0;
-int gpfsmpio_read_aggmethod = 0;
-int gpfsmpio_onesided_always_rmw = 0;
#endif
+
#include <pthread.h>
// #define onesidedtrace 1
@@ -776,7 +772,7 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
MPI_Win write_buf_window = fd->io_buf_window;
int *write_buf_put_amounts = fd->io_buf_put_amounts;
- if(!gpfsmpio_onesided_no_rmw) {
+ if(!romio_onesided_no_rmw) {
*hole_found = 0;
for (i=0;i<nprocs;i++)
write_buf_put_amounts[i] = 0;
@@ -800,7 +796,7 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
#ifdef onesidedtrace
printf("iAmUsedAgg - currentRoundFDStart initialized to %ld currentRoundFDEnd to %ld\n",currentRoundFDStart,currentRoundFDEnd);
#endif
- if (gpfsmpio_onesided_always_rmw) { // read in the first buffer
+ if (romio_onesided_always_rmw) { // read in the first buffer
ADIO_Offset tmpCurrentRoundFDEnd = 0;
if ((fd_end[myAggRank] - currentRoundFDStart) < coll_bufsize) {
if (myAggRank == greatestFileDomainAggRank) {
@@ -815,14 +811,14 @@ printf("iAmUsedAgg - currentRoundFDStart initialized to %ld currentRoundFDEnd to
else
tmpCurrentRoundFDEnd = currentRoundFDStart + coll_bufsize - (ADIO_Offset)1;
#ifdef onesidedtrace
-printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %ld to %ld total is %d\n",currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
+printf("romio_onesided_always_rmw - first buffer pre-read for file offsets %ld to %ld total is %d\n",currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
#endif
ADIO_ReadContig(fd, write_buf, (int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1,
MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
}
}
- if (gpfsmpio_onesided_always_rmw) // wait until the first buffer is read
+ if (romio_onesided_always_rmw) // wait until the first buffer is read
MPI_Barrier(fd->comm);
#ifdef ROMIO_GPFS
@@ -832,10 +828,10 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
#endif
/* This is the second main loop of the algorithm, actually nested loop of target aggs within rounds. There are 2 flavors of this.
- * For gpfsmpio_write_aggmethod of 1 each nested iteration for the target
+ * For romio_write_aggmethod of 1 each nested iteration for the target
* agg does an mpi_put on a contiguous chunk using a primative datatype
* determined using the data structures from the first main loop. For
- * gpfsmpio_write_aggmethod of 2 each nested iteration for the target agg
+ * romio_write_aggmethod of 2 each nested iteration for the target agg
* builds up data to use in created a derived data type for 1 mpi_put that is done for the target agg for each round.
* To support lustre there will need to be an additional layer of nesting
* for the multiple file domains within target aggs.
@@ -859,7 +855,7 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
int targetAggContigAccessCount = 0;
/* These data structures are used for the derived datatype mpi_put
- * in the gpfsmpio_write_aggmethod of 2 case.
+ * in the romio_write_aggmethod of 2 case.
*/
int *targetAggBlockLengths=NULL;
MPI_Aint *targetAggDisplacements=NULL, *sourceBufferDisplacements=NULL;
@@ -920,7 +916,7 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
printf("bufferAmountToSend is %d\n",bufferAmountToSend);
#endif
if (bufferAmountToSend > 0) { /* we have data to send this round */
- if (gpfsmpio_write_aggmethod == 2) {
+ if (romio_write_aggmethod == 2) {
/* Only allocate these arrays if we are using method 2 and only do it once for this round/target agg.
*/
if (!allocatedDerivedTypeArrays) {
@@ -955,11 +951,11 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
targetDisplacementToUseThisRound += (MPI_Aint) coll_bufsize;
}
- /* For gpfsmpio_write_aggmethod of 1 do the mpi_put using the primitive MPI_BYTE type for each contiguous
+ /* For romio_write_aggmethod of 1 do the mpi_put using the primitive MPI_BYTE type for each contiguous
* chunk in the target, of source data is non-contiguous then pack the data first.
*/
- if (gpfsmpio_write_aggmethod == 1) {
+ if (romio_write_aggmethod == 1) {
MPI_Win_lock(MPI_LOCK_SHARED, targetAggsForMyData[aggIter], 0, write_buf_window);
if (bufTypeIsContig) {
MPI_Put(((char*)buf) + currentFDSourceBufferState[aggIter].sourceBufferOffset,bufferAmountToSend, MPI_BYTE,targetAggsForMyData[aggIter],targetDisplacementToUseThisRound, bufferAmountToSend,MPI_BYTE,write_buf_window);
@@ -974,11 +970,11 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
MPI_Win_unlock(targetAggsForMyData[aggIter], write_buf_window);
}
- /* For gpfsmpio_write_aggmethod of 2 populate the data structures for this round/agg for this offset iter
+ /* For romio_write_aggmethod of 2 populate the data structures for this round/agg for this offset iter
* to be used subsequently when building the derived type for 1 mpi_put for all the data for this
* round/agg.
*/
- else if (gpfsmpio_write_aggmethod == 2) {
+ else if (romio_write_aggmethod == 2) {
if (bufTypeIsContig) {
targetAggBlockLengths[targetAggContigAccessCount]= bufferAmountToSend;
@@ -1005,9 +1001,9 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
} // bufferAmountToSend > 0
} // contig list
- /* For gpfsmpio_write_aggmethod of 2 now build the derived type using the data from this round/agg and do 1 single mpi_put.
+ /* For romio_write_aggmethod of 2 now build the derived type using the data from this round/agg and do 1 single mpi_put.
*/
- if (gpfsmpio_write_aggmethod == 2) {
+ if (romio_write_aggmethod == 2) {
MPI_Datatype sourceBufferDerivedDataType, targetBufferDerivedDataType;
MPI_Type_create_struct(targetAggContigAccessCount, targetAggBlockLengths, sourceBufferDisplacements, targetAggDataTypes, &sourceBufferDerivedDataType);
@@ -1045,7 +1041,7 @@ printf("gpfsmpio_onesided_always_rmw - first buffer pre-read for file offsets %l
MPI_Type_free(&targetBufferDerivedDataType);
}
}
- if (!gpfsmpio_onesided_no_rmw) {
+ if (!romio_onesided_no_rmw) {
MPI_Win_lock(MPI_LOCK_SHARED, targetAggsForMyData[aggIter], 0, fd->io_buf_put_amounts_window);
MPI_Put(&numBytesPutThisAggRound,1, MPI_INT,targetAggsForMyData[aggIter],myrank, 1,MPI_INT,fd->io_buf_put_amounts_window);
MPI_Win_unlock(targetAggsForMyData[aggIter], fd->io_buf_put_amounts_window);
@@ -1080,7 +1076,7 @@ printf("first barrier roundIter %d\n",roundIter);
#endif
int doWriteContig = 1;
- if (!gpfsmpio_onesided_no_rmw) {
+ if (!romio_onesided_no_rmw) {
int numBytesPutIntoBuf = 0;
for (i=0;i<nprocs;i++) {
numBytesPutIntoBuf += write_buf_put_amounts[i];
@@ -1149,7 +1145,7 @@ printf("first barrier roundIter %d\n",roundIter);
if (iAmUsedAgg) {
currentRoundFDStart += coll_bufsize;
- if (gpfsmpio_onesided_always_rmw && (roundIter<(numberOfRounds-1))) { // read in the buffer for the next round unless this is the last round
+ if (romio_onesided_always_rmw && (roundIter<(numberOfRounds-1))) { // read in the buffer for the next round unless this is the last round
ADIO_Offset tmpCurrentRoundFDEnd = 0;
if ((fd_end[myAggRank] - currentRoundFDStart) < coll_bufsize) {
if (myAggRank == greatestFileDomainAggRank) {
@@ -1164,7 +1160,7 @@ printf("first barrier roundIter %d\n",roundIter);
else
tmpCurrentRoundFDEnd = currentRoundFDStart + coll_bufsize - (ADIO_Offset)1;
#ifdef onesidedtrace
-printf("gpfsmpio_onesided_always_rmw - round %d buffer pre-read for file offsets %ld to %ld total is %d\n",roundIter, currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
+printf("romio_onesided_always_rmw - round %d buffer pre-read for file offsets %ld to %ld total is %d\n",roundIter, currentRoundFDStart,tmpCurrentRoundFDEnd,(int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1);
#endif
ADIO_ReadContig(fd, write_buf, (int)(tmpCurrentRoundFDEnd - currentRoundFDStart)+1,
MPI_BYTE, ADIO_EXPLICIT_OFFSET,currentRoundFDStart, &status, error_code);
@@ -1720,7 +1716,7 @@ printf("end_offsets[%d] is %ld st_offsets[%d] is %ld\n",j,end_offsets[j],j,st_of
}
additionalFDCounter++;
-
+
#ifdef onesidedtrace
printf("block extended beyond fd init settings numSourceAggs %d offset_list[%d] with value %ld past fd border %ld with len %ld\n",numSourceAggs,i,offset_list[blockIter],fd_start[currentAggRankListIndex],len_list[blockIter]);
@@ -1820,8 +1816,8 @@ printf("iAmUsedAgg - currentRoundFDStart initialized "
/* This is the second main loop of the algorithm, actually nested loop of target aggs within rounds. There are 2 flavors of this.
- * For gpfsmpio_read_aggmethod of 1 each nested iteration for the source agg does an mpi_put on a contiguous chunk using a primative datatype
- * determined using the data structures from the first main loop. For gpfsmpio_read_aggmethod of 2 each nested iteration for the source agg
+ * For romio_read_aggmethod of 1 each nested iteration for the source agg does an mpi_put on a contiguous chunk using a primative datatype
+ * determined using the data structures from the first main loop. For romio_read_aggmethod of 2 each nested iteration for the source agg
* builds up data to use in created a derived data type for 1 mpi_put that is done for the target agg for each round.
* To support lustre there will need to be an additional layer of nesting for the multiple file domains
* within target aggs.
@@ -1959,7 +1955,7 @@ printf("iAmUsedAgg - currentRoundFDStart initialized "
int sourceAggContigAccessCount = 0;
/* These data structures are used for the derived datatype mpi_get
- * in the gpfsmpio_read_aggmethod of 2 case.
+ * in the romio_read_aggmethod of 2 case.
*/
int *sourceAggBlockLengths=NULL;
MPI_Aint *sourceAggDisplacements=NULL, *recvBufferDisplacements=NULL;
@@ -2004,7 +2000,7 @@ printf("iAmUsedAgg - currentRoundFDStart initialized "
}
if (bufferAmountToRecv > 0) { /* we have data to recv this round */
- if (gpfsmpio_read_aggmethod == 2) {
+ if (romio_read_aggmethod == 2) {
/* Only allocate these arrays if we are using method 2 and only do it once for this round/source agg.
*/
if (!allocatedDerivedTypeArrays) {
@@ -2039,11 +2035,11 @@ printf("iAmUsedAgg - currentRoundFDStart initialized "
sourceDisplacementToUseThisRound += (MPI_Aint)coll_bufsize;
}
- /* For gpfsmpio_read_aggmethod of 1 do the mpi_get using the primitive MPI_BYTE type from each
+ /* For romio_read_aggmethod of 1 do the mpi_get using the primitive MPI_BYTE type from each
* contiguous chunk from the target, if the source is non-contiguous then unpack the data after
* the MPI_Win_unlock is done to make sure the data has arrived first.
*/
- if (gpfsmpio_read_aggmethod == 1) {
+ if (romio_read_aggmethod == 1) {
MPI_Win_lock(MPI_LOCK_SHARED, sourceAggsForMyData[aggIter], 0, read_buf_window);
char *getSourceData = NULL;
if (bufTypeIsContig) {
@@ -2063,11 +2059,11 @@ printf("iAmUsedAgg - currentRoundFDStart initialized "
}
}
- /* For gpfsmpio_read_aggmethod of 2 populate the data structures for this round/agg for this offset iter
+ /* For romio_read_aggmethod of 2 populate the data structures for this round/agg for this offset iter
* to be used subsequently when building the derived type for 1 mpi_put for all the data for this
* round/agg.
*/
- else if (gpfsmpio_read_aggmethod == 2) {
+ else if (romio_read_aggmethod == 2) {
if (bufTypeIsContig) {
sourceAggBlockLengths[sourceAggContigAccessCount]= bufferAmountToRecv;
sourceAggDataTypes[sourceAggContigAccessCount] = MPI_BYTE;
@@ -2088,9 +2084,9 @@ printf("iAmUsedAgg - currentRoundFDStart initialized "
} // bufferAmountToRecv > 0
} // contig list
- /* For gpfsmpio_read_aggmethod of 2 now build the derived type using the data from this round/agg and do 1 single mpi_put.
+ /* For romio_read_aggmethod of 2 now build the derived type using the data from this round/agg and do 1 single mpi_put.
*/
- if (gpfsmpio_read_aggmethod == 2) {
+ if (romio_read_aggmethod == 2) {
MPI_Datatype recvBufferDerivedDataType, sourceBufferDerivedDataType;
MPI_Type_create_struct(sourceAggContigAccessCount, sourceAggBlockLengths, recvBufferDisplacements, sourceAggDataTypes, &recvBufferDerivedDataType);
diff --git a/src/mpi/romio/adio/common/p2p_aggregation.c b/src/mpi/romio/adio/common/p2p_aggregation.c
index ac77a8f..5ea590f 100644
--- a/src/mpi/romio/adio/common/p2p_aggregation.c
+++ b/src/mpi/romio/adio/common/p2p_aggregation.c
@@ -6,6 +6,7 @@
#include "adio.h"
#include "adio_extern.h"
+#include "ad_tuning.h"
#include "../ad_gpfs/ad_gpfs_tuning.h"
#include <pthread.h>
diff --git a/src/mpi/romio/adio/include/ad_tuning.h b/src/mpi/romio/adio/include/ad_tuning.h
new file mode 100644
index 0000000..51fc926
--- /dev/null
+++ b/src/mpi/romio/adio/include/ad_tuning.h
@@ -0,0 +1,38 @@
+/* ---------------------------------------------------------------- */
+/* (C)Copyright IBM Corp. 2007, 2008 */
+/* ---------------------------------------------------------------- */
+/**
+ * \file ad_tuning.h
+ * \brief Defines common performance tuning env var options
+ */
+
+/*---------------------------------------------------------------------
+ * ad_tuning.h
+ *
+ * declares common global variables and functions for performance tuning
+ * and functional debugging.
+ *---------------------------------------------------------------------*/
+
+#ifndef AD_TUNING_H_
+#define AD_TUNING_H_
+
+#include "adio.h"
+
+
+/*-----------------------------------------
+ * Global variables for the control of performance tuning.
+ *-----------------------------------------*/
+
+/* corresponds to environment variables to select optimizations and timing level */
+extern int romio_pthreadio;
+extern int romio_p2pcontig;
+extern int romio_write_aggmethod;
+extern int romio_read_aggmethod;
+extern int romio_onesided_no_rmw;
+extern int romio_onesided_always_rmw;
+extern int romio_onesided_inform_rmw;
+
+/* set internal variables for tuning environment variables */
+void ad_get_env_vars(void);
+
+#endif /* AD_TUNING_H_ */
-----------------------------------------------------------------------
Summary of changes:
src/mpi/romio/adio/ad_gpfs/ad_gpfs.h | 1 +
src/mpi/romio/adio/ad_gpfs/ad_gpfs_hints.c | 1 +
src/mpi/romio/adio/ad_gpfs/ad_gpfs_rdcoll.c | 16 +-
src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.c | 74 ----
src/mpi/romio/adio/ad_gpfs/ad_gpfs_tuning.h | 6 -
src/mpi/romio/adio/ad_gpfs/ad_gpfs_wrcoll.c | 61 ++-
src/mpi/romio/adio/ad_lustre/ad_lustre.h | 1 +
src/mpi/romio/adio/ad_lustre/ad_lustre_wrcoll.c | 443 +++++++++++++++++++++-
src/mpi/romio/adio/common/Makefile.mk | 1 +
src/mpi/romio/adio/common/ad_hints.c | 2 +
src/mpi/romio/adio/common/ad_tuning.c | 111 ++++++
src/mpi/romio/adio/common/onesided_aggregation.c | 331 +++++++++++-----
src/mpi/romio/adio/common/p2p_aggregation.c | 1 +
src/mpi/romio/adio/include/ad_tuning.h | 36 ++
src/mpi/romio/adio/include/adio.h | 2 +-
src/mpi/romio/adio/include/adioi.h | 29 ++-
16 files changed, 899 insertions(+), 217 deletions(-)
create mode 100644 src/mpi/romio/adio/common/ad_tuning.c
create mode 100644 src/mpi/romio/adio/include/ad_tuning.h
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-351-gea008be
by noreply@mpich.org 25 Jul '16
by noreply@mpich.org 25 Jul '16
25 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via ea008be1976a301092ccb7a35b3ee1f9a4ec4d07 (commit)
via c46336bb6ce6a2a70e4bcd99478a8faa068abde0 (commit)
from e64f798aeb003aed58cb4deebda9a9ef7473fb0a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/ea008be1976a301092ccb7a35b3ee1f9a…
commit ea008be1976a301092ccb7a35b3ee1f9a4ec4d07
Author: Rob Latham <robl(a)mcs.anl.gov>
Date: Fri Jul 1 09:54:56 2016 -0500
clean up romio tests a bit
give the ROMIO tests better error handling. While here, removed
whitespace and fixed error reporting of errors in hindexed test. clean
up open files in error case remove whitepsace and properly format
unexpected output
No Reviewer
diff --git a/src/mpi/romio/test/atomicity.c b/src/mpi/romio/test/atomicity.c
index 7797075..e2cd0c6 100644
--- a/src/mpi/romio/test/atomicity.c
+++ b/src/mpi/romio/test/atomicity.c
@@ -84,7 +84,8 @@ int main(int argc, char **argv)
err = MPI_File_set_atomicity(fh, 1);
if (err != MPI_SUCCESS) {
fprintf(stderr, "Atomic mode not supported on this file system.\n");fflush(stderr);
- MPI_Abort(MPI_COMM_WORLD, 1);
+ errs++;
+ goto fn_exit;
}
MPI_Barrier(MPI_COMM_WORLD);
@@ -102,7 +103,7 @@ int main(int argc, char **argv)
if (readbuf[i] != 0) {
errs++;
fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 0\n", mynod, i, readbuf[i]);
- MPI_Abort(MPI_COMM_WORLD, 1);
+ goto fn_exit;
}
}
else if (readbuf[0] == 10) { /* the rest must also be 10 */
@@ -110,7 +111,7 @@ int main(int argc, char **argv)
if (readbuf[i] != 10) {
errs++;
fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 10\n", mynod, i, readbuf[i]);
- MPI_Abort(MPI_COMM_WORLD, 1);
+ goto fn_exit;
}
}
else {
@@ -168,7 +169,7 @@ int main(int argc, char **argv)
if (readbuf[i] != 0) {
errs++;
fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 0\n", mynod, i, readbuf[i]);
- MPI_Abort(MPI_COMM_WORLD, 1);
+ goto fn_exit;
}
}
else if (readbuf[0] == 10) {
@@ -176,7 +177,7 @@ int main(int argc, char **argv)
if (readbuf[i] != 10) {
errs++;
fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 10\n", mynod, i, readbuf[i]);
- MPI_Abort(MPI_COMM_WORLD, 1);
+ goto fn_exit;
}
}
else {
@@ -186,6 +187,9 @@ int main(int argc, char **argv)
}
}
+ MPI_Type_free(&newtype);
+ MPI_Info_free(&info);
+fn_exit:
MPI_File_close(&fh);
MPI_Barrier(MPI_COMM_WORLD);
@@ -199,8 +203,6 @@ int main(int argc, char **argv)
fprintf( stdout, " No Errors\n" );
}
}
- MPI_Type_free(&newtype);
- MPI_Info_free(&info);
free(writebuf);
free(readbuf);
free(filename);
diff --git a/src/mpi/romio/test/excl.c b/src/mpi/romio/test/excl.c
index e48bb3d..b531acc 100644
--- a/src/mpi/romio/test/excl.c
+++ b/src/mpi/romio/test/excl.c
@@ -10,6 +10,13 @@
/* tests MPI_MODE_EXCL */
+static void handle_error(int errcode, const char *str)
+{
+ char msg[MPI_MAX_ERROR_STRING];
+ int resultlen;
+ MPI_Error_string(errcode, msg, &resultlen);
+ fprintf(stderr, "%s: %s\n", str, msg);
+}
int main(int argc, char **argv)
{
MPI_File fh;
@@ -53,6 +60,7 @@ int main(int argc, char **argv)
err = MPI_File_open(MPI_COMM_WORLD, filename,
MPI_MODE_CREATE | MPI_MODE_EXCL | MPI_MODE_RDWR, MPI_INFO_NULL , &fh);
if (err != MPI_SUCCESS) {
+ handle_error(err, "MPI_File_open");
errs++;
fprintf(stderr, "Process %d: open failed when it should have succeeded\n", rank);
}
@@ -66,6 +74,7 @@ int main(int argc, char **argv)
if (err == MPI_SUCCESS) {
errs++;
fprintf(stderr, "Process %d: open succeeded when it should have failed\n", rank);
+ MPI_File_close(&fh);
}
MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
diff --git a/src/mpi/romio/test/hindexed.c b/src/mpi/romio/test/hindexed.c
index ebc0ae8..9fff194 100644
--- a/src/mpi/romio/test/hindexed.c
+++ b/src/mpi/romio/test/hindexed.c
@@ -109,29 +109,29 @@ int main(int argc, char **argv) {
P0's 's layout P1's layout
[ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
-[ 0] 0 1 2 3 4 5 | D E F G H I
-[ 1] |
-[ 2] 6 7 8 9 : ; | J K L M N O
-[ 3] |
-[ 4] |
-[ 5] |
-[ 6] |
-[ 7] |
-[ 8] |
-[ 9] |
+[ 0] 0 1 2 3 4 5 | D E F G H I
+[ 1] |
+[ 2] 6 7 8 9 : ; | J K L M N O
+[ 3] |
+[ 4] |
+[ 5] |
+[ 6] |
+[ 7] |
+[ 8] |
+[ 9] |
P2's 's layout P3's layout
[ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
-[ 0] |
-[ 1] |
-[ 2] |
-[ 3] |
-[ 4] |
-[ 5] X Y Z [ \ ] | l m n o p q
-[ 6] |
-[ 7] ^ _ ` a b c | r s t u v w
-[ 8] |
-[ 9] |
+[ 0] |
+[ 1] |
+[ 2] |
+[ 3] |
+[ 4] |
+[ 5] X Y Z [ \ ] | l m n o p q
+[ 6] |
+[ 7] ^ _ ` a b c | r s t u v w
+[ 8] |
+[ 9] |
*/
/* initialize the write buffer */
@@ -205,7 +205,7 @@ int main(int argc, char **argv) {
for(i=0; i<2*YLEN*num_io; i++) {
for(j=0; j<2*XLEN; j++) {
if( *ptr != compare_buf[i][j]) {
- fprintf(stderr, "expected %d got %d at [%d][%d]\n",
+ fprintf(stderr, "expected %c got %c at [%d][%d]\n",
*ptr, compare_buf[i][j], i, j);
nr_errors++;
}
@@ -235,26 +235,26 @@ int main(int argc, char **argv) {
[ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 ]
[ 0] 0 1 2 3 4 5 D E F G H I
-[ 1]
+[ 1]
[ 2] 6 7 8 9 : ; J K L M N O
-[ 3]
-[ 4]
+[ 3]
+[ 4]
[ 5] X Y Z [ \ ] l m n o p q
-[ 6]
+[ 6]
[ 7] ^ _ ` a b c r s t u v w
-[ 8]
-[ 9]
+[ 8]
+[ 9]
[10] 0 1 2 3 4 5 D E F G H I
-[11]
+[11]
[12] 6 7 8 9 : ; J K L M N O
-[13]
-[14]
+[13]
+[14]
[15] X Y Z [ \ ] l m n o p q
-[16]
+[16]
[17] ^ _ ` a b c r s t u v w
-[18]
-[19]
+[18]
+[19]
*/
diff --git a/src/mpi/romio/test/ordered_fp.c b/src/mpi/romio/test/ordered_fp.c
index 8090e1f..36eea93 100644
--- a/src/mpi/romio/test/ordered_fp.c
+++ b/src/mpi/romio/test/ordered_fp.c
@@ -19,7 +19,6 @@ void handle_error(int errcode, const char *str)
int resultlen;
MPI_Error_string(errcode, msg, &resultlen);
fprintf(stderr, "%s: %s\n", str, msg);
- MPI_Abort(MPI_COMM_WORLD, 1);
}
/* tests shared file pointer functions */
diff --git a/src/mpi/romio/test/shared_fp.c b/src/mpi/romio/test/shared_fp.c
index df41bdd..62174b3 100644
--- a/src/mpi/romio/test/shared_fp.c
+++ b/src/mpi/romio/test/shared_fp.c
@@ -18,7 +18,6 @@ void handle_error(int errcode, const char *str)
int resultlen;
MPI_Error_string(errcode, msg, &resultlen);
fprintf(stderr, "%s: %s\n", str, msg);
- MPI_Abort(MPI_COMM_WORLD, 1);
}
/* tests shared file pointer functions */
@@ -70,11 +69,13 @@ int main(int argc, char **argv)
MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
if (errcode != MPI_SUCCESS) {
handle_error(errcode, "MPI_File_open");
+ errs++;
}
errcode = MPI_File_write_shared(fh, buf, COUNT, MPI_INT, &status);
if (errcode != MPI_SUCCESS) {
handle_error(errcode, "MPI_File_write_shared");
+ errs++;
}
for (i=0; i<COUNT; i++) buf[i] = 0;
@@ -84,11 +85,13 @@ int main(int argc, char **argv)
errcode = MPI_File_seek_shared(fh, 0, MPI_SEEK_SET);
if (errcode != MPI_SUCCESS) {
handle_error(errcode, "MPI_File_seek_shared");
+ errs++;
}
errcode = MPI_File_read_shared(fh, buf, COUNT, MPI_INT, &status);
if (errcode != MPI_SUCCESS) {
handle_error(errcode, "MPI_File_read_shared");
+ errs++;
}
MPI_File_close(&fh);
http://git.mpich.org/mpich.git/commitdiff/c46336bb6ce6a2a70e4bcd99478a8faa0…
commit c46336bb6ce6a2a70e4bcd99478a8faa068abde0
Author: Rob Latham <robl(a)mcs.anl.gov>
Date: Wed Jun 8 10:48:14 2016 -0500
ensure drivers which communicate get only comm self
e.g. say fs-specific code wants to dup a communicator. ensure
fs-specific open does not try to dup the whole communicator by itself
(it will wait forever...)
No Reviewer
diff --git a/src/mpi/romio/adio/common/ad_opencoll_failsafe.c b/src/mpi/romio/adio/common/ad_opencoll_failsafe.c
index e7ac871..962f191 100644
--- a/src/mpi/romio/adio/common/ad_opencoll_failsafe.c
+++ b/src/mpi/romio/adio/common/ad_opencoll_failsafe.c
@@ -15,6 +15,7 @@
void ADIOI_FAILSAFE_OpenColl(ADIO_File fd, int rank,
int access_mode, int *error_code)
{
+ MPI_Comm tmp_comm;
int orig_amode_excl, orig_amode_wronly;
orig_amode_excl = access_mode;
@@ -25,12 +26,20 @@ void ADIOI_FAILSAFE_OpenColl(ADIO_File fd, int rank,
* and others who reach later will return error. */
if(rank == fd->hints->ranklist[0]) {
fd->access_mode = access_mode;
+
+ /* if the lower-level file system tries to communicate, COMM_SELF
+ * will ensure it doesn't get stuck waiting for non-existant
+ * participants */
+ tmp_comm = fd->comm;
+ fd->comm = MPI_COMM_SELF;
(*(fd->fns->ADIOI_xxx_Open))(fd, error_code);
MPI_Bcast(error_code, 1, MPI_INT, \
- fd->hints->ranklist[0], fd->comm);
+ fd->hints->ranklist[0], tmp_comm);
/* if no error, close the file and reopen normally below */
if (*error_code == MPI_SUCCESS)
(*(fd->fns->ADIOI_xxx_Close))(fd, error_code);
+ /* and put it all back the way we found it for subsequent code */
+ fd->comm = tmp_comm;
}
else MPI_Bcast(error_code, 1, MPI_INT,
fd->hints->ranklist[0], fd->comm);
-----------------------------------------------------------------------
Summary of changes:
src/mpi/romio/adio/common/ad_opencoll_failsafe.c | 11 +++-
src/mpi/romio/test/atomicity.c | 16 +++--
src/mpi/romio/test/excl.c | 9 +++
src/mpi/romio/test/hindexed.c | 66 +++++++++++-----------
src/mpi/romio/test/ordered_fp.c | 1 -
src/mpi/romio/test/shared_fp.c | 5 +-
6 files changed, 65 insertions(+), 43 deletions(-)
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-349-ge64f798
by noreply@mpich.org 15 Jul '16
by noreply@mpich.org 15 Jul '16
15 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via e64f798aeb003aed58cb4deebda9a9ef7473fb0a (commit)
via 9152093f090e4fb67888889a43076c5fd97e8ab9 (commit)
from 8f196d6f1209a8a652adf495f3cd5a138b05f4e3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/e64f798aeb003aed58cb4deebda9a9ef7…
commit e64f798aeb003aed58cb4deebda9a9ef7473fb0a
Author: Hajime Fujita <hajime.fujita(a)intel.com>
Date: Thu Jun 2 17:28:13 2016 -0500
Add a test case for many large message transfers
This patch adds a test case to check if MPICH can handle multiple
outstanding large message transfers correctly.
This is a test case for csr/mpich-opa#26.
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore
index 015ea7d..3978431 100644
--- a/test/mpi/.gitignore
+++ b/test/mpi/.gitignore
@@ -1057,6 +1057,7 @@
/pt2pt/icsend
/pt2pt/isendselfprobe
/pt2pt/large_message
+/pt2pt/manylmt
/pt2pt/mprobe
/pt2pt/pingping
/pt2pt/probe-unexp
diff --git a/test/mpi/pt2pt/Makefile.am b/test/mpi/pt2pt/Makefile.am
index 3ff3c3b..9b047b4 100644
--- a/test/mpi/pt2pt/Makefile.am
+++ b/test/mpi/pt2pt/Makefile.am
@@ -54,5 +54,5 @@ noinst_PROGRAMS = \
large_message \
mprobe \
big_count_status \
- many_isend
-
+ many_isend \
+ manylmt
diff --git a/test/mpi/pt2pt/manylmt.c b/test/mpi/pt2pt/manylmt.c
new file mode 100644
index 0000000..711f2d6
--- /dev/null
+++ b/test/mpi/pt2pt/manylmt.c
@@ -0,0 +1,61 @@
+/*
+ * (C) 2016 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ *
+ * Portions of this code were written by Intel Corporation.
+ * Copyright (C) 2011-2016 Intel Corporation. Intel provides this material
+ * to Argonne National Laboratory subject to Software Grant and Corporate
+ * Contributor License Agreement dated February 8, 2012.
+ *
+ *
+ * This program checks if MPICH can correctly handle
+ * many outstanding large message transfers
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <mpi.h>
+
+#define N_TRY 32
+#define BLKSIZE (10*1024*1024)
+
+int main(int argc, char *argv[])
+{
+ int size, rank;
+ int dest;
+ int i;
+ char *buff;
+ MPI_Request reqs[N_TRY];
+
+ MPI_Init(&argc, &argv);
+
+ buff = malloc(N_TRY * BLKSIZE);
+ memset(buff, -1, N_TRY * BLKSIZE);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+ dest = size - 1;
+
+ if (rank == 0) {
+ for (i = 0; i < N_TRY; i++)
+ MPI_Isend(buff + BLKSIZE*i, BLKSIZE, MPI_BYTE, dest, 0, MPI_COMM_WORLD, &reqs[i]);
+ MPI_Waitall(N_TRY, reqs, MPI_STATUSES_IGNORE);
+ }
+ else if (rank == dest) {
+ for (i = 0; i < N_TRY; i++)
+ MPI_Irecv(buff + BLKSIZE*i, BLKSIZE, MPI_BYTE, 0, 0, MPI_COMM_WORLD, &reqs[i]);
+ MPI_Waitall(N_TRY, reqs, MPI_STATUSES_IGNORE);
+ }
+
+ free(buff);
+
+ if (rank == 0)
+ puts(" No Errors");
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/test/mpi/pt2pt/testlist b/test/mpi/pt2pt/testlist
index 7810c64..5613224 100644
--- a/test/mpi/pt2pt/testlist
+++ b/test/mpi/pt2pt/testlist
@@ -43,3 +43,4 @@ large_message 3
mprobe 2 mpiversion=3.0
big_count_status 1 mpiversion=3.0
many_isend 128 xfail=ticket2312
+manylmt 2
http://git.mpich.org/mpich.git/commitdiff/9152093f090e4fb67888889a43076c5fd…
commit 9152093f090e4fb67888889a43076c5fd97e8ab9
Author: Hajime Fujita <hajime.fujita(a)intel.com>
Date: Thu Jun 2 17:14:09 2016 -0500
Add a test case for Rget+unlock synchronization
This patch adds a test case to make sure the synchronization in unlock
works correctly.
Essentially this program does the following:
lock_all
req=rget(buf)
unlock_all
re-use buf
wait(req)
This program is valid but if unlock_all does not implement the synchronization
semantics correctly reusing the buffer would race with outstanding rgets.
This is a test case for csr/mpich-opa#294.
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/test/mpi/.gitignore b/test/mpi/.gitignore
index ed14c0f..015ea7d 100644
--- a/test/mpi/.gitignore
+++ b/test/mpi/.gitignore
@@ -1128,6 +1128,7 @@
/rma/putfidx
/rma/req_example
/rma/reqops
+/rma/rget-unlock
/rma/rmanull
/rma/rmazero
/rma/selfrma
diff --git a/test/mpi/rma/Makefile.am b/test/mpi/rma/Makefile.am
index c48a59b..bf84531 100644
--- a/test/mpi/rma/Makefile.am
+++ b/test/mpi/rma/Makefile.am
@@ -168,7 +168,8 @@ noinst_PROGRAMS = \
win_shared_acc_flush_load \
win_shared_gacc_flush_load \
win_shared_fop_flush_load \
- win_shared_cas_flush_load
+ win_shared_cas_flush_load \
+ rget-unlock
if BUILD_MPIX_TESTS
noinst_PROGRAMS += aint
@@ -275,4 +276,4 @@ win_shared_put_flush_load_CPPFLAGS = -DTEST_PUT $(AM_CPPFLAGS)
win_shared_acc_flush_load_CPPFLAGS = -DTEST_ACC $(AM_CPPFLAGS)
win_shared_gacc_flush_load_CPPFLAGS = -DTEST_GACC $(AM_CPPFLAGS)
win_shared_fop_flush_load_CPPFLAGS = -DTEST_FOP $(AM_CPPFLAGS)
-win_shared_cas_flush_load_CPPFLAGS = -DTEST_CAS $(AM_CPPFLAGS)
\ No newline at end of file
+win_shared_cas_flush_load_CPPFLAGS = -DTEST_CAS $(AM_CPPFLAGS)
diff --git a/test/mpi/rma/rget-unlock.c b/test/mpi/rma/rget-unlock.c
new file mode 100644
index 0000000..4c854df
--- /dev/null
+++ b/test/mpi/rma/rget-unlock.c
@@ -0,0 +1,87 @@
+/*
+ * (C) 2016 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ *
+ * Portions of this code were written by Intel Corporation.
+ * Copyright (C) 2011-2016 Intel Corporation. Intel provides this material
+ * to Argonne National Laboratory subject to Software Grant and Corporate
+ * Contributor License Agreement dated February 8, 2012.
+ *
+ *
+ * This is a test case to make sure synchronization in unlock works correctly.
+ *
+ * Essentially this program does the following:
+ *
+ * lock_all
+ * req=rget(buf)
+ * unlock_all
+ * re-use buf
+ * wait(req)
+ *
+ * This program is valid but if unlock_all does not implement the synchronization
+ * semantics correctly reusing the buffer would race with outstanding rgets.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <mpi.h>
+
+#define N_ELMS (128)
+#define BLOCKSIZE (1)
+#define N_BLOCKS (N_ELMS/BLOCKSIZE)
+
+int main(int argc, char *argv[])
+{
+ MPI_Win win;
+ int i;
+ int *rbuf, *lbuf;
+ int rank, size, trg;
+ MPI_Request *reqs;
+ int n_errors = 0;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+ trg = (rank + 1) % size;
+
+ rbuf = malloc(sizeof(int) * N_ELMS);
+ for (i = 0; i < N_ELMS; i++)
+ rbuf[i] = rank;
+
+ lbuf = malloc(sizeof(int) * N_ELMS);
+ memset(lbuf, -1, sizeof(int) * N_ELMS);
+
+ reqs = malloc(sizeof(MPI_Request) * N_BLOCKS);
+
+ MPI_Win_create(rbuf, sizeof(int) * N_ELMS, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+ MPI_Win_lock_all(MPI_MODE_NOCHECK, win);
+ for (i = 0; i < N_BLOCKS; i++)
+ MPI_Rget(lbuf+i*BLOCKSIZE, BLOCKSIZE, MPI_INT, trg, i*BLOCKSIZE, BLOCKSIZE, MPI_INT, win, &reqs[i]);
+ MPI_Win_unlock_all(win);
+ for (i = 0; i < N_ELMS; i++)
+ lbuf[i] = -2;
+
+ MPI_Waitall(N_BLOCKS, reqs, MPI_STATUSES_IGNORE);
+ for (i = 0; i < N_ELMS; i++) {
+ int v = lbuf[i];
+ if (v != -2) {
+ printf("lbuf[%d]=%d, expected -2\n", i, v);
+ n_errors++;
+ }
+ }
+ MPI_Win_free(&win);
+
+ free(reqs);
+ free(lbuf);
+ free(rbuf);
+
+ if (rank == 0 && n_errors == 0)
+ printf(" No Errors\n");
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/mpi/rma/testlist.in b/test/mpi/rma/testlist.in
index 3f1c6a5..b6ee786 100644
--- a/test/mpi/rma/testlist.in
+++ b/test/mpi/rma/testlist.in
@@ -157,6 +157,7 @@ acc_flush_get 3 mpiversion=3.0
gacc_flush_get 3 mpiversion=3.0
fop_flush_get 3 mpiversion=3.0
cas_flush_get 3 mpiversion=3.0
+rget-unlock 2 mpiversion=3.0
## This test is not strictly correct. This was meant to test out the
## case when MPI_Test is not nonblocking. However, we ended up
-----------------------------------------------------------------------
Summary of changes:
test/mpi/.gitignore | 2 +
test/mpi/pt2pt/Makefile.am | 4 +-
test/mpi/pt2pt/manylmt.c | 61 +++++++++++++++++++++++++++++++
test/mpi/pt2pt/testlist | 1 +
test/mpi/rma/Makefile.am | 5 ++-
test/mpi/rma/rget-unlock.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
test/mpi/rma/testlist.in | 1 +
7 files changed, 157 insertions(+), 4 deletions(-)
create mode 100644 test/mpi/pt2pt/manylmt.c
create mode 100644 test/mpi/rma/rget-unlock.c
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-347-g8f196d6
by noreply@mpich.org 12 Jul '16
by noreply@mpich.org 12 Jul '16
12 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via 8f196d6f1209a8a652adf495f3cd5a138b05f4e3 (commit)
via 433cc4a53ab3b3858b7a0ad40f45574ec4cddd0c (commit)
via 47f36a20357a7612b4a186a8d96a6d3819e558ed (commit)
via 0caa766bf38fcd8f037d1d59d8dba4489072280d (commit)
via 2b9276df85fabd0c21883dcb8cd81f3e7c7bdd02 (commit)
from ff7e3f37effa1132126dfe9616b8a563c61cc91b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/8f196d6f1209a8a652adf495f3cd5a138…
commit 8f196d6f1209a8a652adf495f3cd5a138b05f4e3
Author: Gengbin Zheng <gengbin.zheng(a)intel.com>
Date: Fri Feb 26 00:36:24 2016 -0600
CH4PREREQ: POBJ Threads: fix race condition
In thread multiple with per-obj locks, function MPIR_Get_contextid_sparse()
may be called from multiple threads. And accessing global/static variables
like next_gcn and mask_in_use need to protected to prevent race condition.
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpi/comm/contextid.c b/src/mpi/comm/contextid.c
index 5951b60..bffb158 100644
--- a/src/mpi/comm/contextid.c
+++ b/src/mpi/comm/contextid.c
@@ -618,8 +618,11 @@ int MPIR_Get_contextid_sparse_group(MPIR_Comm * comm_ptr, MPIR_Group * group_ptr
if (st.first_iter == 1) {
st.first_iter = 0;
/* to avoid deadlocks, the element is not added to the list bevore the first iteration */
- if (!ignore_id && *context_id == 0)
+ if (!ignore_id && *context_id == 0) {
+ MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_CTX_MUTEX);
add_gcn_to_list(&st);
+ MPID_THREAD_CS_EXIT(POBJ, MPIR_THREAD_POBJ_CTX_MUTEX);
+ }
}
}
@@ -633,8 +636,8 @@ int MPIR_Get_contextid_sparse_group(MPIR_Comm * comm_ptr, MPIR_Group * group_ptr
/* --BEGIN ERROR HANDLING-- */
fn_fail:
/* Release the masks */
+ MPID_THREAD_CS_ENTER(POBJ, MPIR_THREAD_POBJ_CTX_MUTEX);
if (st.own_mask) {
- /* is it safe to access this without holding the CS? */
mask_in_use = 0;
}
/*If in list, remove it */
@@ -647,6 +650,7 @@ int MPIR_Get_contextid_sparse_group(MPIR_Comm * comm_ptr, MPIR_Group * group_ptr
tmp->next = st.next;
}
}
+ MPID_THREAD_CS_EXIT(POBJ, MPIR_THREAD_POBJ_CTX_MUTEX);
goto fn_exit;
http://git.mpich.org/mpich.git/commitdiff/433cc4a53ab3b3858b7a0ad40f45574ec…
commit 433cc4a53ab3b3858b7a0ad40f45574ec4cddd0c
Author: Hajime Fujita <hajime.fujita(a)intel.com>
Date: Tue May 24 11:08:31 2016 -0500
CH4PREREQ: Remove obsolete debug macro
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_impl.h b/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_impl.h
index 3974407..e3be01b 100644
--- a/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_impl.h
+++ b/src/mpid/ch3/channels/nemesis/netmod/ofi/ofi_impl.h
@@ -251,7 +251,6 @@ static inline int MPID_nem_ofi_create_req(MPIR_Request ** request, int refcnt)
MPIR_Request *req;
req = MPIR_Request_create(MPIR_REQUEST_KIND__UNDEFINED);
MPIR_Assert(req);
- MPIDI_Request_clear_dbg(req);
MPIR_Object_set_ref(req, refcnt);
MPID_nem_ofi_init_req(req);
*request = req;
diff --git a/src/mpid/ch3/include/mpidimpl.h b/src/mpid/ch3/include/mpidimpl.h
index b8fb113..e7d2456 100644
--- a/src/mpid/ch3/include/mpidimpl.h
+++ b/src/mpid/ch3/include/mpidimpl.h
@@ -266,12 +266,6 @@ extern MPIDI_Process_t MPIDI_Process;
#define MPIDI_CH3_REQUEST_INIT(a_)
#endif
-#ifdef HAVE_DEBUGGER_SUPPORT
-#define MPIDI_Request_clear_dbg(sreq_) ((sreq_)->u.send.dbg_next = NULL)
-#else
-#define MPIDI_Request_clear_dbg(sreq_)
-#endif
-
/* FIXME: Why does a send request need the match information?
Is that for debugging information? In case the initial envelope
cannot be sent? Ditto for the dev.user_buf, count, and datatype
@@ -299,7 +293,6 @@ extern MPIDI_Process_t MPIDI_Process;
(sreq_)->dev.user_count = count; \
(sreq_)->dev.datatype = datatype; \
(sreq_)->dev.iov_count = 0; \
- MPIDI_Request_clear_dbg(sreq_); \
}
/* This is the receive request version of MPIDI_Request_create_sreq */
http://git.mpich.org/mpich.git/commitdiff/47f36a20357a7612b4a186a8d96a6d381…
commit 47f36a20357a7612b4a186a8d96a6d3819e558ed
Author: Hajime Fujita <hajime.fujita(a)intel.com>
Date: Tue May 24 11:10:19 2016 -0500
CH4PREREQ: Clear send.dbg_next on request creation
Clear the dbg_next, else it could cause a crash.
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/include/mpir_debugger.h b/src/include/mpir_debugger.h
index 67dc5f8..1287c7c 100644
--- a/src/include/mpir_debugger.h
+++ b/src/include/mpir_debugger.h
@@ -26,11 +26,13 @@ void MPII_CommL_forget( MPIR_Comm * );
#define MPII_SENDQ_FORGET(_a) MPII_Sendq_forget(_a)
#define MPII_COMML_REMEMBER(_a) MPII_CommL_remember( _a )
#define MPII_COMML_FORGET(_a) MPII_CommL_forget( _a )
+#define MPII_REQUEST_CLEAR_DBG(_r) ((_r)->u.send.dbg_next = NULL)
#else
#define MPII_SENDQ_REMEMBER(a,b,c,d)
#define MPII_SENDQ_FORGET(a)
#define MPII_COMML_REMEMBER(_a)
#define MPII_COMML_FORGET(_a)
+#define MPII_REQUEST_CLEAR_DBG(_r)
#endif
#endif /* MPIR_DEBUGGER_H_INCLUDED */
diff --git a/src/include/mpir_request.h b/src/include/mpir_request.h
index 475616f..af212ed 100644
--- a/src/include/mpir_request.h
+++ b/src/include/mpir_request.h
@@ -214,6 +214,9 @@ static inline MPIR_Request *MPIR_Request_create(MPIR_Request_kind_t kind)
req->request_completed_cb = NULL;
switch(kind) {
+ case MPIR_REQUEST_KIND__SEND:
+ MPII_REQUEST_CLEAR_DBG(req);
+ break;
case MPIR_REQUEST_KIND__COLL:
req->u.nbc.errflag = MPIR_ERR_NONE;
break;
http://git.mpich.org/mpich.git/commitdiff/0caa766bf38fcd8f037d1d59d8dba4489…
commit 0caa766bf38fcd8f037d1d59d8dba4489072280d
Author: Hajime Fujita <hajime.fujita(a)intel.com>
Date: Tue May 24 11:09:11 2016 -0500
CH4PREREQ: Create sreq with REQUEST_KIND__SEND
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpid/ch3/include/mpidimpl.h b/src/mpid/ch3/include/mpidimpl.h
index 506e9d6..b8fb113 100644
--- a/src/mpid/ch3/include/mpidimpl.h
+++ b/src/mpid/ch3/include/mpidimpl.h
@@ -287,9 +287,8 @@ extern MPIDI_Process_t MPIDI_Process;
*/
#define MPIDI_Request_create_sreq(sreq_, mpi_errno_, FAIL_) \
{ \
- (sreq_) = MPIR_Request_create(MPIR_REQUEST_KIND__UNDEFINED); \
+ (sreq_) = MPIR_Request_create(MPIR_REQUEST_KIND__SEND); \
MPIR_Object_set_ref((sreq_), 2); \
- (sreq_)->kind = MPIR_REQUEST_KIND__SEND; \
(sreq_)->comm = comm; \
(sreq_)->dev.partner_request = NULL; \
MPIR_Comm_add_ref(comm); \
http://git.mpich.org/mpich.git/commitdiff/2b9276df85fabd0c21883dcb8cd81f3e7…
commit 2b9276df85fabd0c21883dcb8cd81f3e7c7bdd02
Author: Charles J Archer <charles.j.archer(a)intel.com>
Date: Tue Dec 15 06:41:03 2015 -0800
CH4PREREQ: Properly initialize mutexes for per-object builds
Signed-off-by: Ken Raffenetti <raffenet(a)mcs.anl.gov>
diff --git a/src/mpi/comm/commutil.c b/src/mpi/comm/commutil.c
index 305fb9c..53190ec 100644
--- a/src/mpi/comm/commutil.c
+++ b/src/mpi/comm/commutil.c
@@ -70,7 +70,7 @@ static struct MPIR_Comm_hint_fn_elt *MPID_hint_fns = NULL;
* !!! The resulting struct is _not_ ready for communication !!! */
int MPII_Comm_init(MPIR_Comm * comm_p)
{
- int mpi_errno = MPI_SUCCESS;
+ int thr_err, mpi_errno = MPI_SUCCESS;
MPIR_Object_set_ref(comm_p, 1);
@@ -104,6 +104,10 @@ int MPII_Comm_init(MPIR_Comm * comm_p)
comm_p->mapper_head = NULL;
comm_p->mapper_tail = NULL;
+#if MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__POBJ
+ MPID_Thread_mutex_create(&MPIR_THREAD_POBJ_COMM_MUTEX(comm_p), &thr_err);
+ MPIR_Assert(thr_err == 0);
+#endif
/* Fields not set include context_id, remote and local size, and
* kind, since different communicator construction routines need
* different values */
@@ -921,7 +925,7 @@ int MPII_Comm_copy_data(MPIR_Comm * comm_ptr, MPIR_Comm ** outcomm_ptr)
#define FCNAME MPL_QUOTE(FUNCNAME)
int MPIR_Comm_delete_internal(MPIR_Comm * comm_ptr)
{
- int in_use;
+ int in_use,thr_err;
int mpi_errno = MPI_SUCCESS;
MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_COMM_DELETE_INTERNAL);
@@ -999,6 +1003,10 @@ int MPIR_Comm_delete_internal(MPIR_Comm * comm_ptr)
* allocated out of the remote group's bit vector, not ours. */
MPIR_Free_contextid(comm_ptr->recvcontext_id);
+#if MPICH_THREAD_GRANULARITY == MPICH_THREAD_GRANULARITY__POBJ
+ MPID_Thread_mutex_destroy(&MPIR_THREAD_POBJ_COMM_MUTEX(comm_ptr), &thr_err);
+ MPIR_Assert(thr_err == 0);
+#endif
/* We need to release the error handler */
if (comm_ptr->errhandler &&
!(HANDLE_GET_KIND(comm_ptr->errhandler->handle) == HANDLE_KIND_BUILTIN)) {
-----------------------------------------------------------------------
Summary of changes:
src/include/mpir_debugger.h | 2 ++
src/include/mpir_request.h | 3 +++
src/mpi/comm/commutil.c | 12 ++++++++++--
src/mpi/comm/contextid.c | 8 ++++++--
.../ch3/channels/nemesis/netmod/ofi/ofi_impl.h | 1 -
src/mpid/ch3/include/mpidimpl.h | 10 +---------
6 files changed, 22 insertions(+), 14 deletions(-)
hooks/post-receive
--
MPICH primary repository
1
0
[mpich] MPICH primary repository branch, master, updated. v3.2-342-gff7e3f3
by noreply@mpich.org 12 Jul '16
by noreply@mpich.org 12 Jul '16
12 Jul '16
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "MPICH primary repository".
The branch, master has been updated
via ff7e3f37effa1132126dfe9616b8a563c61cc91b (commit)
from 702baeed4b46166aea2b292ac556f0b2589cc8f3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.mpich.org/mpich.git/commitdiff/ff7e3f37effa1132126dfe9616b8a563c…
commit ff7e3f37effa1132126dfe9616b8a563c61cc91b
Author: Ken Raffenetti <raffenet(a)mcs.anl.gov>
Date: Mon Jul 11 15:58:34 2016 -0500
test/mpi/topo: add sentinel value to baddims.h
Ensure proper loop termniation when testing values from baddims.h.
No reviewer.
diff --git a/test/mpi/topo/baddims.h b/test/mpi/topo/baddims.h
index 25b8130..cfe257a 100644
--- a/test/mpi/topo/baddims.h
+++ b/test/mpi/topo/baddims.h
@@ -75392,3 +75392,4 @@
{ 884736, 16, {4,4,3,3,3,2,2,2,2,2,2,2,2,2,2,2}},
{ 995328, 16, {4,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2}},
{ 884736, 17, {4,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2}},
+{ 0, 0, {0}} /* sentinel value - must stay at the end! */
-----------------------------------------------------------------------
Summary of changes:
test/mpi/topo/baddims.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
hooks/post-receive
--
MPICH primary repository
1
0