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); }
/* * Don't use show_help() here (or print any error message at all). * Let the upper layer output a relevant message, because doing so may * be complicated (e.g., this might be called from the ORTE ODLS, * which has to do some extra steps to get error messages to be * displayed). */ int opal_hwloc_base_set_process_membind_policy(void) { int rc = 0, flags; hwloc_membind_policy_t policy; hwloc_cpuset_t cpuset; /* Make sure opal_hwloc_topology has been set by the time we've been called */ if (OPAL_SUCCESS != opal_hwloc_base_get_topology()) { return OPAL_ERR_BAD_PARAM; } /* Set the default memory allocation policy according to MCA param */ switch (opal_hwloc_base_map) { case OPAL_HWLOC_BASE_MAP_LOCAL_ONLY: policy = HWLOC_MEMBIND_BIND; flags = HWLOC_MEMBIND_STRICT; break; case OPAL_HWLOC_BASE_MAP_NONE: default: policy = HWLOC_MEMBIND_DEFAULT; flags = 0; break; } cpuset = hwloc_bitmap_alloc(); if (NULL == cpuset) { rc = OPAL_ERR_OUT_OF_RESOURCE; } else { int e; hwloc_get_cpubind(opal_hwloc_topology, cpuset, 0); rc = hwloc_set_membind(opal_hwloc_topology, cpuset, policy, flags); e = errno; hwloc_bitmap_free(cpuset); /* See if hwloc was able to do it. If hwloc failed due to ENOSYS, but the base_map == NONE, then it's not really an error. */ if (0 != rc && ENOSYS == e && OPAL_HWLOC_BASE_MAP_NONE == opal_hwloc_base_map) { rc = 0; } } return (0 == rc) ? OPAL_SUCCESS : OPAL_ERROR; }
void initialize_hwloc(int nb_workers) { #ifdef HAVE_HWLOC hwloc_topology_init(&topology); hwloc_topology_load(topology); bool numa_alloc_interleaved = (nb_workers == 0) ? false : true; numa_alloc_interleaved = cmdline::parse_or_default("numa_alloc_interleaved", numa_alloc_interleaved); if (numa_alloc_interleaved) { hwloc_cpuset_t all_cpus = hwloc_bitmap_dup(hwloc_topology_get_topology_cpuset(topology)); int err = hwloc_set_membind(topology, all_cpus, HWLOC_MEMBIND_INTERLEAVE, 0); if (err < 0) { printf("Warning: failed to set NUMA round-robin allocation policy\n"); } } #endif }
int location_membind(hwloc_topology_t topology, hwloc_obj_t location) { hwloc_obj_t bind = location; while(bind != NULL && bind->type != HWLOC_OBJ_NODE) bind = bind->parent; if(bind == NULL){ char * name = location_name(location); fprintf(stderr, "Cannot bind memory to %s\n", name); free(name); return -1; } if(hwloc_set_membind(topology, bind->nodeset, HWLOC_MEMBIND_BIND,HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET) == -1){ perror("membind"); return -1; } return chk_mem_bind(topology, bind->nodeset, 0); }
void AbstractCoreBoundQueue::launchThread(int core) { //get the number of cores on system int NUM_PROCS = getNumberOfCoresOnSystem(); if (core < NUM_PROCS) { _thread = new std::thread(&AbstractTaskQueue::executeTask, this); hwloc_cpuset_t cpuset; hwloc_obj_t obj; hwloc_topology_t topology = getHWTopology(); obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_CORE, core); // the bitmap to modify cpuset = hwloc_bitmap_dup(obj->cpuset); // remove hyperthreads hwloc_bitmap_singlify(cpuset); // bind if (hwloc_set_thread_cpubind(topology, _thread->native_handle(), cpuset, HWLOC_CPUBIND_STRICT | HWLOC_CPUBIND_NOMEMBIND)) { char *str; int error = errno; hwloc_bitmap_asprintf(&str, obj->cpuset); fprintf(stderr, "Couldn't bind to cpuset %s: %s\n", str, strerror(error)); fprintf(stderr, "Continuing as normal, however, no guarantees\n"); //throw std::runtime_error(strerror(error)); } if(hwloc_set_membind (topology, cpuset, HWLOC_MEMBIND_FIRSTTOUCH , HWLOC_MEMBIND_THREAD )){ char *str; int error = errno; hwloc_bitmap_asprintf(&str, obj->cpuset); fprintf(stderr, "Couldn't bind to memory %s: %s\n", str, strerror(error)); fprintf(stderr, "Continuing as normal, however, no guarantees\n"); //throw std::runtime_error(strerror(error)); } hwloc_bitmap_free(cpuset); } else { // this case should never happen, as TaskQueue is only initialized from SimpleTaskScheduler, which captures this case throw std::logic_error("CPU to run thread on is larger than number of total cores; seems that TaskQueue was initialized outside of SimpleTaskScheduler, which should not happen"); } }
int main(int argc, char *argv[]) { hwloc_topology_t topology; int loaded = 0; unsigned depth; hwloc_bitmap_t cpubind_set, membind_set; int got_cpubind = 0, got_membind = 0; int working_on_cpubind = 1; /* membind if 0 */ int get_binding = 0; int get_last_cpu_location = 0; unsigned long flags = 0; int force = 0; int single = 0; int verbose = 0; int logical = 1; int taskset = 0; int cpubind_flags = 0; hwloc_membind_policy_t membind_policy = HWLOC_MEMBIND_BIND; int membind_flags = 0; int opt; int ret; int pid_number = -1; hwloc_pid_t pid = 0; /* only valid when pid_number > 0, but gcc-4.8 still reports uninitialized warnings */ char *callname; cpubind_set = hwloc_bitmap_alloc(); membind_set = hwloc_bitmap_alloc(); /* don't load now, in case some options change the config before the topology is actually used */ #define LOADED() (loaded) #define ENSURE_LOADED() do { \ if (!loaded) { \ hwloc_topology_init(&topology); \ hwloc_topology_set_all_types_filter(topology, HWLOC_TYPE_FILTER_KEEP_ALL); \ hwloc_topology_set_flags(topology, flags); \ hwloc_topology_load(topology); \ depth = hwloc_topology_get_depth(topology); \ loaded = 1; \ } \ } while (0) callname = argv[0]; /* skip argv[0], handle options */ argv++; argc--; while (argc >= 1) { if (!strcmp(argv[0], "--")) { argc--; argv++; break; } opt = 0; if (*argv[0] == '-') { if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--verbose")) { verbose++; goto next; } if (!strcmp(argv[0], "-q") || !strcmp(argv[0], "--quiet")) { verbose--; goto next; } if (!strcmp(argv[0], "--help")) { usage("hwloc-bind", stdout); return EXIT_SUCCESS; } if (!strcmp(argv[0], "--single")) { single = 1; goto next; } if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--force")) { force = 1; goto next; } if (!strcmp(argv[0], "--strict")) { cpubind_flags |= HWLOC_CPUBIND_STRICT; membind_flags |= HWLOC_MEMBIND_STRICT; goto next; } if (!strcmp(argv[0], "--pid")) { if (argc < 2) { usage ("hwloc-bind", stderr); exit(EXIT_FAILURE); } pid_number = atoi(argv[1]); opt = 1; goto next; } if (!strcmp (argv[0], "--version")) { printf("%s %s\n", callname, HWLOC_VERSION); exit(EXIT_SUCCESS); } if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--logical")) { logical = 1; goto next; } if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--physical")) { logical = 0; goto next; } if (!strcmp(argv[0], "--taskset")) { taskset = 1; goto next; } if (!strcmp (argv[0], "-e") || !strncmp (argv[0], "--get-last-cpu-location", 10)) { get_last_cpu_location = 1; goto next; } if (!strcmp (argv[0], "--get")) { get_binding = 1; goto next; } if (!strcmp (argv[0], "--cpubind")) { working_on_cpubind = 1; goto next; } if (!strcmp (argv[0], "--membind")) { working_on_cpubind = 0; goto next; } if (!strcmp (argv[0], "--mempolicy")) { if (!strncmp(argv[1], "default", 2)) membind_policy = HWLOC_MEMBIND_DEFAULT; else if (!strncmp(argv[1], "firsttouch", 2)) membind_policy = HWLOC_MEMBIND_FIRSTTOUCH; else if (!strncmp(argv[1], "bind", 2)) membind_policy = HWLOC_MEMBIND_BIND; else if (!strncmp(argv[1], "interleave", 2)) membind_policy = HWLOC_MEMBIND_INTERLEAVE; else if (!strncmp(argv[1], "nexttouch", 2)) membind_policy = HWLOC_MEMBIND_NEXTTOUCH; else { fprintf(stderr, "Unrecognized memory binding policy %s\n", argv[1]); usage ("hwloc-bind", stderr); exit(EXIT_FAILURE); } opt = 1; goto next; } if (!strcmp (argv[0], "--whole-system")) { if (loaded) { fprintf(stderr, "Input option %s disallowed after options using the topology\n", argv[0]); exit(EXIT_FAILURE); } flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM; goto next; } if (!strcmp (argv[0], "--restrict")) { hwloc_bitmap_t restrictset; int err; if (argc < 2) { usage (callname, stdout); exit(EXIT_FAILURE); } restrictset = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(restrictset, argv[1]); ENSURE_LOADED(); err = hwloc_topology_restrict (topology, restrictset, 0); if (err) { perror("Restricting the topology"); /* fallthrough */ } hwloc_bitmap_free(restrictset); argc--; argv++; goto next; } fprintf (stderr, "Unrecognized option: %s\n", argv[0]); usage("hwloc-bind", stderr); return EXIT_FAILURE; } ENSURE_LOADED(); ret = hwloc_calc_process_arg(topology, depth, argv[0], logical, working_on_cpubind ? cpubind_set : membind_set, verbose); if (ret < 0) { if (verbose > 0) fprintf(stderr, "assuming the command starts at %s\n", argv[0]); break; } if (working_on_cpubind) got_cpubind = 1; else got_membind = 1; next: argc -= opt+1; argv += opt+1; } ENSURE_LOADED(); if (pid_number > 0) { pid = hwloc_pid_from_number(pid_number, !(get_binding || get_last_cpu_location)); /* no need to set_pid() * the doc just says we're operating on pid, not that we're retrieving the topo/cpuset as seen from inside pid */ } if (get_last_cpu_location && !working_on_cpubind) { fprintf(stderr, "Options --membind and --get-last-cpu-location cannot be combined.\n"); return EXIT_FAILURE; } if ((get_binding || get_last_cpu_location) && (got_cpubind || got_membind)) { /* doesn't work because get_binding/get_last_cpu_location overwrites cpubind_set */ fprintf(stderr, "Cannot display and set binding at the same time.\n"); return EXIT_FAILURE; } if (get_binding || get_last_cpu_location) { char *s; const char *policystr = NULL; int err; if (working_on_cpubind) { if (get_last_cpu_location) { if (pid_number > 0) err = hwloc_get_proc_last_cpu_location(topology, pid, cpubind_set, 0); else err = hwloc_get_last_cpu_location(topology, cpubind_set, 0); } else { if (pid_number > 0) err = hwloc_get_proc_cpubind(topology, pid, cpubind_set, 0); else err = hwloc_get_cpubind(topology, cpubind_set, 0); } if (err) { const char *errmsg = strerror(errno); if (pid_number > 0) fprintf(stderr, "hwloc_get_proc_%s %d failed (errno %d %s)\n", get_last_cpu_location ? "last_cpu_location" : "cpubind", pid_number, errno, errmsg); else fprintf(stderr, "hwloc_get_%s failed (errno %d %s)\n", get_last_cpu_location ? "last_cpu_location" : "cpubind", errno, errmsg); return EXIT_FAILURE; } if (taskset) hwloc_bitmap_taskset_asprintf(&s, cpubind_set); else hwloc_bitmap_asprintf(&s, cpubind_set); } else { hwloc_membind_policy_t policy; if (pid_number > 0) err = hwloc_get_proc_membind(topology, pid, membind_set, &policy, 0); else err = hwloc_get_membind(topology, membind_set, &policy, 0); if (err) { const char *errmsg = strerror(errno); if (pid_number > 0) fprintf(stderr, "hwloc_get_proc_membind %d failed (errno %d %s)\n", pid_number, errno, errmsg); else fprintf(stderr, "hwloc_get_membind failed (errno %d %s)\n", errno, errmsg); return EXIT_FAILURE; } if (taskset) hwloc_bitmap_taskset_asprintf(&s, membind_set); else hwloc_bitmap_asprintf(&s, membind_set); switch (policy) { case HWLOC_MEMBIND_DEFAULT: policystr = "default"; break; case HWLOC_MEMBIND_FIRSTTOUCH: policystr = "firsttouch"; break; case HWLOC_MEMBIND_BIND: policystr = "bind"; break; case HWLOC_MEMBIND_INTERLEAVE: policystr = "interleave"; break; case HWLOC_MEMBIND_NEXTTOUCH: policystr = "nexttouch"; break; default: fprintf(stderr, "unknown memory policy %d\n", policy); assert(0); break; } } if (policystr) printf("%s (%s)\n", s, policystr); else printf("%s\n", s); free(s); } if (got_membind) { if (hwloc_bitmap_iszero(membind_set)) { if (verbose >= 0) fprintf(stderr, "cannot membind to empty set\n"); if (!force) goto failed_binding; } if (verbose > 0) { char *s; hwloc_bitmap_asprintf(&s, membind_set); fprintf(stderr, "binding on memory set %s\n", s); free(s); } if (single) hwloc_bitmap_singlify(membind_set); if (pid_number > 0) ret = hwloc_set_proc_membind(topology, pid, membind_set, membind_policy, membind_flags); else ret = hwloc_set_membind(topology, membind_set, membind_policy, membind_flags); if (ret && verbose >= 0) { int bind_errno = errno; const char *errmsg = strerror(bind_errno); char *s; hwloc_bitmap_asprintf(&s, membind_set); if (pid_number > 0) fprintf(stderr, "hwloc_set_proc_membind %s %d failed (errno %d %s)\n", s, pid_number, bind_errno, errmsg); else fprintf(stderr, "hwloc_set_membind %s failed (errno %d %s)\n", s, bind_errno, errmsg); free(s); } if (ret && !force) goto failed_binding; } if (got_cpubind) { if (hwloc_bitmap_iszero(cpubind_set)) { if (verbose >= 0) fprintf(stderr, "cannot cpubind to empty set\n"); if (!force) goto failed_binding; } if (verbose > 0) { char *s; hwloc_bitmap_asprintf(&s, cpubind_set); fprintf(stderr, "binding on cpu set %s\n", s); free(s); } if (single) hwloc_bitmap_singlify(cpubind_set); if (pid_number > 0) ret = hwloc_set_proc_cpubind(topology, pid, cpubind_set, cpubind_flags); else ret = hwloc_set_cpubind(topology, cpubind_set, cpubind_flags); if (ret && verbose >= 0) { int bind_errno = errno; const char *errmsg = strerror(bind_errno); char *s; hwloc_bitmap_asprintf(&s, cpubind_set); if (pid_number > 0) fprintf(stderr, "hwloc_set_proc_cpubind %s %d failed (errno %d %s)\n", s, pid_number, bind_errno, errmsg); else fprintf(stderr, "hwloc_set_cpubind %s failed (errno %d %s)\n", s, bind_errno, errmsg); free(s); } if (ret && !force) goto failed_binding; } hwloc_bitmap_free(cpubind_set); hwloc_bitmap_free(membind_set); hwloc_topology_destroy(topology); if (pid_number > 0) return EXIT_SUCCESS; if (0 == argc) { if (get_binding || get_last_cpu_location) return EXIT_SUCCESS; fprintf(stderr, "%s: nothing to do!\n", callname); return EXIT_FAILURE; } /* FIXME: check whether Windows execvp() passes INHERIT_PARENT_AFFINITY to CreateProcess() * because we need to propagate processor group affinity. However process-wide affinity * isn't supported with processor groups so far. */ ret = execvp(argv[0], argv); if (ret) { fprintf(stderr, "%s: Failed to launch executable \"%s\"\n", callname, argv[0]); perror("execvp"); } return EXIT_FAILURE; failed_binding: hwloc_bitmap_free(cpubind_set); hwloc_bitmap_free(membind_set); hwloc_topology_destroy(topology); return EXIT_FAILURE; }
int main(int argc, char *argv[]) { hwloc_topology_t topology; unsigned depth; hwloc_bitmap_t cpubind_set, membind_set; int got_cpubind = 0, got_membind = 0; int working_on_cpubind = 1; /* membind if 0 */ int get_binding = 0; int get_last_cpu_location = 0; unsigned long flags = HWLOC_TOPOLOGY_FLAG_WHOLE_IO|HWLOC_TOPOLOGY_FLAG_ICACHES; int force = 0; int single = 0; int verbose = 0; int logical = 1; int taskset = 0; int cpubind_flags = 0; hwloc_membind_policy_t membind_policy = HWLOC_MEMBIND_BIND; int membind_flags = 0; int opt; int ret; int pid_number = 0; hwloc_pid_t pid; char *callname; cpubind_set = hwloc_bitmap_alloc(); membind_set = hwloc_bitmap_alloc(); hwloc_topology_init(&topology); hwloc_topology_set_flags(topology, flags); hwloc_topology_load(topology); depth = hwloc_topology_get_depth(topology); callname = argv[0]; /* skip argv[0], handle options */ argv++; argc--; while (argc >= 1) { if (!strcmp(argv[0], "--")) { argc--; argv++; break; } opt = 0; if (*argv[0] == '-') { if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--verbose")) { verbose++; goto next; } else if (!strcmp(argv[0], "-q") || !strcmp(argv[0], "--quiet")) { verbose--; goto next; } else if (!strcmp(argv[0], "--help")) { usage("hwloc-bind", stdout); return EXIT_SUCCESS; } else if (!strcmp(argv[0], "--single")) { single = 1; goto next; } else if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--force")) { force = 1; goto next; } else if (!strcmp(argv[0], "--strict")) { cpubind_flags |= HWLOC_CPUBIND_STRICT; membind_flags |= HWLOC_MEMBIND_STRICT; goto next; } else if (!strcmp(argv[0], "--pid")) { if (argc < 2) { usage ("hwloc-bind", stderr); exit(EXIT_FAILURE); } pid_number = atoi(argv[1]); opt = 1; goto next; } else if (!strcmp (argv[0], "--version")) { printf("%s %s\n", callname, VERSION); exit(EXIT_SUCCESS); } if (!strcmp(argv[0], "-l") || !strcmp(argv[0], "--logical")) { logical = 1; goto next; } if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--physical")) { logical = 0; goto next; } if (!strcmp(argv[0], "--taskset")) { taskset = 1; goto next; } else if (!strcmp (argv[0], "-e") || !strncmp (argv[0], "--get-last-cpu-location", 10)) { get_last_cpu_location = 1; goto next; } else if (!strcmp (argv[0], "--get")) { get_binding = 1; goto next; } else if (!strcmp (argv[0], "--cpubind")) { working_on_cpubind = 1; goto next; } else if (!strcmp (argv[0], "--membind")) { working_on_cpubind = 0; goto next; } else if (!strcmp (argv[0], "--mempolicy")) { if (!strncmp(argv[1], "default", 2)) membind_policy = HWLOC_MEMBIND_DEFAULT; else if (!strncmp(argv[1], "firsttouch", 2)) membind_policy = HWLOC_MEMBIND_FIRSTTOUCH; else if (!strncmp(argv[1], "bind", 2)) membind_policy = HWLOC_MEMBIND_BIND; else if (!strncmp(argv[1], "interleave", 2)) membind_policy = HWLOC_MEMBIND_INTERLEAVE; else if (!strncmp(argv[1], "replicate", 2)) membind_policy = HWLOC_MEMBIND_REPLICATE; else if (!strncmp(argv[1], "nexttouch", 2)) membind_policy = HWLOC_MEMBIND_NEXTTOUCH; else { fprintf(stderr, "Unrecognized memory binding policy %s\n", argv[1]); usage ("hwloc-bind", stderr); exit(EXIT_FAILURE); } opt = 1; goto next; } else if (!strcmp (argv[0], "--whole-system")) { flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM; hwloc_topology_destroy(topology); hwloc_topology_init(&topology); hwloc_topology_set_flags(topology, flags); hwloc_topology_load(topology); depth = hwloc_topology_get_depth(topology); goto next; } else if (!strcmp (argv[0], "--restrict")) { hwloc_bitmap_t restrictset; int err; if (argc < 2) { usage (callname, stdout); exit(EXIT_FAILURE); } restrictset = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(restrictset, argv[1]); err = hwloc_topology_restrict (topology, restrictset, 0); if (err) { perror("Restricting the topology"); /* fallthrough */ } hwloc_bitmap_free(restrictset); argc--; argv++; goto next; } fprintf (stderr, "Unrecognized option: %s\n", argv[0]); usage("hwloc-bind", stderr); return EXIT_FAILURE; } ret = hwloc_calc_process_arg(topology, depth, argv[0], logical, working_on_cpubind ? cpubind_set : membind_set, verbose); if (ret < 0) { if (verbose > 0) fprintf(stderr, "assuming the command starts at %s\n", argv[0]); break; } if (working_on_cpubind) got_cpubind = 1; else got_membind = 1; next: argc -= opt+1; argv += opt+1; } pid = hwloc_pid_from_number(pid_number, !(get_binding || get_last_cpu_location)); if (get_binding || get_last_cpu_location) { char *s; const char *policystr = NULL; int err; if (working_on_cpubind) { if (get_last_cpu_location) { if (pid_number) err = hwloc_get_proc_last_cpu_location(topology, pid, cpubind_set, 0); else err = hwloc_get_last_cpu_location(topology, cpubind_set, 0); } else { if (pid_number) err = hwloc_get_proc_cpubind(topology, pid, cpubind_set, 0); else err = hwloc_get_cpubind(topology, cpubind_set, 0); } if (err) { const char *errmsg = strerror(errno); if (pid_number) fprintf(stderr, "hwloc_get_proc_%s %d failed (errno %d %s)\n", get_last_cpu_location ? "last_cpu_location" : "cpubind", pid_number, errno, errmsg); else fprintf(stderr, "hwloc_get_%s failed (errno %d %s)\n", get_last_cpu_location ? "last_cpu_location" : "cpubind", errno, errmsg); return EXIT_FAILURE; } if (taskset) hwloc_bitmap_taskset_asprintf(&s, cpubind_set); else hwloc_bitmap_asprintf(&s, cpubind_set); } else { hwloc_membind_policy_t policy; if (pid_number) err = hwloc_get_proc_membind(topology, pid, membind_set, &policy, 0); else err = hwloc_get_membind(topology, membind_set, &policy, 0); if (err) { const char *errmsg = strerror(errno); if (pid_number) fprintf(stderr, "hwloc_get_proc_membind %d failed (errno %d %s)\n", pid_number, errno, errmsg); else fprintf(stderr, "hwloc_get_membind failed (errno %d %s)\n", errno, errmsg); return EXIT_FAILURE; } if (taskset) hwloc_bitmap_taskset_asprintf(&s, membind_set); else hwloc_bitmap_asprintf(&s, membind_set); switch (policy) { case HWLOC_MEMBIND_DEFAULT: policystr = "default"; break; case HWLOC_MEMBIND_FIRSTTOUCH: policystr = "firsttouch"; break; case HWLOC_MEMBIND_BIND: policystr = "bind"; break; case HWLOC_MEMBIND_INTERLEAVE: policystr = "interleave"; break; case HWLOC_MEMBIND_REPLICATE: policystr = "replicate"; break; case HWLOC_MEMBIND_NEXTTOUCH: policystr = "nexttouch"; break; default: fprintf(stderr, "unknown memory policy %d\n", policy); assert(0); break; } } if (policystr) printf("%s (%s)\n", s, policystr); else printf("%s\n", s); free(s); return EXIT_SUCCESS; } if (got_membind) { if (hwloc_bitmap_iszero(membind_set)) { if (verbose >= 0) fprintf(stderr, "cannot membind to empty set\n"); if (!force) goto failed_binding; } if (verbose > 0) { char *s; hwloc_bitmap_asprintf(&s, membind_set); fprintf(stderr, "binding on memory set %s\n", s); free(s); } if (single) hwloc_bitmap_singlify(membind_set); if (pid_number) ret = hwloc_set_proc_membind(topology, pid, membind_set, membind_policy, membind_flags); else ret = hwloc_set_membind(topology, membind_set, membind_policy, membind_flags); if (ret && verbose >= 0) { int bind_errno = errno; const char *errmsg = strerror(bind_errno); char *s; hwloc_bitmap_asprintf(&s, membind_set); if (pid_number) fprintf(stderr, "hwloc_set_proc_membind %s %d failed (errno %d %s)\n", s, pid_number, bind_errno, errmsg); else fprintf(stderr, "hwloc_set_membind %s failed (errno %d %s)\n", s, bind_errno, errmsg); free(s); } if (ret && !force) goto failed_binding; } if (got_cpubind) { if (hwloc_bitmap_iszero(cpubind_set)) { if (verbose >= 0) fprintf(stderr, "cannot cpubind to empty set\n"); if (!force) goto failed_binding; } if (verbose > 0) { char *s; hwloc_bitmap_asprintf(&s, cpubind_set); fprintf(stderr, "binding on cpu set %s\n", s); free(s); } if (single) hwloc_bitmap_singlify(cpubind_set); if (pid_number) ret = hwloc_set_proc_cpubind(topology, pid, cpubind_set, cpubind_flags); else ret = hwloc_set_cpubind(topology, cpubind_set, cpubind_flags); if (ret && verbose >= 0) { int bind_errno = errno; const char *errmsg = strerror(bind_errno); char *s; hwloc_bitmap_asprintf(&s, cpubind_set); if (pid_number) fprintf(stderr, "hwloc_set_proc_cpubind %s %d failed (errno %d %s)\n", s, pid_number, bind_errno, errmsg); else fprintf(stderr, "hwloc_set_cpubind %s failed (errno %d %s)\n", s, bind_errno, errmsg); free(s); } if (ret && !force) goto failed_binding; } hwloc_bitmap_free(cpubind_set); hwloc_bitmap_free(membind_set); hwloc_topology_destroy(topology); if (pid_number) return EXIT_SUCCESS; if (0 == argc) { fprintf(stderr, "%s: nothing to do!\n", callname); return EXIT_FAILURE; } ret = execvp(argv[0], argv); if (ret) { fprintf(stderr, "%s: Failed to launch executable \"%s\"\n", callname, argv[0]); perror("execvp"); } return EXIT_FAILURE; failed_binding: hwloc_bitmap_free(cpubind_set); hwloc_bitmap_free(membind_set); hwloc_topology_destroy(topology); return EXIT_FAILURE; }