/******************* FUNCTION *********************/ int TopoHwloc::getCurrentId ( int level, int depth ) const { //vars int res = -1; //get absolute depth int absDepth = getAbsDepth(level,depth); //search current thread binding hwloc_cpuset_t cpuset = hwloc_bitmap_alloc(); int status = hwloc_get_cpubind (topology, cpuset, 0); allocAssume(status >= 0,"Failed to get the current thread CPU binding with hwloc."); //count overlap over current level int cnt = hwloc_get_nbobjs_inside_cpuset_by_depth(topology,cpuset,absDepth); //if get only one return its ID if (cnt == 1) { hwloc_obj_t obj = hwloc_get_obj_inside_cpuset_by_depth(topology,cpuset,absDepth,0); //TODO maybe their is an accessor for this res = obj->logical_index; } //clean memory hwloc_bitmap_free(cpuset); return res; }
int get_max_objs_inside_cpuset_by_type(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_obj_type_t type){ int depth = hwloc_get_type_depth(topology, type); if(depth == HWLOC_TYPE_DEPTH_UNKNOWN){ fprintf(stderr, "Cannot find depth %s\n", hwloc_type_name(type)); return -1; } if(depth == HWLOC_TYPE_DEPTH_MULTIPLE){ hwloc_obj_t deepest_of_type = hwloc_get_obj_inside_cpuset_by_type(topology, cpuset, HWLOC_OBJ_PU,0); while(deepest_of_type !=NULL && deepest_of_type->type != type) deepest_of_type = deepest_of_type->parent; if(deepest_of_type == NULL) return -1; else depth = deepest_of_type->depth; } return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, cpuset, depth); }
int hmonitor_eventset_add_named_event(void * monitor_eventset, const char * event) { struct accumulate_eventset * set = (struct accumulate_eventset *) monitor_eventset; harray child_events = NULL; hwloc_obj_t obj; unsigned depth,index,i, n_events = 0; hmon m; if(event==NULL || monitor_eventset == NULL) return -1; /* Decend depth by depth to look if event exists */ int topo_depth = hwloc_topology_get_depth(hmon_topology); for(depth=set->location->depth; depth<topo_depth; depth++){ /* Traverse depth to find matching event */ for(index=0; index<hwloc_get_nbobjs_inside_cpuset_by_depth(hmon_topology, set->location->cpuset, depth); index++){ obj = hwloc_get_obj_inside_cpuset_by_depth(hmon_topology, set->location->cpuset, depth, index); child_events = obj->userdata; if(child_events != NULL){ /* Walk monitor list at this location to find matching event */ for(i=0; i<harray_length(child_events); i++){ m = harray_get(child_events,i); if(!strcmp(m->id, event)){ harray_push(set->child_events, m); n_events=m->n_samples; } } } } } if(n_events == 0){ /* Exit failure */ fprintf(stderr, "Unrecognized event name %s, expected defined monitor name, deeper than %s.\n", event, hwloc_type_name(set->location->type)); return -1; } return n_events; }
void chpl_topo_init(void) { // // We only load hwloc topology information in configurations where // the locale model is other than "flat" or the tasking is based on // Qthreads (which will use the topology we load). We don't use // it otherwise (so far) because loading it is somewhat expensive. // if (strcmp(CHPL_LOCALE_MODEL, "flat") != 0 || strcmp(CHPL_TASKS, "qthreads") == 0) { haveTopology = true; } else { haveTopology = false; return; } // Check hwloc API version. // Require at least hwloc version 1.11 (we need 1.11.5 to not crash // in some NUMA configurations). // Check both at build time and run time. #define REQUIRE_HWLOC_VERSION 0x00010b00 #if HWLOC_API_VERSION < REQUIRE_HWLOC_VERSION #error hwloc version 1.11.5 or newer is required #endif CHK_ERR(hwloc_get_api_version() >= REQUIRE_HWLOC_VERSION); // // Allocate and initialize topology object. // CHK_ERR_ERRNO(hwloc_topology_init(&topology) == 0); // // Perform the topology detection. // CHK_ERR_ERRNO(hwloc_topology_load(topology) == 0); // // What is supported? // topoSupport = hwloc_topology_get_support(topology); // // TODO: update comment // For now, don't support setting memory locality when comm=ugni or // comm=gasnet, seg!=everything. Those are the two configurations in // which we use hugepages and/or memory registered with the comm // interface, both of which may be a problem for the set-membind call. // We will have other ways to achieve locality for these configs in // the future. // do_set_area_membind = true; if ((strcmp(CHPL_COMM, "gasnet") == 0 && strcmp(CHPL_GASNET_SEGMENT, "everything") != 0)) { do_set_area_membind = false; } // // We need depth information. // topoDepth = hwloc_topology_get_depth(topology); // // How many NUMA domains do we have? // { int level; // // Note: If there are multiple levels with NUMA nodes, this finds // only the uppermost. // for (level = 0, numaLevel = -1; level < topoDepth && numaLevel == -1; level++) { if (hwloc_get_depth_type(topology, level) == HWLOC_OBJ_NUMANODE) { numaLevel = level; } } } // // Find the NUMA nodes, that is, the objects at numaLevel that also // have CPUs. This is as opposed to things like Xeon Phi HBM, which // is memory-only, no CPUs. // { const hwloc_cpuset_t cpusetAll = hwloc_get_root_obj(topology)->cpuset; numNumaDomains = hwloc_get_nbobjs_inside_cpuset_by_depth(topology, cpusetAll, numaLevel); } }
void chpl_topo_init(void) { // // For now we don't load topology information for locModel=flat, since // we won't use it in that case and loading it is somewhat expensive. // Eventually we will probably load it even for locModel=flat and use // it as the information source for what's currently in chplsys, and // also pass it to Qthreads when we use that (so it doesn't load it // again), but that's work for the future. // haveTopology = (strcmp(CHPL_LOCALE_MODEL, "flat") != 0) ? true : false; if (!haveTopology) { return; } // Check hwloc API version. // Require at least hwloc version 1.11 (we need 1.11.5 to not crash // in some NUMA configurations). // Check both at build time and run time. #define REQUIRE_HWLOC_VERSION 0x00010b00 #if HWLOC_API_VERSION < REQUIRE_HWLOC_VERSION #error hwloc version 1.11.5 or newer is required #else { unsigned version = hwloc_get_api_version(); // check that the version is at least REQUIRE_HWLOC_VERSION if (version < REQUIRE_HWLOC_VERSION) chpl_internal_error("hwloc version 1.11.5 or newer is required"); } #endif // // Allocate and initialize topology object. // if (hwloc_topology_init(&topology)) { report_error("hwloc_topology_init()", errno); } // // Perform the topology detection. // if (hwloc_topology_load(topology)) { report_error("hwloc_topology_load()", errno); } // // What is supported? // topoSupport = hwloc_topology_get_support(topology); // // TODO: update comment // For now, don't support setting memory locality when comm=ugni or // comm=gasnet, seg!=everything. Those are the two configurations in // which we use hugepages and/or memory registered with the comm // interface, both of which may be a problem for the set-membind call. // We will have other ways to achieve locality for these configs in // the future. // do_set_area_membind = true; if ((strcmp(CHPL_COMM, "gasnet") == 0 && strcmp(CHPL_GASNET_SEGMENT, "everything") != 0)) { do_set_area_membind = false; } // // We need depth information. // topoDepth = hwloc_topology_get_depth(topology); // // How many NUMA domains do we have? // { int level; // // Note: If there are multiple levels with NUMA nodes, this finds // only the uppermost. // for (level = 0, numaLevel = -1; level < topoDepth && numaLevel == -1; level++) { if (hwloc_get_depth_type(topology, level) == HWLOC_OBJ_NUMANODE) { numaLevel = level; } } } // // Find the NUMA nodes, that is, the objects at numaLevel that also // have CPUs. This is as opposed to things like Xeon Phi HBM, which // is memory-only, no CPUs. // { const hwloc_cpuset_t cpusetAll = hwloc_get_root_obj(topology)->cpuset; numNumaDomains = hwloc_get_nbobjs_inside_cpuset_by_depth(topology, cpusetAll, numaLevel); } }