2008-02-28 04:57:57 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2015-06-24 06:59:57 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
2008-02-28 04:57:57 +03:00
|
|
|
* University of Stuttgart. All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2014-01-08 19:17:16 +04:00
|
|
|
* Copyright (c) 2013 Cisco Systems, Inc. All rights reserved.
|
Per the discussion on the telecon, change the -host behavior so we only run one instance if no slots were provided and the user didn't specify #procs to run. However, if no slots are given and the user does specify #procs, then let the number of slots default to the #found processing elements
Ensure the returned exit status is non-zero if we fail to map
If no -np is given, but either -host and/or -hostfile was given, then error out with a message telling the user that this combination is not supported.
If -np is given, and -host is given with only one instance of each host, then default the #slots to the detected #pe's and enforce oversubscription rules.
If -np is given, and -host is given with more than one instance of a given host, then set the #slots for that host to the number of times it was given and enforce oversubscription rules. Alternatively, the #slots can be specified via "-host foo:N". I therefore believe that row #7 on Jeff's spreadsheet is incorrect.
With that one correction, this now passes all the given use-cases on that spreadsheet.
Make things behave under unmanaged allocations more like their managed cousins - if the #slots is given, then no-np shall fill things up.
Fixes #1344
2016-02-10 20:17:03 +03:00
|
|
|
* Copyright (c) 2014-2016 Intel, Inc. All rights reserved.
|
2015-03-02 14:06:27 +03:00
|
|
|
* Copyright (c) 2015 Research Organization for Information Science
|
|
|
|
* and Technology (RIST). All rights reserved.
|
2016-08-25 20:57:00 +03:00
|
|
|
* Copyright (c) 2016 IBM Corporation. All rights reserved.
|
2008-02-28 04:57:57 +03:00
|
|
|
* $COPYRIGHT$
|
2015-06-24 06:59:57 +03:00
|
|
|
*
|
2008-02-28 04:57:57 +03:00
|
|
|
* Additional copyrights may follow
|
2015-06-24 06:59:57 +03:00
|
|
|
*
|
2008-02-28 04:57:57 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "orte_config.h"
|
2009-03-13 05:10:32 +03:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "orte/constants.h"
|
|
|
|
#include "orte/types.h"
|
|
|
|
|
2008-06-09 18:53:58 +04:00
|
|
|
#include "orte/util/show_help.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "opal/util/argv.h"
|
|
|
|
#include "opal/util/if.h"
|
2016-09-02 19:33:34 +03:00
|
|
|
#include "opal/util/net.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
|
2014-01-08 19:17:16 +04:00
|
|
|
#include "orte/mca/ras/base/base.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "orte/mca/plm/plm_types.h"
|
2010-03-08 12:54:49 +03:00
|
|
|
#include "orte/mca/errmgr/errmgr.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "orte/util/proc_info.h"
|
|
|
|
#include "orte/runtime/orte_globals.h"
|
|
|
|
|
|
|
|
#include "dash_host.h"
|
|
|
|
|
2008-08-19 19:16:27 +04:00
|
|
|
/* we can only enter this routine if no other allocation
|
|
|
|
* was found, so we only need to know that finding any
|
|
|
|
* relative node syntax should generate an immediate error
|
|
|
|
*/
|
2008-02-28 04:57:57 +03:00
|
|
|
int orte_util_add_dash_host_nodes(opal_list_t *nodes,
|
2015-11-01 05:00:46 +03:00
|
|
|
char *hosts, bool allocating)
|
2008-02-28 04:57:57 +03:00
|
|
|
{
|
2013-12-21 05:38:27 +04:00
|
|
|
opal_list_item_t *item, *itm;
|
2008-02-28 04:57:57 +03:00
|
|
|
orte_std_cntr_t i, j, k;
|
2015-11-01 05:00:46 +03:00
|
|
|
int rc, nodeidx;
|
2014-06-01 20:14:10 +04:00
|
|
|
char **host_argv=NULL;
|
2015-03-17 02:25:01 +03:00
|
|
|
char **mapped_nodes = NULL, **mini_map, *ndname;
|
2013-12-21 05:38:27 +04:00
|
|
|
orte_node_t *node, *nd;
|
|
|
|
opal_list_t adds;
|
|
|
|
bool found;
|
2015-12-17 02:30:40 +03:00
|
|
|
int slots=0;
|
2015-05-01 06:33:43 +03:00
|
|
|
bool slots_given;
|
|
|
|
char *cptr;
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2014-01-08 19:17:16 +04:00
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
|
2015-11-01 05:00:46 +03:00
|
|
|
"%s dashhost: parsing args %s",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hosts));
|
2014-01-08 19:17:16 +04:00
|
|
|
|
2013-12-21 05:38:27 +04:00
|
|
|
OBJ_CONSTRUCT(&adds, opal_list_t);
|
2014-06-01 20:14:10 +04:00
|
|
|
host_argv = opal_argv_split(hosts, ',');
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
/* Accumulate all of the host name mappings */
|
2008-03-06 01:12:27 +03:00
|
|
|
for (j = 0; j < opal_argv_count(host_argv); ++j) {
|
|
|
|
mini_map = opal_argv_split(host_argv[j], ',');
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-03-06 01:12:27 +03:00
|
|
|
if (mapped_nodes == NULL) {
|
|
|
|
mapped_nodes = mini_map;
|
|
|
|
} else {
|
|
|
|
for (k = 0; NULL != mini_map[k]; ++k) {
|
2015-06-24 06:59:57 +03:00
|
|
|
rc = opal_argv_append_nosize(&mapped_nodes,
|
2008-03-06 01:12:27 +03:00
|
|
|
mini_map[k]);
|
|
|
|
if (OPAL_SUCCESS != rc) {
|
2015-03-02 14:06:27 +03:00
|
|
|
opal_argv_free(host_argv);
|
|
|
|
opal_argv_free(mini_map);
|
2008-03-06 01:12:27 +03:00
|
|
|
goto cleanup;
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
|
|
|
}
|
2015-11-05 18:57:54 +03:00
|
|
|
opal_argv_free(mini_map);
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
|
|
|
}
|
2015-03-02 14:06:27 +03:00
|
|
|
opal_argv_free(host_argv);
|
2015-11-01 05:00:46 +03:00
|
|
|
mini_map = NULL;
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
/* Did we find anything? If not, then do nothing */
|
|
|
|
if (NULL == mapped_nodes) {
|
2013-12-21 05:38:27 +04:00
|
|
|
rc = ORTE_SUCCESS;
|
|
|
|
goto cleanup;
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
for (i = 0; NULL != mapped_nodes[i]; ++i) {
|
2008-08-19 19:16:27 +04:00
|
|
|
/* if the specified node contains a relative node syntax,
|
2015-11-01 05:00:46 +03:00
|
|
|
* and we are allocating, then ignore it
|
2008-08-19 19:16:27 +04:00
|
|
|
*/
|
|
|
|
if ('+' == mapped_nodes[i][0]) {
|
2015-11-01 05:00:46 +03:00
|
|
|
if (!allocating) {
|
|
|
|
if ('e' == mapped_nodes[i][1] ||
|
|
|
|
'E' == mapped_nodes[i][1]) {
|
|
|
|
/* request for empty nodes - do they want
|
|
|
|
* all of them?
|
|
|
|
*/
|
|
|
|
if (NULL != (cptr = strchr(mapped_nodes[i], ':'))) {
|
|
|
|
/* the colon indicates a specific # are requested */
|
|
|
|
++cptr;
|
|
|
|
j = strtoul(cptr, NULL, 10);
|
|
|
|
} else if ('\0' != mapped_nodes[0][2]) {
|
|
|
|
j = strtoul(&mapped_nodes[0][2], NULL, 10);
|
|
|
|
} else {
|
|
|
|
/* add them all */
|
|
|
|
j = orte_node_pool->size;
|
|
|
|
}
|
|
|
|
for (k=0; 0 < j && k < orte_node_pool->size; k++) {
|
|
|
|
if (NULL != (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, k))) {
|
|
|
|
if (0 == node->num_procs) {
|
|
|
|
opal_argv_append_nosize(&mini_map, node->name);
|
|
|
|
--j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ('n' == mapped_nodes[i][1] ||
|
|
|
|
'N' == mapped_nodes[i][1]) {
|
|
|
|
/* they want a specific relative node #, so
|
|
|
|
* look it up on global pool
|
|
|
|
*/
|
2015-11-04 04:30:51 +03:00
|
|
|
if ('\0' == mapped_nodes[i][2]) {
|
|
|
|
/* they forgot to tell us the # */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
|
|
|
|
true, mapped_nodes[i]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2015-11-01 05:00:46 +03:00
|
|
|
nodeidx = strtol(&mapped_nodes[i][2], NULL, 10);
|
|
|
|
if (nodeidx < 0 ||
|
|
|
|
nodeidx > (int)orte_node_pool->size) {
|
|
|
|
/* this is an error */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:relative-node-out-of-bounds",
|
|
|
|
true, nodeidx, mapped_nodes[i]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* if the HNP is not allocated, then we need to
|
|
|
|
* adjust the index as the node pool is offset
|
|
|
|
* by one
|
|
|
|
*/
|
|
|
|
if (!orte_hnp_is_allocated) {
|
|
|
|
nodeidx++;
|
|
|
|
}
|
|
|
|
/* see if that location is filled */
|
|
|
|
|
|
|
|
if (NULL == (node = (orte_node_t *) opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
|
|
|
|
/* this is an error */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:relative-node-not-found",
|
|
|
|
true, nodeidx, mapped_nodes[i]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* add this node to the list */
|
|
|
|
opal_argv_append_nosize(&mini_map, node->name);
|
|
|
|
} else {
|
|
|
|
/* invalid relative node syntax */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
|
|
|
|
true, mapped_nodes[i]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* just one node was given */
|
|
|
|
opal_argv_append_nosize(&mini_map, mapped_nodes[i]);
|
2008-08-19 19:16:27 +04:00
|
|
|
}
|
2015-11-01 05:00:46 +03:00
|
|
|
}
|
|
|
|
if (NULL == mini_map) {
|
|
|
|
rc = ORTE_SUCCESS;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* go through the names found and
|
|
|
|
add them to the host list. If they're not unique, then
|
|
|
|
bump the slots count for each duplicate */
|
|
|
|
for (i=0; NULL != mini_map[i]; i++) {
|
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
|
|
|
|
"%s dashhost: working node %s",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), mini_map[i]));
|
|
|
|
|
2015-05-01 06:33:43 +03:00
|
|
|
/* see if the node contains the number of slots */
|
|
|
|
slots_given = false;
|
2015-11-01 05:00:46 +03:00
|
|
|
if (NULL != (cptr = strchr(mini_map[i], ':'))) {
|
2015-05-01 06:33:43 +03:00
|
|
|
*cptr = '\0';
|
|
|
|
++cptr;
|
|
|
|
if ('*' == *cptr) {
|
|
|
|
slots = 0;
|
|
|
|
} else {
|
|
|
|
slots = strtol(cptr, NULL, 10);
|
|
|
|
}
|
|
|
|
slots_given = true;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2015-03-17 02:25:01 +03:00
|
|
|
/* check for local name */
|
2015-11-01 05:00:46 +03:00
|
|
|
if (orte_ifislocal(mini_map[i])) {
|
2015-03-17 02:25:01 +03:00
|
|
|
ndname = orte_process_info.nodename;
|
|
|
|
} else {
|
2015-11-01 05:00:46 +03:00
|
|
|
ndname = mini_map[i];
|
2015-03-17 02:25:01 +03:00
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2016-09-02 19:33:34 +03:00
|
|
|
// Strip off the FQDN if present, ignore IP addresses
|
|
|
|
if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(ndname) ) {
|
2016-08-25 20:57:00 +03:00
|
|
|
char *ptr;
|
2016-09-02 19:33:34 +03:00
|
|
|
if (NULL != (ptr = strchr(ndname, '.'))) {
|
|
|
|
*ptr = '\0';
|
2016-08-25 20:57:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-19 19:16:27 +04:00
|
|
|
/* see if the node is already on the list */
|
2013-12-21 05:38:27 +04:00
|
|
|
found = false;
|
|
|
|
OPAL_LIST_FOREACH(node, &adds, orte_node_t) {
|
2015-03-17 02:25:01 +03:00
|
|
|
if (0 == strcmp(node->name, ndname)) {
|
2013-12-21 05:38:27 +04:00
|
|
|
found = true;
|
2015-05-01 06:33:43 +03:00
|
|
|
if (slots_given) {
|
|
|
|
node->slots += slots;
|
|
|
|
if (0 < slots) {
|
|
|
|
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
++node->slots;
|
|
|
|
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
|
|
|
|
}
|
2014-01-08 19:17:16 +04:00
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
|
|
|
|
"%s dashhost: node %s already on list - slots %d",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, node->slots));
|
2008-02-28 04:57:57 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
/* If we didn't find it, add it to the list */
|
2013-12-21 05:38:27 +04:00
|
|
|
if (!found) {
|
2008-02-28 04:57:57 +03:00
|
|
|
node = OBJ_NEW(orte_node_t);
|
|
|
|
if (NULL == node) {
|
2015-06-03 07:14:49 +03:00
|
|
|
opal_argv_free(mapped_nodes);
|
2008-02-28 04:57:57 +03:00
|
|
|
return ORTE_ERR_OUT_OF_RESOURCE;
|
|
|
|
}
|
2015-03-17 02:25:01 +03:00
|
|
|
node->name = strdup(ndname);
|
2014-01-08 19:17:16 +04:00
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
|
2015-12-17 02:30:40 +03:00
|
|
|
"%s dashhost: added node %s to list - slots %d",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, slots));
|
2008-02-28 04:57:57 +03:00
|
|
|
node->state = ORTE_NODE_STATE_UP;
|
|
|
|
node->slots_inuse = 0;
|
|
|
|
node->slots_max = 0;
|
2015-05-01 06:33:43 +03:00
|
|
|
if (slots_given) {
|
|
|
|
node->slots = slots;
|
|
|
|
if (0 < slots) {
|
|
|
|
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
node->slots = 1;
|
|
|
|
}
|
2013-12-21 05:38:27 +04:00
|
|
|
opal_list_append(&adds, &node->super);
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
|
|
|
}
|
2015-11-01 05:00:46 +03:00
|
|
|
opal_argv_free(mini_map);
|
2013-12-21 05:38:27 +04:00
|
|
|
|
|
|
|
/* transfer across all unique nodes */
|
|
|
|
while (NULL != (item = opal_list_remove_first(&adds))) {
|
|
|
|
nd = (orte_node_t*)item;
|
2014-01-08 19:17:16 +04:00
|
|
|
found = false;
|
2013-12-21 05:38:27 +04:00
|
|
|
for (itm = opal_list_get_first(nodes);
|
|
|
|
itm != opal_list_get_end(nodes);
|
|
|
|
itm = opal_list_get_next(itm)) {
|
|
|
|
node = (orte_node_t*)itm;
|
|
|
|
if (0 == strcmp(nd->name, node->name)) {
|
|
|
|
found = true;
|
2014-01-08 19:17:16 +04:00
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
|
2016-05-15 18:55:43 +03:00
|
|
|
"%s dashhost: found existing node %s on input list - adding slots",
|
2014-01-08 19:17:16 +04:00
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name));
|
2015-05-01 06:33:43 +03:00
|
|
|
if (ORTE_FLAG_TEST(nd, ORTE_NODE_FLAG_SLOTS_GIVEN)) {
|
2016-08-23 01:54:41 +03:00
|
|
|
/* transfer across the number of slots */
|
|
|
|
node->slots = nd->slots;
|
2015-05-01 06:33:43 +03:00
|
|
|
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
|
|
|
|
}
|
2013-12-21 05:38:27 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
2014-01-08 19:17:16 +04:00
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
|
2015-05-01 06:33:43 +03:00
|
|
|
"%s dashhost: adding node %s with %d slots to final list",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), nd->name, nd->slots));
|
2013-12-21 05:38:27 +04:00
|
|
|
opal_list_append(nodes, &nd->super);
|
|
|
|
} else {
|
|
|
|
OBJ_RELEASE(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = ORTE_SUCCESS;
|
|
|
|
|
2014-01-08 19:17:16 +04:00
|
|
|
cleanup:
|
2008-02-28 04:57:57 +03:00
|
|
|
if (NULL != mapped_nodes) {
|
|
|
|
opal_argv_free(mapped_nodes);
|
|
|
|
}
|
2013-12-21 05:38:27 +04:00
|
|
|
OPAL_LIST_DESTRUCT(&adds);
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-19 19:16:27 +04:00
|
|
|
/* the -host option can always be used in both absolute
|
|
|
|
* and relative mode, so we have to check for pre-existing
|
|
|
|
* allocations if we are to use relative node syntax
|
|
|
|
*/
|
2014-06-01 20:14:10 +04:00
|
|
|
static int parse_dash_host(char ***mapped_nodes, char *hosts)
|
2008-02-28 04:57:57 +03:00
|
|
|
{
|
2010-03-08 12:54:49 +03:00
|
|
|
orte_std_cntr_t j, k;
|
2010-04-03 04:20:19 +04:00
|
|
|
int rc=ORTE_SUCCESS;
|
2014-06-01 20:14:10 +04:00
|
|
|
char **mini_map=NULL, *cptr;
|
2008-08-19 19:16:27 +04:00
|
|
|
int nodeidx;
|
2010-03-08 12:54:49 +03:00
|
|
|
orte_node_t *node;
|
2014-06-01 20:14:10 +04:00
|
|
|
char **host_argv=NULL;
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2014-06-01 20:14:10 +04:00
|
|
|
host_argv = opal_argv_split(hosts, ',');
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
/* Accumulate all of the host name mappings */
|
2008-03-06 01:12:27 +03:00
|
|
|
for (j = 0; j < opal_argv_count(host_argv); ++j) {
|
|
|
|
mini_map = opal_argv_split(host_argv[j], ',');
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-08-19 19:16:27 +04:00
|
|
|
for (k = 0; NULL != mini_map[k]; ++k) {
|
|
|
|
if ('+' == mini_map[k][0]) {
|
|
|
|
/* see if we specified empty nodes */
|
|
|
|
if ('e' == mini_map[k][1] ||
|
|
|
|
'E' == mini_map[k][1]) {
|
|
|
|
/* request for empty nodes - do they want
|
|
|
|
* all of them?
|
|
|
|
*/
|
|
|
|
if (NULL != (cptr = strchr(mini_map[k], ':'))) {
|
|
|
|
/* the colon indicates a specific # are requested */
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
*cptr = '*';
|
2010-03-08 12:54:49 +03:00
|
|
|
opal_argv_append_nosize(mapped_nodes, cptr);
|
2008-08-19 19:16:27 +04:00
|
|
|
} else {
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
/* add a marker to the list */
|
2010-03-08 12:54:49 +03:00
|
|
|
opal_argv_append_nosize(mapped_nodes, "*");
|
2008-08-19 19:16:27 +04:00
|
|
|
}
|
|
|
|
} else if ('n' == mini_map[k][1] ||
|
|
|
|
'N' == mini_map[k][1]) {
|
|
|
|
/* they want a specific relative node #, so
|
|
|
|
* look it up on global pool
|
|
|
|
*/
|
|
|
|
nodeidx = strtol(&mini_map[k][2], NULL, 10);
|
|
|
|
if (nodeidx < 0 ||
|
|
|
|
nodeidx > (int)orte_node_pool->size) {
|
|
|
|
/* this is an error */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:relative-node-out-of-bounds",
|
|
|
|
true, nodeidx, mini_map[k]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* if the HNP is not allocated, then we need to
|
|
|
|
* adjust the index as the node pool is offset
|
|
|
|
* by one
|
|
|
|
*/
|
|
|
|
if (!orte_hnp_is_allocated) {
|
|
|
|
nodeidx++;
|
|
|
|
}
|
|
|
|
/* see if that location is filled */
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2010-03-09 13:02:50 +03:00
|
|
|
if (NULL == (node = (orte_node_t *) opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
|
2008-08-19 19:16:27 +04:00
|
|
|
/* this is an error */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:relative-node-not-found",
|
|
|
|
true, nodeidx, mini_map[k]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* add this node to the list */
|
2010-03-08 12:54:49 +03:00
|
|
|
opal_argv_append_nosize(mapped_nodes, node->name);
|
2008-08-19 19:16:27 +04:00
|
|
|
} else {
|
|
|
|
/* invalid relative node syntax */
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
|
|
|
|
true, mini_map[k]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
} else { /* non-relative syntax - add to list */
|
2015-05-01 06:33:43 +03:00
|
|
|
/* remove any modifier */
|
|
|
|
if (NULL != (cptr = strchr(mini_map[k], ':'))) {
|
|
|
|
*cptr = '\0';
|
|
|
|
}
|
2015-03-17 02:25:01 +03:00
|
|
|
/* check for local alias */
|
|
|
|
if (orte_ifislocal(mini_map[k])) {
|
|
|
|
opal_argv_append_nosize(mapped_nodes, orte_process_info.nodename);
|
|
|
|
} else {
|
|
|
|
opal_argv_append_nosize(mapped_nodes, mini_map[k]);
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-08-19 19:16:27 +04:00
|
|
|
opal_argv_free(mini_map);
|
2010-03-08 12:54:49 +03:00
|
|
|
mini_map = NULL;
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2010-03-08 12:54:49 +03:00
|
|
|
cleanup:
|
2014-06-01 20:14:10 +04:00
|
|
|
if (NULL != host_argv) {
|
|
|
|
opal_argv_free(host_argv);
|
|
|
|
}
|
2010-03-08 12:54:49 +03:00
|
|
|
if (NULL != mini_map) {
|
|
|
|
opal_argv_free(mini_map);
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int orte_util_filter_dash_host_nodes(opal_list_t *nodes,
|
2014-06-01 20:14:10 +04:00
|
|
|
char *hosts,
|
2011-12-15 00:01:15 +04:00
|
|
|
bool remove)
|
2010-03-08 12:54:49 +03:00
|
|
|
{
|
|
|
|
opal_list_item_t* item;
|
|
|
|
opal_list_item_t *next;
|
|
|
|
orte_std_cntr_t i, j, len_mapped_node=0;
|
|
|
|
int rc;
|
|
|
|
char **mapped_nodes = NULL;
|
2015-03-17 02:25:01 +03:00
|
|
|
orte_node_t *node;
|
2010-03-08 12:54:49 +03:00
|
|
|
int num_empty=0;
|
|
|
|
opal_list_t keep;
|
|
|
|
bool want_all_empty=false;
|
2015-05-01 06:33:43 +03:00
|
|
|
char *cptr;
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2010-03-08 12:54:49 +03:00
|
|
|
/* if the incoming node list is empty, then there
|
|
|
|
* is nothing to filter!
|
|
|
|
*/
|
|
|
|
if (opal_list_is_empty(nodes)) {
|
|
|
|
return ORTE_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-06-01 20:14:10 +04:00
|
|
|
if (ORTE_SUCCESS != (rc = parse_dash_host(&mapped_nodes, hosts))) {
|
2010-03-08 12:54:49 +03:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
/* Did we find anything? If not, then do nothing */
|
2010-03-08 12:54:49 +03:00
|
|
|
if (NULL == mapped_nodes) {
|
2008-02-28 04:57:57 +03:00
|
|
|
return ORTE_SUCCESS;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2011-12-15 00:01:15 +04:00
|
|
|
/* NOTE: The following logic is based on knowing that
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
* any node can only be included on the incoming
|
|
|
|
* nodes list ONCE.
|
2008-02-28 04:57:57 +03:00
|
|
|
*/
|
2012-02-29 20:56:00 +04:00
|
|
|
|
2008-08-19 19:16:27 +04:00
|
|
|
len_mapped_node = opal_argv_count(mapped_nodes);
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
/* setup a working list so we can put the final list
|
|
|
|
* of nodes in order. This way, if the user specifies a
|
|
|
|
* set of nodes, we will use them in the order in which
|
|
|
|
* they were specifed. Note that empty node requests
|
|
|
|
* will always be appended to the end
|
|
|
|
*/
|
|
|
|
OBJ_CONSTRUCT(&keep, opal_list_t);
|
2015-06-24 06:59:57 +03:00
|
|
|
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
for (i = 0; i < len_mapped_node; ++i) {
|
|
|
|
/* check if we are supposed to add some number of empty
|
|
|
|
* nodes here
|
|
|
|
*/
|
|
|
|
if ('*' == mapped_nodes[i][0]) {
|
|
|
|
/* if there is a number after the '*', then we are
|
|
|
|
* to insert a specific # of nodes
|
|
|
|
*/
|
|
|
|
if ('\0' == mapped_nodes[i][1]) {
|
|
|
|
/* take all empty nodes from the list */
|
|
|
|
num_empty = INT_MAX;
|
2010-03-08 12:54:49 +03:00
|
|
|
want_all_empty = true;
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
} else {
|
|
|
|
/* extract number of nodes to take */
|
|
|
|
num_empty = strtol(&mapped_nodes[i][1], NULL, 10);
|
|
|
|
}
|
|
|
|
/* search for empty nodes and take them */
|
|
|
|
item = opal_list_get_first(nodes);
|
|
|
|
while (0 < num_empty && item != opal_list_get_end(nodes)) {
|
|
|
|
next = opal_list_get_next(item); /* save this position */
|
|
|
|
node = (orte_node_t*)item;
|
|
|
|
/* see if this node is empty */
|
|
|
|
if (0 == node->slots_inuse) {
|
2008-08-26 07:02:28 +04:00
|
|
|
/* check to see if it is specified later */
|
|
|
|
for (j=i+1; j < len_mapped_node; j++) {
|
|
|
|
if (0 == strcmp(mapped_nodes[j], node->name)) {
|
|
|
|
/* specified later - skip this one */
|
|
|
|
goto skipnode;
|
|
|
|
}
|
|
|
|
}
|
2011-12-15 00:01:15 +04:00
|
|
|
if (remove) {
|
|
|
|
/* remove item from list */
|
|
|
|
opal_list_remove_item(nodes, item);
|
|
|
|
/* xfer to keep list */
|
|
|
|
opal_list_append(&keep, item);
|
|
|
|
} else {
|
|
|
|
/* mark the node as found */
|
2014-06-01 20:14:10 +04:00
|
|
|
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_MAPPED);
|
2011-12-15 00:01:15 +04:00
|
|
|
}
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
--num_empty;
|
|
|
|
}
|
2008-08-26 07:02:28 +04:00
|
|
|
skipnode:
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
item = next;
|
|
|
|
}
|
|
|
|
} else {
|
2015-03-17 02:25:01 +03:00
|
|
|
/* we are looking for a specific node on the list. The
|
|
|
|
* parser will have substituted our local name for any
|
|
|
|
* alias, so we only have to do a strcmp here */
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
item = opal_list_get_first(nodes);
|
|
|
|
while (item != opal_list_get_end(nodes)) {
|
|
|
|
next = opal_list_get_next(item); /* save this position */
|
|
|
|
node = (orte_node_t*)item;
|
2015-05-01 06:33:43 +03:00
|
|
|
/* remove any modifier */
|
|
|
|
if (NULL != (cptr = strchr(mapped_nodes[i], ':'))) {
|
|
|
|
*cptr = '\0';
|
|
|
|
}
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
/* search -host list to see if this one is found */
|
2015-03-17 02:25:01 +03:00
|
|
|
if (0 == strcmp(node->name, mapped_nodes[i])) {
|
2011-12-15 00:01:15 +04:00
|
|
|
if (remove) {
|
|
|
|
/* remove item from list */
|
|
|
|
opal_list_remove_item(nodes, item);
|
|
|
|
/* xfer to keep list */
|
|
|
|
opal_list_append(&keep, item);
|
|
|
|
} else {
|
|
|
|
/* mark the node as found */
|
2014-06-01 20:14:10 +04:00
|
|
|
ORTE_FLAG_SET(node, ORTE_NODE_FLAG_MAPPED);
|
2011-12-15 00:01:15 +04:00
|
|
|
}
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
item = next;
|
2008-08-19 19:16:27 +04:00
|
|
|
}
|
|
|
|
}
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
/* done with the mapped entry */
|
|
|
|
free(mapped_nodes[i]);
|
|
|
|
mapped_nodes[i] = NULL;
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
/* was something specified that was -not- found? */
|
2008-08-19 19:16:27 +04:00
|
|
|
for (i=0; i < len_mapped_node; i++) {
|
|
|
|
if (NULL != mapped_nodes[i]) {
|
|
|
|
orte_show_help("help-dash-host.txt", "not-all-mapped-alloc",
|
|
|
|
true, mapped_nodes[i]);
|
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2011-12-15 00:01:15 +04:00
|
|
|
if (!remove) {
|
|
|
|
/* all done */
|
|
|
|
rc = ORTE_SUCCESS;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
/* clear the rest of the nodes list */
|
|
|
|
while (NULL != (item = opal_list_remove_first(nodes))) {
|
|
|
|
OBJ_RELEASE(item);
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
Per request from Terry, make -host and -hostfile respect order when used as filters. In other words, if you specify -host host1,host3,host2, then we should use the hosts in that order. Previously, we used them in whatever order they were found in the allocation - all the -host did was tell us which nodes to use, not what order to use them in.
Relative node syntax remains supported. Also, if you specify empty nodes, but have a specific empty node called out later, we will not include that node in the empties we add. I'll provide examples in the manpage.
This commit was SVN r19402.
2008-08-26 06:56:10 +04:00
|
|
|
/* the nodes list has been cleared - rebuild it in order */
|
|
|
|
while (NULL != (item = opal_list_remove_first(&keep))) {
|
|
|
|
opal_list_append(nodes, item);
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-08-19 19:16:27 +04:00
|
|
|
/* did they ask for more than we could provide */
|
|
|
|
if (!want_all_empty && 0 < num_empty) {
|
|
|
|
orte_show_help("help-dash-host.txt", "dash-host:not-enough-empty",
|
|
|
|
true, num_empty);
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = ORTE_ERR_SILENT;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
rc = ORTE_SUCCESS;
|
|
|
|
/* done filtering existing list */
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
cleanup:
|
2008-08-19 19:16:27 +04:00
|
|
|
for (i=0; i < len_mapped_node; i++) {
|
|
|
|
if (NULL != mapped_nodes[i]) {
|
|
|
|
free(mapped_nodes[i]);
|
|
|
|
mapped_nodes[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
if (NULL != mapped_nodes) {
|
2008-08-19 19:16:27 +04:00
|
|
|
free(mapped_nodes);
|
2008-02-28 04:57:57 +03:00
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-03-08 12:54:49 +03:00
|
|
|
int orte_util_get_ordered_dash_host_list(opal_list_t *nodes,
|
2014-06-01 20:14:10 +04:00
|
|
|
char *hosts)
|
2010-03-08 12:54:49 +03:00
|
|
|
{
|
|
|
|
int rc, i;
|
|
|
|
char **mapped_nodes = NULL;
|
|
|
|
orte_node_t *node;
|
|
|
|
|
2014-06-01 20:14:10 +04:00
|
|
|
if (ORTE_SUCCESS != (rc = parse_dash_host(&mapped_nodes, hosts))) {
|
2010-03-08 12:54:49 +03:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2010-03-08 12:54:49 +03:00
|
|
|
/* for each entry, create a node entry on the list */
|
|
|
|
for (i=0; NULL != mapped_nodes[i]; i++) {
|
|
|
|
node = OBJ_NEW(orte_node_t);
|
|
|
|
node->name = strdup(mapped_nodes[i]);
|
|
|
|
opal_list_append(nodes, &node->super);
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2010-03-08 12:54:49 +03:00
|
|
|
/* cleanup */
|
|
|
|
opal_argv_free(mapped_nodes);
|
|
|
|
return rc;
|
|
|
|
}
|