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

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

DEFINITIONS

This source file includes following definitions.
  1. opal_hwloc_pack
  2. opal_hwloc_unpack
  3. opal_hwloc_copy
  4. opal_hwloc_compare
  5. print_hwloc_obj
  6. opal_hwloc_print

   1 /*
   2  * Copyright (c) 2011-2012 Cisco Systems, Inc.  All rights reserved.
   3  * Copyright (c) 2017      Research Organization for Information Science
   4  *                         and Technology (RIST). All rights reserved.
   5  *
   6  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
   7  * $COPYRIGHT$
   8  *
   9  * Additional copyrights may follow
  10  */
  11 
  12 #include "opal_config.h"
  13 #include "opal/constants.h"
  14 
  15 #include "opal/util/output.h"
  16 #include "opal/util/printf.h"
  17 
  18 #include "opal/dss/dss.h"
  19 #include "opal/mca/hwloc/base/base.h"
  20 
  21 int opal_hwloc_pack(opal_buffer_t *buffer, const void *src,
  22                     int32_t num_vals,
  23                     opal_data_type_t type)
  24 {
  25     /* NOTE: hwloc defines topology_t as a pointer to a struct! */
  26     hwloc_topology_t t, *tarray  = (hwloc_topology_t*)src;
  27     int rc, i;
  28     char *xmlbuffer=NULL;
  29     int len;
  30     struct hwloc_topology_support *support;
  31 
  32     for (i=0; i < num_vals; i++) {
  33         t = tarray[i];
  34 
  35         /* extract an xml-buffer representation of the tree */
  36         if (0 != opal_hwloc_base_topology_export_xmlbuffer(t, &xmlbuffer, &len)) {
  37             return OPAL_ERROR;
  38         }
  39 
  40         /* add to buffer */
  41         if (OPAL_SUCCESS != (rc = opal_dss.pack(buffer, &xmlbuffer, 1, OPAL_STRING))) {
  42             free(xmlbuffer);
  43             return rc;
  44         }
  45 
  46         /* cleanup */
  47         if (NULL != xmlbuffer) {
  48             free(xmlbuffer);
  49         }
  50 
  51         /* get the available support - hwloc unfortunately does
  52          * not include this info in its xml export!
  53          */
  54         support = (struct hwloc_topology_support*)hwloc_topology_get_support(t);
  55         /* pack the discovery support */
  56         if (OPAL_SUCCESS != (rc = opal_dss.pack(buffer, support->discovery,
  57                                                 sizeof(struct hwloc_topology_discovery_support),
  58                                                 OPAL_BYTE))) {
  59             return rc;
  60         }
  61         /* pack the cpubind support */
  62         if (OPAL_SUCCESS != (rc = opal_dss.pack(buffer, support->cpubind,
  63                                                 sizeof(struct hwloc_topology_cpubind_support),
  64                                                 OPAL_BYTE))) {
  65             return rc;
  66         }
  67         /* pack the membind support */
  68         if (OPAL_SUCCESS != (rc = opal_dss.pack(buffer, support->membind,
  69                                                 sizeof(struct hwloc_topology_membind_support),
  70                                                 OPAL_BYTE))) {
  71             return rc;
  72         }
  73     }
  74 
  75     return OPAL_SUCCESS;
  76 }
  77 
  78 int opal_hwloc_unpack(opal_buffer_t *buffer, void *dest,
  79                       int32_t *num_vals,
  80                       opal_data_type_t type)
  81 {
  82     /* NOTE: hwloc defines topology_t as a pointer to a struct! */
  83     hwloc_topology_t t, *tarray  = (hwloc_topology_t*)dest;
  84     int rc=OPAL_SUCCESS, i, cnt, j;
  85     char *xmlbuffer;
  86     struct hwloc_topology_support *support;
  87 
  88     for (i=0, j=0; i < *num_vals; i++) {
  89         /* unpack the xml string */
  90         cnt=1;
  91         if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, &xmlbuffer, &cnt, OPAL_STRING))) {
  92             goto cleanup;
  93         }
  94 
  95         /* convert the xml */
  96         if (0 != hwloc_topology_init(&t)) {
  97             rc = OPAL_ERROR;
  98             free(xmlbuffer);
  99             goto cleanup;
 100         }
 101         if (0 != hwloc_topology_set_xmlbuffer(t, xmlbuffer, strlen(xmlbuffer)+1)) {
 102             rc = OPAL_ERROR;
 103             free(xmlbuffer);
 104             hwloc_topology_destroy(t);
 105             goto cleanup;
 106         }
 107         free(xmlbuffer);
 108         /* since we are loading this from an external source, we have to
 109          * explicitly set a flag so hwloc sets things up correctly
 110          */
 111         if (0 != opal_hwloc_base_topology_set_flags(t, HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM, true)) {
 112             rc = OPAL_ERROR;
 113             hwloc_topology_destroy(t);
 114             goto cleanup;
 115         }
 116         /* now load the topology */
 117         if (0 != hwloc_topology_load(t)) {
 118             rc = OPAL_ERROR;
 119             hwloc_topology_destroy(t);
 120             goto cleanup;
 121         }
 122 
 123         /* get the available support - hwloc unfortunately does
 124          * not include this info in its xml import!
 125          */
 126         support = (struct hwloc_topology_support*)hwloc_topology_get_support(t);
 127         cnt = sizeof(struct hwloc_topology_discovery_support);
 128         if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, support->discovery, &cnt, OPAL_BYTE))) {
 129             goto cleanup;
 130         }
 131         cnt = sizeof(struct hwloc_topology_cpubind_support);
 132         if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, support->cpubind, &cnt, OPAL_BYTE))) {
 133             goto cleanup;
 134         }
 135         cnt = sizeof(struct hwloc_topology_membind_support);
 136         if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, support->membind, &cnt, OPAL_BYTE))) {
 137             goto cleanup;
 138         }
 139 
 140         /* pass it back */
 141         tarray[i] = t;
 142 
 143         /* track the number added */
 144         j++;
 145     }
 146 
 147  cleanup:
 148     *num_vals = j;
 149     return rc;
 150 }
 151 
 152 int opal_hwloc_copy(hwloc_topology_t *dest, hwloc_topology_t src, opal_data_type_t type)
 153 {
 154 #ifdef HAVE_HWLOC_TOPOLOGY_DUP
 155     /* use the hwloc dup function */
 156     return hwloc_topology_dup(dest, src);
 157 #else
 158     /* hwloc_topology_dup() was introduced in hwloc v1.8.0.
 159      * Note that as of March 2017, opal_hwloc_copy() is not (yet?) used in the code base anywhere. */
 160     return OPAL_ERR_NOT_SUPPORTED;
 161 #endif
 162 }
 163 
 164 int opal_hwloc_compare(const hwloc_topology_t topo1,
 165                        const hwloc_topology_t topo2,
 166                        opal_data_type_t type)
 167 {
 168     hwloc_topology_t t1, t2;
 169     unsigned d1, d2;
 170     struct hwloc_topology_support *s1, *s2;
 171     char *x1=NULL, *x2=NULL;
 172     int l1, l2;
 173     int s;
 174 
 175     /* stop stupid compiler warnings */
 176     t1 = (hwloc_topology_t)topo1;
 177     t2 = (hwloc_topology_t)topo2;
 178 
 179     /* do something quick first */
 180     d1 = hwloc_topology_get_depth(t1);
 181     d2 = hwloc_topology_get_depth(t2);
 182     if (d1 > d2) {
 183         return OPAL_VALUE1_GREATER;
 184     } else if (d2 > d1) {
 185         return OPAL_VALUE2_GREATER;
 186     }
 187 
 188 
 189     /* do the comparison the "cheat" way - get an xml representation
 190      * of each tree, and strcmp! This will work fine for inventory
 191      * comparisons, but might not meet the need for comparing topology
 192      * where we really need to do a tree-wise search so we only compare
 193      * the things we care about, and ignore stuff like MAC addresses
 194      */
 195     if (0 != opal_hwloc_base_topology_export_xmlbuffer(t1, &x1, &l1)) {
 196         return OPAL_EQUAL;
 197     }
 198     if (0 != opal_hwloc_base_topology_export_xmlbuffer(t2, &x2, &l2)) {
 199         free(x1);
 200         return OPAL_EQUAL;
 201     }
 202 
 203     s = strcmp(x1, x2);
 204     free(x1);
 205     free(x2);
 206     if (s > 0) {
 207         return OPAL_VALUE1_GREATER;
 208     } else if (s < 0) {
 209         return OPAL_VALUE2_GREATER;
 210     }
 211 
 212     /* compare the available support - hwloc unfortunately does
 213      * not include this info in its xml support!
 214      */
 215     if (NULL == (s1 = (struct hwloc_topology_support*)hwloc_topology_get_support(t1)) ||
 216         NULL == s1->cpubind || NULL == s1->membind) {
 217         return OPAL_EQUAL;
 218     }
 219     if (NULL == (s2 = (struct hwloc_topology_support*)hwloc_topology_get_support(t2)) ||
 220         NULL == s2->cpubind || NULL == s2->membind) {
 221         return OPAL_EQUAL;
 222     }
 223     /* compare the fields we care about */
 224     if (s1->cpubind->set_thisproc_cpubind != s2->cpubind->set_thisproc_cpubind ||
 225         s1->cpubind->set_thisthread_cpubind != s2->cpubind->set_thisthread_cpubind ||
 226         s1->membind->set_thisproc_membind != s2->membind->set_thisproc_membind ||
 227         s1->membind->set_thisthread_membind != s2->membind->set_thisthread_membind) {
 228         OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
 229                              "hwloc:base:compare BINDING CAPABILITIES DIFFER"));
 230         return OPAL_VALUE1_GREATER;
 231     }
 232 
 233     return OPAL_EQUAL;
 234 }
 235 
 236 #define OPAL_HWLOC_MAX_STRING   2048
 237 
 238 static void print_hwloc_obj(char **output, char *prefix,
 239                             hwloc_topology_t topo, hwloc_obj_t obj)
 240 {
 241     hwloc_obj_t obj2;
 242     char string[1024], *tmp, *tmp2, *pfx;
 243     unsigned i;
 244     struct hwloc_topology_support *support;
 245 
 246     /* print the object type */
 247     hwloc_obj_type_snprintf(string, 1024, obj, 1);
 248     opal_asprintf(&pfx, "\n%s\t", (NULL == prefix) ? "" : prefix);
 249     opal_asprintf(&tmp, "%sType: %s Number of child objects: %u%sName=%s",
 250              (NULL == prefix) ? "" : prefix, string, obj->arity,
 251              pfx, (NULL == obj->name) ? "NULL" : obj->name);
 252     if (0 < hwloc_obj_attr_snprintf(string, 1024, obj, pfx, 1)) {
 253         /* print the attributes */
 254         opal_asprintf(&tmp2, "%s%s%s", tmp, pfx, string);
 255         free(tmp);
 256         tmp = tmp2;
 257     }
 258     /* print the cpusets - apparently, some new HWLOC types don't
 259      * have cpusets, so protect ourselves here
 260      */
 261     if (NULL != obj->cpuset) {
 262         hwloc_bitmap_snprintf(string, OPAL_HWLOC_MAX_STRING, obj->cpuset);
 263         opal_asprintf(&tmp2, "%s%sCpuset:  %s", tmp, pfx, string);
 264         free(tmp);
 265         tmp = tmp2;
 266     }
 267     if (HWLOC_OBJ_MACHINE == obj->type) {
 268         /* root level object - add support values */
 269         support = (struct hwloc_topology_support*)hwloc_topology_get_support(topo);
 270         opal_asprintf(&tmp2, "%s%sBind CPU proc:   %s%sBind CPU thread: %s", tmp, pfx,
 271                  (support->cpubind->set_thisproc_cpubind) ? "TRUE" : "FALSE", pfx,
 272                  (support->cpubind->set_thisthread_cpubind) ? "TRUE" : "FALSE");
 273         free(tmp);
 274         tmp = tmp2;
 275         opal_asprintf(&tmp2, "%s%sBind MEM proc:   %s%sBind MEM thread: %s", tmp, pfx,
 276                  (support->membind->set_thisproc_membind) ? "TRUE" : "FALSE", pfx,
 277                  (support->membind->set_thisthread_membind) ? "TRUE" : "FALSE");
 278         free(tmp);
 279         tmp = tmp2;
 280     }
 281     opal_asprintf(&tmp2, "%s%s\n", (NULL == *output) ? "" : *output, tmp);
 282     free(tmp);
 283     free(pfx);
 284     opal_asprintf(&pfx, "%s\t", (NULL == prefix) ? "" : prefix);
 285     for (i=0; i < obj->arity; i++) {
 286         obj2 = obj->children[i];
 287         /* print the object */
 288         print_hwloc_obj(&tmp2, pfx, topo, obj2);
 289     }
 290     free(pfx);
 291     if (NULL != *output) {
 292         free(*output);
 293     }
 294     *output = tmp2;
 295 }
 296 
 297 int opal_hwloc_print(char **output, char *prefix, hwloc_topology_t src, opal_data_type_t type)
 298 {
 299     hwloc_obj_t obj;
 300     char *tmp=NULL;
 301 
 302     /* get root object */
 303     obj = hwloc_get_root_obj(src);
 304     /* print it */
 305     print_hwloc_obj(&tmp, prefix, src, obj);
 306     *output = tmp;
 307     return OPAL_SUCCESS;
 308 }
 309 

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