int hwloc_get_obj_depth_by_name(hwloc_topology_t topology, char * obj_name){ /* find hwloc obj depth */ hwloc_obj_type_t type; int depthattrp; hwloc_obj_cache_type_t cache_type; if(hwloc_obj_type_sscanf(obj_name,&type,&depthattrp,&cache_type,sizeof(cache_type))==-1){ fprintf(stderr,"type \"%s\" was not recognized\n",obj_name); return -1; } int depth = hwloc_get_type_depth(topology,type); if(depth==HWLOC_TYPE_DEPTH_MULTIPLE){ if(type==HWLOC_OBJ_CACHE){ depth = hwloc_get_cache_type_depth(topology,depthattrp,cache_type); if(depth == HWLOC_TYPE_DEPTH_UNKNOWN){ fprintf(stderr,"type %s cannot be found, level=%d\n",obj_name,depthattrp); return -1; } if(depth == HWLOC_TYPE_DEPTH_MULTIPLE){ fprintf(stderr,"type %s multiple caches match for\n",obj_name); return -1; } } else{ fprintf(stderr,"type \"%s\" isn't handled...\n",obj_name); return -1; } } return depth; }
void check_hwloc_obj_name(char * obj_name) { hwloc_obj_type_t typep; int depthattrp; char typeattrp[sizeof(hwloc_obj_cache_type_t)]; if(hwloc_obj_type_sscanf(obj_name, &typep, &depthattrp, typeattrp, sizeof(hwloc_obj_cache_type_t))==-1){ fprintf(stderr,"Wrong hwloc_obj name: %s\n",obj_name); fprintf(stderr,"Available objs are:\n"); dump_avail(get_avail_hwloc_objs_names); exit(1); } }
static void hwloc_synthetic_process_level_indexes(struct hwloc_synthetic_backend_data_s *data, unsigned curleveldepth, int verbose) { struct hwloc_synthetic_level_data_s *curlevel = &data->level[curleveldepth]; unsigned long total = curlevel->totalwidth; const char *attr = curlevel->index_string; unsigned long length = curlevel->index_string_length; unsigned *array = NULL; struct hwloc_synthetic_intlv_loop_s * loops = NULL; size_t i; if (!attr) return; array = calloc(total, sizeof(*array)); if (!array) { if (verbose) fprintf(stderr, "Failed to allocate synthetic index array of size %lu\n", total); goto out; } i = strspn(attr, "0123456789,"); if (i == length) { /* explicit array of indexes */ for(i=0; i<total; i++) { const char *next; unsigned idx = strtoul(attr, (char **) &next, 10); if (next == attr) { if (verbose) fprintf(stderr, "Failed to read synthetic index #%lu at '%s'\n", (unsigned long) i, attr); goto out_with_array; } array[i] = idx; if (i != total-1) { if (*next != ',') { if (verbose) fprintf(stderr, "Missing comma after synthetic index #%lu at '%s'\n", (unsigned long) i, attr); goto out_with_array; } attr = next+1; } else { attr = next; } } curlevel->index_array = array; } else { /* interleaving */ unsigned nr_loops = 1, cur_loop; unsigned minstep = total; unsigned long nbs = 1; unsigned j, mul; const char *tmp; tmp = attr; while (tmp) { tmp = strchr(tmp, ':'); if (!tmp || tmp >= attr+length) break; nr_loops++; tmp++; } /* nr_loops colon-separated fields, but we may need one more at the end */ loops = malloc((nr_loops+1)*sizeof(*loops)); if (!loops) { if (verbose) fprintf(stderr, "Failed to allocate synthetic index interleave loop array of size %u\n", nr_loops); goto out_with_array; } if (*attr >= '0' && *attr <= '9') { /* interleaving as x*y:z*t:... */ unsigned step, nb; tmp = attr; cur_loop = 0; while (tmp) { char *tmp2, *tmp3; step = (unsigned) strtol(tmp, &tmp2, 0); if (tmp2 == tmp || *tmp2 != '*') { if (verbose) fprintf(stderr, "Failed to read synthetic index interleaving loop '%s' without number before '*'\n", tmp); goto out_with_loops; } if (!step) { if (verbose) fprintf(stderr, "Invalid interleaving loop with step 0 at '%s'\n", tmp); goto out_with_loops; } tmp2++; nb = (unsigned) strtol(tmp2, &tmp3, 0); if (tmp3 == tmp2 || (*tmp3 && *tmp3 != ':' && *tmp3 != ')' && *tmp3 != ' ')) { if (verbose) fprintf(stderr, "Failed to read synthetic index interleaving loop '%s' without number between '*' and ':'\n", tmp); goto out_with_loops; } if (!nb) { if (verbose) fprintf(stderr, "Invalid interleaving loop with number 0 at '%s'\n", tmp2); goto out_with_loops; } loops[cur_loop].step = step; loops[cur_loop].nb = nb; if (step < minstep) minstep = step; nbs *= nb; cur_loop++; if (*tmp3 == ')' || *tmp3 == ' ') break; tmp = (const char*) (tmp3+1); } } else { /* interleaving as type1:type2:... */ hwloc_obj_type_t type; hwloc_obj_cache_type_t cachetypeattr; int depthattr; int err; /* find level depths for each interleaving loop */ tmp = attr; cur_loop = 0; while (tmp) { err = hwloc_obj_type_sscanf(tmp, &type, &depthattr, &cachetypeattr, sizeof(cachetypeattr)); if (err < 0) { if (verbose) fprintf(stderr, "Failed to read synthetic index interleaving loop type '%s'\n", tmp); goto out_with_loops; } if (type == HWLOC_OBJ_MISC || type == HWLOC_OBJ_BRIDGE || type == HWLOC_OBJ_PCI_DEVICE || type == HWLOC_OBJ_OS_DEVICE) { if (verbose) fprintf(stderr, "Misc object type disallowed in synthetic index interleaving loop type '%s'\n", tmp); goto out_with_loops; } for(i=0; i<curleveldepth; i++) { if (type != data->level[i].type) continue; if ((type == HWLOC_OBJ_GROUP || type == HWLOC_OBJ_CACHE) && depthattr != -1 && (unsigned) depthattr != data->level[i].depth) continue; if (type == HWLOC_OBJ_CACHE && cachetypeattr != (hwloc_obj_cache_type_t) -1 && cachetypeattr != data->level[i].cachetype) continue; loops[cur_loop].level_depth = (unsigned)i; break; } if (i == curleveldepth) { if (verbose) fprintf(stderr, "Failed to find level for synthetic index interleaving loop type '%s' above '%s'\n", tmp, hwloc_obj_type_string(curlevel->type)); goto out_with_loops; } tmp = strchr(tmp, ':'); if (!tmp || tmp > attr+length) break; tmp++; cur_loop++; } /* compute actual loop step/nb */ for(cur_loop=0; cur_loop<nr_loops; cur_loop++) { unsigned mydepth = loops[cur_loop].level_depth; unsigned prevdepth = 0; unsigned step, nb; for(i=0; i<nr_loops; i++) { if (loops[i].level_depth == mydepth && i != cur_loop) { if (verbose) fprintf(stderr, "Invalid duplicate interleaving loop type in synthetic index '%s'\n", attr); goto out_with_loops; } if (loops[i].level_depth < mydepth && loops[i].level_depth > prevdepth) prevdepth = loops[i].level_depth; } step = curlevel->totalwidth / data->level[mydepth].totalwidth; /* number of objects below us */ nb = data->level[mydepth].totalwidth / data->level[prevdepth].totalwidth; /* number of us within parent */ loops[cur_loop].step = step; loops[cur_loop].nb = nb; assert(nb); assert(step); if (step < minstep) minstep = step; nbs *= nb; } } assert(nbs); if (nbs != total) { /* one loop of total/nbs steps is missing, add it if it's just the smallest one */ if (minstep == total/nbs) { loops[nr_loops].step = 1; loops[nr_loops].nb = total/nbs; nr_loops++; } else { if (verbose) fprintf(stderr, "Invalid index interleaving total width %lu instead of %lu\n", nbs, total); goto out_with_loops; } } /* generate the array of indexes */ mul = 1; for(i=0; i<nr_loops; i++) { unsigned step = loops[i].step; unsigned nb = loops[i].nb; for(j=0; j<total; j++) array[j] += ((j / step) % nb) * mul; mul *= nb; } /* check that we have the right values (cannot pass total, cannot give duplicate 0) */ for(j=0; j<total; j++) { if (array[j] >= total) { if (verbose) fprintf(stderr, "Invalid index interleaving generates out-of-range index %u\n", array[j]); goto out_with_loops; } if (!array[j] && j) { if (verbose) fprintf(stderr, "Invalid index interleaving generates duplicate index values\n"); goto out_with_loops; } } free(loops); curlevel->index_array = array; } return; out_with_loops: free(loops); out_with_array: free(array); out: return; }
/* Read from description a series of integers describing a symmetrical topology and update the hwloc_synthetic_backend_data_s accordingly. On success, return zero. */ static int hwloc_backend_synthetic_init(struct hwloc_synthetic_backend_data_s *data, const char *description) { const char *pos, *next_pos; unsigned long item, count; unsigned i; int cache_depth = 0, group_depth = 0; int nb_machine_levels = 0, nb_node_levels = 0; int nb_pu_levels = 0; int verbose = 0; const char *env = getenv("HWLOC_SYNTHETIC_VERBOSE"); int err; unsigned long totalarity = 1; if (env) verbose = atoi(env); /* default values before we add root attributes */ data->level[0].totalwidth = 1; data->level[0].type = HWLOC_OBJ_MACHINE; data->level[0].index_string = NULL; data->level[0].index_array = NULL; data->level[0].memorysize = 0; if (*description == '(') { err = hwloc_synthetic_parse_level_attrs(description+1, &description, &data->level[0], verbose); if (err < 0) return err; } for (pos = description, count = 1; *pos; pos = next_pos) { #define HWLOC_OBJ_TYPE_UNKNOWN ((hwloc_obj_type_t) -1) hwloc_obj_type_t type = HWLOC_OBJ_TYPE_UNKNOWN; int typedepth = -1; hwloc_obj_cache_type_t cachetype = (hwloc_obj_cache_type_t) -1; /* initialize parent arity to 0 so that the levels are not infinite */ data->level[count-1].arity = 0; while (*pos == ' ') pos++; if (!*pos) break; if (*pos < '0' || *pos > '9') { if (hwloc_obj_type_sscanf(pos, &type, &typedepth, &cachetype, sizeof(cachetype)) < 0) { if (verbose) fprintf(stderr, "Synthetic string with unknown object type at '%s'\n", pos); errno = EINVAL; goto error; } if (type == HWLOC_OBJ_SYSTEM || type == HWLOC_OBJ_MISC || type == HWLOC_OBJ_BRIDGE || type == HWLOC_OBJ_PCI_DEVICE || type == HWLOC_OBJ_OS_DEVICE) { if (verbose) fprintf(stderr, "Synthetic string with disallowed object type at '%s'\n", pos); errno = EINVAL; goto error; } next_pos = strchr(pos, ':'); if (!next_pos) { if (verbose) fprintf(stderr,"Synthetic string doesn't have a `:' after object type at '%s'\n", pos); errno = EINVAL; goto error; } pos = next_pos + 1; } data->level[count].type = type; data->level[count].depth = (unsigned) typedepth; data->level[count].cachetype = cachetype; item = strtoul(pos, (char **)&next_pos, 0); if (next_pos == pos) { if (verbose) fprintf(stderr,"Synthetic string doesn't have a number of objects at '%s'\n", pos); errno = EINVAL; goto error; } if (!item) { if (verbose) fprintf(stderr,"Synthetic string with disallow 0 number of objects at '%s'\n", pos); errno = EINVAL; goto error; } totalarity *= item; data->level[count].totalwidth = totalarity; data->level[count].index_string = NULL; data->level[count].index_array = NULL; data->level[count].memorysize = 0; if (*next_pos == '(') { err = hwloc_synthetic_parse_level_attrs(next_pos+1, &next_pos, &data->level[count], verbose); if (err < 0) goto error; } if (count + 1 >= HWLOC_SYNTHETIC_MAX_DEPTH) { if (verbose) fprintf(stderr,"Too many synthetic levels, max %d\n", HWLOC_SYNTHETIC_MAX_DEPTH); errno = EINVAL; goto error; } if (item > UINT_MAX) { if (verbose) fprintf(stderr,"Too big arity, max %u\n", UINT_MAX); errno = EINVAL; goto error; } data->level[count-1].arity = (unsigned)item; count++; } if (count <= 0) { if (verbose) fprintf(stderr, "Synthetic string doesn't contain any object\n"); errno = EINVAL; goto error; } for(i=count-1; i>0; i--) { struct hwloc_synthetic_level_data_s *curlevel = &data->level[i]; hwloc_obj_type_t type; type = curlevel->type; if (i == count-1 && type != HWLOC_OBJ_TYPE_UNKNOWN && type != HWLOC_OBJ_PU) { if (verbose) fprintf(stderr, "Synthetic string cannot use non-PU type for last level\n"); errno = EINVAL; return -1; } if (i != count-1 && type == HWLOC_OBJ_PU) { if (verbose) fprintf(stderr, "Synthetic string cannot use PU type for non-last level\n"); errno = EINVAL; return -1; } if (type == HWLOC_OBJ_TYPE_UNKNOWN) { if (i == count-1) type = HWLOC_OBJ_PU; else { switch (data->level[i+1].type) { case HWLOC_OBJ_PU: type = HWLOC_OBJ_CORE; break; case HWLOC_OBJ_CORE: type = HWLOC_OBJ_CACHE; break; case HWLOC_OBJ_CACHE: type = HWLOC_OBJ_PACKAGE; break; case HWLOC_OBJ_PACKAGE: type = HWLOC_OBJ_NUMANODE; break; case HWLOC_OBJ_NUMANODE: case HWLOC_OBJ_MACHINE: case HWLOC_OBJ_GROUP: type = HWLOC_OBJ_GROUP; break; default: assert(0); } } curlevel->type = type; } switch (type) { case HWLOC_OBJ_PU: nb_pu_levels++; break; case HWLOC_OBJ_CACHE: cache_depth++; break; case HWLOC_OBJ_GROUP: group_depth++; break; case HWLOC_OBJ_NUMANODE: nb_node_levels++; break; case HWLOC_OBJ_MACHINE: nb_machine_levels++; break; default: break; } } if (!nb_pu_levels) { if (verbose) fprintf(stderr, "Synthetic string missing ending number of PUs\n"); errno = EINVAL; return -1; } if (nb_pu_levels > 1) { if (verbose) fprintf(stderr, "Synthetic string can not have several PU levels\n"); errno = EINVAL; return -1; } if (nb_node_levels > 1) { if (verbose) fprintf(stderr, "Synthetic string can not have several NUMA node levels\n"); errno = EINVAL; return -1; } if (nb_machine_levels > 1) { if (verbose) fprintf(stderr, "Synthetic string can not have several machine levels\n"); errno = EINVAL; return -1; } if (nb_machine_levels) data->level[0].type = HWLOC_OBJ_SYSTEM; else { data->level[0].type = HWLOC_OBJ_MACHINE; nb_machine_levels++; } if (cache_depth == 1) /* if there is a single cache level, make it L2 */ cache_depth = 2; for (i=0; i<count; i++) { struct hwloc_synthetic_level_data_s *curlevel = &data->level[i]; hwloc_obj_type_t type = curlevel->type; if (type == HWLOC_OBJ_GROUP) { if (curlevel->depth == (unsigned)-1) curlevel->depth = group_depth--; } else if (type == HWLOC_OBJ_CACHE) { if (curlevel->depth == (unsigned)-1) curlevel->depth = cache_depth--; if (curlevel->cachetype == (hwloc_obj_cache_type_t) -1) curlevel->cachetype = curlevel->depth == 1 ? HWLOC_OBJ_CACHE_DATA : HWLOC_OBJ_CACHE_UNIFIED; if (!curlevel->memorysize) { if (1 == curlevel->depth) /* 32Kb in L1 */ curlevel->memorysize = 32*1024; else /* *4 at each level, starting from 1MB for L2, unified */ curlevel->memorysize = 256ULL*1024 << (2*curlevel->depth); } } else if (type == HWLOC_OBJ_NUMANODE && !curlevel->memorysize) { /* 1GB in memory nodes. */ curlevel->memorysize = 1024*1024*1024; } hwloc_synthetic_process_level_indexes(data, i, verbose); } data->string = strdup(description); data->level[count-1].arity = 0; return 0; error: for(i=0; i<HWLOC_SYNTHETIC_MAX_DEPTH; i++) { struct hwloc_synthetic_level_data_s *curlevel = &data->level[i]; free(curlevel->index_array); if (!curlevel->arity) break; } return -1; }
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_obj_type_t type; unsigned old_index, new_index; const char *callname = argv[0]; hwloc_topology_t topology; int err; if (argc < 6) { usage(stderr, callname); exit(EXIT_FAILURE); } #ifdef HWLOC2 err = hwloc_type_sscanf(argv[3], &type, NULL, 0); #else err = hwloc_obj_type_sscanf(argv[3], &type, NULL, NULL, 0); #endif if (err < 0) { fprintf(stderr, "Failed to recognize type `%s'\n", argv[3]); usage(stderr, callname); exit(EXIT_FAILURE); } if (type != HWLOC_OBJ_PU && type != HWLOC_OBJ_NUMANODE) { fprintf(stderr, "Invalid type `%s', should be PU or NUMA node\n", argv[3]); usage(stderr, callname); exit(EXIT_FAILURE); } old_index = atoi(argv[4]); new_index = atoi(argv[5]); if (old_index == new_index) { fprintf(stderr, "Nothing to do\n"); exit(EXIT_SUCCESS); } err = hwloc_topology_init(&topology); if (err < 0) { fprintf(stderr, "hwloc_topology_init() failed (%s)\n", strerror(errno)); usage(stderr, callname); exit(EXIT_FAILURE); } err = hwloc_topology_set_xml(topology, argv[1]); if (err < 0) { fprintf(stderr, "hwloc_topology_set_xml() on file `%s' failed (%s)\n", argv[1], strerror(errno)); usage(stderr, callname); exit(EXIT_FAILURE); } #ifdef HWLOC2 err = hwloc_topology_set_flags(topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM); err = hwloc_topology_set_all_types_filter(topology, HWLOC_TYPE_FILTER_KEEP_ALL); #else err = hwloc_topology_set_flags(topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM | HWLOC_TOPOLOGY_FLAG_WHOLE_IO | HWLOC_TOPOLOGY_FLAG_ICACHES); #endif err = hwloc_topology_load(topology); if (err < 0) { fprintf(stderr, "hwloc_topology_load() failed (%s)\n", strerror(errno)); usage(stderr, callname); exit(EXIT_FAILURE); } if (HWLOC_OBJ_PU == type) { hwloc_const_bitmap_t cpset = hwloc_topology_get_complete_cpuset(topology); if (!hwloc_bitmap_isset(cpset, old_index)) { fprintf(stderr, "Old PU os_index %u doesn't exist\n", old_index); usage(stderr, callname); exit(EXIT_FAILURE); } if (hwloc_bitmap_isset(cpset, new_index)) { fprintf(stderr, "New PU os_index %u already exists\n", new_index); usage(stderr, callname); exit(EXIT_FAILURE); } switch_pu_index(hwloc_get_root_obj(topology), old_index, new_index); } else if (HWLOC_OBJ_NUMANODE == type) { hwloc_const_bitmap_t cnset = hwloc_topology_get_complete_nodeset(topology); if (!cnset || hwloc_bitmap_isfull(cnset)) { fprintf(stderr, "Topology doesn't have NUMA nodes\n"); usage(stderr, callname); exit(EXIT_FAILURE); } if (!hwloc_bitmap_isset(cnset, old_index)) { fprintf(stderr, "Old NUMA node os_index %u doesn't exist\n", old_index); usage(stderr, callname); exit(EXIT_FAILURE); } if (hwloc_bitmap_isset(cnset, new_index)) { fprintf(stderr, "New NUMA node os_index %u already exists\n", new_index); usage(stderr, callname); exit(EXIT_FAILURE); } switch_numa_index(hwloc_get_root_obj(topology), old_index, new_index); } err = hwloc_topology_export_xml(topology, argv[2], 0); if (err < 0) { fprintf(stderr, "hwloc_topology_export_xml() on file `%s' failed (%s)\n", argv[2], strerror(errno)); usage(stderr, callname); exit(EXIT_FAILURE); } hwloc_topology_destroy(topology); printf("Beware that hwloc may warn about out-of-order objects when reloading %s\n", argv[2]); return 0; }