root/opal/mca/hwloc/base/hwloc_base_frame.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_hwloc_base_register
  2. opal_hwloc_base_open
  3. opal_hwloc_base_close
  4. buffer_cleanup
  5. opal_hwloc_get_print_buffer
  6. opal_hwloc_base_print_locality
  7. obj_data_const
  8. sum_const
  9. sum_dest
  10. topo_data_const
  11. topo_data_dest
  12. opal_hwloc_base_set_binding_policy

   1 /*
   2  * Copyright (c) 2011-2018 Cisco Systems, Inc.  All rights reserved
   3  * Copyright (c) 2013-2018 Intel, Inc. All rights reserved.
   4  * Copyright (c) 2016-2017 Research Organization for Information Science
   5  *                         and Technology (RIST). All rights reserved.
   6  * Copyright (c) 2019 IBM Corporation. All rights reserved.
   7  * $COPYRIGHT$
   8  *
   9  * Additional copyrights may follow
  10  *
  11  * $HEADER$
  12  */
  13 
  14 
  15 #include "opal_config.h"
  16 
  17 #include "opal/constants.h"
  18 #include "opal/dss/dss.h"
  19 #include "opal/util/argv.h"
  20 #include "opal/util/output.h"
  21 #include "opal/util/show_help.h"
  22 #include "opal/mca/mca.h"
  23 #include "opal/mca/base/base.h"
  24 #include "opal/threads/tsd.h"
  25 
  26 #include "opal/mca/hwloc/hwloc-internal.h"
  27 #include "opal/mca/hwloc/base/base.h"
  28 
  29 
  30 /*
  31  * The following file was created by configure.  It contains extern
  32  * statements and the definition of an array of pointers to each
  33  * component's public mca_base_component_t struct.
  34  */
  35 #include "opal/mca/hwloc/base/static-components.h"
  36 
  37 
  38 /*
  39  * Globals
  40  */
  41 bool opal_hwloc_base_inited = false;
  42 hwloc_topology_t opal_hwloc_topology=NULL;
  43 hwloc_cpuset_t opal_hwloc_my_cpuset=NULL;
  44 hwloc_cpuset_t opal_hwloc_base_given_cpus=NULL;
  45 opal_hwloc_base_map_t opal_hwloc_base_map = OPAL_HWLOC_BASE_MAP_NONE;
  46 opal_hwloc_base_mbfa_t opal_hwloc_base_mbfa = OPAL_HWLOC_BASE_MBFA_WARN;
  47 opal_binding_policy_t opal_hwloc_binding_policy=0;
  48 char *opal_hwloc_base_cpu_list=NULL;
  49 bool opal_hwloc_report_bindings=false;
  50 hwloc_obj_type_t opal_hwloc_levels[] = {
  51     HWLOC_OBJ_MACHINE,
  52     HWLOC_OBJ_NODE,
  53     HWLOC_OBJ_SOCKET,
  54     HWLOC_OBJ_L3CACHE,
  55     HWLOC_OBJ_L2CACHE,
  56     HWLOC_OBJ_L1CACHE,
  57     HWLOC_OBJ_CORE,
  58     HWLOC_OBJ_PU
  59 };
  60 bool opal_hwloc_use_hwthreads_as_cpus = false;
  61 char *opal_hwloc_base_topo_file = NULL;
  62 
  63 static mca_base_var_enum_value_t hwloc_base_map[] = {
  64     {OPAL_HWLOC_BASE_MAP_NONE, "none"},
  65     {OPAL_HWLOC_BASE_MAP_LOCAL_ONLY, "local_only"},
  66     {0, NULL}
  67 };
  68 
  69 static mca_base_var_enum_value_t hwloc_failure_action[] = {
  70     {OPAL_HWLOC_BASE_MBFA_SILENT, "silent"},
  71     {OPAL_HWLOC_BASE_MBFA_WARN, "warn"},
  72     {OPAL_HWLOC_BASE_MBFA_ERROR, "error"},
  73     {0, NULL}
  74 };
  75 
  76 static int opal_hwloc_base_register(mca_base_register_flag_t flags);
  77 static int opal_hwloc_base_open(mca_base_open_flag_t flags);
  78 static int opal_hwloc_base_close(void);
  79 
  80 MCA_BASE_FRAMEWORK_DECLARE(opal, hwloc, NULL, opal_hwloc_base_register, opal_hwloc_base_open, opal_hwloc_base_close,
  81                            mca_hwloc_base_static_components, 0);
  82 
  83 static char *opal_hwloc_base_binding_policy = NULL;
  84 static bool opal_hwloc_base_bind_to_core = false;
  85 static bool opal_hwloc_base_bind_to_socket = false;
  86 
  87 static int opal_hwloc_base_register(mca_base_register_flag_t flags)
  88 {
  89     mca_base_var_enum_t *new_enum;
  90     int ret, varid;
  91 
  92     /* hwloc_base_mbind_policy */
  93 
  94     opal_hwloc_base_map = OPAL_HWLOC_BASE_MAP_NONE;
  95     mca_base_var_enum_create("hwloc memory allocation policy", hwloc_base_map, &new_enum);
  96     ret = mca_base_var_register("opal", "hwloc", "base", "mem_alloc_policy",
  97                                 "General memory allocations placement policy (this is not memory binding). "
  98                                 "\"none\" means that no memory policy is applied. \"local_only\" means that a process' memory allocations will be restricted to its local NUMA node. "
  99                                 "If using direct launch, this policy will not be in effect until after MPI_INIT. "
 100                                 "Note that operating system paging policies are unaffected by this setting. For example, if \"local_only\" is used and local NUMA node memory is exhausted, a new memory allocation may cause paging.",
 101                                 MCA_BASE_VAR_TYPE_INT, new_enum, 0, 0, OPAL_INFO_LVL_9,
 102                                 MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_map);
 103     OBJ_RELEASE(new_enum);
 104     if (0 > ret) {
 105         return ret;
 106     }
 107 
 108     /* hwloc_base_bind_failure_action */
 109     opal_hwloc_base_mbfa = OPAL_HWLOC_BASE_MBFA_WARN;
 110     mca_base_var_enum_create("hwloc memory bind failure action", hwloc_failure_action, &new_enum);
 111     ret = mca_base_var_register("opal", "hwloc", "base", "mem_bind_failure_action",
 112                                 "What Open MPI will do if it explicitly tries to bind memory to a specific NUMA location, and fails.  Note that this is a different case than the general allocation policy described by hwloc_base_alloc_policy.  A value of \"silent\" means that Open MPI will proceed without comment. A value of \"warn\" means that Open MPI will warn the first time this happens, but allow the job to continue (possibly with degraded performance).  A value of \"error\" means that Open MPI will abort the job if this happens.",
 113                                 MCA_BASE_VAR_TYPE_INT, new_enum, 0, 0, OPAL_INFO_LVL_9,
 114                                 MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_mbfa);
 115     OBJ_RELEASE(new_enum);
 116     if (0 > ret) {
 117         return ret;
 118     }
 119 
 120     opal_hwloc_base_binding_policy = NULL;
 121     (void) mca_base_var_register("opal", "hwloc", "base", "binding_policy",
 122                                  "Policy for binding processes. Allowed values: none, hwthread, core, l1cache, l2cache, "
 123                                  "l3cache, socket, numa, board, cpu-list (\"none\" is the default when oversubscribed, \"core\" is "
 124                                  "the default when np<=2, and \"numa\" is the default when np>2). Allowed qualifiers: "
 125                                  "overload-allowed, if-supported, ordered",
 126                                  MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, OPAL_INFO_LVL_9,
 127                                  MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_binding_policy);
 128 
 129     /* backward compatibility */
 130     opal_hwloc_base_bind_to_core = false;
 131     (void) mca_base_var_register("opal", "hwloc", "base", "bind_to_core", "Bind processes to cores",
 132                                  MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, OPAL_INFO_LVL_9,
 133                                  MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_bind_to_core);
 134 
 135     opal_hwloc_base_bind_to_socket = false;
 136     (void) mca_base_var_register("opal", "hwloc", "base", "bind_to_socket", "Bind processes to sockets",
 137                                  MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, OPAL_INFO_LVL_9,
 138                                  MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_bind_to_socket);
 139 
 140     opal_hwloc_report_bindings = false;
 141     (void) mca_base_var_register("opal", "hwloc", "base", "report_bindings", "Report bindings to stderr",
 142                                  MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, OPAL_INFO_LVL_9,
 143                                  MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_report_bindings);
 144 
 145     opal_hwloc_base_cpu_list = NULL;
 146     varid = mca_base_var_register("opal", "hwloc", "base", "cpu_list",
 147                                   "Comma-separated list of ranges specifying logical cpus to be used by these processes [default: none]",
 148                                   MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, OPAL_INFO_LVL_9,
 149                                   MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_cpu_list);
 150     mca_base_var_register_synonym (varid, "opal", "hwloc", "base", "slot_list", MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
 151     mca_base_var_register_synonym (varid, "opal", "hwloc", "base", "cpu_set", MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
 152 
 153     /* declare hwthreads as independent cpus */
 154     opal_hwloc_use_hwthreads_as_cpus = false;
 155     (void) mca_base_var_register("opal", "hwloc", "base", "use_hwthreads_as_cpus",
 156                                  "Use hardware threads as independent cpus",
 157                                  MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0, OPAL_INFO_LVL_9,
 158                                  MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_use_hwthreads_as_cpus);
 159 
 160     opal_hwloc_base_topo_file = NULL;
 161     (void) mca_base_var_register("opal", "hwloc", "base", "topo_file",
 162                                  "Read local topology from file instead of directly sensing it",
 163                                  MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0, OPAL_INFO_LVL_9,
 164                                  MCA_BASE_VAR_SCOPE_READONLY, &opal_hwloc_base_topo_file);
 165 
 166     /* register parameters */
 167     return OPAL_SUCCESS;
 168 }
 169 
 170 static int opal_hwloc_base_open(mca_base_open_flag_t flags)
 171 {
 172     int rc;
 173     opal_data_type_t tmp;
 174 
 175     if (opal_hwloc_base_inited) {
 176         return OPAL_SUCCESS;
 177     }
 178     opal_hwloc_base_inited = true;
 179 
 180     if (OPAL_SUCCESS != (rc = opal_hwloc_base_set_binding_policy(&opal_hwloc_binding_policy,
 181                                                                  opal_hwloc_base_binding_policy))) {
 182         return rc;
 183     }
 184 
 185     if (opal_hwloc_base_bind_to_core) {
 186         opal_show_help("help-opal-hwloc-base.txt", "deprecated", true,
 187                        "--bind-to-core", "--bind-to core",
 188                        "hwloc_base_bind_to_core", "hwloc_base_binding_policy=core");
 189         /* set binding policy to core - error if something else already set */
 190         if (OPAL_BINDING_POLICY_IS_SET(opal_hwloc_binding_policy) &&
 191             OPAL_GET_BINDING_POLICY(opal_hwloc_binding_policy) != OPAL_BIND_TO_CORE) {
 192             /* error - cannot redefine the default ranking policy */
 193             opal_show_help("help-opal-hwloc-base.txt", "redefining-policy", true,
 194                            "core", opal_hwloc_base_print_binding(opal_hwloc_binding_policy));
 195             return OPAL_ERR_BAD_PARAM;
 196         }
 197         OPAL_SET_BINDING_POLICY(opal_hwloc_binding_policy, OPAL_BIND_TO_CORE);
 198     }
 199 
 200     if (opal_hwloc_base_bind_to_socket) {
 201         opal_show_help("help-opal-hwloc-base.txt", "deprecated", true,
 202                        "--bind-to-socket", "--bind-to socket",
 203                        "hwloc_base_bind_to_socket", "hwloc_base_binding_policy=socket");
 204         /* set binding policy to socket - error if something else already set */
 205         if (OPAL_BINDING_POLICY_IS_SET(opal_hwloc_binding_policy) &&
 206             OPAL_GET_BINDING_POLICY(opal_hwloc_binding_policy) != OPAL_BIND_TO_SOCKET) {
 207             /* error - cannot redefine the default ranking policy */
 208             opal_show_help("help-opal-hwloc-base.txt", "redefining-policy", true,
 209                            "socket", opal_hwloc_base_print_binding(opal_hwloc_binding_policy));
 210             return OPAL_ERR_SILENT;
 211         }
 212         OPAL_SET_BINDING_POLICY(opal_hwloc_binding_policy, OPAL_BIND_TO_SOCKET);
 213     }
 214 
 215     /* did the user provide a slot list? */
 216     if (NULL != opal_hwloc_base_cpu_list) {
 217         /* it is okay if a binding policy was already given - just ensure that
 218          * we do bind to the given cpus if provided, otherwise this would be
 219          * ignored if someone didn't also specify a binding policy
 220          */
 221 // Restoring pre ef86707fbe3392c8ed15f79cc4892f0313b409af behavior.
 222 // Formerly -cpu-set #,#,# along with -use_hwthread-cpus resulted
 223 // in the binding policy staying OPAL_BIND_TO_HWTHREAD
 224 // I think that should be right because I thought -cpu-set was a contraint you put
 225 // on another binding policy, not a binding policy in itself.
 226         if (!OPAL_BINDING_POLICY_IS_SET(opal_hwloc_binding_policy)) {
 227             OPAL_SET_BINDING_POLICY(opal_hwloc_binding_policy, OPAL_BIND_TO_CPUSET);
 228         }
 229     }
 230 
 231     /* if we are binding to hwthreads, then we must use hwthreads as cpus */
 232     if (OPAL_GET_BINDING_POLICY(opal_hwloc_binding_policy) == OPAL_BIND_TO_HWTHREAD) {
 233         opal_hwloc_use_hwthreads_as_cpus = true;
 234     }
 235 
 236     /* to support tools such as ompi_info, add the components
 237      * to a list
 238      */
 239     if (OPAL_SUCCESS !=
 240         mca_base_framework_components_open(&opal_hwloc_base_framework, flags)) {
 241         return OPAL_ERROR;
 242     }
 243 
 244     /* declare the hwloc data types */
 245     tmp = OPAL_HWLOC_TOPO;
 246     if (OPAL_SUCCESS != (rc = opal_dss.register_type(opal_hwloc_pack,
 247                                                      opal_hwloc_unpack,
 248                                                      (opal_dss_copy_fn_t)opal_hwloc_copy,
 249                                                      (opal_dss_compare_fn_t)opal_hwloc_compare,
 250                                                      (opal_dss_print_fn_t)opal_hwloc_print,
 251                                                      OPAL_DSS_STRUCTURED,
 252                                                      "OPAL_HWLOC_TOPO", &tmp))) {
 253         return rc;
 254     }
 255 
 256     return OPAL_SUCCESS;
 257 }
 258 
 259 static int opal_hwloc_base_close(void)
 260 {
 261     int ret;
 262     if (!opal_hwloc_base_inited) {
 263         return OPAL_SUCCESS;
 264     }
 265 
 266     /* no need to close the component as it was statically opened */
 267 
 268     /* for support of tools such as ompi_info */
 269     ret = mca_base_framework_components_close (&opal_hwloc_base_framework, NULL);
 270     if (OPAL_SUCCESS != ret) {
 271         return ret;
 272     }
 273 
 274     /* free memory */
 275     if (NULL != opal_hwloc_my_cpuset) {
 276         hwloc_bitmap_free(opal_hwloc_my_cpuset);
 277         opal_hwloc_my_cpuset = NULL;
 278     }
 279 
 280     /* destroy the topology */
 281     if (NULL != opal_hwloc_topology) {
 282         opal_hwloc_base_free_topology(opal_hwloc_topology);
 283         opal_hwloc_topology = NULL;
 284     }
 285 
 286 
 287     /* All done */
 288     opal_hwloc_base_inited = false;
 289     return OPAL_SUCCESS;
 290 }
 291 
 292 static bool fns_init=false;
 293 static opal_tsd_key_t print_tsd_key;
 294 char* opal_hwloc_print_null = "NULL";
 295 
 296 static void buffer_cleanup(void *value)
 297 {
 298     int i;
 299     opal_hwloc_print_buffers_t *ptr;
 300 
 301     if (NULL != value) {
 302         ptr = (opal_hwloc_print_buffers_t*)value;
 303         for (i=0; i < OPAL_HWLOC_PRINT_NUM_BUFS; i++) {
 304             free(ptr->buffers[i]);
 305         }
 306         free(ptr);
 307     }
 308 }
 309 
 310 opal_hwloc_print_buffers_t *opal_hwloc_get_print_buffer(void)
 311 {
 312     opal_hwloc_print_buffers_t *ptr;
 313     int ret, i;
 314 
 315     if (!fns_init) {
 316         /* setup the print_args function */
 317         if (OPAL_SUCCESS != (ret = opal_tsd_key_create(&print_tsd_key, buffer_cleanup))) {
 318             return NULL;
 319         }
 320         fns_init = true;
 321     }
 322 
 323     ret = opal_tsd_getspecific(print_tsd_key, (void**)&ptr);
 324     if (OPAL_SUCCESS != ret) return NULL;
 325 
 326     if (NULL == ptr) {
 327         ptr = (opal_hwloc_print_buffers_t*)malloc(sizeof(opal_hwloc_print_buffers_t));
 328         for (i=0; i < OPAL_HWLOC_PRINT_NUM_BUFS; i++) {
 329             ptr->buffers[i] = (char *) malloc((OPAL_HWLOC_PRINT_MAX_SIZE+1) * sizeof(char));
 330         }
 331         ptr->cntr = 0;
 332         ret = opal_tsd_setspecific(print_tsd_key, (void*)ptr);
 333     }
 334 
 335     return (opal_hwloc_print_buffers_t*) ptr;
 336 }
 337 
 338 char* opal_hwloc_base_print_locality(opal_hwloc_locality_t locality)
 339 {
 340     opal_hwloc_print_buffers_t *ptr;
 341     int idx;
 342 
 343     ptr = opal_hwloc_get_print_buffer();
 344     if (NULL == ptr) {
 345         return opal_hwloc_print_null;
 346     }
 347     /* cycle around the ring */
 348     if (OPAL_HWLOC_PRINT_NUM_BUFS == ptr->cntr) {
 349         ptr->cntr = 0;
 350     }
 351 
 352     idx = 0;
 353 
 354     if (OPAL_PROC_ON_LOCAL_CLUSTER(locality)) {
 355         ptr->buffers[ptr->cntr][idx++] = 'C';
 356         ptr->buffers[ptr->cntr][idx++] = 'L';
 357         ptr->buffers[ptr->cntr][idx++] = ':';
 358     }
 359     if (OPAL_PROC_ON_LOCAL_CU(locality)) {
 360         ptr->buffers[ptr->cntr][idx++] = 'C';
 361         ptr->buffers[ptr->cntr][idx++] = 'U';
 362         ptr->buffers[ptr->cntr][idx++] = ':';
 363     }
 364     if (OPAL_PROC_ON_LOCAL_NODE(locality)) {
 365         ptr->buffers[ptr->cntr][idx++] = 'N';
 366         ptr->buffers[ptr->cntr][idx++] = ':';
 367     }
 368     if (OPAL_PROC_ON_LOCAL_BOARD(locality)) {
 369         ptr->buffers[ptr->cntr][idx++] = 'B';
 370         ptr->buffers[ptr->cntr][idx++] = ':';
 371     }
 372     if (OPAL_PROC_ON_LOCAL_NUMA(locality)) {
 373         ptr->buffers[ptr->cntr][idx++] = 'N';
 374         ptr->buffers[ptr->cntr][idx++] = 'u';
 375         ptr->buffers[ptr->cntr][idx++] = ':';
 376     }
 377     if (OPAL_PROC_ON_LOCAL_SOCKET(locality)) {
 378         ptr->buffers[ptr->cntr][idx++] = 'S';
 379         ptr->buffers[ptr->cntr][idx++] = ':';
 380     }
 381     if (OPAL_PROC_ON_LOCAL_L3CACHE(locality)) {
 382         ptr->buffers[ptr->cntr][idx++] = 'L';
 383         ptr->buffers[ptr->cntr][idx++] = '3';
 384         ptr->buffers[ptr->cntr][idx++] = ':';
 385     }
 386     if (OPAL_PROC_ON_LOCAL_L2CACHE(locality)) {
 387         ptr->buffers[ptr->cntr][idx++] = 'L';
 388         ptr->buffers[ptr->cntr][idx++] = '2';
 389         ptr->buffers[ptr->cntr][idx++] = ':';
 390     }
 391     if (OPAL_PROC_ON_LOCAL_L1CACHE(locality)) {
 392         ptr->buffers[ptr->cntr][idx++] = 'L';
 393         ptr->buffers[ptr->cntr][idx++] = '1';
 394         ptr->buffers[ptr->cntr][idx++] = ':';
 395     }
 396     if (OPAL_PROC_ON_LOCAL_CORE(locality)) {
 397         ptr->buffers[ptr->cntr][idx++] = 'C';
 398         ptr->buffers[ptr->cntr][idx++] = ':';
 399     }
 400     if (OPAL_PROC_ON_LOCAL_HWTHREAD(locality)) {
 401         ptr->buffers[ptr->cntr][idx++] = 'H';
 402         ptr->buffers[ptr->cntr][idx++] = 'w';
 403         ptr->buffers[ptr->cntr][idx++] = 't';
 404         ptr->buffers[ptr->cntr][idx++] = ':';
 405     }
 406     if (0 < idx) {
 407         ptr->buffers[ptr->cntr][idx-1] = '\0';
 408     } else if (OPAL_PROC_NON_LOCAL & locality) {
 409         ptr->buffers[ptr->cntr][idx++] = 'N';
 410         ptr->buffers[ptr->cntr][idx++] = 'O';
 411         ptr->buffers[ptr->cntr][idx++] = 'N';
 412         ptr->buffers[ptr->cntr][idx++] = '\0';
 413     } else {
 414         /* must be an unknown locality */
 415         ptr->buffers[ptr->cntr][idx++] = 'U';
 416         ptr->buffers[ptr->cntr][idx++] = 'N';
 417         ptr->buffers[ptr->cntr][idx++] = 'K';
 418         ptr->buffers[ptr->cntr][idx++] = '\0';
 419     }
 420 
 421     return ptr->buffers[ptr->cntr];
 422 }
 423 
 424 static void obj_data_const(opal_hwloc_obj_data_t *ptr)
 425 {
 426     ptr->npus_calculated = false;
 427     ptr->npus = 0;
 428     ptr->idx = UINT_MAX;
 429     ptr->num_bound = 0;
 430 }
 431 OBJ_CLASS_INSTANCE(opal_hwloc_obj_data_t,
 432                    opal_object_t,
 433                    obj_data_const, NULL);
 434 
 435 static void sum_const(opal_hwloc_summary_t *ptr)
 436 {
 437     ptr->num_objs = 0;
 438     ptr->rtype = 0;
 439     OBJ_CONSTRUCT(&ptr->sorted_by_dist_list, opal_list_t);
 440 }
 441 static void sum_dest(opal_hwloc_summary_t *ptr)
 442 {
 443     opal_list_item_t *item;
 444     while (NULL != (item = opal_list_remove_first(&ptr->sorted_by_dist_list))) {
 445         OBJ_RELEASE(item);
 446     }
 447     OBJ_DESTRUCT(&ptr->sorted_by_dist_list);
 448 }
 449 OBJ_CLASS_INSTANCE(opal_hwloc_summary_t,
 450                    opal_list_item_t,
 451                    sum_const, sum_dest);
 452 static void topo_data_const(opal_hwloc_topo_data_t *ptr)
 453 {
 454     ptr->available = NULL;
 455     OBJ_CONSTRUCT(&ptr->summaries, opal_list_t);
 456     ptr->userdata = NULL;
 457 }
 458 static void topo_data_dest(opal_hwloc_topo_data_t *ptr)
 459 {
 460     opal_list_item_t *item;
 461 
 462     if (NULL != ptr->available) {
 463         hwloc_bitmap_free(ptr->available);
 464     }
 465     while (NULL != (item = opal_list_remove_first(&ptr->summaries))) {
 466         OBJ_RELEASE(item);
 467     }
 468     OBJ_DESTRUCT(&ptr->summaries);
 469     ptr->userdata = NULL;
 470 }
 471 OBJ_CLASS_INSTANCE(opal_hwloc_topo_data_t,
 472                    opal_object_t,
 473                    topo_data_const,
 474                    topo_data_dest);
 475 
 476 OBJ_CLASS_INSTANCE(opal_rmaps_numa_node_t,
 477         opal_list_item_t,
 478         NULL,
 479         NULL);
 480 
 481 int opal_hwloc_base_set_binding_policy(opal_binding_policy_t *policy, char *spec)
 482 {
 483     int i;
 484     opal_binding_policy_t tmp;
 485     char **tmpvals, **quals;
 486 
 487     /* set default */
 488     tmp = 0;
 489 
 490     /* binding specification */
 491     if (NULL == spec) {
 492         if (opal_hwloc_use_hwthreads_as_cpus) {
 493             /* default to bind-to hwthread */
 494             OPAL_SET_DEFAULT_BINDING_POLICY(tmp, OPAL_BIND_TO_HWTHREAD);
 495         } else {
 496             /* default to bind-to core */
 497             OPAL_SET_DEFAULT_BINDING_POLICY(tmp, OPAL_BIND_TO_CORE);
 498         }
 499     } else if (0 == strncasecmp(spec, "none", strlen("none"))) {
 500         OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_NONE);
 501     } else {
 502         tmpvals = opal_argv_split(spec, ':');
 503         if (1 < opal_argv_count(tmpvals) || ':' == spec[0]) {
 504             if (':' == spec[0]) {
 505                 quals = opal_argv_split(&spec[1], ',');
 506             } else {
 507                 quals = opal_argv_split(tmpvals[1], ',');
 508             }
 509             for (i=0; NULL != quals[i]; i++) {
 510                 if (0 == strncasecmp(quals[i], "if-supported", strlen(quals[i]))) {
 511                     tmp |= OPAL_BIND_IF_SUPPORTED;
 512                 } else if (0 == strncasecmp(quals[i], "overload-allowed", strlen(quals[i])) ||
 513                            0 == strncasecmp(quals[i], "oversubscribe-allowed", strlen(quals[i]))) {
 514                     tmp |= OPAL_BIND_ALLOW_OVERLOAD;
 515                 } else if (0 == strncasecmp(quals[i], "ordered", strlen(quals[i]))) {
 516                     tmp |= OPAL_BIND_ORDERED;
 517                 } else {
 518                     /* unknown option */
 519                     opal_output(0, "Unknown qualifier to binding policy: %s", spec);
 520                     opal_argv_free(quals);
 521                     opal_argv_free(tmpvals);
 522                     return OPAL_ERR_BAD_PARAM;
 523                 }
 524             }
 525             opal_argv_free(quals);
 526         }
 527         if (NULL == tmpvals[0] || ':' == spec[0]) {
 528             OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_CORE);
 529             tmp &= ~OPAL_BIND_GIVEN;
 530         } else {
 531             if (0 == strcasecmp(tmpvals[0], "hwthread")) {
 532                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_HWTHREAD);
 533             } else if (0 == strcasecmp(tmpvals[0], "core")) {
 534                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_CORE);
 535             } else if (0 == strcasecmp(tmpvals[0], "l1cache")) {
 536                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_L1CACHE);
 537             } else if (0 == strcasecmp(tmpvals[0], "l2cache")) {
 538                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_L2CACHE);
 539             } else if (0 == strcasecmp(tmpvals[0], "l3cache")) {
 540                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_L3CACHE);
 541             } else if (0 == strcasecmp(tmpvals[0], "socket")) {
 542                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_SOCKET);
 543             } else if (0 == strcasecmp(tmpvals[0], "numa")) {
 544                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_NUMA);
 545             } else if (0 == strcasecmp(tmpvals[0], "board")) {
 546                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_BOARD);
 547             } else if (0 == strcasecmp(tmpvals[0], "cpu-list") ||
 548                        0 == strcasecmp(tmpvals[0], "cpulist")) {
 549                 // Accept both "cpu-list" (which matches the
 550                 // "--cpu-list" CLI option) and "cpulist" (because
 551                 // people will be lazy)
 552                 OPAL_SET_BINDING_POLICY(tmp, OPAL_BIND_TO_CPUSET);
 553             } else {
 554                 opal_show_help("help-opal-hwloc-base.txt", "invalid binding_policy", true, "binding", spec);
 555                 opal_argv_free(tmpvals);
 556                 return OPAL_ERR_BAD_PARAM;
 557             }
 558         }
 559         opal_argv_free(tmpvals);
 560     }
 561 
 562     *policy = tmp;
 563     return OPAL_SUCCESS;
 564 }

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