int main(void) { hwloc_bitmap_t orig, expected; orig = hwloc_bitmap_alloc(); expected = hwloc_bitmap_alloc(); /* empty set gives empty set */ hwloc_bitmap_singlify(orig); assert(hwloc_bitmap_iszero(orig)); /* full set gives first bit only */ hwloc_bitmap_fill(orig); hwloc_bitmap_singlify(orig); hwloc_bitmap_zero(expected); hwloc_bitmap_set(expected, 0); assert(hwloc_bitmap_isequal(orig, expected)); assert(!hwloc_bitmap_compare(orig, expected)); /* actual non-trivial set */ hwloc_bitmap_zero(orig); hwloc_bitmap_set(orig, 45); hwloc_bitmap_set(orig, 46); hwloc_bitmap_set(orig, 517); hwloc_bitmap_singlify(orig); hwloc_bitmap_zero(expected); hwloc_bitmap_set(expected, 45); assert(hwloc_bitmap_isequal(orig, expected)); assert(!hwloc_bitmap_compare(orig, expected)); hwloc_bitmap_free(orig); hwloc_bitmap_free(expected); return 0; }
void AbstractCoreBoundTaskQueue::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)); } 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"); } }
inline void __pact_reuse_add(void *ary, long long start, long long end, long long mem_ac) { hwloc_bitmap_t set = hwloc_bitmap_alloc(); hwloc_get_cpubind(__pact_topo, set, HWLOC_CPUBIND_THREAD); hwloc_get_last_cpu_location(__pact_topo, set, HWLOC_CPUBIND_THREAD); hwloc_bitmap_singlify(set); hwloc_set_area_membind ( __pact_topo, (const void*)ary, abs(end-start), (hwloc_const_cpuset_t)set, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_MIGRATE ); hwloc_bitmap_free(set); }
bool Core::bind() { auto cpuset = hwloc_bitmap_dup(core_->cpuset); hwloc_bitmap_singlify(cpuset); if (hwloc_set_cpubind(topology_, cpuset, 0)) { auto error = errno; LOG(thread_logger, warning) << "Error setting thread affinity: " << strerror(error); hwloc_bitmap_free(cpuset); return false; } hwloc_bitmap_free(cpuset); return true; }
void migrate(long PageStart, long PageEnd) { SPMR_DEBUG(std::cout << "Runtime: migrate pages: " << PageStart << " to " << PageEnd << "\n"); SPMR_DEBUG(std::cout << "Runtime: hwloc call: " << (PageStart << PAGE_EXP) << ", " << ((PageEnd - PageStart) << PAGE_EXP) << "\n"); hwloc_bitmap_t set = hwloc_bitmap_alloc(); hwloc_get_cpubind(__spm_topo, set, HWLOC_CPUBIND_THREAD); hwloc_get_last_cpu_location(__spm_topo, set, HWLOC_CPUBIND_THREAD); hwloc_bitmap_singlify(set); assert( hwloc_set_area_membind(__spm_topo, (const void*)(PageStart << PAGE_EXP), (PageEnd - PageStart) << PAGE_EXP, (hwloc_const_cpuset_t)set, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_MIGRATE) != -1 && "Unable to migrate requested pages"); hwloc_bitmap_free(set); }
void bindCurrentThreadToCore(int core) { hwloc_topology_t topology = getHWTopology(); hwloc_cpuset_t cpuset; hwloc_obj_t obj; // The actual core obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_CORE, core); cpuset = hwloc_bitmap_dup(obj->cpuset); hwloc_bitmap_singlify(cpuset); // bind if (hwloc_set_cpubind(topology, cpuset, HWLOC_CPUBIND_STRICT | HWLOC_CPUBIND_NOMEMBIND | HWLOC_CPUBIND_THREAD)) { 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); throw std::runtime_error(strerror(error)); } // free duplicated cpuset hwloc_bitmap_free(cpuset); // assuming single machine system obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_MACHINE, 0); // set membind policy interleave for this thread if (hwloc_set_membind_nodeset( topology, obj->nodeset, HWLOC_MEMBIND_INTERLEAVE, HWLOC_MEMBIND_STRICT | HWLOC_MEMBIND_THREAD) && errno != ENOSYS) { char* str; int error = errno; hwloc_bitmap_asprintf(&str, obj->nodeset); fprintf(stderr, "Couldn't membind to nodeset %s: %s\n", str, strerror(error)); fprintf(stderr, "Continuing as normal, however, no guarantees\n"); free(str); } }
int bind_myself_to_core(hwloc_topology_t topology, int id){ hwloc_cpuset_t cpuset; hwloc_obj_t obj; char *str; int binding_res; int depth = hwloc_topology_get_depth(topology); int nb_cores = hwloc_get_nbobjs_by_depth(topology, depth-1); int my_core; int nb_threads = get_nb_threads(); /* printf("depth=%d\n",depth); */ switch (mapping_policy){ case SCATTER: my_core = id*(nb_cores/nb_threads); break; default: if(verbose_level>=WARNING){ printf("Wrong scheduling policy. Using COMPACT\n"); } case COMPACT: my_core = id%nb_cores; } if(verbose_level>=INFO){ printf("Mapping thread %d on core %d\n",id,my_core); } /* Get my core. */ obj = hwloc_get_obj_by_depth(topology, depth-1, my_core); 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/hyperthreaded). */ hwloc_bitmap_singlify(cpuset); /*hwloc_bitmap_asprintf(&str, cpuset); printf("Binding thread %d to cpuset %s\n", my_core,str); FREE(str); */ /* And try to bind ourself there. */ binding_res = hwloc_set_cpubind(topology, cpuset, HWLOC_CPUBIND_THREAD); if (binding_res == -1){ int error = errno; hwloc_bitmap_asprintf(&str, obj->cpuset); if(verbose_level>=WARNING) printf("Thread %d couldn't bind to cpuset %s: %s.\n This thread is not bound to any core...\n", my_core, str, strerror(error)); free(str); /* str is allocated by hlwoc, free it normally*/ return 0; } /* FREE our cpuset copy */ hwloc_bitmap_free(cpuset); return 1; }else{ if(verbose_level>=WARNING) printf("No valid object for core id %d!\n",my_core); return 0; } }
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(void) { hwloc_bitmap_t set; hwloc_obj_t obj; char *str = NULL; hwloc_topology_init(&topology); hwloc_topology_load(topology); support = hwloc_topology_get_support(topology); obj = hwloc_get_root_obj(topology); set = hwloc_bitmap_dup(obj->cpuset); while (hwloc_bitmap_isequal(obj->cpuset, set)) { if (!obj->arity) break; obj = obj->children[0]; } hwloc_bitmap_asprintf(&str, set); printf("system set is %s\n", str); free(str); test(set, 0); printf("now strict\n"); test(set, HWLOC_CPUBIND_STRICT); hwloc_bitmap_free(set); set = hwloc_bitmap_dup(obj->cpuset); hwloc_bitmap_asprintf(&str, set); printf("obj set is %s\n", str); free(str); test(set, 0); printf("now strict\n"); test(set, HWLOC_CPUBIND_STRICT); hwloc_bitmap_singlify(set); hwloc_bitmap_asprintf(&str, set); printf("singlified to %s\n", str); free(str); test(set, 0); printf("now strict\n"); test(set, HWLOC_CPUBIND_STRICT); hwloc_bitmap_free(set); printf("\n\nmemory tests\n\n"); printf("complete node set\n"); set = hwloc_bitmap_dup(hwloc_get_root_obj(topology)->cpuset); hwloc_bitmap_asprintf(&str, set); printf("i.e. cpuset %s\n", str); free(str); testmem3(set); hwloc_bitmap_free(set); obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NODE, 0); if (obj) { set = hwloc_bitmap_dup(obj->cpuset); hwloc_bitmap_asprintf(&str, set); printf("cpuset set is %s\n", str); free(str); testmem3(set); obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NODE, 1); if (obj) { hwloc_bitmap_or(set, set, obj->cpuset); hwloc_bitmap_asprintf(&str, set); printf("cpuset set is %s\n", str); free(str); testmem3(set); } hwloc_bitmap_free(set); } hwloc_topology_destroy(topology); return 0; }
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; }
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; }
PASTIX_INT sopalin_bindthread(PASTIX_INT cpu) { #ifdef MARCEL { marcel_vpset_t vpset = MARCEL_VPSET_ZERO; marcel_vpset_vp(&vpset, cpu); marcel_apply_vpset(&vpset); } #else /* Dans les autres cas on se preoccupe de l'archi */ #ifdef WITH_HWLOC { hwloc_topology_t topology; /* Topology object */ hwloc_obj_t obj; /* Hwloc object */ hwloc_cpuset_t cpuset; /* HwLoc cpuset */ /* Allocate and initialize topology object. */ hwloc_topology_init(&topology); /* Perform the topology detection. */ hwloc_topology_load(topology); /* Get last one. */ obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_CORE, cpu); if (!obj) return 0; /* Get a copy of its cpuset that we may modify. */ /* Get only one logical processor (in case the core is SMT/hyperthreaded). */ #if !defined(HWLOC_BITMAP_H) cpuset = hwloc_cpuset_dup(obj->cpuset); hwloc_cpuset_singlify(cpuset); #else cpuset = hwloc_bitmap_dup(obj->cpuset); hwloc_bitmap_singlify(cpuset); #endif /* And try to bind ourself there. */ if (hwloc_set_cpubind(topology, cpuset, HWLOC_CPUBIND_THREAD)) { char *str = NULL; #if !defined(HWLOC_BITMAP_H) hwloc_cpuset_asprintf(&str, obj->cpuset); #else hwloc_bitmap_asprintf(&str, obj->cpuset); #endif printf("Couldn't bind to cpuset %s\n", str); free(str); } /* Get the number at Proc level */ cpu = obj->children[0]->os_index; /* Free our cpuset copy */ #if !defined(HWLOC_BITMAP_H) hwloc_cpuset_free(cpuset); #else hwloc_bitmap_free(cpuset); #endif /* Destroy topology object. */ hwloc_topology_destroy(topology); } #else /* WITH_HWLOC */ #ifdef X_ARCHpower_ibm_aix { tid_t self_ktid = thread_self (); bindprocessor(BINDTHREAD, self_ktid, cpu); } #elif (defined X_ARCHalpha_compaq_osf1) { bind_to_cpu_id(getpid(), cpu, 0); } #elif (defined X_ARCHi686_pc_linux) #ifndef X_ARCHi686_mac { cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(cpu, &mask); #ifdef HAVE_OLD_SCHED_SETAFFINITY if(sched_setaffinity(0,&mask) < 0) #else /* HAVE_OLD_SCHED_SETAFFINITY */ if(sched_setaffinity(0,sizeof(mask),&mask) < 0) #endif /* HAVE_OLD_SCHED_SETAFFINITY */ { perror("sched_setaffinity"); EXIT(MOD_SOPALIN, INTERNAL_ERR); } } #else /* X_ARCHi686_mac */ { thread_affinity_policy_data_t ap; int ret; ap.affinity_tag = 1; /* non-null affinity tag */ ret = thread_policy_set( mach_thread_self(), THREAD_AFFINITY_POLICY, (integer_t*) &ap, THREAD_AFFINITY_POLICY_COUNT ); if(ret != 0) { perror("thread_policy_set"); EXIT(MOD_SOPALIN, INTERNAL_ERR); } } #endif /* X_ARCHi686_mac */ #endif /* X_ACHIxxx */ #endif /* WITH_HWLOC */ #endif /* MARCEL */ return cpu; }