LCOV - code coverage report
Current view: top level - home/fuchsto/workspaces/dash-development/dart-impl/base/src - locality.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 215 353 60.9 %
Date: 2016-06-29 12:30:40 Functions: 11 15 73.3 %

          Line data    Source code
       1             : /**
       2             :  * \file dash/dart/base/locality.c
       3             :  */
       4             : 
       5             : #include <dash/dart/base/locality.h>
       6             : #include <dash/dart/base/macro.h>
       7             : #include <dash/dart/base/logging.h>
       8             : #include <dash/dart/base/logging.h>
       9             : #include <dash/dart/base/assert.h>
      10             : #include <dash/dart/base/hwinfo.h>
      11             : 
      12             : #include <dash/dart/base/internal/host_topology.h>
      13             : #include <dash/dart/base/internal/unit_locality.h>
      14             : #include <dash/dart/base/internal/domain_locality.h>
      15             : 
      16             : #include <dash/dart/base/string.h>
      17             : 
      18             : #include <dash/dart/if/dart_types.h>
      19             : #include <dash/dart/if/dart_locality.h>
      20             : #include <dash/dart/if/dart_communication.h>
      21             : 
      22             : #include <inttypes.h>
      23             : #include <string.h>
      24             : #include <unistd.h>
      25             : #include <stdio.h>
      26             : #include <sched.h>
      27             : #include <limits.h>
      28             : 
      29             : /* ====================================================================== *
      30             :  * Private Data                                                           *
      31             :  * ====================================================================== */
      32             : 
      33             : #define DART__BASE__LOCALITY__MAX_TEAM_DOMAINS 32
      34             : 
      35             : dart_host_topology_t *
      36             : dart__base__locality__host_topology_[DART__BASE__LOCALITY__MAX_TEAM_DOMAINS];
      37             : 
      38             : dart_unit_mapping_t *
      39             : dart__base__locality__unit_mapping_[DART__BASE__LOCALITY__MAX_TEAM_DOMAINS];
      40             : 
      41             : dart_domain_locality_t *
      42             : dart__base__locality__global_domain_[DART__BASE__LOCALITY__MAX_TEAM_DOMAINS];
      43             : 
      44             : /* ====================================================================== *
      45             :  * Private Functions                                                      *
      46             :  * ====================================================================== */
      47             : 
      48           0 : static int cmpstr_(const void * p1, const void * p2)
      49             : {
      50           0 :   return strcmp(* (char * const *) p1, * (char * const *) p2);
      51             : }
      52             : 
      53             : dart_ret_t dart__base__locality__scope_domains_rec(
      54             :   const dart_domain_locality_t   * domain,
      55             :   dart_locality_scope_t            scope,
      56             :   int                            * num_domains_out,
      57             :   char                         *** domain_tags_out);
      58             : 
      59             : dart_locality_scope_t dart__base__locality__scope_parent(
      60             :   dart_locality_scope_t            scope);
      61             : 
      62             : dart_locality_scope_t dart__base__locality__scope_child(
      63             :   dart_locality_scope_t            scope);
      64             : 
      65             : dart_ret_t dart__base__locality__group_subdomains(
      66             :   dart_domain_locality_t         * domain,
      67             :   const char                    ** group_subdomain_tags,
      68             :   int                              num_group_subdomain_tags,
      69             :   char                           * group_domain_tag_out);
      70             : 
      71             : /* ====================================================================== *
      72             :  * Init / Finalize                                                        *
      73             :  * ====================================================================== */
      74             : 
      75           4 : dart_ret_t dart__base__locality__init()
      76             : {
      77         132 :   for (int td = 0; td < DART__BASE__LOCALITY__MAX_TEAM_DOMAINS; ++td) {
      78         128 :     dart__base__locality__global_domain_[td] = NULL;
      79         128 :     dart__base__locality__host_topology_[td] = NULL;
      80         128 :     dart__base__locality__unit_mapping_[td]  = NULL;
      81             :   }
      82           4 :   return dart__base__locality__create(DART_TEAM_ALL);
      83             : }
      84             : 
      85           4 : dart_ret_t dart__base__locality__finalize()
      86             : {
      87         132 :   for (dart_team_t t = 0; t < DART__BASE__LOCALITY__MAX_TEAM_DOMAINS; ++t) {
      88         128 :     dart__base__locality__delete(t);
      89             :   }
      90             : 
      91           4 :   dart_barrier(DART_TEAM_ALL);
      92           4 :   return DART_OK;
      93             : }
      94             : 
      95             : /* ====================================================================== *
      96             :  * Create / Delete                                                        *
      97             :  * ====================================================================== */
      98             : 
      99             : /**
     100             :  * Exchange and collect locality information of all units in the specified
     101             :  * team.
     102             :  *
     103             :  * The team's unit locality information is stored in private array
     104             :  * \c dart__base__locality__unit_mapping_[team] with a capacity for
     105             :  * \c DART__BASE__LOCALITY__MAX_TEAM_DOMAINS teams.
     106             :  *
     107             :  */
     108           4 : dart_ret_t dart__base__locality__create(
     109             :   dart_team_t team)
     110             : {
     111             :   DART_LOG_DEBUG("dart__base__locality__create() team(%d)", team);
     112             : 
     113             :   /*
     114             :    * TODO: Clarify if returning would be sufficient instead of failing
     115             :    *       assertion.
     116             :    */
     117           4 :   DART_ASSERT_MSG(
     118             :     NULL == dart__base__locality__unit_mapping_[team],
     119             :     "dash__base__locality__create(): "
     120             :     "locality data of team is already initialized");
     121             : 
     122           4 :   dart_hwinfo_t * hwinfo = malloc(sizeof(dart_hwinfo_t));
     123           4 :   DART_ASSERT_RETURNS(dart_hwinfo(hwinfo), DART_OK);
     124             : 
     125           4 :   dart_domain_locality_t * team_global_domain =
     126             :     malloc(sizeof(dart_domain_locality_t));
     127           4 :   dart__base__locality__global_domain_[team] =
     128             :     team_global_domain;
     129             : 
     130             :   /* Initialize the global domain as the root entry in the locality
     131             :    * hierarchy:
     132             :    */
     133           4 :   team_global_domain->scope          = DART_LOCALITY_SCOPE_GLOBAL;
     134           4 :   team_global_domain->level          = 0;
     135           4 :   team_global_domain->relative_index = 0;
     136           4 :   team_global_domain->team           = team;
     137           4 :   team_global_domain->parent         = NULL;
     138           4 :   team_global_domain->num_domains    = 0;
     139           4 :   team_global_domain->domains        = NULL;
     140           4 :   team_global_domain->hwinfo         = *hwinfo;
     141           4 :   team_global_domain->num_units      = 0;
     142           4 :   team_global_domain->host[0]        = '\0';
     143           4 :   team_global_domain->domain_tag[0]  = '.';
     144           4 :   team_global_domain->domain_tag[1]  = '\0';
     145             : 
     146           4 :   size_t num_units = 0;
     147           4 :   DART_ASSERT_RETURNS(dart_team_size(team, &num_units), DART_OK);
     148           4 :   team_global_domain->num_units = num_units;
     149             : 
     150           4 :   team_global_domain->unit_ids =
     151           4 :     malloc(num_units * sizeof(dart_unit_t));
     152          20 :   for (size_t u = 0; u < num_units; ++u) {
     153          16 :     team_global_domain->unit_ids[u] = u;
     154             :   }
     155             : 
     156             :   /* Exchange unit locality information between all units:
     157             :    */
     158             :   dart_unit_mapping_t * unit_mapping;
     159           4 :   DART_ASSERT_RETURNS(
     160             :     dart__base__unit_locality__create(team, &unit_mapping),
     161             :     DART_OK);
     162           4 :   dart__base__locality__unit_mapping_[team] = unit_mapping;
     163             : 
     164             :   /* Copy host names of all units into array:
     165             :    */
     166           4 :   const int max_host_len = DART_LOCALITY_HOST_MAX_SIZE;
     167             :   DART_LOG_TRACE("dart__base__locality__create: copying host names");
     168           4 :   char ** hosts = malloc(sizeof(char *) * num_units);
     169          20 :   for (size_t u = 0; u < num_units; ++u) {
     170          16 :     hosts[u] = malloc(sizeof(char) * max_host_len);
     171             :     dart_unit_locality_t * ul;
     172          16 :     DART_ASSERT_RETURNS(
     173             :       dart__base__unit_locality__at(unit_mapping, u, &ul),
     174             :       DART_OK);
     175          16 :     strncpy(hosts[u], ul->host, max_host_len);
     176             :   }
     177             : 
     178             :   /* Resolve host topology from the unit's host names:
     179             :    */
     180           4 :   dart_host_topology_t * topo = malloc(sizeof(dart_host_topology_t));
     181           4 :   DART_ASSERT_RETURNS(
     182             :     dart__base__host_topology__create(
     183             :       hosts, team, unit_mapping, topo),
     184             :     DART_OK);
     185           4 :   dart__base__locality__host_topology_[team] = topo;
     186           4 :   size_t num_nodes = topo->num_nodes;
     187             :   DART_LOG_TRACE("dart__base__locality__create: nodes: %d", num_nodes);
     188             : 
     189           4 :   team_global_domain->num_nodes = num_nodes;
     190             : 
     191             : #ifdef DART_ENABLE_LOGGING
     192             :   for (int h = 0; h < topo->num_hosts; ++h) {
     193             :     dart_node_units_t * node_units = &topo->node_units[h];
     194             :     char * hostname = topo->host_names[h];
     195             :     DART_LOG_TRACE("dart__base__locality__create: "
     196             :                    "host %s: units:%d level:%d parent:%s", hostname,
     197             :                    node_units->num_units, node_units->level,
     198             :                    node_units->parent);
     199             :     for (int u = 0; u < node_units->num_units; ++u) {
     200             :       DART_LOG_TRACE("dart__base__locality__create: %s unit[%d]: %d",
     201             :                      hostname, u, node_units->units[u]);
     202             :     }
     203             :   }
     204             : #endif
     205             : 
     206             :   DART_LOG_DEBUG("dart__base__locality__create: "
     207             :                  "constructing domain hierarchy");
     208             :   /* Recursively create locality information of the global domain's
     209             :    * sub-domains:
     210             :    */
     211           4 :   DART_ASSERT_RETURNS(
     212             :     dart__base__locality__domain__create_subdomains(
     213             :       dart__base__locality__global_domain_[team],
     214             :       dart__base__locality__host_topology_[team],
     215             :       dart__base__locality__unit_mapping_[team]),
     216             :     DART_OK);
     217             : 
     218             :   DART_LOG_DEBUG("dart__base__locality__create >");
     219           4 :   return DART_OK;
     220             : }
     221             : 
     222         128 : dart_ret_t dart__base__locality__delete(
     223             :   dart_team_t team)
     224             : {
     225         128 :   dart_ret_t ret = DART_OK;
     226             : 
     227         252 :   if (NULL == dart__base__locality__global_domain_[team] &&
     228         248 :       NULL == dart__base__locality__host_topology_[team] &&
     229         124 :       NULL == dart__base__locality__unit_mapping_[team]) {
     230         124 :     return ret;
     231             :   }
     232             : 
     233             :   DART_LOG_DEBUG("dart__base__locality__delete() team(%d)", team);
     234             : 
     235           4 :   if (NULL != dart__base__locality__global_domain_[team]) {
     236           4 :     ret = dart__base__locality__domain__destruct(
     237             :             dart__base__locality__global_domain_[team]);
     238           4 :     if (ret != DART_OK) {
     239           0 :       DART_LOG_ERROR("dart__base__locality__delete ! "
     240             :                      "dart__base__locality__domain_delete failed: %d", ret);
     241           0 :       return ret;
     242             :     }
     243           4 :     free(dart__base__locality__global_domain_[team]);
     244           4 :     dart__base__locality__global_domain_[team] = NULL;
     245             :   }
     246             : 
     247           4 :   if (NULL != dart__base__locality__host_topology_[team]) {
     248           4 :     ret = dart__base__host_topology__destruct(
     249             :             dart__base__locality__host_topology_[team]);
     250           4 :     if (ret != DART_OK) {
     251           0 :       DART_LOG_ERROR("dart__base__locality__delete ! "
     252             :                      "dart__base__host_topology__destruct failed: %d", ret);
     253           0 :       return ret;
     254             :     }
     255           4 :     free(dart__base__locality__host_topology_[team]);
     256           4 :     dart__base__locality__host_topology_[team] = NULL;
     257             :   }
     258             : 
     259           4 :   if (NULL != dart__base__locality__unit_mapping_[team]) {
     260           4 :     ret = dart__base__unit_locality__destruct(
     261             :             dart__base__locality__unit_mapping_[team]);
     262           4 :     if (ret != DART_OK) {
     263           0 :       DART_LOG_ERROR("dart__base__locality__delete ! "
     264             :                      "dart__base__unit_locality__destruct failed: %d", ret);
     265           0 :       return ret;
     266             :     }
     267           4 :     free(dart__base__locality__unit_mapping_[team]);
     268           4 :     dart__base__locality__unit_mapping_[team] = NULL;
     269             :   }
     270             : 
     271             :   DART_LOG_DEBUG("dart__base__locality__delete > team(%d)", team);
     272           4 :   return DART_OK;
     273             : }
     274             : 
     275             : /* ====================================================================== *
     276             :  * Domain Locality                                                        *
     277             :  * ====================================================================== */
     278             : 
     279          26 : dart_ret_t dart__base__locality__team_domain(
     280             :   dart_team_t                        team,
     281             :   dart_domain_locality_t          ** domain_out)
     282             : {
     283             :   DART_LOG_DEBUG("dart__base__locality__team_domain() team(%d)", team);
     284          26 :   dart_ret_t ret = DART_ERR_NOTFOUND;
     285             : 
     286          26 :   *domain_out = NULL;
     287          26 :   dart_domain_locality_t * domain =
     288             :     dart__base__locality__global_domain_[team];
     289             : 
     290          26 :   ret = dart__base__locality__domain(domain, ".", domain_out);
     291             : 
     292             :   DART_LOG_DEBUG("dart__base__locality__team_domain > "
     293             :                  "team(%d) -> domain(%p)", team, *domain_out);
     294          26 :   return ret;
     295             : }
     296             : 
     297          36 : dart_ret_t dart__base__locality__domain(
     298             :   const dart_domain_locality_t     * domain_in,
     299             :   const char                       * domain_tag,
     300             :   dart_domain_locality_t          ** domain_out)
     301             : {
     302          36 :   return dart__base__locality__domain__child(
     303             :            domain_in, domain_tag, domain_out);
     304             : }
     305             : 
     306           4 : dart_ret_t dart__base__locality__scope_domains(
     307             :   const dart_domain_locality_t     * domain_in,
     308             :   dart_locality_scope_t              scope,
     309             :   int                              * num_domains_out,
     310             :   char                           *** domain_tags_out)
     311             : {
     312           4 :   *num_domains_out = 0;
     313           4 :   *domain_tags_out = NULL;
     314           4 :   return dart__base__locality__scope_domains_rec(
     315             :            domain_in, scope, num_domains_out, domain_tags_out);
     316             : }
     317             : 
     318           2 : dart_ret_t dart__base__locality__domain_split_tags(
     319             :   const dart_domain_locality_t     * domain_in,
     320             :   dart_locality_scope_t              scope,
     321             :   int                                num_parts,
     322             :   int                             ** group_sizes_out,
     323             :   char                          **** group_domain_tags_out)
     324             : {
     325             :   /* For 4 domains in the specified scope, a split into 2 parts results
     326             :    * in a domain hierarchy like:
     327             :    *
     328             :    *   group_domain_tags[g][d] -> {
     329             :    *                                0: [ domain_0, domain_1 ],
     330             :    *                                1: [ domain_2, domain_3 ], ...
     331             :    *                              }
     332             :    *
     333             :    */
     334             : 
     335             :   DART_LOG_TRACE("dart__base__locality__domain_split_tags() "
     336             :                  "team(%d) domain(%s) scope(%d) parts(%d)",
     337             :                  domain_in->team, domain_in->domain_tag, scope, num_parts);
     338             : 
     339             :   /* Subdomains of global domain.
     340             :    * Domains of split parts, grouping domains at split scope. */
     341           2 :   char *** group_domain_tags = malloc(num_parts * sizeof(char **));
     342           2 :   int    * group_sizes       = malloc(num_parts * sizeof(int));
     343             : 
     344             :   /* Get total number and tags of domains in split scope: */
     345             :   int     num_domains;
     346             :   char ** domain_tags;
     347           2 :   DART_ASSERT_RETURNS(
     348             :     dart__base__locality__scope_domains(
     349             :       domain_in, scope, &num_domains, &domain_tags),
     350             :     DART_OK);
     351             : 
     352             :   DART_LOG_TRACE("dart__base__locality__domain_split_tags: "
     353             :                  "number of domains in scope %d: %d", scope, num_domains);
     354             : 
     355             :   /* Group domains in split scope into specified number of parts: */
     356           2 :   int max_group_domains      = (num_domains + (num_parts-1)) / num_parts;
     357           2 :   int group_first_domain_idx = 0;
     358             : 
     359             :   DART_LOG_TRACE("dart__base__locality__domain_split_tags: "
     360             :                  "max. domains per group: %d", max_group_domains);
     361             :   /*
     362             :    * TODO: Preliminary implementation, should balance number of units in
     363             :    *       groups.
     364             :    */
     365           6 :   for (int g = 0; g < num_parts; ++g) {
     366           4 :     int num_group_subdomains = max_group_domains;
     367           4 :     if ((g+1) * max_group_domains > num_domains) {
     368           1 :       num_group_subdomains = num_domains - (g * max_group_domains);
     369             :     }
     370             :     DART_LOG_TRACE("dart__base__locality__domain_split_tags: "
     371             :                    "domains in group %d: %d", g, num_group_subdomains);
     372             : 
     373           4 :     group_sizes[g]       = num_group_subdomains;
     374           4 :     group_domain_tags[g] = malloc(sizeof(char *) * num_group_subdomains);
     375             : 
     376           9 :     for (int d_rel = 0; d_rel < num_group_subdomains; ++d_rel) {
     377           5 :       int d_abs   = group_first_domain_idx + d_rel;
     378           5 :       int tag_len = strlen(domain_tags[d_abs]);
     379           5 :       group_domain_tags[g][d_rel] = malloc(sizeof(char) * (tag_len + 1));
     380           5 :       strncpy(group_domain_tags[g][d_rel], domain_tags[d_abs],
     381             :               DART_LOCALITY_DOMAIN_TAG_MAX_SIZE);
     382           5 :       group_domain_tags[g][d_rel][tag_len] = '\0';
     383             :     }
     384             :     /* Create domain of group: */
     385           4 :     group_first_domain_idx += num_group_subdomains;
     386             :   }
     387             : 
     388           2 :   *group_sizes_out       = group_sizes;
     389           2 :   *group_domain_tags_out = group_domain_tags;
     390             : 
     391             :   DART_LOG_TRACE("dart__base__locality__domain_split_tags >");
     392           2 :   return DART_OK;
     393             : }
     394             : 
     395           2 : dart_ret_t dart__base__locality__domain_group(
     396             :   dart_domain_locality_t           * domain,
     397             :   int                                group_size,
     398             :   const char                      ** group_subdomain_tags,
     399             :   char                             * group_domain_tag_out)
     400             : {
     401             :   DART_LOG_TRACE("dart__base__locality__domain_group() "
     402             :                  "domain_in: (%s: %d @ %d) group size: %d",
     403             :                  domain->domain_tag, domain->scope, domain->level,
     404             :                  group_size);
     405             : #ifdef DART_ENABLE_LOGGING
     406             :   for (int sd = 0; sd < group_size; sd++) {
     407             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     408             :                    "group_subdomain_tags[%d]: %s",
     409             :                    sd, group_subdomain_tags[sd]);
     410             :   }
     411             : #endif
     412             : 
     413           2 :   if (group_size < 1) {
     414           0 :     return DART_ERR_INVAL;
     415             :   }
     416             : 
     417           2 :   dart_ret_t ret = DART_OK;
     418             : 
     419             :   DART_LOG_TRACE("dart__base__locality__domain_group: "
     420             :                  "group size: %d", group_size);
     421             : 
     422           2 :   group_domain_tag_out[0] = '\0';
     423             : 
     424             :   /* The group's parent domain: */
     425             :   dart_domain_locality_t * group_parent_domain;
     426           2 :   ret = dart__base__locality__domain__parent(
     427             :           domain,
     428             :           group_subdomain_tags, group_size,
     429             :           &group_parent_domain);
     430             : 
     431           2 :   if (ret != DART_OK) {
     432           0 :     return ret;
     433             :   }
     434             : 
     435             :   DART_LOG_TRACE("dart__base__locality__domain_group: "
     436             :                  "group parent: %s",
     437             :                  group_parent_domain->domain_tag);
     438             : 
     439             :   /* Find parents of specified subdomains that are an immediate child node
     440             :    * of the input domain.
     441             :    */
     442           2 :   int immediate_subdomains_group = 1;
     443           2 :   int num_group_parent_domain_tag_parts =
     444           2 :         dart__base__strcnt(group_parent_domain->domain_tag, '.');
     445           2 :   for (int sd = 0; sd < group_size; sd++) {
     446           2 :     const char * group_domain_tag = group_subdomain_tags[sd];
     447             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     448             :                    "    group_subdomain_tags[%d]: %s",
     449             :                    sd, group_domain_tag);
     450           4 :     if (dart__base__strcnt(group_domain_tag, '.') !=
     451           2 :         num_group_parent_domain_tag_parts + 1) {
     452           2 :       immediate_subdomains_group = 0;
     453           2 :       break;
     454             :     }
     455             :   }
     456           2 :   if (immediate_subdomains_group) {
     457             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     458             :                    "group of immediate child domains");
     459             :     /* Subdomains in group are immediate child nodes of group parent
     460             :      * domain:
     461             :      */
     462           0 :     ret = dart__base__locality__group_subdomains(
     463             :             group_parent_domain,
     464             :             group_subdomain_tags, group_size,
     465             :             group_domain_tag_out);
     466           0 :     if (ret != DART_OK) {
     467           0 :       return ret;
     468             :     }
     469             :   } else {
     470             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     471             :                    "group of indirect child domains");
     472             : 
     473             :     /* Subdomains in group are in indirect child nodes of group parent
     474             :      * domain.
     475             :      * Find immediate child nodes that are parents of group subdomains.
     476             :      * Example:
     477             :      *
     478             :      *     parent:        .0
     479             :      *     group domains: { .0.1.2, .0.1.3, .0.2.0 }
     480             :      *
     481             :      *     --> { .0.1, .0.1, .0.2 }
     482             :      *
     483             :      *     --> groups:  { .0.1, .0.2 }
     484             :      */
     485           2 :     char ** immediate_subdomain_tags    = malloc(sizeof(char *) *
     486             :                                                  group_size);
     487           2 :     char *  group_parent_domain_tag     = group_parent_domain->domain_tag;
     488           2 :     int     group_parent_domain_tag_len = strlen(group_parent_domain_tag);
     489             :     DART_LOG_TRACE("dart__base__locality__domain_group: parent: %s",
     490             :                    group_parent_domain_tag);
     491           6 :     for (int sd = 0; sd < group_size; sd++) {
     492             :       /* Resolve relative index of subdomain: */
     493           8 :       immediate_subdomain_tags[sd] =
     494           4 :         calloc(sizeof(char) * DART_LOCALITY_DOMAIN_TAG_MAX_SIZE,
     495             :                sizeof(char));
     496             : 
     497           8 :       char * dot_pos = strchr(group_subdomain_tags[sd] +
     498           4 :                               group_parent_domain_tag_len + 1, '.');
     499             :       int immediate_subdomain_tag_len;
     500           4 :       if (dot_pos == NULL) {
     501             :         /* subdomain is immediate child of parent: */
     502           4 :         immediate_subdomain_tag_len = strlen(group_subdomain_tags[sd]);
     503             :       } else {
     504             :         /* subdomain is indirect child of parent: */
     505           0 :         immediate_subdomain_tag_len = dot_pos -
     506           0 :                                       group_subdomain_tags[sd];
     507             :       }
     508           4 :       strncpy(immediate_subdomain_tags[sd], group_subdomain_tags[sd],
     509             :               immediate_subdomain_tag_len);
     510           4 :       immediate_subdomain_tags[sd][immediate_subdomain_tag_len] = '\0';
     511             :     }
     512           2 :     int num_group_subdomains = dart__base__strsunique(
     513             :                                  immediate_subdomain_tags,
     514             :                                  group_size);
     515             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     516             :                    "num_group_subdomains: %d", num_group_subdomains);
     517             : #ifdef DART_ENABLE_LOGGING
     518             :     for (int gsd = 0; gsd < num_group_subdomains; gsd++) {
     519             :       DART_LOG_TRACE("dart__base__locality__domain_group: "
     520             :                      "group.subdomain[%d]: %s",
     521             :                      gsd, immediate_subdomain_tags[gsd]);
     522             :     }
     523             : #endif
     524             :     /*
     525             :      * Note: Required to append group domain at the end of the group
     526             :      *       parent's subdomain list to ensure that tags of domains not
     527             :      *       included in group remain valid.
     528             :      */
     529           4 :     group_parent_domain->domains =
     530           2 :       realloc(group_parent_domain->domains,
     531             :               sizeof(dart_domain_locality_t) *
     532           2 :                 (group_parent_domain->num_domains + 1));
     533           2 :     dart_domain_locality_t * group_domain =
     534           2 :       group_parent_domain->domains + group_parent_domain->num_domains;
     535             : 
     536           2 :     dart__base__locality__domain__init(group_domain);
     537             : 
     538             :     /* TODO: hwinfo of group domain is not correctly initialized, and doing
     539             :      *       so is not trivial.
     540             :      *       Using parent domain's hwinfo as an intermediate solution.
     541             :      */
     542           2 :     group_domain->hwinfo         = group_parent_domain->hwinfo;
     543           2 :     group_domain->team           = group_parent_domain->team;
     544           2 :     group_domain->scope          = DART_LOCALITY_SCOPE_GROUP;
     545           2 :     group_domain->level          = group_parent_domain->level + 1;
     546           2 :     group_domain->parent         = group_parent_domain;
     547           2 :     group_domain->relative_index = group_parent_domain->num_domains;
     548           2 :     group_domain->num_nodes      = group_parent_domain->num_nodes;
     549           2 :     group_domain->num_units      = 0;
     550           2 :     group_domain->unit_ids       = NULL;
     551           2 :     group_domain->num_domains    = 0;
     552           2 :     group_domain->domains        = malloc(sizeof(dart_domain_locality_t) *
     553             :                                           num_group_subdomains);
     554             : 
     555           2 :     strncpy(group_domain->domain_tag, group_parent_domain_tag,
     556             :             group_parent_domain_tag_len);
     557           2 :     group_domain->domain_tag[group_parent_domain_tag_len] = '\0';
     558             : 
     559             :     /* TODO: Check if this implementation is correct.
     560             :              Incrementing an existing domain's relative index could result
     561             :              in naming collisions as the relative index of the subdomain can
     562             :              differ from the last place in their domain tag.
     563             :     */
     564           2 :     int group_domain_tag_len =
     565           2 :       sprintf(group_domain->domain_tag + group_parent_domain_tag_len,
     566             :               ".%d", group_domain->relative_index) +
     567             :       group_parent_domain_tag_len;
     568           2 :     group_domain->domain_tag[group_domain_tag_len] = '\0';
     569             : 
     570           2 :     strcpy(group_domain_tag_out, group_domain->domain_tag);
     571             : 
     572             :     /* Initialize group subdomains:
     573             :      */
     574             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     575             :                    "initialize %d subdomains of group (%s)",
     576             :                    num_group_subdomains, group_domain->domain_tag);
     577             : 
     578           8 :     for (int gsd = 0; gsd < num_group_subdomains; gsd++) {
     579             :       dart_domain_locality_t * group_subdomain_in;
     580             : 
     581             :       /* Copy
     582             :        *   domain.domains[domain_tag = group[g].immediate_subdomains[gsd]]
     583             :        * to
     584             :        *   group[g].domains[gsd]:
     585             :        */
     586             :       DART_LOG_TRACE("dart__base__locality__domain_group: "
     587             :                      "load domain.domains[domain_tag = "
     588             :                      "(group.immediate_subdomain_tags[%d] = %s])",
     589             :                      gsd, immediate_subdomain_tags[gsd]);
     590             : 
     591           2 :       ret = dart__base__locality__domain(
     592           2 :               domain, immediate_subdomain_tags[gsd],
     593             :               &group_subdomain_in);
     594           2 :       if (ret != DART_OK) { break; }
     595             : 
     596             :       DART_LOG_TRACE("dart__base__locality__domain_group: "
     597             :                      "copy domain.domains[domain_tag = %s] to "
     598             :                      "group.domains[%d]",
     599             :                      immediate_subdomain_tags[gsd], gsd);
     600           4 :       ret = dart__base__locality__domain__copy(
     601             :               group_subdomain_in,
     602           4 :               group_domain->domains + gsd);
     603           2 :       if (ret != DART_OK) { break; }
     604             : 
     605           2 :       group_domain->domains[gsd].parent = group_domain;
     606           2 :       group_domain->num_domains++;
     607           2 :       group_domain->num_units += group_domain[gsd].num_units;
     608             : 
     609             :     } /* for group_domain.domains */
     610             : 
     611           2 :     if (ret != DART_OK) { return ret; }
     612             : 
     613           2 :     group_domain->unit_ids = malloc(sizeof(dart_unit_t) *
     614           2 :                                     group_domain->num_units);
     615             : 
     616             :     /* Remove entries from group domain that are not part of the group:
     617             :      */
     618             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     619             :                    "select %d subdomains in group = %s",
     620             :                    group_size, group_domain->domain_tag);
     621           2 :     ret = dart__base__locality__domain_select_subdomains(
     622             :             group_domain,
     623             :             group_subdomain_tags,
     624             :             group_size);
     625           2 :     if (ret != DART_OK) { return ret; }
     626             : 
     627             :     DART_LOG_TRACE("dart__base__locality__domain_group: "
     628             :                    "update group (%s) after adding subdomains",
     629             :                    group_domain->domain_tag);
     630           2 :     ret = dart__base__locality__domain__update_subdomains(
     631             :             group_domain);
     632           2 :     if (ret != DART_OK) { return ret; }
     633             : 
     634             :     /* Remove grouped domains from parent's subdomains:
     635             :      */
     636           3 :     for (int sd = 0; sd < group_parent_domain->num_domains; sd++) {
     637           1 :       dart_domain_locality_t * group_parent_subdomain =
     638           1 :                                  group_parent_domain->domains + sd;
     639             :       /* Whether this sibling of the group domain contains subdomains
     640             :        * affected by the group:
     641             :        */
     642           1 :       int contains_grouped_domains = 0;
     643           3 :       for (int gd = 0; gd < group_size; ++gd) {
     644           2 :         if (strcmp(group_parent_subdomain->domain_tag,
     645           2 :                    immediate_subdomain_tags[gd]) == 0) {
     646           0 :           contains_grouped_domains = 1;
     647           0 :           break;
     648             :         }
     649             :       }
     650           1 :       if (contains_grouped_domains) {
     651             :         DART_LOG_TRACE("dart__base__locality__domain_group: "
     652             :                        "remove grouped domains from %s",
     653             :                        group_parent_subdomain->domain_tag);
     654           0 :         ret = dart__base__locality__domain_exclude_subdomains(
     655             :                 group_parent_subdomain,
     656             :                 group_subdomain_tags,
     657             :                 group_size);
     658           0 :         if (ret != DART_OK) { break; }
     659             :       }
     660             :     }
     661             : 
     662           6 :     for (int sd = 0; sd < group_size; sd++) {
     663           4 :       free(immediate_subdomain_tags[sd]);
     664             :     }
     665           2 :     free(immediate_subdomain_tags);
     666             : 
     667           2 :     if (ret != DART_OK) { return ret; }
     668             : 
     669           2 :     group_parent_domain->num_domains++;
     670             :   }
     671           2 :   if (ret != DART_OK) { return ret; }
     672             : 
     673             :   DART_LOG_TRACE("dart__base__locality__domain_group >");
     674           2 :   return DART_OK;
     675             : }
     676             : 
     677             : /* ====================================================================== *
     678             :  * Unit Locality                                                          *
     679             :  * ====================================================================== */
     680             : 
     681          69 : dart_ret_t dart__base__locality__unit(
     682             :   dart_team_t                        team,
     683             :   dart_unit_t                        unit,
     684             :   dart_unit_locality_t            ** locality)
     685             : {
     686             :   DART_LOG_DEBUG("dart__base__locality__unit() team(%d) unit(%d)",
     687             :                  team, unit);
     688          69 :   *locality = NULL;
     689             : 
     690             :   dart_unit_locality_t * uloc;
     691          69 :   dart_ret_t ret = dart__base__unit_locality__at(
     692             :                      dart__base__locality__unit_mapping_[team], unit,
     693             :                      &uloc);
     694          69 :   if (ret != DART_OK) {
     695           0 :     DART_LOG_ERROR("dart_unit_locality: "
     696             :                    "dart__base__locality__unit(team:%d unit:%d) "
     697             :                    "failed (%d)", team, unit, ret);
     698           0 :     return ret;
     699             :   }
     700          69 :   *locality = uloc;
     701             : 
     702             :   DART_LOG_DEBUG("dart__base__locality__unit > team(%d) unit(%d)",
     703             :                  team, unit);
     704          69 :   return DART_OK;
     705             : }
     706             : 
     707             : /* ====================================================================== *
     708             :  * Private Function Definitions                                           *
     709             :  * ====================================================================== */
     710             : 
     711             : /**
     712             :  * Move subset of a domain's immediate child nodes into a group subdomain.
     713             :  */
     714           0 : dart_ret_t dart__base__locality__group_subdomains(
     715             :   dart_domain_locality_t           * domain,
     716             :   /** Domain tags of child nodes to move into group subdomain. */
     717             :   const char                      ** group_subdomain_tags,
     718             :   /** Number of child nodes to move into group subdomain. */
     719             :   int                                num_group_subdomain_tags,
     720             :   /** Domain tag of the created group subdomain. */
     721             :   char                             * group_domain_tag_out)
     722             : {
     723             :   DART_LOG_TRACE("dart__base__locality__group_subdomains() "
     724             :                  "group parent domain: %s num domains: %d "
     725             :                  "num_group_subdomain_tags: %d",
     726             :                  domain->domain_tag, domain->num_domains,
     727             :                  num_group_subdomain_tags);
     728             : 
     729           0 :   group_domain_tag_out[0] = '\0';
     730             : 
     731           0 :   if (domain->num_domains < 1) {
     732           0 :     DART_LOG_ERROR("dart__base__locality__group_subdomains ! "
     733             :                    "no subdomains, cannot create group");
     734           0 :     return DART_ERR_NOTFOUND;
     735             :   }
     736             : 
     737           0 :   int num_grouped         = num_group_subdomain_tags;
     738           0 :   int num_ungrouped       = domain->num_domains - num_grouped;
     739           0 :   int num_subdomains_new  = num_ungrouped + 1;
     740             : 
     741             :   /* The domain tag of the group to be added must be a successor of the last
     742             :    * subdomain's (the group domain's last sibling) tag to avoid collisions.
     743             :    * Relative index of last subdomain can differ from its last domain tag
     744             :    * segment, so we need to read and increment the suffix of its domain tag
     745             :    * to obtain the group's domain tag. */
     746             : #if 0
     747             :   int domain_last_rel_idx = domain->domains[domain->num_domains - 1]
     748             :                               .relative_index;
     749             : #endif
     750           0 :   char * domain_last_tag_suffix_pos =
     751           0 :            strrchr(domain->domains[domain->num_domains - 1].domain_tag, '.');
     752           0 :   int    domain_last_tag_suffix     = atoi(domain_last_tag_suffix_pos + 1);
     753             : 
     754             :   /* Child nodes are ordered by domain tag.
     755             :    * Create sorted copy of subdomain tags to partition child nodes in a
     756             :    * single pass:
     757             :    */
     758           0 :   char ** group_subdomain_tags_sorted =
     759           0 :     malloc(num_group_subdomain_tags * sizeof(char *));
     760           0 :   for (int sdt = 0; sdt < num_group_subdomain_tags; ++sdt) {
     761           0 :     group_subdomain_tags_sorted[sdt] =
     762           0 :       malloc((strlen(group_subdomain_tags[sdt]) + 1) * sizeof(char));
     763           0 :     strcpy(group_subdomain_tags_sorted[sdt], group_subdomain_tags[sdt]);
     764             :   }
     765           0 :   qsort(group_subdomain_tags_sorted, num_group_subdomain_tags,
     766             :         sizeof(char*), cmpstr_);
     767             : 
     768           0 :   int num_existing_domain_groups = 0;
     769           0 :   for (int sd = 0; sd < domain->num_domains; sd++) {
     770           0 :     if (domain->domains[sd].scope == DART_LOCALITY_SCOPE_GROUP) {
     771           0 :       num_existing_domain_groups++;
     772             :     }
     773             :   }
     774           0 :   num_ungrouped -= num_existing_domain_groups;
     775             : 
     776             :   /* Partition child nodes of domain into grouped and ungrouped
     777             :    * subdomains:
     778             :    */
     779           0 :   dart_domain_locality_t * ungrouped_domains =
     780           0 :     malloc(sizeof(dart_domain_locality_t) * num_ungrouped);
     781           0 :   dart_domain_locality_t * group_domains =
     782           0 :     malloc(sizeof(dart_domain_locality_t) * num_existing_domain_groups);
     783           0 :   dart_domain_locality_t * grouped_domains =
     784           0 :     malloc(sizeof(dart_domain_locality_t) * num_grouped);
     785             : 
     786             :   /* Copy child nodes into partitions:
     787             :    */
     788           0 :   int sdt                  = 0;
     789           0 :   int group_idx            = 0;
     790           0 :   int grouped_idx          = 0;
     791           0 :   int ungrouped_idx        = 0;
     792           0 :   int group_domain_rel_idx = num_ungrouped + num_existing_domain_groups;
     793             : 
     794           0 :   for (int sd = 0; sd < domain->num_domains; sd++) {
     795           0 :     dart_domain_locality_t * subdom        = &domain->domains[sd];
     796             :     dart_domain_locality_t * domain_copy;
     797             : 
     798           0 :     if (subdom->scope == DART_LOCALITY_SCOPE_GROUP) {
     799           0 :       domain_copy = &group_domains[group_idx];
     800           0 :       group_idx++;
     801             :     }
     802           0 :     else if (sdt < num_group_subdomain_tags &&
     803           0 :              strcmp(subdom->domain_tag, group_subdomain_tags_sorted[sdt])
     804             :              == 0) {
     805           0 :       domain_copy = &grouped_domains[grouped_idx];
     806           0 :       grouped_idx++;
     807           0 :       sdt++;
     808             :     } else {
     809           0 :       domain_copy = &ungrouped_domains[ungrouped_idx];
     810           0 :       ungrouped_idx++;
     811             :     }
     812           0 :     memcpy(domain_copy, subdom, sizeof(dart_domain_locality_t));
     813             :   }
     814             : 
     815           0 :   for (int sdt = 0; sdt < num_group_subdomain_tags; ++sdt) {
     816           0 :     free(group_subdomain_tags_sorted[sdt]);
     817             :   }
     818           0 :   free(group_subdomain_tags_sorted);
     819             : 
     820             :   /* Check that all subdomains have been found: */
     821           0 :   if (sdt != num_group_subdomain_tags) {
     822           0 :     DART_LOG_ERROR("dart__base__locality__group_subdomains ! "
     823             :                    "only found %d of %d requested subdomains",
     824             :                    sdt, num_group_subdomain_tags);
     825           0 :     return DART_ERR_NOTFOUND;
     826             :   }
     827             : 
     828             :   /* Append group domain to subdomains:
     829             :    */
     830           0 :   domain->domains =
     831           0 :     realloc(domain->domains,
     832             :             sizeof(dart_domain_locality_t) * num_subdomains_new);
     833           0 :   DART_ASSERT(domain->domains != NULL);
     834             : 
     835           0 :   domain->num_domains = num_subdomains_new;
     836             : 
     837             :   /* Initialize group domain and set it as the input domain's last child
     838             :    * node:
     839             :    */
     840           0 :   dart_domain_locality_t * group_domain =
     841           0 :     &domain->domains[group_domain_rel_idx];
     842             : 
     843           0 :   dart__base__locality__domain__init(group_domain);
     844             : 
     845             :   /* TODO: hwinfo of group domain is not initialized.
     846             :    */
     847           0 :   group_domain->parent         = domain;
     848           0 :   group_domain->relative_index = group_domain_rel_idx;
     849           0 :   group_domain->level          = domain->level + 1;
     850           0 :   group_domain->scope          = DART_LOCALITY_SCOPE_GROUP;
     851           0 :   group_domain->num_domains    = num_grouped;
     852           0 :   group_domain->domains        = malloc(sizeof(dart_domain_locality_t) *
     853             :                                         num_grouped);
     854             : 
     855           0 :   int tag_len      = sprintf(group_domain->domain_tag, "%s",
     856           0 :                              domain->domain_tag);
     857           0 :   int tag_last_idx = domain_last_tag_suffix + 1;
     858           0 :   sprintf(group_domain->domain_tag + tag_len, ".%d", tag_last_idx);
     859             :   DART_LOG_TRACE("dart__base__locality__group_subdomains: "
     860             :                  "group_domain.tag: %s relative index: %d grouped: %d "
     861             :                  "ungrouped: %d",
     862             :                  group_domain->domain_tag, group_domain->relative_index,
     863             :                  num_grouped, num_ungrouped);
     864             : 
     865           0 :   strcpy(group_domain_tag_out, group_domain->domain_tag);
     866             : 
     867             :   /*
     868             :    * Set grouped partition of subdomains as child nodes of group domain:
     869             :    */
     870           0 :   group_domain->num_units = 0;
     871           0 :   group_domain->num_nodes = 0;
     872           0 :   for (int gd = 0; gd < num_grouped; gd++) {
     873           0 :     memcpy(&group_domain->domains[gd], &grouped_domains[gd],
     874             :            sizeof(dart_domain_locality_t));
     875             :   }
     876           0 :   dart__base__locality__domain__update_subdomains(
     877             :     group_domain);
     878             : 
     879             :   /*
     880             :    * Collect unit ids of group domain:
     881             :    */
     882           0 :   group_domain->unit_ids = malloc(sizeof(dart_unit_t) *
     883           0 :                                   group_domain->num_units);
     884           0 :   int group_domain_unit_idx = 0;
     885           0 :   for (int gd = 0; gd < num_grouped; gd++) {
     886           0 :     dart_domain_locality_t * group_subdomain = group_domain->domains + gd;
     887           0 :     memcpy(group_domain->unit_ids + group_domain_unit_idx,
     888           0 :            group_subdomain->unit_ids,
     889           0 :            sizeof(dart_unit_t) * group_subdomain->num_units);
     890           0 :     group_domain_unit_idx += group_subdomain->num_units;
     891             :   }
     892             : 
     893           0 :   for (int sd = 0; sd < num_ungrouped; sd++) {
     894             :     DART_LOG_TRACE(
     895             :       "dart__base__locality__group_subdomains: ==> domains[%d] u: %s",
     896             :       sd, domain->domains[sd].domain_tag);
     897           0 :     memcpy(&domain->domains[sd],
     898           0 :            &ungrouped_domains[sd],
     899             :            sizeof(dart_domain_locality_t));
     900             : 
     901             :     /* Pointers are invalidated by realloc, update parent pointers of
     902             :      * subdomains: */
     903           0 :     domain->domains[sd].parent         = domain;
     904           0 :     domain->domains[sd].relative_index = sd;
     905             :   }
     906             : 
     907           0 :   for (int g = 0; g < num_existing_domain_groups; g++) {
     908           0 :     int abs_g = g + num_ungrouped;
     909             :     DART_LOG_TRACE(
     910             :       "dart__base__locality__group_subdomains: ==> domains[%d] g: %s",
     911             :       abs_g, domain->domains[abs_g].domain_tag);
     912           0 :     memcpy(&domain->domains[abs_g], &group_domains[g],
     913             :            sizeof(dart_domain_locality_t));
     914             : 
     915             :     /* Pointers are invalidated by realloc, update parent pointers of
     916             :      * subdomains: */
     917           0 :     domain->domains[abs_g].parent         = domain;
     918           0 :     domain->domains[abs_g].relative_index = abs_g;
     919             :   }
     920             :   DART_LOG_TRACE(
     921             :     "dart__base__locality__group_subdomains: ==> domains[%d] *: %s",
     922             :     group_domain->relative_index, group_domain->domain_tag);
     923             : 
     924             : #ifdef DART_ENABLE_LOGGING
     925             :   int g_idx = 0;
     926             :   for (int sd = 0; sd < domain->num_domains; sd++) {
     927             :     dart_domain_locality_t * subdom = domain->domains + sd;
     928             :     DART_LOG_TRACE(
     929             :       "dart__base__locality__group_subdomains: --> domains[%d:%d]: "
     930             :       "tag: %s scope: %d subdomains: %d ADDR[%p]",
     931             :       sd, subdom->relative_index, subdom->domain_tag,
     932             :       subdom->scope, subdom->num_domains, subdom);
     933             :     if (subdom->scope == DART_LOCALITY_SCOPE_GROUP) {
     934             :       for (int gsd = 0; gsd < subdom->num_domains; gsd++) {
     935             :         dart_domain_locality_t * group_subdom = &(subdom->domains[gsd]);
     936             :         dart__unused(group_subdom);
     937             :         DART_LOG_TRACE(
     938             :           "dart__base__locality__group_subdomains: -->   groups[%d:%d]."
     939             :           "domains[%d]: tag: %s scope: %d subdomains: %d",
     940             :           g_idx, group_subdom->relative_index, gsd,
     941             :           group_subdom->domain_tag,
     942             :           group_subdom->scope, group_subdom->num_domains);
     943             :       }
     944             :       g_idx++;
     945             :     }
     946             :   }
     947             : #endif
     948             : 
     949           0 :   free(grouped_domains);
     950           0 :   free(ungrouped_domains);
     951             : 
     952             :   DART_LOG_TRACE("dart__base__locality__group_subdomains >");
     953           0 :   return DART_OK;
     954             : }
     955             : 
     956          24 : dart_ret_t dart__base__locality__scope_domains_rec(
     957             :   const dart_domain_locality_t     * domain,
     958             :   dart_locality_scope_t              scope,
     959             :   int                              * num_domains_out,
     960             :   char                           *** domain_tags_out)
     961             : {
     962             :   dart_ret_t ret;
     963             :   DART_LOG_TRACE("dart__base__locality__scope_domains() level %d",
     964             :                  domain->level);
     965             : 
     966          24 :   if (domain->scope == scope) {
     967             :     DART_LOG_TRACE("dart__base__locality__scope_domains domain %s matched",
     968             :                    domain->domain_tag);
     969          10 :     int     dom_idx           = *num_domains_out;
     970          10 :     *num_domains_out         += 1;
     971          10 :     char ** domain_tags_temp  = (char **)(
     972          10 :                                   realloc(*domain_tags_out,
     973             :                                             sizeof(char *) *
     974          10 :                                             (*num_domains_out)));
     975          10 :     if (domain_tags_temp != NULL) {
     976          10 :       int domain_tag_size         = strlen(domain->domain_tag) + 1;
     977          10 :       *domain_tags_out            = domain_tags_temp;
     978          10 :       (*domain_tags_out)[dom_idx] = malloc(sizeof(char) * domain_tag_size);
     979          10 :       strncpy((*domain_tags_out)[dom_idx], domain->domain_tag,
     980             :               DART_LOCALITY_DOMAIN_TAG_MAX_SIZE);
     981             :     } else {
     982           0 :       DART_LOG_ERROR("dart__base__locality__scope_domains ! "
     983             :                      "realloc failed");
     984           0 :       return DART_ERR_OTHER;
     985             :     }
     986             :   } else {
     987          34 :     for (int d = 0; d < domain->num_domains; ++d) {
     988          40 :       ret = dart__base__locality__scope_domains_rec(
     989          40 :               &domain->domains[d],
     990             :               scope,
     991             :               num_domains_out,
     992             :               domain_tags_out);
     993          20 :       if (ret != DART_OK) {
     994           0 :         return ret;
     995             :       }
     996             :     }
     997             :   }
     998          24 :   if (*num_domains_out <= 0) {
     999           0 :     DART_LOG_ERROR("dart__base__locality__scope_domains ! "
    1000             :                    "no domains found");
    1001           0 :     return DART_ERR_NOTFOUND;
    1002             :   }
    1003             :   DART_LOG_TRACE("dart__base__locality__scope_domains >");
    1004          24 :   return DART_OK;
    1005             : }
    1006             : 
    1007           0 : dart_locality_scope_t dart__base__locality__scope_parent(
    1008             :   dart_locality_scope_t scope)
    1009             : {
    1010           0 :   switch (scope) {
    1011           0 :     case DART_LOCALITY_SCOPE_GLOBAL: return DART_LOCALITY_SCOPE_NODE;
    1012           0 :     case DART_LOCALITY_SCOPE_NODE:   return DART_LOCALITY_SCOPE_MODULE;
    1013           0 :     case DART_LOCALITY_SCOPE_MODULE: return DART_LOCALITY_SCOPE_NUMA;
    1014           0 :     case DART_LOCALITY_SCOPE_NUMA:   return DART_LOCALITY_SCOPE_CORE;
    1015           0 :     default:                         return DART_LOCALITY_SCOPE_UNDEFINED;
    1016             :   }
    1017             : }
    1018             : 
    1019           0 : dart_locality_scope_t dart__base__locality__scope_child(
    1020             :   dart_locality_scope_t scope)
    1021             : {
    1022           0 :   switch (scope) {
    1023           0 :     case DART_LOCALITY_SCOPE_CORE:   return DART_LOCALITY_SCOPE_NUMA;
    1024           0 :     case DART_LOCALITY_SCOPE_NUMA:   return DART_LOCALITY_SCOPE_MODULE;
    1025           0 :     case DART_LOCALITY_SCOPE_MODULE: return DART_LOCALITY_SCOPE_NODE;
    1026           0 :     case DART_LOCALITY_SCOPE_NODE:   return DART_LOCALITY_SCOPE_GLOBAL;
    1027           0 :     default:                         return DART_LOCALITY_SCOPE_UNDEFINED;
    1028             :   }
    1029             : }

Generated by: LCOV version 1.12