static void testmem(hwloc_const_bitmap_t nodeset, hwloc_membind_policy_t policy, int flags, int expected) { hwloc_bitmap_t new_nodeset = hwloc_bitmap_alloc(); hwloc_membind_policy_t newpolicy; void *area; size_t area_size = 1024; result_set("Bind this singlethreaded process memory", hwloc_set_membind(topology, nodeset, policy, flags), (support->membind->set_thisproc_membind || support->membind->set_thisthread_membind) && expected); result_get("Get this singlethreaded process memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags), (support->membind->get_thisproc_membind || support->membind->get_thisthread_membind) && expected); result_set("Bind this thread memory", hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_THREAD), support->membind->set_thisproc_membind && expected); result_get("Get this thread memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags | HWLOC_MEMBIND_THREAD), support->membind->get_thisproc_membind && expected); result_set("Bind this whole process memory", hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_PROCESS), support->membind->set_thisproc_membind && expected); result_get("Get this whole process memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags | HWLOC_MEMBIND_PROCESS), support->membind->get_thisproc_membind && expected); #ifdef HWLOC_WIN_SYS result_set("Bind process memory", hwloc_set_proc_membind(topology, GetCurrentProcess(), nodeset, policy, flags), support->membind->set_proc_membind && expected); result_get("Get process memory", nodeset, new_nodeset, hwloc_get_proc_membind(topology, GetCurrentProcess(), new_nodeset, &newpolicy, flags), support->membind->get_proc_membind && expected); #else /* !HWLOC_WIN_SYS */ result_set("Bind process memory", hwloc_set_proc_membind(topology, getpid(), nodeset, policy, flags), support->membind->set_proc_membind && expected); result_get("Get process memory", nodeset, new_nodeset, hwloc_get_proc_membind(topology, getpid(), new_nodeset, &newpolicy, flags), support->membind->get_proc_membind && expected); #endif /* !HWLOC_WIN_SYS */ result_set("Bind area", hwloc_set_area_membind(topology, &new_nodeset, sizeof(new_nodeset), nodeset, policy, flags), support->membind->set_area_membind && expected); result_get("Get area", nodeset, new_nodeset, hwloc_get_area_membind(topology, &new_nodeset, sizeof(new_nodeset), new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected); if (!(flags & HWLOC_MEMBIND_MIGRATE)) { result_set("Alloc bound area", (area = hwloc_alloc_membind(topology, area_size, nodeset, policy, flags)) == NULL, (support->membind->alloc_membind && expected) || !(flags & HWLOC_MEMBIND_STRICT)); if (area) { memset(area, 0, area_size); result_get("Get bound area", nodeset, new_nodeset, hwloc_get_area_membind(topology, area, area_size, new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected); result_get("Free bound area", NULL, NULL, hwloc_free(topology, area, area_size), support->membind->alloc_membind && expected); } } printf("\n"); hwloc_bitmap_free(new_nodeset); }
int main(void) { int depth; unsigned i, n; unsigned long size; int levels; char string[128]; int topodepth; void *m; hwloc_topology_t topology; hwloc_cpuset_t cpuset; hwloc_obj_t obj; /* Allocate and initialize topology object. */ hwloc_topology_init(&topology); /* ... Optionally, put detection configuration here to ignore some objects types, define a synthetic topology, etc.... The default is to detect all the objects of the machine that the caller is allowed to access. See Configure Topology Detection. */ /* Perform the topology detection. */ hwloc_topology_load(topology); /* Optionally, get some additional topology information in case we need the topology depth later. */ topodepth = hwloc_topology_get_depth(topology); /***************************************************************** * First example: * Walk the topology with an array style, from level 0 (always * the system level) to the lowest level (always the proc level). *****************************************************************/ for (depth = 0; depth < topodepth; depth++) { printf("*** Objects at level %d\n", depth); for (i = 0; i < hwloc_get_nbobjs_by_depth(topology, depth); i++) { hwloc_obj_type_snprintf(string, sizeof(string), hwloc_get_obj_by_depth(topology, depth, i), 0); printf("Index %u: %s\n", i, string); } } /***************************************************************** * Second example: * Walk the topology with a tree style. *****************************************************************/ printf("*** Printing overall tree\n"); print_children(topology, hwloc_get_root_obj(topology), 0); /***************************************************************** * Third example: * Print the number of packages. *****************************************************************/ depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PACKAGE); if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) { printf("*** The number of packages is unknown\n"); } else { printf("*** %u package(s)\n", hwloc_get_nbobjs_by_depth(topology, depth)); } /***************************************************************** * Fourth example: * Compute the amount of cache that the first logical processor * has above it. *****************************************************************/ levels = 0; size = 0; for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0); obj; obj = obj->parent) if (obj->type == HWLOC_OBJ_CACHE) { levels++; size += obj->attr->cache.size; } printf("*** Logical processor 0 has %d caches totaling %luKB\n", levels, size / 1024); /***************************************************************** * Fifth example: * Bind to only one thread of the last core of the machine. * * First find out where cores are, or else smaller sets of CPUs if * the OS doesn't have the notion of a "core". *****************************************************************/ depth = hwloc_get_type_or_below_depth(topology, HWLOC_OBJ_CORE); /* Get last core. */ obj = hwloc_get_obj_by_depth(topology, depth, hwloc_get_nbobjs_by_depth(topology, depth) - 1); if (obj) { /* Get a copy of its cpuset that we may modify. */ cpuset = hwloc_bitmap_dup(obj->cpuset); /* Get only one logical processor (in case the core is SMT/hyper-threaded). */ hwloc_bitmap_singlify(cpuset); /* And try to bind ourself there. */ if (hwloc_set_cpubind(topology, cpuset, 0)) { char *str; int error = errno; hwloc_bitmap_asprintf(&str, obj->cpuset); printf("Couldn't bind to cpuset %s: %s\n", str, strerror(error)); free(str); } /* Free our cpuset copy */ hwloc_bitmap_free(cpuset); } /***************************************************************** * Sixth example: * Allocate some memory on the last NUMA node, bind some existing * memory to the last NUMA node. *****************************************************************/ /* Get last node. There's always at least one. */ n = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_NUMANODE); obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, n - 1); size = 1024*1024; m = hwloc_alloc_membind_nodeset(topology, size, obj->nodeset, HWLOC_MEMBIND_BIND, 0); hwloc_free(topology, m, size); m = malloc(size); hwloc_set_area_membind_nodeset(topology, m, size, obj->nodeset, HWLOC_MEMBIND_BIND, 0); free(m); /* Destroy topology object. */ hwloc_topology_destroy(topology); return 0; }
int main(void) { const struct hwloc_topology_support *support; char *buffer; hwloc_topology_t topology; hwloc_bitmap_t set = hwloc_bitmap_alloc(); hwloc_bitmap_t total = hwloc_bitmap_alloc(); hwloc_obj_t node; char *s; int err; err = hwloc_topology_init(&topology); assert(!err); err = hwloc_topology_load(topology); assert(!err); support = hwloc_topology_get_support(topology); if (!support->membind->get_area_memlocation) goto out; buffer = hwloc_alloc(topology, LEN); assert(buffer); printf("buffer %p length %u\n", buffer, LEN); err = hwloc_get_area_memlocation(topology, buffer, LEN, set, HWLOC_MEMBIND_BYNODESET); if (err < 0 && errno == ENOSYS) { fprintf(stderr, "hwloc_get_area_memlocation() failed with ENOSYS, aborting\n"); goto out_with_buffer; } assert(!err); hwloc_bitmap_asprintf(&s, set); printf("address %p length %u allocated in nodeset %s\n", buffer, LEN, s); free(s); hwloc_bitmap_copy(total, set); node = NULL; next1: node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, node); if (!node) goto out_with_buffer; if (!node->memory.local_memory) goto next1; printf("binding to 1st node and touching 1st quarter\n"); err = hwloc_set_area_membind(topology, buffer, LEN, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_BYNODESET); if (err < 0 && errno == ENOSYS) { fprintf(stderr, "hwloc_set_area_membind() failed with ENOSYS, aborting\n"); goto out_with_buffer; } assert(!err); memset(buffer, 0, LEN/4); err = hwloc_get_area_memlocation(topology, buffer, 1, set, HWLOC_MEMBIND_BYNODESET); assert(!err); hwloc_bitmap_asprintf(&s, set); printf("address %p length %u allocated in nodeset %s\n", buffer, LEN/4, s); free(s); hwloc_bitmap_or(total, total, set); next2: node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, node); if (!node) goto out_with_nomorenodes; if (!node->memory.local_memory) goto next2; printf("binding to 2nd node and touching 2nd quarter\n"); err = hwloc_set_area_membind(topology, buffer, LEN, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_BYNODESET); assert(!err); memset(buffer+LEN/4, 0, LEN/4); err = hwloc_get_area_memlocation(topology, buffer+LEN/4, LEN/4, set, HWLOC_MEMBIND_BYNODESET); assert(!err); hwloc_bitmap_asprintf(&s, set); printf("address %p length %u allocated in nodeset %s\n", buffer+LEN/4, LEN/4, s); free(s); hwloc_bitmap_or(total, total, set); next3: node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, node); if (!node) goto out_with_nomorenodes; if (!node->memory.local_memory) goto next3; printf("binding to 3rd node and touching 3rd quarter\n"); err = hwloc_set_area_membind(topology, buffer, LEN, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_BYNODESET); assert(!err); memset(buffer+LEN/2, 0, LEN/4); err = hwloc_get_area_memlocation(topology, buffer+LEN/2, LEN/4, set, HWLOC_MEMBIND_BYNODESET); assert(!err); hwloc_bitmap_asprintf(&s, set); printf("address %p length %u allocated in nodeset %s\n", buffer+LEN/2, LEN/4, s); free(s); hwloc_bitmap_or(total, total, set); next4: node = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, node); if (!node) goto out_with_nomorenodes; if (!node->memory.local_memory) goto next4; printf("binding to 4th node and touching 4th quarter\n"); err = hwloc_set_area_membind(topology, buffer, LEN, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_BYNODESET); assert(!err); memset(buffer+3*LEN/4, 0, LEN/4); err = hwloc_get_area_memlocation(topology, buffer+3*LEN/4, LEN/4, set, HWLOC_MEMBIND_BYNODESET); assert(!err); hwloc_bitmap_asprintf(&s, set); printf("address %p length %u allocated in nodeset %s\n", buffer+3*LEN/4, LEN/4, s); free(s); hwloc_bitmap_or(total, total, set); out_with_nomorenodes: err = hwloc_get_area_memlocation(topology, buffer, LEN, set, HWLOC_MEMBIND_BYNODESET); assert(!err); hwloc_bitmap_asprintf(&s, set); printf("address %p length %u located on %s\n", buffer, LEN, s); free(s); assert(hwloc_bitmap_isincluded(total, set)); out_with_buffer: hwloc_free(topology, buffer, LEN); out: hwloc_topology_destroy(topology); hwloc_bitmap_free(set); hwloc_bitmap_free(total); return 0; }