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

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