root/opal/mca/compress/fwd/regx_fwd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nidmap_create

   1 /*
   2  * Copyright (c) 2016-2019 Intel, Inc.  All rights reserved.
   3  * Copyright (c) 2018      Research Organization for Information Science
   4  *                         and Technology (RIST). All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  *
  11  */
  12 
  13 #include "orte_config.h"
  14 #include "orte/types.h"
  15 #include "opal/types.h"
  16 
  17 #ifdef HAVE_UNISTD_H
  18 #include <unistd.h>
  19 #endif
  20 #include <ctype.h>
  21 
  22 #include "opal/util/argv.h"
  23 #include "opal/util/basename.h"
  24 #include "opal/util/opal_environ.h"
  25 
  26 #include "orte/runtime/orte_globals.h"
  27 #include "orte/util/name_fns.h"
  28 #include "orte/util/show_help.h"
  29 #include "orte/mca/errmgr/errmgr.h"
  30 #include "orte/mca/rmaps/base/base.h"
  31 #include "orte/mca/routed/routed.h"
  32 #include "orte/mca/regx/base/base.h"
  33 
  34 #include "regx_fwd.h"
  35 
  36 static int nidmap_create(opal_pointer_array_t *pool, char **regex);
  37 
  38 orte_regx_base_module_t orte_regx_fwd_module = {
  39     .nidmap_create = nidmap_create,
  40     .nidmap_parse = orte_regx_base_nidmap_parse,
  41     .extract_node_names = orte_regx_base_extract_node_names,
  42     .encode_nodemap = orte_regx_base_encode_nodemap,
  43     .decode_daemon_nodemap = orte_regx_base_decode_daemon_nodemap,
  44     .generate_ppn = orte_regx_base_generate_ppn,
  45     .parse_ppn = orte_regx_base_parse_ppn
  46 };
  47 
  48 static int nidmap_create(opal_pointer_array_t *pool, char **regex)
  49 {
  50     char *node;
  51     char prefix[ORTE_MAX_NODE_PREFIX];
  52     int i, j, n, len, startnum, nodenum, numdigits;
  53     bool found;
  54     char *suffix, *sfx, *nodenames;
  55     orte_regex_node_t *ndreg;
  56     orte_regex_range_t *range, *rng;
  57     opal_list_t nodenms, dvpids;
  58     opal_list_item_t *item, *itm2;
  59     char **regexargs = NULL, *tmp, *tmp2;
  60     orte_node_t *nptr;
  61     orte_vpid_t vpid;
  62 
  63     OBJ_CONSTRUCT(&nodenms, opal_list_t);
  64     OBJ_CONSTRUCT(&dvpids, opal_list_t);
  65 
  66     rng = NULL;
  67     for (n=0; n < pool->size; n++) {
  68         if (NULL == (nptr = (orte_node_t*)opal_pointer_array_get_item(pool, n))) {
  69             continue;
  70         }
  71         /* if no daemon has been assigned, then this node is not being used */
  72         if (NULL == nptr->daemon) {
  73             vpid = -1;  // indicates no daemon assigned
  74         } else {
  75             vpid = nptr->daemon->name.vpid;
  76         }
  77         /* deal with the daemon vpid - see if it is next in the
  78          * current range */
  79         if (NULL == rng) {
  80             /* just starting */
  81             rng = OBJ_NEW(orte_regex_range_t);
  82             rng->vpid = vpid;
  83             rng->cnt = 1;
  84             opal_list_append(&dvpids, &rng->super);
  85         } else if (UINT32_MAX == vpid) {
  86             if (-1 == rng->vpid) {
  87                 rng->cnt++;
  88             } else {
  89                 /* need to start another range */
  90                 rng = OBJ_NEW(orte_regex_range_t);
  91                 rng->vpid = vpid;
  92                 rng->cnt = 1;
  93                 opal_list_append(&dvpids, &rng->super);
  94             }
  95         } else if (-1 == rng->vpid) {
  96             /* need to start another range */
  97             rng = OBJ_NEW(orte_regex_range_t);
  98             rng->vpid = vpid;
  99             rng->cnt = 1;
 100             opal_list_append(&dvpids, &rng->super);
 101         } else {
 102             /* is this the next in line */
 103             if (vpid == (orte_vpid_t)(rng->vpid + rng->cnt)) {
 104                 rng->cnt++;
 105             } else {
 106                 /* need to start another range */
 107                 rng = OBJ_NEW(orte_regex_range_t);
 108                 rng->vpid = vpid;
 109                 rng->cnt = 1;
 110                 opal_list_append(&dvpids, &rng->super);
 111             }
 112         }
 113         node = nptr->name;
 114         /* determine this node's prefix by looking for first digit char */
 115         len = strlen(node);
 116         startnum = -1;
 117         memset(prefix, 0, ORTE_MAX_NODE_PREFIX);
 118         for (i=0, j=0; i < len; i++) {
 119             /* valid hostname characters are ascii letters, digits and the '-' character. */
 120             if (isdigit(node[i])) {
 121                 /* count the size of the numeric field - but don't
 122                  * add the digits to the prefix
 123                  */
 124                 if (startnum < 0) {
 125                     /* okay, this defines end of the prefix */
 126                     startnum = i;
 127                 }
 128                 continue;
 129             }
 130             /* this must be either an alpha, a '.', or '-' */
 131             if (!isalpha(node[i]) && '-' != node[i] && '.' != node[i]) {
 132                 orte_show_help("help-regex.txt", "regex:invalid-name", true, node);
 133                 return ORTE_ERR_SILENT;
 134             }
 135             if (startnum < 0) {
 136                 prefix[j++] = node[i];
 137             }
 138         }
 139         if (startnum < 0) {
 140             /* can't compress this name - just add it to the list */
 141             ndreg = OBJ_NEW(orte_regex_node_t);
 142             ndreg->prefix = strdup(node);
 143             opal_list_append(&nodenms, &ndreg->super);
 144             continue;
 145         }
 146         /* convert the digits and get any suffix */
 147         nodenum = strtol(&node[startnum], &sfx, 10);
 148         if (NULL != sfx) {
 149             suffix = strdup(sfx);
 150             numdigits = (int)(sfx - &node[startnum]);
 151         } else {
 152             suffix = NULL;
 153             numdigits = (int)strlen(&node[startnum]);
 154         }
 155         /* is this node name already on our list? */
 156         found = false;
 157         if (0 != opal_list_get_size(&nodenms)) {
 158             ndreg = (orte_regex_node_t*)opal_list_get_last(&nodenms);
 159 
 160             if ((0 < strlen(prefix) && NULL == ndreg->prefix) ||
 161                 (0 == strlen(prefix) && NULL != ndreg->prefix) ||
 162                 (0 < strlen(prefix) && NULL != ndreg->prefix &&
 163                     0 != strcmp(prefix, ndreg->prefix)) ||
 164                 (NULL == suffix && NULL != ndreg->suffix) ||
 165                 (NULL != suffix && NULL == ndreg->suffix) ||
 166                 (NULL != suffix && NULL != ndreg->suffix &&
 167                     0 != strcmp(suffix, ndreg->suffix)) ||
 168                 (numdigits != ndreg->num_digits)) {
 169                 found = false;
 170             } else {
 171                 /* found a match - flag it */
 172                 found = true;
 173             }
 174         }
 175         if (found) {
 176             range = (orte_regex_range_t*)opal_list_get_last(&ndreg->ranges);
 177             if (NULL == range) {
 178                 /* first range for this nodeid */
 179                 range = OBJ_NEW(orte_regex_range_t);
 180                 range->vpid = nodenum;
 181                 range->cnt = 1;
 182                 opal_list_append(&ndreg->ranges, &range->super);
 183             /* see if the node number is out of sequence */
 184             } else if (nodenum != (range->vpid + range->cnt)) {
 185                 /* start a new range */
 186                 range = OBJ_NEW(orte_regex_range_t);
 187                 range->vpid = nodenum;
 188                 range->cnt = 1;
 189                 opal_list_append(&ndreg->ranges, &range->super);
 190             } else {
 191                 /* everything matches - just increment the cnt */
 192                 range->cnt++;
 193             }
 194         } else {
 195             /* need to add it */
 196             ndreg = OBJ_NEW(orte_regex_node_t);
 197             if (0 < strlen(prefix)) {
 198                 ndreg->prefix = strdup(prefix);
 199             }
 200             if (NULL != suffix) {
 201                 ndreg->suffix = strdup(suffix);
 202             }
 203             ndreg->num_digits = numdigits;
 204             opal_list_append(&nodenms, &ndreg->super);
 205             /* record the first range for this nodeid - we took
 206              * care of names we can't compress above
 207              */
 208             range = OBJ_NEW(orte_regex_range_t);
 209             range->vpid = nodenum;
 210             range->cnt = 1;
 211             opal_list_append(&ndreg->ranges, &range->super);
 212         }
 213         if (NULL != suffix) {
 214             free(suffix);
 215         }
 216     }
 217     /* begin constructing the regular expression */
 218     while (NULL != (item = opal_list_remove_first(&nodenms))) {
 219         ndreg = (orte_regex_node_t*)item;
 220 
 221         /* if no ranges, then just add the name */
 222         if (0 == opal_list_get_size(&ndreg->ranges)) {
 223             if (NULL != ndreg->prefix) {
 224                 /* solitary node */
 225                 opal_asprintf(&tmp, "%s", ndreg->prefix);
 226                 opal_argv_append_nosize(&regexargs, tmp);
 227                 free(tmp);
 228             }
 229             OBJ_RELEASE(ndreg);
 230             continue;
 231         }
 232         /* start the regex for this nodeid with the prefix */
 233         if (NULL != ndreg->prefix) {
 234             opal_asprintf(&tmp, "%s[%d:", ndreg->prefix, ndreg->num_digits);
 235         } else {
 236             opal_asprintf(&tmp, "[%d:", ndreg->num_digits);
 237         }
 238         /* add the ranges */
 239         while (NULL != (itm2 = opal_list_remove_first(&ndreg->ranges))) {
 240             range = (orte_regex_range_t*)itm2;
 241             if (1 == range->cnt) {
 242                 opal_asprintf(&tmp2, "%s%u,", tmp, range->vpid);
 243             } else {
 244                 opal_asprintf(&tmp2, "%s%u-%u,", tmp, range->vpid, range->vpid + range->cnt - 1);
 245             }
 246             free(tmp);
 247             tmp = tmp2;
 248             OBJ_RELEASE(range);
 249         }
 250         /* replace the final comma */
 251         tmp[strlen(tmp)-1] = ']';
 252         if (NULL != ndreg->suffix) {
 253             /* add in the suffix, if provided */
 254             opal_asprintf(&tmp2, "%s%s", tmp, ndreg->suffix);
 255             free(tmp);
 256             tmp = tmp2;
 257         }
 258         opal_argv_append_nosize(&regexargs, tmp);
 259         free(tmp);
 260         OBJ_RELEASE(ndreg);
 261     }
 262 
 263     /* assemble final result */
 264     nodenames = opal_argv_join(regexargs, ',');
 265     /* cleanup */
 266     opal_argv_free(regexargs);
 267     OBJ_DESTRUCT(&nodenms);
 268 
 269     /* do the same for the vpids */
 270     tmp = NULL;
 271     while (NULL != (item = opal_list_remove_first(&dvpids))) {
 272         rng = (orte_regex_range_t*)item;
 273         if (1 < rng->cnt) {
 274             if (NULL == tmp) {
 275                 opal_asprintf(&tmp, "%u(%u)", rng->vpid, rng->cnt);
 276             } else {
 277                 opal_asprintf(&tmp2, "%s,%u(%u)", tmp, rng->vpid, rng->cnt);
 278                 free(tmp);
 279                 tmp = tmp2;
 280             }
 281         } else {
 282             if (NULL == tmp) {
 283                 opal_asprintf(&tmp, "%u", rng->vpid);
 284             } else {
 285                 opal_asprintf(&tmp2, "%s,%u", tmp, rng->vpid);
 286                 free(tmp);
 287                 tmp = tmp2;
 288             }
 289         }
 290         OBJ_RELEASE(rng);
 291     }
 292     OPAL_LIST_DESTRUCT(&dvpids);
 293 
 294     /* now concatenate the results into one string */
 295     opal_asprintf(&tmp2, "%s@%s", nodenames, tmp);
 296     free(nodenames);
 297     free(tmp);
 298     *regex = tmp2;
 299     return ORTE_SUCCESS;
 300 }

/* [<][>][^][v][top][bottom][index][help] */