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 hwloc_pci_forced_locality_parse_one(struct hwloc_topology *topology, const char *string /* must contain a ' ' */, unsigned *allocated) { unsigned nr = topology->pci_forced_locality_nr; unsigned domain, bus_first, bus_last, dummy; hwloc_bitmap_t set; char *tmp; if (sscanf(string, "%x:%x-%x %x", &domain, &bus_first, &bus_last, &dummy) == 4) { /* fine */ } else if (sscanf(string, "%x:%x %x", &domain, &bus_first, &dummy) == 3) { bus_last = bus_first; } else if (sscanf(string, "%x %x", &domain, &dummy) == 2) { bus_first = 0; bus_last = 255; } else return; tmp = strchr(string, ' '); if (!tmp) return; tmp++; set = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(set, tmp); if (!*allocated) { topology->pci_forced_locality = malloc(sizeof(*topology->pci_forced_locality)); if (!topology->pci_forced_locality) goto out_with_set; /* failed to allocate, ignore this forced locality */ *allocated = 1; } else if (nr >= *allocated) { struct hwloc_pci_forced_locality_s *tmp; tmp = realloc(topology->pci_forced_locality, 2 * *allocated * sizeof(*topology->pci_forced_locality)); if (!tmp) goto out_with_set; /* failed to allocate, ignore this forced locality */ topology->pci_forced_locality = tmp; *allocated *= 2; } topology->pci_forced_locality[nr].domain = domain; topology->pci_forced_locality[nr].bus_first = bus_first; topology->pci_forced_locality[nr].bus_last = bus_last; topology->pci_forced_locality[nr].cpuset = set; topology->pci_forced_locality_nr++; return; out_with_set: hwloc_bitmap_free(set); return; }
int main (int argc, char *argv[]) { int err; hwloc_topology_t topology; const char *filename = NULL; unsigned long flags = HWLOC_TOPOLOGY_FLAG_IO_DEVICES | HWLOC_TOPOLOGY_FLAG_IO_BRIDGES | HWLOC_TOPOLOGY_FLAG_ICACHES; unsigned long restrict_flags = 0; int merge = 0; int ignorecache = 0; char * callname; char * input = NULL; enum hwloc_utils_input_format input_format = HWLOC_UTILS_INPUT_DEFAULT; enum output_format output_format = LSTOPO_OUTPUT_DEFAULT; char *restrictstring = NULL; struct lstopo_output loutput; int opt; unsigned i; loutput.overwrite = 0; loutput.logical = -1; loutput.legend = 1; loutput.verbose_mode = LSTOPO_VERBOSE_MODE_DEFAULT; for(i=0; i<HWLOC_OBJ_TYPE_MAX; i++) force_orient[i] = LSTOPO_ORIENT_NONE; force_orient[HWLOC_OBJ_PU] = LSTOPO_ORIENT_HORIZ; force_orient[HWLOC_OBJ_CACHE] = LSTOPO_ORIENT_HORIZ; force_orient[HWLOC_OBJ_NUMANODE] = LSTOPO_ORIENT_HORIZ; /* enable verbose backends */ putenv("HWLOC_XML_VERBOSE=1"); putenv("HWLOC_SYNTHETIC_VERBOSE=1"); #ifdef HAVE_SETLOCALE setlocale(LC_ALL, ""); #endif callname = strrchr(argv[0], '/'); if (!callname) callname = argv[0]; else callname++; /* skip argv[0], handle options */ argc--; argv++; err = hwloc_topology_init (&topology); if (err) return EXIT_FAILURE; while (argc >= 1) { opt = 0; if (!strcmp (argv[0], "-v") || !strcmp (argv[0], "--verbose")) { loutput.verbose_mode++; } else if (!strcmp (argv[0], "-s") || !strcmp (argv[0], "--silent")) { loutput.verbose_mode--; } else if (!strcmp (argv[0], "-h") || !strcmp (argv[0], "--help")) { usage(callname, stdout); exit(EXIT_SUCCESS); } else if (!strcmp (argv[0], "-f") || !strcmp (argv[0], "--force")) loutput.overwrite = 1; else if (!strcmp (argv[0], "-l") || !strcmp (argv[0], "--logical")) loutput.logical = 1; else if (!strcmp (argv[0], "-p") || !strcmp (argv[0], "--physical")) loutput.logical = 0; else if (!strcmp (argv[0], "-c") || !strcmp (argv[0], "--cpuset")) lstopo_show_cpuset = 1; else if (!strcmp (argv[0], "-C") || !strcmp (argv[0], "--cpuset-only")) lstopo_show_cpuset = 2; else if (!strcmp (argv[0], "--taskset")) { lstopo_show_taskset = 1; if (!lstopo_show_cpuset) lstopo_show_cpuset = 1; } else if (!strcmp (argv[0], "--only")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } if (hwloc_obj_type_sscanf(argv[1], &lstopo_show_only, NULL, NULL, 0) < 0) fprintf(stderr, "Unsupported type `%s' passed to --only, ignoring.\n", argv[1]); opt = 1; } else if (!strcmp (argv[0], "--ignore")) { hwloc_obj_type_t type; if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } if (hwloc_obj_type_sscanf(argv[1], &type, NULL, NULL, 0) < 0) fprintf(stderr, "Unsupported type `%s' passed to --ignore, ignoring.\n", argv[1]); else if (type == HWLOC_OBJ_PU) lstopo_ignore_pus = 1; else hwloc_topology_ignore_type(topology, type); opt = 1; } else if (!strcmp (argv[0], "--no-caches")) ignorecache = 2; else if (!strcmp (argv[0], "--no-useless-caches")) ignorecache = 1; else if (!strcmp (argv[0], "--no-icaches")) flags &= ~HWLOC_TOPOLOGY_FLAG_ICACHES; else if (!strcmp (argv[0], "--whole-system")) flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM; else if (!strcmp (argv[0], "--no-io")) flags &= ~(HWLOC_TOPOLOGY_FLAG_IO_DEVICES | HWLOC_TOPOLOGY_FLAG_IO_BRIDGES); else if (!strcmp (argv[0], "--no-bridges")) flags &= ~(HWLOC_TOPOLOGY_FLAG_IO_BRIDGES); else if (!strcmp (argv[0], "--whole-io")) flags |= HWLOC_TOPOLOGY_FLAG_WHOLE_IO; else if (!strcmp (argv[0], "--merge")) merge = 1; else if (!strcmp (argv[0], "--no-collapse")) lstopo_collapse = 0; else if (!strcmp (argv[0], "--thissystem")) flags |= HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM; else if (!strcmp (argv[0], "--restrict")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } restrictstring = strdup(argv[1]); opt = 1; } else if (!strcmp (argv[0], "--restrict-flags")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } restrict_flags = (unsigned long) strtoull(argv[1], NULL, 0); opt = 1; } else if (!strcmp (argv[0], "--export-synthetic-flags")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } lstopo_export_synthetic_flags = (unsigned long) strtoull(argv[1], NULL, 0); opt = 1; } else if (!strcmp (argv[0], "--horiz")) for(i=0; i<HWLOC_OBJ_TYPE_MAX; i++) force_orient[i] = LSTOPO_ORIENT_HORIZ; else if (!strcmp (argv[0], "--vert")) for(i=0; i<HWLOC_OBJ_TYPE_MAX; i++) force_orient[i] = LSTOPO_ORIENT_VERT; else if (!strcmp (argv[0], "--rect")) for(i=0; i<HWLOC_OBJ_TYPE_MAX; i++) force_orient[i] = LSTOPO_ORIENT_RECT; else if (!strncmp (argv[0], "--horiz=", 8) || !strncmp (argv[0], "--vert=", 7) || !strncmp (argv[0], "--rect=", 7)) { enum lstopo_orient_e orient = (argv[0][2] == 'h') ? LSTOPO_ORIENT_HORIZ : (argv[0][2] == 'v') ? LSTOPO_ORIENT_VERT : LSTOPO_ORIENT_RECT; char *tmp = argv[0] + ((argv[0][2] == 'h') ? 8 : 7); while (tmp) { char *end = strchr(tmp, ','); hwloc_obj_type_t type; if (end) *end = '\0'; if (hwloc_obj_type_sscanf(tmp, &type, NULL, NULL, 0) < 0) fprintf(stderr, "Unsupported type `%s' passed to %s, ignoring.\n", tmp, argv[0]); else force_orient[type] = orient; if (!end) break; tmp = end+1; } } else if (!strcmp (argv[0], "--fontsize")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } fontsize = atoi(argv[1]); opt = 1; } else if (!strcmp (argv[0], "--gridsize")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } gridsize = atoi(argv[1]); opt = 1; } else if (!strcmp (argv[0], "--no-legend")) { loutput.legend = 0; } else if (!strcmp (argv[0], "--append-legend")) { char **tmp; if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } tmp = realloc(lstopo_append_legends, (lstopo_append_legends_nr+1) * sizeof(*lstopo_append_legends)); if (!tmp) { fprintf(stderr, "Failed to realloc legend append array, legend ignored.\n"); } else { lstopo_append_legends = tmp; lstopo_append_legends[lstopo_append_legends_nr] = strdup(argv[1]); lstopo_append_legends_nr++; } opt = 1; } else if (hwloc_utils_lookup_input_option(argv, argc, &opt, &input, &input_format, callname)) { /* nothing to do anymore */ } else if (!strcmp (argv[0], "--pid")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } lstopo_pid_number = atoi(argv[1]); opt = 1; } else if (!strcmp (argv[0], "--ps") || !strcmp (argv[0], "--top")) top = 1; else if (!strcmp (argv[0], "--version")) { printf("%s %s\n", callname, HWLOC_VERSION); exit(EXIT_SUCCESS); } else if (!strcmp (argv[0], "--output-format") || !strcmp (argv[0], "--of")) { if (argc < 2) { usage (callname, stderr); exit(EXIT_FAILURE); } output_format = parse_output_format(argv[1], callname); opt = 1; } else { if (filename) { fprintf (stderr, "Unrecognized option: %s\n", argv[0]); usage (callname, stderr); exit(EXIT_FAILURE); } else filename = argv[0]; } argc -= opt+1; argv += opt+1; } if (lstopo_show_only != (hwloc_obj_type_t)-1) merge = 0; hwloc_topology_set_flags(topology, flags); if (ignorecache > 1) { hwloc_topology_ignore_type(topology, HWLOC_OBJ_CACHE); } else if (ignorecache) { hwloc_topology_ignore_type_keep_structure(topology, HWLOC_OBJ_CACHE); } if (merge) hwloc_topology_ignore_all_keep_structure(topology); if (input) { err = hwloc_utils_enable_input_format(topology, input, &input_format, loutput.verbose_mode > 1, callname); if (err) return err; } if (lstopo_pid_number > 0) { lstopo_pid = hwloc_pid_from_number(lstopo_pid_number, 0); if (hwloc_topology_set_pid(topology, lstopo_pid)) { perror("Setting target pid"); return EXIT_FAILURE; } } /* if the output format wasn't enforced, look at the filename */ if (filename && output_format == LSTOPO_OUTPUT_DEFAULT) { if (!strcmp(filename, "-") || !strcmp(filename, "/dev/stdout")) { output_format = LSTOPO_OUTPUT_CONSOLE; } else { char *dot = strrchr(filename, '.'); if (dot) output_format = parse_output_format(dot+1, callname); else { fprintf(stderr, "Cannot infer output type for file `%s' without any extension, using default output.\n", filename); filename = NULL; } } } /* if the output format wasn't enforced, think a bit about what the user probably want */ if (output_format == LSTOPO_OUTPUT_DEFAULT) { if (lstopo_show_cpuset || lstopo_show_only != (hwloc_obj_type_t)-1 || loutput.verbose_mode != LSTOPO_VERBOSE_MODE_DEFAULT) output_format = LSTOPO_OUTPUT_CONSOLE; } if (input_format == HWLOC_UTILS_INPUT_XML && output_format == LSTOPO_OUTPUT_XML) { /* must be after parsing output format and before loading the topology */ putenv("HWLOC_XML_USERDATA_NOT_DECODED=1"); hwloc_topology_set_userdata_import_callback(topology, hwloc_utils_userdata_import_cb); hwloc_topology_set_userdata_export_callback(topology, hwloc_utils_userdata_export_cb); } err = hwloc_topology_load (topology); if (err) { fprintf(stderr, "hwloc_topology_load() failed (%s).\n", strerror(errno)); return EXIT_FAILURE; } if (top) add_process_objects(topology); if (restrictstring) { hwloc_bitmap_t restrictset = hwloc_bitmap_alloc(); if (!strcmp (restrictstring, "binding")) { if (lstopo_pid_number > 0) hwloc_get_proc_cpubind(topology, lstopo_pid, restrictset, HWLOC_CPUBIND_PROCESS); else hwloc_get_cpubind(topology, restrictset, HWLOC_CPUBIND_PROCESS); } else { hwloc_bitmap_sscanf(restrictset, restrictstring); } err = hwloc_topology_restrict (topology, restrictset, restrict_flags); if (err) { perror("Restricting the topology"); /* fallthrough */ } hwloc_bitmap_free(restrictset); free(restrictstring); } if (loutput.logical == -1) { if (output_format == LSTOPO_OUTPUT_CONSOLE) loutput.logical = 1; else if (output_format != LSTOPO_OUTPUT_DEFAULT) loutput.logical = 0; } loutput.topology = topology; loutput.file = NULL; lstopo_populate_userdata(hwloc_get_root_obj(topology)); if (output_format != LSTOPO_OUTPUT_XML && lstopo_collapse) lstopo_add_collapse_attributes(topology); switch (output_format) { case LSTOPO_OUTPUT_DEFAULT: #ifdef LSTOPO_HAVE_GRAPHICS #if CAIRO_HAS_XLIB_SURFACE && defined HWLOC_HAVE_X11_KEYSYM if (getenv("DISPLAY")) { if (loutput.logical == -1) loutput.logical = 0; output_x11(&loutput, NULL); } else #endif /* CAIRO_HAS_XLIB_SURFACE */ #ifdef HWLOC_WIN_SYS { if (loutput.logical == -1) loutput.logical = 0; output_windows(&loutput, NULL); } #endif #endif /* !LSTOPO_HAVE_GRAPHICS */ #if !defined HWLOC_WIN_SYS || !defined LSTOPO_HAVE_GRAPHICS { if (loutput.logical == -1) loutput.logical = 1; output_console(&loutput, NULL); } #endif break; case LSTOPO_OUTPUT_CONSOLE: output_console(&loutput, filename); break; case LSTOPO_OUTPUT_SYNTHETIC: output_synthetic(&loutput, filename); break; case LSTOPO_OUTPUT_ASCII: output_ascii(&loutput, filename); break; case LSTOPO_OUTPUT_FIG: output_fig(&loutput, filename); break; #ifdef LSTOPO_HAVE_GRAPHICS # if CAIRO_HAS_PNG_FUNCTIONS case LSTOPO_OUTPUT_PNG: output_png(&loutput, filename); break; # endif /* CAIRO_HAS_PNG_FUNCTIONS */ # if CAIRO_HAS_PDF_SURFACE case LSTOPO_OUTPUT_PDF: output_pdf(&loutput, filename); break; # endif /* CAIRO_HAS_PDF_SURFACE */ # if CAIRO_HAS_PS_SURFACE case LSTOPO_OUTPUT_PS: output_ps(&loutput, filename); break; #endif /* CAIRO_HAS_PS_SURFACE */ #if CAIRO_HAS_SVG_SURFACE case LSTOPO_OUTPUT_SVG: output_svg(&loutput, filename); break; #endif /* CAIRO_HAS_SVG_SURFACE */ #endif /* LSTOPO_HAVE_GRAPHICS */ case LSTOPO_OUTPUT_XML: output_xml(&loutput, filename); break; default: fprintf(stderr, "file format not supported\n"); usage(callname, stderr); exit(EXIT_FAILURE); } lstopo_destroy_userdata(hwloc_get_root_obj(topology)); hwloc_utils_userdata_free_recursive(hwloc_get_root_obj(topology)); hwloc_topology_destroy (topology); for(i=0; i<lstopo_append_legends_nr; i++) free(lstopo_append_legends[i]); free(lstopo_append_legends); return EXIT_SUCCESS; }
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; }
int main (void) { hwloc_topology_t topology; hwloc_bitmap_t set; hwloc_obj_t obj; int depth; int err; set = hwloc_bitmap_alloc(); err = hwloc_topology_init (&topology); if (err) return EXIT_FAILURE; hwloc_topology_set_synthetic (topology, "pack:8 cores:2 1"); err = hwloc_topology_load (topology); if (err) return EXIT_FAILURE; hwloc_bitmap_sscanf(set, "00008f18"); obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PACKAGE, NULL); assert(obj == hwloc_get_obj_by_depth(topology, 1, 1)); obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PACKAGE, obj); assert(obj == hwloc_get_obj_by_depth(topology, 1, 2)); obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PACKAGE, obj); assert(obj == hwloc_get_obj_by_depth(topology, 1, 4)); obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PACKAGE, obj); assert(obj == hwloc_get_obj_by_depth(topology, 1, 5)); obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PACKAGE, obj); assert(obj == hwloc_get_obj_by_depth(topology, 1, 7)); obj = hwloc_get_next_obj_covering_cpuset_by_type(topology, set, HWLOC_OBJ_PACKAGE, obj); assert(!obj); hwloc_topology_destroy (topology); err = hwloc_topology_init (&topology); if (err) return EXIT_FAILURE; hwloc_topology_set_synthetic (topology, "nodes:2 pack:5 cores:3 4"); err = hwloc_topology_load (topology); if (err) return EXIT_FAILURE; hwloc_bitmap_sscanf(set, "0ff08000"); depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PACKAGE); assert(depth == 2); obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, NULL); assert(obj == hwloc_get_obj_by_depth(topology, depth, 1)); obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, obj); assert(obj == hwloc_get_obj_by_depth(topology, depth, 2)); obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, obj); assert(!obj); hwloc_topology_destroy (topology); hwloc_bitmap_free(set); return EXIT_SUCCESS; }
int main(void) { hwloc_topology_t topology; unsigned depth; hwloc_obj_t objs[OBJ_MAX]; hwloc_obj_t obj; hwloc_bitmap_t set; int ret; hwloc_topology_init(&topology); hwloc_topology_set_synthetic(topology, SYNTHETIC_TOPOLOGY_DESCRIPTION); hwloc_topology_load(topology); depth = hwloc_topology_get_depth(topology); /* just get the system object */ obj = hwloc_get_root_obj(topology); ret = hwloc_get_largest_objs_inside_cpuset(topology, obj->cpuset, objs, 1); assert(ret == 1); assert(objs[0] == obj); objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, obj->cpuset); assert(objs[0] == obj); /* just get the very last object */ obj = hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1)-1); ret = hwloc_get_largest_objs_inside_cpuset(topology, obj->cpuset, objs, 1); assert(ret == 1); assert(objs[0] == obj); /* try an empty one */ set = hwloc_bitmap_alloc(); ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 1); assert(ret == 0); objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set); assert(objs[0] == NULL); hwloc_bitmap_free(set); /* try an impossible one */ set = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(set, GIVEN_TOOLARGE_CPUSET_STRING); ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 1); assert(ret == -1); objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set); assert(objs[0] == NULL); hwloc_bitmap_free(set); /* try a harder one with 1 obj instead of 2 needed */ set = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(set, GIVEN_LARGESPLIT_CPUSET_STRING); ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 1); assert(ret == 1); assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0)); objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set); assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0)); /* try a harder one with lots of objs instead of 2 needed */ ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, 2); assert(ret == 2); assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0)); assert(objs[1] == hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1)-1)); objs[0] = hwloc_get_first_largest_obj_inside_cpuset(topology, set); hwloc_bitmap_andnot(set, set, objs[0]->cpuset); objs[1] = hwloc_get_first_largest_obj_inside_cpuset(topology, set); hwloc_bitmap_andnot(set, set, objs[1]->cpuset); objs[2] = hwloc_get_first_largest_obj_inside_cpuset(topology, set); assert(objs[0] == hwloc_get_obj_by_depth(topology, depth-1, 0)); assert(objs[1] == hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1)-1)); assert(objs[2] == NULL); assert(hwloc_bitmap_iszero(set)); hwloc_bitmap_free(set); /* try a very hard one */ set = hwloc_bitmap_alloc(); hwloc_bitmap_sscanf(set, GIVEN_HARD_CPUSET_STRING); ret = hwloc_get_largest_objs_inside_cpuset(topology, set, objs, OBJ_MAX); assert(objs[0] == hwloc_get_obj_by_depth(topology, 5, 29)); assert(objs[1] == hwloc_get_obj_by_depth(topology, 3, 5)); assert(objs[2] == hwloc_get_obj_by_depth(topology, 3, 6)); assert(objs[3] == hwloc_get_obj_by_depth(topology, 3, 7)); assert(objs[4] == hwloc_get_obj_by_depth(topology, 2, 2)); assert(objs[5] == hwloc_get_obj_by_depth(topology, 4, 36)); assert(objs[6] == hwloc_get_obj_by_depth(topology, 5, 74)); hwloc_bitmap_free(set); hwloc_topology_destroy(topology); return EXIT_SUCCESS; }