static hwloc_const_bitmap_t hwloc_fix_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set) { hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology); hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology); if (!topology_set) { /* The topology is composed of several systems, the cpuset is ambiguous. */ errno = EXDEV; return NULL; } if (hwloc_bitmap_iszero(set)) { errno = EINVAL; return NULL; } if (!hwloc_bitmap_isincluded(set, complete_set)) { errno = EINVAL; return NULL; } if (hwloc_bitmap_isincluded(topology_set, set)) set = complete_set; return set; }
unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_obj *src, struct hwloc_obj **objs, unsigned max) { struct hwloc_obj *parent, *nextparent, **src_objs; int i,src_nbobjects; unsigned stored = 0; src_nbobjects = topology->level_nbobjects[src->depth]; src_objs = topology->levels[src->depth]; parent = src; while (stored < max) { while (1) { nextparent = parent->parent; if (!nextparent) goto out; if (!hwloc_bitmap_isequal(parent->cpuset, nextparent->cpuset)) break; parent = nextparent; } /* traverse src's objects and find those that are in nextparent and were not in parent */ for(i=0; i<src_nbobjects; i++) { if (hwloc_bitmap_isincluded(src_objs[i]->cpuset, nextparent->cpuset) && !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) { objs[stored++] = src_objs[i]; if (stored == max) goto out; } } parent = nextparent; } out: return stored; }
static int check_compare(hwloc_const_bitmap_t set1, hwloc_const_bitmap_t set2) { int res = hwloc_bitmap_compare_inclusion(set1, set2); if (hwloc_bitmap_iszero(set1)) { if (hwloc_bitmap_iszero(set2)) { assert(res == HWLOC_BITMAP_EQUAL); } else { assert(res == HWLOC_BITMAP_INCLUDED); } } else if (hwloc_bitmap_iszero(set2)) { assert(res == HWLOC_BITMAP_CONTAINS); } else if (hwloc_bitmap_isequal(set1, set2)) { assert(res == HWLOC_BITMAP_EQUAL); } else if (hwloc_bitmap_isincluded(set1, set2)) { assert(res == HWLOC_BITMAP_INCLUDED); } else if (hwloc_bitmap_isincluded(set2, set1)) { assert(res == HWLOC_BITMAP_CONTAINS); } else if (hwloc_bitmap_intersects(set1, set2)) { assert(res == HWLOC_BITMAP_INTERSECTS); } else { assert(res == HWLOC_BITMAP_DIFFERENT); } return res; }
static hwloc_const_nodeset_t hwloc_fix_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) { hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology); hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology); if (!hwloc_topology_get_topology_cpuset(topology)) { /* The topology is composed of several systems, the nodeset is thus * ambiguous. */ errno = EXDEV; return NULL; } if (!complete_nodeset) { /* There is no NUMA node */ errno = ENODEV; return NULL; } if (hwloc_bitmap_iszero(nodeset)) { errno = EINVAL; return NULL; } if (!hwloc_bitmap_isincluded(nodeset, complete_nodeset)) { errno = EINVAL; return NULL; } if (hwloc_bitmap_isincluded(topology_nodeset, nodeset)) return complete_nodeset; return nodeset; }
static int hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_const_cpuset_t cpuset) { hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology); hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology); hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology); if (!topology_set) { /* The topology is composed of several systems, the cpuset is thus * ambiguous. */ errno = EXDEV; return -1; } if (!complete_nodeset) { /* There is no NUMA node */ errno = ENODEV; return -1; } if (hwloc_bitmap_iszero(cpuset)) { errno = EINVAL; return -1; } if (!hwloc_bitmap_isincluded(cpuset, complete_set)) { errno = EINVAL; return -1; } if (hwloc_bitmap_isincluded(topology_set, cpuset)) { hwloc_bitmap_copy(nodeset, complete_nodeset); return 0; } hwloc_cpuset_to_nodeset(topology, cpuset, nodeset); return 0; }
int hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_const_bitmap_t set, struct hwloc_obj **objs, int max) { struct hwloc_obj *current = topology->levels[0][0]; if (!current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset)) return -1; if (max <= 0) return 0; return hwloc__get_largest_objs_inside_cpuset (current, set, &objs, &max); }
static int hwloc_aix_get_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who, hwloc_bitmap_t nodeset, hwloc_membind_policy_t *policy, int flags __hwloc_attribute_unused) { hwloc_bitmap_t hwloc_set; rsethandle_t rset; unsigned cpu, maxcpus; int res = -1; int depth, n, i; depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); if (depth < 0) { errno = EXDEV; return -1; } n = hwloc_get_nbobjs_by_depth(topology, depth); rset = rs_alloc(RS_EMPTY); if (ra_getrset(what, who, 0, rset) == -1) goto out; hwloc_set = hwloc_bitmap_alloc(); maxcpus = rs_getinfo(rset, R_MAXPROCS, 0); for (cpu = 0; cpu < maxcpus; cpu++) if (rs_op(RS_TESTRESOURCE, rset, NULL, R_PROCS, cpu) == 1) hwloc_bitmap_set(hwloc_set, cpu); hwloc_bitmap_and(hwloc_set, hwloc_set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_zero(nodeset); for (i = 0; i < n; i++) { hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) hwloc_bitmap_set(nodeset, obj->os_index); } hwloc_bitmap_free(hwloc_set); *policy = HWLOC_MEMBIND_BIND; res = 0; out: rs_free(rset); return res; }
int main(void) { hwloc_topology_t topology; char *string = NULL; hwloc_obj_t obj; hwloc_bitmap_t set; hwloc_topology_init(&topology); hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION); hwloc_topology_load(topology); set = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(set, GIVEN_CPUSET_STRING); obj = hwloc_get_obj_covering_cpuset(topology, set); assert(obj); fprintf(stderr, "found covering object type %s covering cpuset %s\n", hwloc_obj_type_string(obj->type), GIVEN_CPUSET_STRING); assert(hwloc_bitmap_isincluded(set, obj->cpuset)); hwloc_bitmap_asprintf(&string, obj->cpuset); fprintf(stderr, "covering object of %s is %s, expected %s\n", GIVEN_CPUSET_STRING, string, EXPECTED_CPUSET_STRING); assert(!strcmp(EXPECTED_CPUSET_STRING, string)); free(string); hwloc_bitmap_sscanf(set, GIVEN_LARGESPLIT_CPUSET_STRING); obj = hwloc_get_obj_covering_cpuset(topology, set); assert(obj == hwloc_get_root_obj(topology)); fprintf(stderr, "found system as covering object of first+last cpus cpuset %s\n", GIVEN_LARGESPLIT_CPUSET_STRING); hwloc_bitmap_sscanf(set, GIVEN_TOOLARGE_CPUSET_STRING); obj = hwloc_get_obj_covering_cpuset(topology, set); assert(!obj); fprintf(stderr, "found no covering object for too-large cpuset %s\n", GIVEN_TOOLARGE_CPUSET_STRING); hwloc_bitmap_free(set); hwloc_topology_destroy(topology); return EXIT_SUCCESS; }
static void add_process_objects(hwloc_topology_t topology) { #ifdef HAVE_DIRENT_H hwloc_obj_t root; hwloc_bitmap_t cpuset; #ifdef HWLOC_LINUX_SYS hwloc_bitmap_t task_cpuset; #endif /* HWLOC_LINUX_SYS */ DIR *dir; struct dirent *dirent; const struct hwloc_topology_support *support; root = hwloc_get_root_obj(topology); support = hwloc_topology_get_support(topology); if (!support->cpubind->get_proc_cpubind) return; dir = opendir("/proc"); if (!dir) return; cpuset = hwloc_bitmap_alloc(); #ifdef HWLOC_LINUX_SYS task_cpuset = hwloc_bitmap_alloc(); #endif /* HWLOC_LINUX_SYS */ while ((dirent = readdir(dir))) { long local_pid_number; hwloc_pid_t local_pid; char *end; char name[80]; int proc_cpubind; local_pid_number = strtol(dirent->d_name, &end, 10); if (*end) /* Not a number */ continue; snprintf(name, sizeof(name), "%ld", local_pid_number); local_pid = hwloc_pid_from_number(local_pid_number, 0); proc_cpubind = hwloc_get_proc_cpubind(topology, local_pid, cpuset, 0) != -1; #ifdef HWLOC_LINUX_SYS { char comm[16]; char *path; size_t pathlen = 6 + strlen(dirent->d_name) + 1 + 7 + 1; path = malloc(pathlen); { /* Get the process name */ char cmd[64]; int file; ssize_t n; snprintf(path, pathlen, "/proc/%s/cmdline", dirent->d_name); file = open(path, O_RDONLY); if (file < 0) { /* Ignore errors */ free(path); continue; } n = read(file, cmd, sizeof(cmd)); close(file); if (n <= 0) { /* Ignore kernel threads and errors */ free(path); continue; } snprintf(path, pathlen, "/proc/%s/comm", dirent->d_name); file = open(path, O_RDONLY); if (file >= 0) { n = read(file, comm, sizeof(comm) - 1); close(file); if (n > 0) { comm[n] = 0; if (n > 1 && comm[n-1] == '\n') comm[n-1] = 0; } else { snprintf(comm, sizeof(comm), "(unknown)"); } } else { /* Old kernel, have to look at old file */ char stats[32]; char *parenl = NULL, *parenr; snprintf(path, pathlen, "/proc/%s/stat", dirent->d_name); file = open(path, O_RDONLY); if (file < 0) { /* Ignore errors */ free(path); continue; } /* "pid (comm) ..." */ n = read(file, stats, sizeof(stats) - 1); close(file); if (n > 0) { stats[n] = 0; parenl = strchr(stats, '('); parenr = strchr(stats, ')'); if (!parenr) parenr = &stats[sizeof(stats)-1]; *parenr = 0; } if (!parenl) { snprintf(comm, sizeof(comm), "(unknown)"); } else { snprintf(comm, sizeof(comm), "%s", parenl+1); } } snprintf(name, sizeof(name), "%ld %s", local_pid_number, comm); } { /* Get threads */ DIR *task_dir; struct dirent *task_dirent; snprintf(path, pathlen, "/proc/%s/task", dirent->d_name); task_dir = opendir(path); if (task_dir) { while ((task_dirent = readdir(task_dir))) { long local_tid; char *task_end; const size_t tid_len = sizeof(local_tid)*3+1; size_t task_pathlen = 6 + strlen(dirent->d_name) + 1 + 4 + 1 + strlen(task_dirent->d_name) + 1 + 4 + 1; char *task_path; int comm_file; char task_comm[16] = ""; char task_name[sizeof(name) + 1 + tid_len + 1 + sizeof(task_comm) + 1]; ssize_t n; local_tid = strtol(task_dirent->d_name, &task_end, 10); if (*task_end) /* Not a number, or the main task */ continue; task_path = malloc(task_pathlen); snprintf(task_path, task_pathlen, "/proc/%s/task/%s/comm", dirent->d_name, task_dirent->d_name); comm_file = open(task_path, O_RDONLY); free(task_path); if (comm_file >= 0) { n = read(comm_file, task_comm, sizeof(task_comm) - 1); if (n < 0) n = 0; close(comm_file); task_comm[n] = 0; if (n > 1 && task_comm[n-1] == '\n') task_comm[n-1] = 0; if (!strcmp(comm, task_comm)) /* Same as process comm, do not show it again */ n = 0; } else { n = 0; } if (hwloc_linux_get_tid_cpubind(topology, local_tid, task_cpuset)) continue; if (proc_cpubind && hwloc_bitmap_isequal(task_cpuset, cpuset)) continue; if (n) { snprintf(task_name, sizeof(task_name), "%s %li %s", name, local_tid, task_comm); } else { snprintf(task_name, sizeof(task_name), "%s %li", name, local_tid); } insert_task(topology, task_cpuset, task_name); } closedir(task_dir); } } free(path); } #endif /* HWLOC_LINUX_SYS */ if (!proc_cpubind) continue; if (hwloc_bitmap_isincluded(root->cpuset, cpuset)) continue; insert_task(topology, cpuset, name); } hwloc_bitmap_free(cpuset); #ifdef HWLOC_LINUX_SYS hwloc_bitmap_free(task_cpuset); #endif /* HWLOC_LINUX_SYS */ closedir(dir); #endif /* HAVE_DIRENT_H */ }
int main(void) { hwloc_topology_t topology; #ifdef HWLOC_HAVE_CPU_SET unsigned depth; hwloc_bitmap_t hwlocset; cpu_set_t schedset; hwloc_obj_t obj; int err; #endif /* HWLOC_HAVE_CPU_SET */ hwloc_topology_init(&topology); hwloc_topology_load(topology); #ifdef HWLOC_HAVE_CPU_SET depth = hwloc_topology_get_depth(topology); hwlocset = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset(topology)); hwloc_cpuset_to_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_setaffinity(0, sizeof(schedset)); #else err = sched_setaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwloc_bitmap_free(hwlocset); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_getaffinity(0, sizeof(schedset)); #else err = sched_getaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwlocset = hwloc_bitmap_alloc(); hwloc_cpuset_from_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); assert(hwloc_bitmap_isincluded(hwlocset, hwloc_topology_get_complete_cpuset(topology))); hwloc_bitmap_andnot(hwlocset, hwlocset, hwloc_topology_get_online_cpuset(topology)); hwloc_bitmap_andnot(hwlocset, hwlocset, hwloc_topology_get_allowed_cpuset(topology)); assert(hwloc_bitmap_iszero(hwlocset)); hwloc_bitmap_free(hwlocset); obj = hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1) - 1); assert(obj); assert(obj->type == HWLOC_OBJ_PU); hwlocset = hwloc_bitmap_dup(obj->cpuset); hwloc_cpuset_to_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_setaffinity(0, sizeof(schedset)); #else err = sched_setaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwloc_bitmap_free(hwlocset); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_getaffinity(0, sizeof(schedset)); #else err = sched_getaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwlocset = hwloc_bitmap_alloc(); hwloc_cpuset_from_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); assert(hwloc_bitmap_isequal(hwlocset, obj->cpuset)); hwloc_bitmap_free(hwlocset); #endif /* HWLOC_HAVE_CPU_SET */ hwloc_topology_destroy(topology); return 0; }
static void add_process_objects(hwloc_topology_t topology) { #ifdef HAVE_DIRENT_H hwloc_obj_t root; hwloc_bitmap_t cpuset; #ifdef HWLOC_LINUX_SYS hwloc_bitmap_t task_cpuset; #endif /* HWLOC_LINUX_SYS */ DIR *dir; struct dirent *dirent; const struct hwloc_topology_support *support; root = hwloc_get_root_obj(topology); support = hwloc_topology_get_support(topology); if (!support->cpubind->get_proc_cpubind) return; dir = opendir("/proc"); if (!dir) return; cpuset = hwloc_bitmap_alloc(); #ifdef HWLOC_LINUX_SYS task_cpuset = hwloc_bitmap_alloc(); #endif /* HWLOC_LINUX_SYS */ while ((dirent = readdir(dir))) { long local_pid_number; hwloc_pid_t local_pid; char *end; char name[64]; int proc_cpubind; local_pid_number = strtol(dirent->d_name, &end, 10); if (*end) /* Not a number */ continue; snprintf(name, sizeof(name), "%ld", local_pid_number); local_pid = hwloc_pid_from_number(local_pid_number, 0); proc_cpubind = hwloc_get_proc_cpubind(topology, local_pid, cpuset, 0) != -1; #ifdef HWLOC_LINUX_SYS { /* Get the process name */ char *path; unsigned pathlen = 6 + strlen(dirent->d_name) + 1 + 7 + 1; char cmd[64], *c; int file; ssize_t n; path = malloc(pathlen); snprintf(path, pathlen, "/proc/%s/cmdline", dirent->d_name); file = open(path, O_RDONLY); free(path); if (file >= 0) { n = read(file, cmd, sizeof(cmd) - 1); close(file); if (n <= 0) /* Ignore kernel threads and errors */ continue; cmd[n] = 0; if ((c = strchr(cmd, ' '))) *c = 0; snprintf(name, sizeof(name), "%ld %s", local_pid_number, cmd); } } { /* Get threads */ char *path; unsigned pathlen = 6+strlen(dirent->d_name) + 1 + 4 + 1; DIR *task_dir; struct dirent *task_dirent; path = malloc(pathlen); snprintf(path, pathlen, "/proc/%s/task", dirent->d_name); task_dir = opendir(path); free(path); if (task_dir) { while ((task_dirent = readdir(task_dir))) { long local_tid; char *task_end; char task_name[64]; local_tid = strtol(task_dirent->d_name, &task_end, 10); if (*task_end) /* Not a number, or the main task */ continue; if (hwloc_linux_get_tid_cpubind(topology, local_tid, task_cpuset)) continue; if (proc_cpubind && hwloc_bitmap_isequal(task_cpuset, cpuset)) continue; snprintf(task_name, sizeof(task_name), "%s %li", name, local_tid); insert_task(topology, task_cpuset, task_name); } closedir(task_dir); } } #endif /* HWLOC_LINUX_SYS */ if (!proc_cpubind) continue; if (hwloc_bitmap_isincluded(root->cpuset, cpuset)) continue; insert_task(topology, cpuset, name); } hwloc_bitmap_free(cpuset); #ifdef HWLOC_LINUX_SYS hwloc_bitmap_free(task_cpuset); #endif /* HWLOC_LINUX_SYS */ closedir(dir); #endif /* HAVE_DIRENT_H */ }
void output_console(hwloc_topology_t topology, const char *filename, int logical, int legend __hwloc_attribute_unused, int verbose_mode) { unsigned topodepth; FILE *output; if (!filename || !strcmp(filename, "-")) output = stdout; else { output = open_file(filename, "w"); if (!output) { fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno)); return; } } topodepth = hwloc_topology_get_depth(topology); /* * if verbose_mode == 0, only print the summary. * if verbose_mode == 1, only print the topology tree. * if verbose_mode > 1, print both. */ if (lstopo_show_only != (hwloc_obj_type_t)-1) { if (verbose_mode > 1) fprintf(output, "Only showing %s objects\n", hwloc_obj_type_string(lstopo_show_only)); output_only (topology, hwloc_get_root_obj(topology), output, logical, verbose_mode); } else if (verbose_mode >= 1) { output_topology (topology, hwloc_get_root_obj(topology), NULL, output, 0, logical, verbose_mode); fprintf(output, "\n"); } if ((verbose_mode > 1 || !verbose_mode) && lstopo_show_only == (hwloc_obj_type_t)-1) { hwloc_lstopo_show_summary(output, topology); } if (verbose_mode > 1 && lstopo_show_only == (hwloc_obj_type_t)-1) { const struct hwloc_distances_s * distances; unsigned depth; for (depth = 0; depth < topodepth; depth++) { distances = hwloc_get_whole_distance_matrix_by_depth(topology, depth); if (!distances || !distances->latency) continue; printf("latency matrix between %ss (depth %u) by %s indexes:\n", hwloc_obj_type_string(hwloc_get_depth_type(topology, depth)), depth, logical ? "logical" : "physical"); hwloc_utils_print_distance_matrix(topology, hwloc_get_root_obj(topology), distances->nbobjs, depth, distances->latency, logical); } } if (verbose_mode > 1 && lstopo_show_only == (hwloc_obj_type_t)-1) { hwloc_const_bitmap_t complete = hwloc_topology_get_complete_cpuset(topology); hwloc_const_bitmap_t topo = hwloc_topology_get_topology_cpuset(topology); hwloc_const_bitmap_t online = hwloc_topology_get_online_cpuset(topology); hwloc_const_bitmap_t allowed = hwloc_topology_get_allowed_cpuset(topology); if (complete && !hwloc_bitmap_isequal(topo, complete)) { hwloc_bitmap_t unknown = hwloc_bitmap_alloc(); char *unknownstr; hwloc_bitmap_copy(unknown, complete); hwloc_bitmap_andnot(unknown, unknown, topo); hwloc_bitmap_asprintf(&unknownstr, unknown); fprintf (output, "%d processors not represented in topology: %s\n", hwloc_bitmap_weight(unknown), unknownstr); free(unknownstr); hwloc_bitmap_free(unknown); } if (complete && !hwloc_bitmap_isequal(online, complete)) { hwloc_bitmap_t offline = hwloc_bitmap_alloc(); char *offlinestr; hwloc_bitmap_copy(offline, complete); hwloc_bitmap_andnot(offline, offline, online); hwloc_bitmap_asprintf(&offlinestr, offline); fprintf (output, "%d processors offline: %s\n", hwloc_bitmap_weight(offline), offlinestr); free(offlinestr); hwloc_bitmap_free(offline); } if (complete && !hwloc_bitmap_isequal(allowed, online)) { if (!hwloc_bitmap_isincluded(online, allowed)) { hwloc_bitmap_t forbidden = hwloc_bitmap_alloc(); char *forbiddenstr; hwloc_bitmap_copy(forbidden, online); hwloc_bitmap_andnot(forbidden, forbidden, allowed); hwloc_bitmap_asprintf(&forbiddenstr, forbidden); fprintf(output, "%d processors online but not allowed: %s\n", hwloc_bitmap_weight(forbidden), forbiddenstr); free(forbiddenstr); hwloc_bitmap_free(forbidden); } if (!hwloc_bitmap_isincluded(allowed, online)) { hwloc_bitmap_t potential = hwloc_bitmap_alloc(); char *potentialstr; hwloc_bitmap_copy(potential, allowed); hwloc_bitmap_andnot(potential, potential, online); hwloc_bitmap_asprintf(&potentialstr, potential); fprintf(output, "%d processors allowed but not online: %s\n", hwloc_bitmap_weight(potential), potentialstr); free(potentialstr); hwloc_bitmap_free(potential); } } if (!hwloc_topology_is_thissystem(topology)) fprintf (output, "Topology not from this system\n"); } if (output != stdout) fclose(output); }
static int hwloc_solaris_set_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_const_bitmap_t hwloc_set, int flags) { unsigned target_cpu; /* The resulting binding is always strict */ if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) { if (processor_bind(idtype, id, PBIND_NONE, NULL) != 0) return -1; #ifdef HAVE_LIBLGRP if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) { int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); if (depth >= 0) { int n = hwloc_get_nbobjs_by_depth(topology, depth); int i; for (i = 0; i < n; i++) { hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE); } } } #endif /* HAVE_LIBLGRP */ return 0; } #ifdef HAVE_LIBLGRP if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) { int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); if (depth >= 0) { int n = hwloc_get_nbobjs_by_depth(topology, depth); int i; int ok; hwloc_bitmap_t target = hwloc_bitmap_alloc(); for (i = 0; i < n; i++) { hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) hwloc_bitmap_or(target, target, obj->cpuset); } ok = hwloc_bitmap_isequal(target, hwloc_set); hwloc_bitmap_free(target); if (ok) { /* Ok, managed to achieve hwloc_set by just combining NUMA nodes */ for (i = 0; i < n; i++) { hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) { lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_STRONG); } else { if (flags & HWLOC_CPUBIND_STRICT) lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE); else lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_WEAK); } } return 0; } } } #endif /* HAVE_LIBLGRP */ if (hwloc_bitmap_weight(hwloc_set) != 1) { errno = EXDEV; return -1; } target_cpu = hwloc_bitmap_first(hwloc_set); if (processor_bind(idtype, id, (processorid_t) (target_cpu), NULL) != 0) return -1; return 0; }
int main(void) { hwloc_topology_t topology; hwloc_bitmap_t set, set2; hwloc_const_bitmap_t cset_available, cset_all; hwloc_obj_t obj; char *buffer; char type[64]; unsigned i; int err; /* create a topology */ err = hwloc_topology_init(&topology); if (err < 0) { fprintf(stderr, "failed to initialize the topology\n"); return EXIT_FAILURE; } err = hwloc_topology_load(topology); if (err < 0) { fprintf(stderr, "failed to load the topology\n"); hwloc_topology_destroy(topology); return EXIT_FAILURE; } /* retrieve the entire set of available PUs */ cset_available = hwloc_topology_get_topology_cpuset(topology); /* retrieve the CPU binding of the current entire process */ set = hwloc_bitmap_alloc(); if (!set) { fprintf(stderr, "failed to allocate a bitmap\n"); hwloc_topology_destroy(topology); return EXIT_FAILURE; } err = hwloc_get_cpubind(topology, set, HWLOC_CPUBIND_PROCESS); if (err < 0) { fprintf(stderr, "failed to get cpu binding\n"); hwloc_bitmap_free(set); hwloc_topology_destroy(topology); } /* display the processing units that cannot be used by this process */ if (hwloc_bitmap_isequal(set, cset_available)) { printf("this process can use all available processing units in the system\n"); } else { /* compute the set where we currently cannot run. * we can't modify cset_available because it's a system read-only one, * so we do set = available &~ set */ hwloc_bitmap_andnot(set, cset_available, set); hwloc_bitmap_asprintf(&buffer, set); printf("process cannot use %d process units (%s) among %u in the system\n", hwloc_bitmap_weight(set), buffer, hwloc_bitmap_weight(cset_available)); free(buffer); /* restore set where it was before the &~ operation above */ hwloc_bitmap_andnot(set, cset_available, set); } /* print the smallest object covering the current process binding */ obj = hwloc_get_obj_covering_cpuset(topology, set); hwloc_obj_type_snprintf(type, sizeof(type), obj, 0); printf("process is bound within object %s logical index %u\n", type, obj->logical_index); /* retrieve the single PU where the current thread actually runs within this process binding */ set2 = hwloc_bitmap_alloc(); if (!set2) { fprintf(stderr, "failed to allocate a bitmap\n"); hwloc_bitmap_free(set); hwloc_topology_destroy(topology); return EXIT_FAILURE; } err = hwloc_get_last_cpu_location(topology, set2, HWLOC_CPUBIND_THREAD); if (err < 0) { fprintf(stderr, "failed to get last cpu location\n"); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); hwloc_topology_destroy(topology); } /* sanity checks that are not actually needed but help the reader */ /* this thread runs within the process binding */ assert(hwloc_bitmap_isincluded(set2, set)); /* this thread runs on a single PU at a time */ assert(hwloc_bitmap_weight(set2) == 1); /* print the logical number of the PU where that thread runs */ /* extract the PU OS index from the bitmap */ i = hwloc_bitmap_first(set2); obj = hwloc_get_pu_obj_by_os_index(topology, i); printf("thread is now running on PU logical index %u (OS/physical index %u)\n", obj->logical_index, i); /* migrate this single thread to where other PUs within the current binding */ hwloc_bitmap_andnot(set2, set, set2); err = hwloc_set_cpubind(topology, set2, HWLOC_CPUBIND_THREAD); if (err < 0) { fprintf(stderr, "failed to set thread binding\n"); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); hwloc_topology_destroy(topology); } /* reprint the PU where that thread runs */ err = hwloc_get_last_cpu_location(topology, set2, HWLOC_CPUBIND_THREAD); if (err < 0) { fprintf(stderr, "failed to get last cpu location\n"); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); hwloc_topology_destroy(topology); } /* print the logical number of the PU where that thread runs */ /* extract the PU OS index from the bitmap */ i = hwloc_bitmap_first(set2); obj = hwloc_get_pu_obj_by_os_index(topology, i); printf("thread is running on PU logical index %u (OS/physical index %u)\n", obj->logical_index, i); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); /* retrieve the entire set of all PUs */ cset_all = hwloc_topology_get_complete_cpuset(topology); if (hwloc_bitmap_isequal(cset_all, cset_available)) { printf("all hardware PUs are available\n"); } else { printf("only %d hardware PUs are available in the machine among %d\n", hwloc_bitmap_weight(cset_available), hwloc_bitmap_weight(cset_all)); } hwloc_topology_destroy(topology); return EXIT_SUCCESS; }
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; }