Next step in reducing launch time: begin reducing the size of the launch message itself. Start by expressing the daemon map as a set of three regular expression strings. On an 8k cluster, this reduces the nidmap contribution from over 200kBytes to 21 bytes in size.
Signed-off-by: Ralph Castain <rhc@open-mpi.org>
Этот коммит содержится в:
родитель
f3920828ed
Коммит
86ab751c5e
@ -374,35 +374,18 @@ static void xcast_recv(int status, orte_process_name_t* sender,
|
||||
orte_orteds_term_ordered = true;
|
||||
} else if (ORTE_DAEMON_ADD_LOCAL_PROCS == command ||
|
||||
ORTE_DAEMON_DVM_NIDMAP_CMD == command) {
|
||||
/* extract the byte object holding the daemonmap */
|
||||
cnt=1;
|
||||
if (ORTE_SUCCESS != (ret = opal_dss.unpack(data, &bo, &cnt, OPAL_BYTE_OBJECT))) {
|
||||
/* update our local nidmap, if required - the decode function
|
||||
* knows what to do
|
||||
*/
|
||||
OPAL_OUTPUT_VERBOSE((5, orte_grpcomm_base_framework.framework_output,
|
||||
"%s grpcomm:direct:xcast updating daemon nidmap",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_util_decode_daemon_nodemap(data))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
goto relay;
|
||||
}
|
||||
|
||||
/* update our local nidmap, if required - the decode function
|
||||
* knows what to do - it will also free the bytes in the byte object
|
||||
*/
|
||||
if (ORTE_PROC_IS_HNP) {
|
||||
/* no need - already have the info */
|
||||
if (NULL != bo) {
|
||||
if (NULL != bo->bytes) {
|
||||
free(bo->bytes);
|
||||
}
|
||||
free(bo);
|
||||
}
|
||||
} else {
|
||||
OPAL_OUTPUT_VERBOSE((5, orte_grpcomm_base_framework.framework_output,
|
||||
"%s grpcomm:direct:xcast updating daemon nidmap",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_util_decode_daemon_nodemap(bo))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
goto relay;
|
||||
}
|
||||
}
|
||||
|
||||
/* update the routing plan */
|
||||
orte_routed.update_routing_plan(rtmod);
|
||||
|
||||
|
@ -77,7 +77,6 @@
|
||||
#include "orte/util/session_dir.h"
|
||||
#include "orte/util/proc_info.h"
|
||||
#include "orte/util/nidmap.h"
|
||||
#include "orte/util/regex.h"
|
||||
#include "orte/util/show_help.h"
|
||||
#include "orte/runtime/orte_globals.h"
|
||||
#include "orte/runtime/orte_wait.h"
|
||||
@ -138,21 +137,12 @@ int orte_odls_base_default_get_add_procs_data(opal_buffer_t *buffer,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* construct a nodemap - only want updated items */
|
||||
if (ORTE_SUCCESS != (rc = orte_util_encode_nodemap(&bo, true))) {
|
||||
/* construct a nodemap of the daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_util_encode_nodemap(buffer))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* store it */
|
||||
boptr = &bo;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(buffer, &boptr, 1, OPAL_BYTE_OBJECT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
/* release the data since it has now been copied into our buffer */
|
||||
free(bo.bytes);
|
||||
|
||||
/* if we are not using static ports, we need to send the wireup info */
|
||||
if (!orte_static_ports) {
|
||||
/* pack a flag indicating wiring info is provided */
|
||||
|
@ -1059,41 +1059,12 @@ void orte_plm_base_daemon_callback(int status, orte_process_name_t* sender,
|
||||
"%s plm:base:orted_report_launch attempting to assign daemon %s to node %s",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
ORTE_NAME_PRINT(&dname), nodename));
|
||||
for (idx=0; idx < orte_node_pool->size; idx++) {
|
||||
if (NULL == (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, idx))) {
|
||||
continue;
|
||||
}
|
||||
if (ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_LOC_VERIFIED)) {
|
||||
/* already assigned */
|
||||
continue;
|
||||
}
|
||||
if (0 == strcmp(nodename, node->name)) {
|
||||
/* flag that we verified the location */
|
||||
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_LOC_VERIFIED);
|
||||
if (node == daemon->node) {
|
||||
/* it wound up right where it should */
|
||||
break;
|
||||
}
|
||||
/* remove the prior association */
|
||||
if (NULL != daemon->node) {
|
||||
OBJ_RELEASE(daemon->node);
|
||||
}
|
||||
if (NULL != node->daemon) {
|
||||
OBJ_RELEASE(node->daemon);
|
||||
}
|
||||
/* associate this daemon with the node */
|
||||
node->daemon = daemon;
|
||||
OBJ_RETAIN(daemon);
|
||||
/* associate this node with the daemon */
|
||||
daemon->node = node;
|
||||
OBJ_RETAIN(node);
|
||||
OPAL_OUTPUT_VERBOSE((5, orte_plm_base_framework.framework_output,
|
||||
"%s plm:base:orted_report_launch assigning daemon %s to node %s",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
ORTE_NAME_PRINT(&daemon->name), node->name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* to "relocate" the daemon, we just update the name of
|
||||
* the node object pointed to by this daemon */
|
||||
free(daemon->node->name);
|
||||
daemon->node->name = strdup(nodename);
|
||||
/* mark that it was verified */
|
||||
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_LOC_VERIFIED);
|
||||
}
|
||||
|
||||
node = daemon->node;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* reserved.
|
||||
* Copyright (c) 2008-2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Copyright (c) 2011 IBM Corporation. All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2015-2017 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -780,7 +780,6 @@ static int remote_spawn(opal_buffer_t *launch)
|
||||
int rc=ORTE_SUCCESS;
|
||||
bool failed_launch = true;
|
||||
orte_std_cntr_t n;
|
||||
opal_byte_object_t *bo;
|
||||
orte_process_name_t target;
|
||||
orte_plm_rsh_caddy_t *caddy;
|
||||
orte_job_t *daemons;
|
||||
@ -802,23 +801,8 @@ static int remote_spawn(opal_buffer_t *launch)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* extract the byte object holding the nidmap */
|
||||
n=1;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.unpack(launch, &bo, &n, OPAL_BYTE_OBJECT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
/* update our nidmap - this will free data in the byte object */
|
||||
if (ORTE_SUCCESS != (rc = orte_util_decode_daemon_nodemap(bo))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* ensure the routing plan is updated */
|
||||
rtmod = orte_rml.get_routed(orte_coll_conduit);
|
||||
orte_routed.update_routing_plan(rtmod);
|
||||
|
||||
/* get the updated routing list */
|
||||
rtmod = orte_rml.get_routed(orte_coll_conduit);
|
||||
OBJ_CONSTRUCT(&coll, opal_list_t);
|
||||
orte_routed.get_routing_list(rtmod, &coll);
|
||||
|
||||
@ -1124,7 +1108,6 @@ static void launch_daemons(int fd, short args, void *cbdata)
|
||||
/* if we are tree launching, find our children and create the launch cmd */
|
||||
if (!mca_plm_rsh_component.no_tree_spawn) {
|
||||
orte_daemon_cmd_flag_t command = ORTE_DAEMON_TREE_SPAWN;
|
||||
opal_byte_object_t bo, *boptr;
|
||||
orte_job_t *jdatorted;
|
||||
|
||||
/* get the tree spawn buffer */
|
||||
@ -1142,21 +1125,12 @@ static void launch_daemons(int fd, short args, void *cbdata)
|
||||
goto cleanup;
|
||||
}
|
||||
/* construct a nodemap of all daemons we know about */
|
||||
if (ORTE_SUCCESS != (rc = orte_util_encode_nodemap(&bo, false))) {
|
||||
if (ORTE_SUCCESS != (rc = orte_util_encode_nodemap(orte_tree_launch_cmd))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(orte_tree_launch_cmd);
|
||||
goto cleanup;
|
||||
}
|
||||
/* store it */
|
||||
boptr = &bo;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(orte_tree_launch_cmd, &boptr, 1, OPAL_BYTE_OBJECT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(orte_tree_launch_cmd);
|
||||
free(bo.bytes);
|
||||
goto cleanup;
|
||||
}
|
||||
/* release the data since it has now been copied into our buffer */
|
||||
free(bo.bytes);
|
||||
|
||||
/* get the orted job data object */
|
||||
if (NULL == (jdatorted = orte_get_job_data_object(ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Intel, Inc. All rights reserved
|
||||
* Copyright (c) 2015-2017 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -260,22 +260,12 @@ static void vm_ready(int fd, short args, void *cbdata)
|
||||
return;
|
||||
}
|
||||
/* construct a nodemap with everything in it */
|
||||
if (ORTE_SUCCESS != (rc = orte_util_encode_nodemap(&bo, false))) {
|
||||
if (ORTE_SUCCESS != (rc = orte_util_encode_nodemap(buf))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* store it */
|
||||
boptr = &bo;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(buf, &boptr, 1, OPAL_BYTE_OBJECT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buf);
|
||||
return;
|
||||
}
|
||||
/* release the data since it has now been copied into our buffer */
|
||||
free(bo.bytes);
|
||||
|
||||
/* pack a flag indicating wiring info is provided */
|
||||
flag = 1;
|
||||
opal_dss.pack(buf, &flag, 1, OPAL_INT8);
|
||||
|
@ -12,7 +12,7 @@
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2012-2014 Los Alamos National Security, LLC.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2013-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2013-2017 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Research Organization for Information Science
|
||||
* and Technology (RIST). All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
@ -184,134 +184,508 @@ int orte_util_build_daemon_nidmap(char **nodes)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int orte_util_encode_nodemap(opal_byte_object_t *boptr, bool update)
|
||||
int orte_util_encode_nodemap(opal_buffer_t *buffer)
|
||||
{
|
||||
orte_node_t *node;
|
||||
int32_t i;
|
||||
char *node;
|
||||
char prefix[ORTE_MAX_NODE_PREFIX];
|
||||
int i, j, n, len, startnum, nodenum, numdigits;
|
||||
bool found, fullname;
|
||||
char *suffix, *sfx;
|
||||
orte_regex_node_t *ndreg;
|
||||
orte_regex_range_t *range, *rng, *idrng;
|
||||
opal_list_t nodeids, nodenms, dvpids;
|
||||
opal_list_item_t *item, *itm2;
|
||||
char **regexargs = NULL, *tmp, *tmp2;
|
||||
orte_node_t *nptr;
|
||||
int rc;
|
||||
opal_buffer_t buf;
|
||||
orte_job_t *daemons;
|
||||
orte_proc_t *dmn;
|
||||
|
||||
/* if the daemon job has not been updated, then there is
|
||||
* nothing to send
|
||||
*/
|
||||
daemons = orte_get_job_data_object(ORTE_PROC_MY_NAME->jobid);
|
||||
if (update && !ORTE_FLAG_TEST(daemons, ORTE_JOB_FLAG_UPDATED)) {
|
||||
boptr->bytes = NULL;
|
||||
boptr->size = 0;
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
/* setup the list of results */
|
||||
OBJ_CONSTRUCT(&nodeids, opal_list_t);
|
||||
OBJ_CONSTRUCT(&nodenms, opal_list_t);
|
||||
OBJ_CONSTRUCT(&dvpids, opal_list_t);
|
||||
|
||||
/* setup a buffer for tmp use */
|
||||
OBJ_CONSTRUCT(&buf, opal_buffer_t);
|
||||
|
||||
/* send the number of nodes */
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(&buf, &daemons->num_procs, 1, ORTE_VPID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i=0; i < daemons->procs->size; i++) {
|
||||
if (NULL == (dmn = (orte_proc_t*)opal_pointer_array_get_item(daemons->procs, i))) {
|
||||
rng = NULL;
|
||||
idrng = NULL;
|
||||
for (n=0; n < orte_node_pool->size; n++) {
|
||||
if (NULL == (nptr = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, n))) {
|
||||
continue;
|
||||
}
|
||||
/* if the daemon doesn't have a node, that's an error */
|
||||
if (NULL == (node = dmn->node)) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND);
|
||||
return ORTE_ERR_NOT_FOUND;
|
||||
/* if no daemon has been assigned, then this node is not being used */
|
||||
if (NULL == nptr->daemon) {
|
||||
continue;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(&buf, &dmn->name.vpid, 1, ORTE_VPID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
/* deal with the nodeids - these are just the index into
|
||||
* the node array. We pass these to ensure coherence across
|
||||
* the virtual machine */
|
||||
if (NULL == idrng) {
|
||||
/* just starting */
|
||||
idrng = OBJ_NEW(orte_regex_range_t);
|
||||
idrng->start = n;
|
||||
idrng->cnt = 1;
|
||||
opal_list_append(&nodeids, &idrng->super);
|
||||
} else {
|
||||
/* is this the next in line */
|
||||
if (n == (idrng->start + idrng->cnt)) {
|
||||
idrng->cnt++;
|
||||
} else {
|
||||
/* need to start another range */
|
||||
idrng = OBJ_NEW(orte_regex_range_t);
|
||||
idrng->start = n;
|
||||
opal_list_append(&nodeids, &idrng->super);
|
||||
}
|
||||
}
|
||||
/* pack the node */
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(&buf, &node, 1, ORTE_NODE))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
/* deal with the daemon vpid - see if it is next in the
|
||||
* current range */
|
||||
if (NULL == rng) {
|
||||
/* just starting */
|
||||
rng = OBJ_NEW(orte_regex_range_t);
|
||||
rng->start = nptr->daemon->name.vpid;
|
||||
rng->cnt = 1;
|
||||
opal_list_append(&dvpids, &rng->super);
|
||||
} else {
|
||||
/* is this the next in line */
|
||||
if (nptr->daemon->name.vpid == (orte_vpid_t)(rng->start + rng->cnt)) {
|
||||
rng->cnt++;
|
||||
} else {
|
||||
/* need to start another range */
|
||||
rng = OBJ_NEW(orte_regex_range_t);
|
||||
rng->start = nptr->daemon->name.vpid;
|
||||
opal_list_append(&dvpids, &rng->super);
|
||||
}
|
||||
}
|
||||
node = nptr->name;
|
||||
/* determine this node's prefix by looking for first non-alpha char */
|
||||
fullname = false;
|
||||
len = strlen(node);
|
||||
startnum = -1;
|
||||
memset(prefix, 0, ORTE_MAX_NODE_PREFIX);
|
||||
numdigits = 0;
|
||||
for (i=0, j=0; i < len; i++) {
|
||||
if (!isalpha(node[i])) {
|
||||
/* found a non-alpha char */
|
||||
if (!isdigit(node[i])) {
|
||||
/* if it is anything but a digit, we just use
|
||||
* the entire name
|
||||
*/
|
||||
fullname = true;
|
||||
break;
|
||||
}
|
||||
/* count the size of the numeric field - but don't
|
||||
* add the digits to the prefix
|
||||
*/
|
||||
numdigits++;
|
||||
if (startnum < 0) {
|
||||
/* okay, this defines end of the prefix */
|
||||
startnum = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (startnum < 0) {
|
||||
prefix[j++] = node[i];
|
||||
}
|
||||
}
|
||||
if (fullname || startnum < 0) {
|
||||
/* can't compress this name - just add it to the list */
|
||||
ndreg = OBJ_NEW(orte_regex_node_t);
|
||||
ndreg->prefix = strdup(node);
|
||||
opal_list_append(&nodenms, &ndreg->super);
|
||||
continue;
|
||||
}
|
||||
/* convert the digits and get any suffix */
|
||||
nodenum = strtol(&node[startnum], &sfx, 10);
|
||||
if (NULL != sfx) {
|
||||
suffix = strdup(sfx);
|
||||
} else {
|
||||
suffix = NULL;
|
||||
}
|
||||
/* is this node name already on our list? */
|
||||
found = false;
|
||||
for (item = opal_list_get_first(&nodenms);
|
||||
!found && item != opal_list_get_end(&nodenms);
|
||||
item = opal_list_get_next(item)) {
|
||||
ndreg = (orte_regex_node_t*)item;
|
||||
if (0 < strlen(prefix) && NULL == ndreg->prefix) {
|
||||
continue;
|
||||
}
|
||||
if (0 == strlen(prefix) && NULL != ndreg->prefix) {
|
||||
continue;
|
||||
}
|
||||
if (0 < strlen(prefix) && NULL != ndreg->prefix
|
||||
&& 0 != strcmp(prefix, ndreg->prefix)) {
|
||||
continue;
|
||||
}
|
||||
if (NULL == suffix && NULL != ndreg->suffix) {
|
||||
continue;
|
||||
}
|
||||
if (NULL != suffix && NULL == ndreg->suffix) {
|
||||
continue;
|
||||
}
|
||||
if (NULL != suffix && NULL != ndreg->suffix &&
|
||||
0 != strcmp(suffix, ndreg->suffix)) {
|
||||
continue;
|
||||
}
|
||||
if (numdigits != ndreg->num_digits) {
|
||||
continue;
|
||||
}
|
||||
/* found a match - flag it */
|
||||
found = true;
|
||||
/* get the last range on this nodeid - we do this
|
||||
* to preserve order
|
||||
*/
|
||||
range = (orte_regex_range_t*)opal_list_get_last(&ndreg->ranges);
|
||||
if (NULL == range) {
|
||||
/* first range for this nodeid */
|
||||
range = OBJ_NEW(orte_regex_range_t);
|
||||
range->start = nodenum;
|
||||
range->cnt = 1;
|
||||
opal_list_append(&ndreg->ranges, &range->super);
|
||||
break;
|
||||
}
|
||||
/* see if the node number is out of sequence */
|
||||
if (nodenum != (range->start + range->cnt)) {
|
||||
/* start a new range */
|
||||
range = OBJ_NEW(orte_regex_range_t);
|
||||
range->start = nodenum;
|
||||
range->cnt = 1;
|
||||
opal_list_append(&ndreg->ranges, &range->super);
|
||||
break;
|
||||
}
|
||||
/* everything matches - just increment the cnt */
|
||||
range->cnt++;
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
/* need to add it */
|
||||
ndreg = OBJ_NEW(orte_regex_node_t);
|
||||
if (0 < strlen(prefix)) {
|
||||
ndreg->prefix = strdup(prefix);
|
||||
}
|
||||
if (NULL != suffix) {
|
||||
ndreg->suffix = strdup(suffix);
|
||||
}
|
||||
ndreg->num_digits = numdigits;
|
||||
opal_list_append(&nodenms, &ndreg->super);
|
||||
/* record the first range for this nodeid - we took
|
||||
* care of names we can't compress above
|
||||
*/
|
||||
range = OBJ_NEW(orte_regex_range_t);
|
||||
range->start = nodenum;
|
||||
range->cnt = 1;
|
||||
opal_list_append(&ndreg->ranges, &range->super);
|
||||
}
|
||||
if (NULL != suffix) {
|
||||
free(suffix);
|
||||
}
|
||||
}
|
||||
|
||||
/* transfer the payload to the byte object */
|
||||
opal_dss.unload(&buf, (void**)&boptr->bytes, &boptr->size);
|
||||
OBJ_DESTRUCT(&buf);
|
||||
/* begin constructing the regular expression */
|
||||
while (NULL != (item = opal_list_remove_first(&nodenms))) {
|
||||
ndreg = (orte_regex_node_t*)item;
|
||||
|
||||
/* if no ranges, then just add the name */
|
||||
if (0 == opal_list_get_size(&ndreg->ranges)) {
|
||||
if (NULL != ndreg->prefix) {
|
||||
/* solitary node */
|
||||
asprintf(&tmp, "%s", ndreg->prefix);
|
||||
opal_argv_append_nosize(®exargs, tmp);
|
||||
free(tmp);
|
||||
}
|
||||
OBJ_RELEASE(ndreg);
|
||||
continue;
|
||||
}
|
||||
/* start the regex for this nodeid with the prefix */
|
||||
if (NULL != ndreg->prefix) {
|
||||
asprintf(&tmp, "%s[%d:", ndreg->prefix, ndreg->num_digits);
|
||||
} else {
|
||||
asprintf(&tmp, "[%d:", ndreg->num_digits);
|
||||
}
|
||||
/* add the ranges */
|
||||
while (NULL != (itm2 = opal_list_remove_first(&ndreg->ranges))) {
|
||||
range = (orte_regex_range_t*)itm2;
|
||||
if (1 == range->cnt) {
|
||||
asprintf(&tmp2, "%s%d,", tmp, range->start);
|
||||
} else {
|
||||
asprintf(&tmp2, "%s%d-%d,", tmp, range->start, range->start + range->cnt - 1);
|
||||
}
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
OBJ_RELEASE(range);
|
||||
}
|
||||
/* replace the final comma */
|
||||
tmp[strlen(tmp)-1] = ']';
|
||||
if (NULL != ndreg->suffix) {
|
||||
/* add in the suffix, if provided */
|
||||
asprintf(&tmp2, "%s%s", tmp, ndreg->suffix);
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
opal_argv_append_nosize(®exargs, tmp);
|
||||
free(tmp);
|
||||
OBJ_RELEASE(ndreg);
|
||||
}
|
||||
|
||||
/* assemble final result */
|
||||
tmp = opal_argv_join(regexargs, ',');
|
||||
/* cleanup */
|
||||
opal_argv_free(regexargs);
|
||||
OBJ_DESTRUCT(&nodenms);
|
||||
|
||||
/* pack the string */
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(buffer, &tmp, 1, OPAL_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OPAL_LIST_DESTRUCT(&dvpids);
|
||||
return rc;
|
||||
}
|
||||
if (NULL != tmp) {
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* do the same for the indices */
|
||||
tmp = NULL;
|
||||
while (NULL != (item = opal_list_remove_first(&nodeids))) {
|
||||
rng = (orte_regex_range_t*)item;
|
||||
if (1 < rng->cnt) {
|
||||
if (NULL == tmp) {
|
||||
asprintf(&tmp, "%d-%d", rng->start, rng->start + rng->cnt - 1);
|
||||
} else {
|
||||
asprintf(&tmp2, "%s,%d-%d", tmp, rng->start, rng->start + rng->cnt - 1);
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
} else {
|
||||
if (NULL == tmp) {
|
||||
asprintf(&tmp, "%d", rng->start);
|
||||
} else {
|
||||
asprintf(&tmp2, "%s,%d", tmp, rng->start);
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
}
|
||||
OBJ_RELEASE(rng);
|
||||
}
|
||||
OPAL_LIST_DESTRUCT(&nodeids);
|
||||
|
||||
/* pack the string */
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(buffer, &tmp, 1, OPAL_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OPAL_LIST_DESTRUCT(&dvpids);
|
||||
return rc;
|
||||
}
|
||||
if (NULL != tmp) {
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* do the same for the vpids */
|
||||
tmp = NULL;
|
||||
while (NULL != (item = opal_list_remove_first(&dvpids))) {
|
||||
rng = (orte_regex_range_t*)item;
|
||||
if (1 < rng->cnt) {
|
||||
if (NULL == tmp) {
|
||||
asprintf(&tmp, "%d-%d", rng->start, rng->start + rng->cnt - 1);
|
||||
} else {
|
||||
asprintf(&tmp2, "%s,%d-%d", tmp, rng->start, rng->start + rng->cnt - 1);
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
} else {
|
||||
if (NULL == tmp) {
|
||||
asprintf(&tmp, "%d", rng->start);
|
||||
} else {
|
||||
asprintf(&tmp2, "%s,%d", tmp, rng->start);
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
}
|
||||
OBJ_RELEASE(rng);
|
||||
}
|
||||
OPAL_LIST_DESTRUCT(&dvpids);
|
||||
|
||||
/* pack the string */
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.pack(buffer, &tmp, 1, OPAL_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OPAL_LIST_DESTRUCT(&dvpids);
|
||||
return rc;
|
||||
}
|
||||
if (NULL != tmp) {
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* decode a nodemap for a daemon */
|
||||
int orte_util_decode_daemon_nodemap(opal_byte_object_t *bo)
|
||||
int orte_util_decode_daemon_nodemap(opal_buffer_t *buffer)
|
||||
{
|
||||
int n;
|
||||
orte_vpid_t vpid;
|
||||
orte_node_t *node, *nptr;
|
||||
opal_buffer_t buf;
|
||||
int rc=ORTE_SUCCESS;
|
||||
int k, m, n, rc, start, endpt;
|
||||
orte_node_t *node;
|
||||
size_t num_nodes;
|
||||
orte_job_t *daemons;
|
||||
orte_proc_t *dptr;
|
||||
orte_vpid_t num_daemons;
|
||||
char **nodes, *indices, *dvpids;
|
||||
char *ndnames, *rmndr, **tmp;
|
||||
int *nodeids, *dids;
|
||||
|
||||
if (NULL == bo->bytes || 0 == bo->size) {
|
||||
/* nothing to unpack */
|
||||
/* unpack the node regex */
|
||||
n = 1;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.unpack(buffer, &ndnames, &n, OPAL_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
/* it is okay for this to be NULL */
|
||||
if (NULL == ndnames) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* xfer the byte object to a buffer for unpacking */
|
||||
OBJ_CONSTRUCT(&buf, opal_buffer_t);
|
||||
opal_dss.load(&buf, bo->bytes, bo->size);
|
||||
|
||||
/* unpack the number of procs */
|
||||
n=1;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.unpack(&buf, &num_daemons, &n, ORTE_VPID))) {
|
||||
/* unpack the index regex */
|
||||
n = 1;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.unpack(buffer, &indices, &n, OPAL_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
free(ndnames);
|
||||
return rc;
|
||||
}
|
||||
/* this is not allowed to be NULL */
|
||||
if (NULL == indices) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
|
||||
free(ndnames);
|
||||
return ORTE_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
/* transfer the data to the nodes */
|
||||
daemons = orte_get_job_data_object(ORTE_PROC_MY_NAME->jobid);
|
||||
daemons->num_procs = num_daemons;
|
||||
n=1;
|
||||
while (OPAL_SUCCESS == (rc = opal_dss.unpack(&buf, &vpid, &n, ORTE_VPID))) {
|
||||
/* unpack and store the node */
|
||||
n=1;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.unpack(&buf, &node, &n, ORTE_NODE))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
/* unpack the daemon vpid regex */
|
||||
n = 1;
|
||||
if (ORTE_SUCCESS != (rc = opal_dss.unpack(buffer, &dvpids, &n, OPAL_STRING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
free(ndnames);
|
||||
free(indices);
|
||||
return rc;
|
||||
}
|
||||
/* this is not allowed to be NULL */
|
||||
if (NULL == dvpids) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
|
||||
free(ndnames);
|
||||
free(indices);
|
||||
return ORTE_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
/* if we are the HNP, then we just discard these strings as we already
|
||||
* have a complete picture - but we needed to unpack them in order to
|
||||
* maintain sync in the unpacking order */
|
||||
if (ORTE_PROC_IS_HNP) {
|
||||
free(ndnames);
|
||||
free(indices);
|
||||
free(dvpids);
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* decompress the regex */
|
||||
nodes = NULL;
|
||||
if (ORTE_SUCCESS != (rc = orte_regex_extract_node_names(ndnames, &nodes))) {
|
||||
free(ndnames);
|
||||
free(indices);
|
||||
free(dvpids);
|
||||
return rc;
|
||||
}
|
||||
free(ndnames);
|
||||
|
||||
if (NULL == nodes) {
|
||||
/* should not happen */
|
||||
free(indices);
|
||||
free(dvpids);
|
||||
return ORTE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* decompress the index ranges */
|
||||
num_nodes = opal_argv_count(nodes);
|
||||
nodeids = (int*)malloc(num_nodes * sizeof(int));
|
||||
tmp = opal_argv_split(indices, ',');
|
||||
k = 0;
|
||||
for (n=0; NULL != tmp[n]; n++) {
|
||||
/* convert the number - since it might be a range,
|
||||
* save the remainder pointer */
|
||||
nodeids[k] = strtoul(tmp[n], &rmndr, 10);
|
||||
if (NULL != rmndr) {
|
||||
/* it must be a range - find the endpoint */
|
||||
++rmndr;
|
||||
endpt = strtoul(rmndr, NULL, 10);
|
||||
start = nodeids[k] + 1;
|
||||
for (m=0; m < endpt; m++) {
|
||||
++k;
|
||||
nodeids[k] = start + m;
|
||||
}
|
||||
}
|
||||
/* set the nodeid */
|
||||
node->index = vpid;
|
||||
/* do we already have this node? */
|
||||
nptr = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, vpid);
|
||||
/* set the new node object into the array */
|
||||
opal_pointer_array_set_item(orte_node_pool, vpid, node);
|
||||
if (NULL == (dptr = (orte_proc_t*)opal_pointer_array_get_item(daemons->procs, vpid))) {
|
||||
++k;
|
||||
}
|
||||
opal_argv_free(tmp);
|
||||
free(indices);
|
||||
|
||||
/* decompress the vpids */
|
||||
dids = (int*)malloc(num_nodes * sizeof(int));
|
||||
tmp = opal_argv_split(dvpids, ',');
|
||||
k = 0;
|
||||
for (n=0; NULL != tmp[n]; n++) {
|
||||
/* convert the number - since it might be a range,
|
||||
* save the remainder pointer */
|
||||
dids[k] = strtoul(tmp[n], &rmndr, 10);
|
||||
if (NULL != rmndr) {
|
||||
/* it must be a range - find the endpoint */
|
||||
++rmndr;
|
||||
endpt = strtoul(rmndr, NULL, 10);
|
||||
start = dids[k] + 1;
|
||||
for (m=0; m < endpt; m++) {
|
||||
++k;
|
||||
dids[k] = start + m;
|
||||
}
|
||||
}
|
||||
++k;
|
||||
}
|
||||
opal_argv_free(tmp);
|
||||
free(dvpids);
|
||||
|
||||
daemons = orte_get_job_data_object(ORTE_PROC_MY_NAME->jobid);
|
||||
/* since this is a complete picture of all the nodes, reset the
|
||||
* counters and regenerate them */
|
||||
orte_process_info.num_daemons = 0;
|
||||
orte_process_info.num_nodes = 0;
|
||||
daemons->num_procs = 0;
|
||||
|
||||
/* update the node array */
|
||||
for (n=0; NULL != nodes[n]; n++) {
|
||||
if (NULL == (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, nodeids[n]))) {
|
||||
node = OBJ_NEW(orte_node_t);
|
||||
node->name = nodes[n];
|
||||
node->index = nodeids[n];
|
||||
opal_pointer_array_set_item(orte_node_pool, node->index, node);
|
||||
} else if (NULL != node->daemon) {
|
||||
OBJ_RELEASE(node->daemon);
|
||||
node->daemon = NULL;
|
||||
}
|
||||
++orte_process_info.num_nodes;
|
||||
if (NULL == (dptr = (orte_proc_t*)opal_pointer_array_get_item(daemons->procs, dids[n]))) {
|
||||
/* create a daemon object for this node */
|
||||
dptr = OBJ_NEW(orte_proc_t);
|
||||
dptr->name.jobid = ORTE_PROC_MY_NAME->jobid;
|
||||
dptr->name.vpid = vpid;
|
||||
dptr->name.vpid = dids[n];
|
||||
ORTE_FLAG_SET(dptr, ORTE_PROC_FLAG_ALIVE); // assume the daemon is alive until discovered otherwise
|
||||
opal_pointer_array_set_item(daemons->procs, vpid, dptr);
|
||||
}
|
||||
if (NULL != node->daemon) {
|
||||
OBJ_RELEASE(node->daemon);
|
||||
opal_pointer_array_set_item(daemons->procs, dids[n], dptr);
|
||||
} else if (NULL != dptr->node) {
|
||||
OBJ_RELEASE(dptr->node);
|
||||
dptr->node = NULL;
|
||||
}
|
||||
++daemons->num_procs;
|
||||
/* link the node to the daemon */
|
||||
OBJ_RETAIN(dptr);
|
||||
node->daemon = dptr;
|
||||
if (NULL != dptr->node) {
|
||||
OBJ_RELEASE(dptr->node);
|
||||
}
|
||||
/* link the node to the daemon */
|
||||
OBJ_RETAIN(node);
|
||||
if (NULL != nptr) {
|
||||
OBJ_RELEASE(nptr);
|
||||
}
|
||||
dptr->node = node;
|
||||
}
|
||||
if (ORTE_ERR_UNPACK_READ_PAST_END_OF_BUFFER != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&buf);
|
||||
return rc;
|
||||
}
|
||||
rc = ORTE_SUCCESS;
|
||||
/* we cannot use opal_argv_free here as this would release
|
||||
* all the node names themselves. Instead, we just free the
|
||||
* array of string pointers, leaving the strings alone */
|
||||
free(nodes);
|
||||
free(nodeids);
|
||||
free(dids);
|
||||
|
||||
/* unpdate num procs */
|
||||
orte_process_info.num_procs = daemons->num_procs;
|
||||
|
||||
if (orte_process_info.max_procs < orte_process_info.num_procs) {
|
||||
@ -334,6 +708,5 @@ int orte_util_decode_daemon_nodemap(opal_byte_object_t *bo)
|
||||
}
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT(&buf);
|
||||
return rc;
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
||||
* Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -41,8 +41,13 @@ BEGIN_C_DECLS
|
||||
#define ORTE_CONTIG_NODE_CMD 0x01
|
||||
#define ORTE_NON_CONTIG_NODE_CMD 0x02
|
||||
|
||||
ORTE_DECLSPEC int orte_util_encode_nodemap(opal_byte_object_t *boptr, bool update);
|
||||
ORTE_DECLSPEC int orte_util_decode_daemon_nodemap(opal_byte_object_t *bo);
|
||||
/* create a regular expression describing the nodes in the
|
||||
* allocation */
|
||||
ORTE_DECLSPEC int orte_util_encode_nodemap(opal_buffer_t *buffer);
|
||||
|
||||
/* decode a regular expression created by the encode function
|
||||
* into the orte_node_pool array */
|
||||
ORTE_DECLSPEC int orte_util_decode_daemon_nodemap(opal_buffer_t *buffer);
|
||||
|
||||
ORTE_DECLSPEC int orte_util_build_daemon_nidmap(char **nodes);
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2013 Cisco Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2017 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
|
@ -9,6 +9,7 @@
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2017 Intel, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user