static void print_task(hwloc_topology_t topology, long pid_number, const char *name, hwloc_bitmap_t cpuset, char *pidoutput, int thread) { printf("%s%ld\t", thread ? " " : "", pid_number); if (show_cpuset) { char *cpuset_str = NULL; hwloc_bitmap_asprintf(&cpuset_str, cpuset); printf("%s", cpuset_str); free(cpuset_str); } else { hwloc_bitmap_t remaining = hwloc_bitmap_dup(cpuset); int first = 1; while (!hwloc_bitmap_iszero(remaining)) { char type[64]; unsigned idx; hwloc_obj_t obj = hwloc_get_first_largest_obj_inside_cpuset(topology, remaining); /* don't show a cache if there's something equivalent and nicer */ while (hwloc_obj_type_is_cache(obj->type) && obj->arity == 1) obj = obj->first_child; hwloc_obj_type_snprintf(type, sizeof(type), obj, 1); idx = logical ? obj->logical_index : obj->os_index; if (idx == (unsigned) -1) printf("%s%s", first ? "" : " ", type); else printf("%s%s:%u", first ? "" : " ", type, idx); hwloc_bitmap_andnot(remaining, remaining, obj->cpuset); first = 0; } hwloc_bitmap_free(remaining); } printf("\t\t%s%s%s\n", name, pidoutput ? "\t" : "", pidoutput ? pidoutput : ""); }
int main(void) { hwloc_topology_t topology; #ifdef HWLOC_HAVE_CPU_SET unsigned depth; hwloc_bitmap_t hwlocset; cpu_set_t schedset; hwloc_obj_t obj; int err; #endif /* HWLOC_HAVE_CPU_SET */ hwloc_topology_init(&topology); hwloc_topology_load(topology); #ifdef HWLOC_HAVE_CPU_SET depth = hwloc_topology_get_depth(topology); hwlocset = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset(topology)); hwloc_cpuset_to_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_setaffinity(0, sizeof(schedset)); #else err = sched_setaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwloc_bitmap_free(hwlocset); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_getaffinity(0, sizeof(schedset)); #else err = sched_getaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwlocset = hwloc_bitmap_alloc(); hwloc_cpuset_from_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); assert(hwloc_bitmap_isincluded(hwlocset, hwloc_topology_get_complete_cpuset(topology))); hwloc_bitmap_andnot(hwlocset, hwlocset, hwloc_topology_get_online_cpuset(topology)); hwloc_bitmap_andnot(hwlocset, hwlocset, hwloc_topology_get_allowed_cpuset(topology)); assert(hwloc_bitmap_iszero(hwlocset)); hwloc_bitmap_free(hwlocset); obj = hwloc_get_obj_by_depth(topology, depth-1, hwloc_get_nbobjs_by_depth(topology, depth-1) - 1); assert(obj); assert(obj->type == HWLOC_OBJ_PU); hwlocset = hwloc_bitmap_dup(obj->cpuset); hwloc_cpuset_to_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_setaffinity(0, sizeof(schedset)); #else err = sched_setaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwloc_bitmap_free(hwlocset); #ifdef HWLOC_HAVE_OLD_SCHED_SETAFFINITY err = sched_getaffinity(0, sizeof(schedset)); #else err = sched_getaffinity(0, sizeof(schedset), &schedset); #endif assert(!err); hwlocset = hwloc_bitmap_alloc(); hwloc_cpuset_from_glibc_sched_affinity(topology, hwlocset, &schedset, sizeof(schedset)); assert(hwloc_bitmap_isequal(hwlocset, obj->cpuset)); hwloc_bitmap_free(hwlocset); #endif /* HWLOC_HAVE_CPU_SET */ hwloc_topology_destroy(topology); return 0; }
void output_console(struct lstopo_output *loutput, const char *filename) { hwloc_topology_t topology = loutput->topology; unsigned topodepth; int verbose_mode = loutput->verbose_mode; int logical = loutput->logical; FILE *output; output = open_output(filename, loutput->overwrite); if (!output) { fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno)); return; } topodepth = hwloc_topology_get_depth(topology); /* * if verbose_mode == 0, only print the summary. * if verbose_mode == 1, only print the topology tree. * if verbose_mode > 1, print both. */ if (lstopo_show_only != (hwloc_obj_type_t)-1) { if (verbose_mode > 1) fprintf(output, "Only showing %s objects\n", hwloc_obj_type_string(lstopo_show_only)); output_only (topology, hwloc_get_root_obj(topology), output, logical, verbose_mode); } else if (verbose_mode >= 1) { output_topology (topology, hwloc_get_root_obj(topology), NULL, output, 0, logical, verbose_mode); fprintf(output, "\n"); } if ((verbose_mode > 1 || !verbose_mode) && lstopo_show_only == (hwloc_obj_type_t)-1) { hwloc_lstopo_show_summary(output, topology); } if (verbose_mode > 1 && lstopo_show_only == (hwloc_obj_type_t)-1) { const struct hwloc_distances_s * distances; unsigned depth; for (depth = 0; depth < topodepth; depth++) { distances = hwloc_get_whole_distance_matrix_by_depth(topology, depth); if (!distances || !distances->latency) continue; fprintf(output, "relative latency matrix between %ss (depth %u) by %s indexes:\n", hwloc_obj_type_string(hwloc_get_depth_type(topology, depth)), depth, logical ? "logical" : "physical"); hwloc_utils_print_distance_matrix(output, topology, hwloc_get_root_obj(topology), distances->nbobjs, depth, distances->latency, logical); } } if (verbose_mode > 1 && lstopo_show_only == (hwloc_obj_type_t)-1) { hwloc_const_bitmap_t complete = hwloc_topology_get_complete_cpuset(topology); hwloc_const_bitmap_t topo = hwloc_topology_get_topology_cpuset(topology); hwloc_const_bitmap_t allowed = hwloc_topology_get_allowed_cpuset(topology); if (!hwloc_bitmap_isequal(topo, complete)) { hwloc_bitmap_t unknown = hwloc_bitmap_alloc(); char *unknownstr; hwloc_bitmap_copy(unknown, complete); hwloc_bitmap_andnot(unknown, unknown, topo); hwloc_bitmap_asprintf(&unknownstr, unknown); fprintf (output, "%d processors not represented in topology: %s\n", hwloc_bitmap_weight(unknown), unknownstr); free(unknownstr); hwloc_bitmap_free(unknown); } if (!hwloc_bitmap_isequal(topo, allowed)) { hwloc_bitmap_t disallowed = hwloc_bitmap_alloc(); char *disallowedstr; hwloc_bitmap_copy(disallowed, topo); hwloc_bitmap_andnot(disallowed, disallowed, allowed); hwloc_bitmap_asprintf(&disallowedstr, disallowed); fprintf(output, "%d processors represented but not allowed: %s\n", hwloc_bitmap_weight(disallowed), disallowedstr); free(disallowedstr); hwloc_bitmap_free(disallowed); } if (!hwloc_topology_is_thissystem(topology)) fprintf (output, "Topology not from this system\n"); } if (output != stdout) fclose(output); }
void output_console(hwloc_topology_t topology, const char *filename, int logical, int legend __hwloc_attribute_unused, int verbose_mode) { unsigned topodepth; FILE *output; if (!filename || !strcmp(filename, "-")) output = stdout; else { output = open_file(filename, "w"); if (!output) { fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno)); return; } } topodepth = hwloc_topology_get_depth(topology); /* * if verbose_mode == 0, only print the summary. * if verbose_mode == 1, only print the topology tree. * if verbose_mode > 1, print both. */ if (lstopo_show_only != (hwloc_obj_type_t)-1) { if (verbose_mode > 1) fprintf(output, "Only showing %s objects\n", hwloc_obj_type_string(lstopo_show_only)); output_only (topology, hwloc_get_root_obj(topology), output, logical, verbose_mode); } else if (verbose_mode >= 1) { output_topology (topology, hwloc_get_root_obj(topology), NULL, output, 0, logical, verbose_mode); fprintf(output, "\n"); } if ((verbose_mode > 1 || !verbose_mode) && lstopo_show_only == (hwloc_obj_type_t)-1) { hwloc_lstopo_show_summary(output, topology); } if (verbose_mode > 1 && lstopo_show_only == (hwloc_obj_type_t)-1) { const struct hwloc_distances_s * distances; unsigned depth; for (depth = 0; depth < topodepth; depth++) { distances = hwloc_get_whole_distance_matrix_by_depth(topology, depth); if (!distances || !distances->latency) continue; printf("latency matrix between %ss (depth %u) by %s indexes:\n", hwloc_obj_type_string(hwloc_get_depth_type(topology, depth)), depth, logical ? "logical" : "physical"); hwloc_utils_print_distance_matrix(topology, hwloc_get_root_obj(topology), distances->nbobjs, depth, distances->latency, logical); } } if (verbose_mode > 1 && lstopo_show_only == (hwloc_obj_type_t)-1) { hwloc_const_bitmap_t complete = hwloc_topology_get_complete_cpuset(topology); hwloc_const_bitmap_t topo = hwloc_topology_get_topology_cpuset(topology); hwloc_const_bitmap_t online = hwloc_topology_get_online_cpuset(topology); hwloc_const_bitmap_t allowed = hwloc_topology_get_allowed_cpuset(topology); if (complete && !hwloc_bitmap_isequal(topo, complete)) { hwloc_bitmap_t unknown = hwloc_bitmap_alloc(); char *unknownstr; hwloc_bitmap_copy(unknown, complete); hwloc_bitmap_andnot(unknown, unknown, topo); hwloc_bitmap_asprintf(&unknownstr, unknown); fprintf (output, "%d processors not represented in topology: %s\n", hwloc_bitmap_weight(unknown), unknownstr); free(unknownstr); hwloc_bitmap_free(unknown); } if (complete && !hwloc_bitmap_isequal(online, complete)) { hwloc_bitmap_t offline = hwloc_bitmap_alloc(); char *offlinestr; hwloc_bitmap_copy(offline, complete); hwloc_bitmap_andnot(offline, offline, online); hwloc_bitmap_asprintf(&offlinestr, offline); fprintf (output, "%d processors offline: %s\n", hwloc_bitmap_weight(offline), offlinestr); free(offlinestr); hwloc_bitmap_free(offline); } if (complete && !hwloc_bitmap_isequal(allowed, online)) { if (!hwloc_bitmap_isincluded(online, allowed)) { hwloc_bitmap_t forbidden = hwloc_bitmap_alloc(); char *forbiddenstr; hwloc_bitmap_copy(forbidden, online); hwloc_bitmap_andnot(forbidden, forbidden, allowed); hwloc_bitmap_asprintf(&forbiddenstr, forbidden); fprintf(output, "%d processors online but not allowed: %s\n", hwloc_bitmap_weight(forbidden), forbiddenstr); free(forbiddenstr); hwloc_bitmap_free(forbidden); } if (!hwloc_bitmap_isincluded(allowed, online)) { hwloc_bitmap_t potential = hwloc_bitmap_alloc(); char *potentialstr; hwloc_bitmap_copy(potential, allowed); hwloc_bitmap_andnot(potential, potential, online); hwloc_bitmap_asprintf(&potentialstr, potential); fprintf(output, "%d processors allowed but not online: %s\n", hwloc_bitmap_weight(potential), potentialstr); free(potentialstr); hwloc_bitmap_free(potential); } } if (!hwloc_topology_is_thissystem(topology)) fprintf (output, "Topology not from this system\n"); } if (output != stdout) fclose(output); }
int main(void) { hwloc_topology_t topology; hwloc_bitmap_t set, set2; hwloc_const_bitmap_t cset_available, cset_all; hwloc_obj_t obj; char *buffer; char type[64]; unsigned i; int err; /* create a topology */ err = hwloc_topology_init(&topology); if (err < 0) { fprintf(stderr, "failed to initialize the topology\n"); return EXIT_FAILURE; } err = hwloc_topology_load(topology); if (err < 0) { fprintf(stderr, "failed to load the topology\n"); hwloc_topology_destroy(topology); return EXIT_FAILURE; } /* retrieve the entire set of available PUs */ cset_available = hwloc_topology_get_topology_cpuset(topology); /* retrieve the CPU binding of the current entire process */ set = hwloc_bitmap_alloc(); if (!set) { fprintf(stderr, "failed to allocate a bitmap\n"); hwloc_topology_destroy(topology); return EXIT_FAILURE; } err = hwloc_get_cpubind(topology, set, HWLOC_CPUBIND_PROCESS); if (err < 0) { fprintf(stderr, "failed to get cpu binding\n"); hwloc_bitmap_free(set); hwloc_topology_destroy(topology); } /* display the processing units that cannot be used by this process */ if (hwloc_bitmap_isequal(set, cset_available)) { printf("this process can use all available processing units in the system\n"); } else { /* compute the set where we currently cannot run. * we can't modify cset_available because it's a system read-only one, * so we do set = available &~ set */ hwloc_bitmap_andnot(set, cset_available, set); hwloc_bitmap_asprintf(&buffer, set); printf("process cannot use %d process units (%s) among %u in the system\n", hwloc_bitmap_weight(set), buffer, hwloc_bitmap_weight(cset_available)); free(buffer); /* restore set where it was before the &~ operation above */ hwloc_bitmap_andnot(set, cset_available, set); } /* print the smallest object covering the current process binding */ obj = hwloc_get_obj_covering_cpuset(topology, set); hwloc_obj_type_snprintf(type, sizeof(type), obj, 0); printf("process is bound within object %s logical index %u\n", type, obj->logical_index); /* retrieve the single PU where the current thread actually runs within this process binding */ set2 = hwloc_bitmap_alloc(); if (!set2) { fprintf(stderr, "failed to allocate a bitmap\n"); hwloc_bitmap_free(set); hwloc_topology_destroy(topology); return EXIT_FAILURE; } err = hwloc_get_last_cpu_location(topology, set2, HWLOC_CPUBIND_THREAD); if (err < 0) { fprintf(stderr, "failed to get last cpu location\n"); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); hwloc_topology_destroy(topology); } /* sanity checks that are not actually needed but help the reader */ /* this thread runs within the process binding */ assert(hwloc_bitmap_isincluded(set2, set)); /* this thread runs on a single PU at a time */ assert(hwloc_bitmap_weight(set2) == 1); /* print the logical number of the PU where that thread runs */ /* extract the PU OS index from the bitmap */ i = hwloc_bitmap_first(set2); obj = hwloc_get_pu_obj_by_os_index(topology, i); printf("thread is now running on PU logical index %u (OS/physical index %u)\n", obj->logical_index, i); /* migrate this single thread to where other PUs within the current binding */ hwloc_bitmap_andnot(set2, set, set2); err = hwloc_set_cpubind(topology, set2, HWLOC_CPUBIND_THREAD); if (err < 0) { fprintf(stderr, "failed to set thread binding\n"); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); hwloc_topology_destroy(topology); } /* reprint the PU where that thread runs */ err = hwloc_get_last_cpu_location(topology, set2, HWLOC_CPUBIND_THREAD); if (err < 0) { fprintf(stderr, "failed to get last cpu location\n"); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); hwloc_topology_destroy(topology); } /* print the logical number of the PU where that thread runs */ /* extract the PU OS index from the bitmap */ i = hwloc_bitmap_first(set2); obj = hwloc_get_pu_obj_by_os_index(topology, i); printf("thread is running on PU logical index %u (OS/physical index %u)\n", obj->logical_index, i); hwloc_bitmap_free(set); hwloc_bitmap_free(set2); /* retrieve the entire set of all PUs */ cset_all = hwloc_topology_get_complete_cpuset(topology); if (hwloc_bitmap_isequal(cset_all, cset_available)) { printf("all hardware PUs are available\n"); } else { printf("only %d hardware PUs are available in the machine among %d\n", hwloc_bitmap_weight(cset_available), hwloc_bitmap_weight(cset_all)); } hwloc_topology_destroy(topology); return EXIT_SUCCESS; }
int main(void) { 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; }