static void pci_device_draw(hwloc_topology_t topology __hwloc_attribute_unused, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { unsigned textwidth = gridsize; unsigned textheight = (fontsize ? fontsize + gridsize : 0); unsigned myheight = textheight; unsigned mywidth = 0; unsigned totwidth, totheight; unsigned overlaidoffset = 0; struct style style; char text[64], _text[64]; const char *collapsestr = hwloc_obj_get_info_by_name(level, "lstopoCollapse"); unsigned collapse = collapsestr ? atoi(collapsestr) : 1; int n; DYNA_CHECK(); if (fontsize) { if (collapse > 1) { n = lstopo_obj_snprintf(_text, sizeof(_text), level, logical); n = snprintf(text, sizeof(text), "%u x { %s }", collapse, _text); } else { n = lstopo_obj_snprintf(text, sizeof(text), level, logical); } textwidth = get_textwidth(output, methods, text, n, fontsize, gridsize); } if (collapse > 1) { /* additional depths and height for overlaid boxes */ depth -= 2; if (collapse > 2) { overlaidoffset = gridsize; } else { overlaidoffset = gridsize/2; } textwidth += overlaidoffset; textheight += overlaidoffset; myheight = textheight; } RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize); lstopo_set_object_color(methods, topology, level, 0, &style); if (collapse > 1) { methods->box(output, style.bg.r, style.bg.g, style.bg.b, depth+2, x + overlaidoffset, *retwidth - overlaidoffset, y + overlaidoffset, *retheight - overlaidoffset); if (collapse > 2) methods->box(output, style.bg.r, style.bg.g, style.bg.b, depth+1, x + overlaidoffset/2, *retwidth - overlaidoffset, y + overlaidoffset/2, *retheight - overlaidoffset); methods->box(output, style.bg.r, style.bg.g, style.bg.b, depth, x, *retwidth - overlaidoffset, y, *retheight - overlaidoffset); } else { methods->box(output, style.bg.r, style.bg.g, style.bg.b, depth, x, *retwidth, y, *retheight); } if (fontsize) methods->text(output, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + gridsize, text); RECURSE_RECT(level, methods, gridsize, gridsize); DYNA_SAVE(); }
static void output_compute_pu_min_textwidth(struct lstopo_output *output) { unsigned fontsize = output->fontsize; char text[64]; int n; hwloc_topology_t topology = output->topology; hwloc_obj_t lastpu; if (!output->methods->textsize) { output->min_pu_textwidth = 0; return; } if (output->logical) { int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); lastpu = hwloc_get_obj_by_depth(topology, depth, hwloc_get_nbobjs_by_depth(topology, depth)-1); } else { unsigned lastidx = hwloc_bitmap_last(hwloc_topology_get_topology_cpuset(topology)); lastpu = hwloc_get_pu_obj_by_os_index(topology, lastidx); } n = lstopo_obj_snprintf(output, text, sizeof(text), lastpu); output->min_pu_textwidth = get_textwidth(output, text, n, fontsize); }
static void core_draw(struct lstopo_output *loutput, struct draw_methods *methods, hwloc_obj_t level, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { hwloc_topology_t topology = loutput->topology; int logical = loutput->logical; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight; unsigned mywidth = 0, totwidth; unsigned textwidth = gridsize; char text[64]; int n; struct style style; DYNA_CHECK(); if (fontsize) { n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(loutput, methods, text, n, fontsize, gridsize); } RECURSE_RECT(level, &null_draw_methods, 0, gridsize); lstopo_set_object_color(methods, topology, level, 0, &style); methods->box(loutput, style.bg.r, style.bg.g, style.bg.b, depth, x, totwidth, y, totheight); if (fontsize) { methods->text(loutput, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + gridsize, text); } RECURSE_RECT(level, methods, 0, gridsize); DYNA_SAVE(); }
static void cache_draw(hwloc_topology_t topology, struct draw_methods *methods, int logical, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { unsigned myheight = gridsize + (fontsize ? (fontsize + gridsize) : 0) + gridsize, totheight; unsigned mywidth = 0, totwidth; unsigned textwidth = gridsize; /* Do not separate objects when in L1 (SMT) */ unsigned separator = level->attr->cache.depth > 1 ? gridsize : 0; char text[64]; int n; struct style style; DYNA_CHECK(); if (fontsize) { n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(output, methods, text, n, fontsize, gridsize); textwidth += gridsize; /* artificially extend the minimal inner size because RECURSE_RECT() uses 0 as border when computing totwidth */ } RECURSE_RECT(level, &null_draw_methods, separator, 0); lstopo_set_object_color(methods, topology, level, 0, &style); methods->box(output, style.bg.r, style.bg.g, style.bg.b, depth, x, totwidth, y, myheight - gridsize); if (fontsize) { methods->text(output, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + gridsize, text); } RECURSE_RECT(level, methods, separator, 0); DYNA_SAVE(); }
static void prepare_text(struct lstopo_output *loutput, hwloc_obj_t obj) { struct lstopo_obj_userdata *lud = obj->userdata; unsigned fontsize = loutput->fontsize; int n; /* sane defaults */ lud->ntext = 0; lud->textwidth = 0; lud->textxoffset = 0; if (!fontsize) return; /* main object identifier line */ if (obj->type == HWLOC_OBJ_PCI_DEVICE && loutput->show_attrs[HWLOC_OBJ_PCI_DEVICE]) { /* PCI text collapsing */ char busid[32]; char _text[64]; lstopo_obj_snprintf(loutput, _text, sizeof(_text), obj); lstopo_busid_snprintf(busid, sizeof(busid), obj, lud->pci_collapsed, loutput->need_pci_domain); if (lud->pci_collapsed > 1) { n = snprintf(lud->text[0], sizeof(lud->text[0]), "%d x { %s %s }", lud->pci_collapsed, _text, busid); } else { n = snprintf(lud->text[0], sizeof(lud->text[0]), "%s %s", _text, busid); } } else { /* normal object text */ n = lstopo_obj_snprintf(loutput, lud->text[0], sizeof(lud->text[0]), obj); } lud->textwidth = get_textwidth(loutput, lud->text[0], n, fontsize); lud->ntext = 1; if (obj->type == HWLOC_OBJ_PU) { /* if smaller than other PU, artificially extend/shift it * to make PU boxes nicer when vertically stacked. */ if (lud->textwidth < loutput->min_pu_textwidth) { lud->textxoffset = (loutput->min_pu_textwidth - lud->textwidth) / 2; lud->textwidth = loutput->min_pu_textwidth; } } /* additional text */ prepare_more_text(loutput, obj); }
static void pu_draw(struct lstopo_output *loutput, struct draw_methods *methods, hwloc_obj_t level, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { hwloc_topology_t topology = loutput->topology; int logical = loutput->logical; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight; unsigned textwidth = gridsize; unsigned mywidth = 0, totwidth; unsigned textxoffset = 0; char text[64]; int n; struct style style; int colorarg; DYNA_CHECK(); if (fontsize) { n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(loutput, methods, text, n, fontsize, gridsize); /* if smaller than other PU, artificially extend/shift it * to make PU boxes nicer when vertically stacked. */ if (textwidth < loutput->min_pu_textwidth) { textxoffset = (loutput->min_pu_textwidth - textwidth) / 2; textwidth = loutput->min_pu_textwidth; } } RECURSE_RECT(level, &null_draw_methods, 0, gridsize); if (lstopo_pu_forbidden(level)) colorarg = 2; else if (lstopo_pu_running(loutput, level)) colorarg = 1; else colorarg = 0; lstopo_set_object_color(methods, topology, level, colorarg, &style); methods->box(loutput, style.bg.r, style.bg.g, style.bg.b, depth, x, *retwidth, y, *retheight); if (fontsize) { methods->text(loutput, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize + textxoffset, y + gridsize, text); } RECURSE_RECT(level, methods, 0, gridsize); DYNA_SAVE(); }
static void node_draw(struct lstopo_output *loutput, struct draw_methods *methods, hwloc_obj_t level, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { hwloc_topology_t topology = loutput->topology; int logical = loutput->logical; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; /* Reserve room for the heading memory box and separator */ unsigned myheight = (fontsize ? (gridsize + fontsize) : 0) + gridsize + gridsize; /* Currently filled height */ unsigned totheight; /* Nothing on the left */ unsigned mywidth = 0; /* Currently filled width */ unsigned totwidth; /* Width of the heading text, thus minimal width */ unsigned textwidth = gridsize; char text[64]; int n; struct style style; /* Check whether dynamic programming can save us time */ DYNA_CHECK(); if (fontsize) { n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(loutput, methods, text, n, fontsize, gridsize); textwidth += 2*gridsize; /* so artificially extend the minimal inner size to include space between space between epoxy and memory box */ } /* Compute the size needed by sublevels */ RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize); lstopo_set_object_color(methods, topology, level, 0 /* node */, &style); /* Draw the epoxy box */ methods->box(loutput, style.bg.r, style.bg.g, style.bg.b, depth, x, totwidth, y, totheight); /* Draw the memory box */ methods->box(loutput, style.bg2.r, style.bg2.g, style.bg2.b, depth-1, x + gridsize, totwidth - 2 * gridsize, y + gridsize, myheight - gridsize); if (fontsize) { methods->text(loutput, style.t2.r, style.t2.g, style.t2.b, fontsize, depth-2, x + 2 * gridsize, y + 2 * gridsize, text); } /* Restart, now really drawing sublevels */ RECURSE_RECT(level, methods, gridsize, gridsize); /* Save result for dynamic programming */ DYNA_SAVE(); }
static void group_draw(struct lstopo_output *loutput, struct draw_methods *methods, hwloc_obj_t level, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { hwloc_topology_t topology = loutput->topology; int logical = loutput->logical; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; unsigned myheight = (fontsize ? (fontsize + gridsize) : 0), totheight; unsigned mywidth = 0, totwidth; unsigned textwidth = gridsize; int vert = prefer_vert(loutput, level, depth, x, y, gridsize); char text[64]; int n; struct style style; DYNA_CHECK(); if (fontsize) { n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(loutput, methods, text, n, fontsize, gridsize); } if (level->arity > 1 && (level->children[0]->type == HWLOC_OBJ_MACHINE || !level->children[0]->cpuset)) NETWORK_DRAW_BEGIN(); else RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize); lstopo_set_object_color(methods, topology, level, 0, &style); methods->box(loutput, style.bg.r, style.bg.g, style.bg.b, depth, x, totwidth, y, totheight); if (fontsize) { methods->text(loutput, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + gridsize, text); } if (level->arity > 1 && (level->children[0]->type == HWLOC_OBJ_MACHINE || !level->children[0]->cpuset)) NETWORK_DRAW_END(); else RECURSE_RECT(level, methods, gridsize, gridsize); DYNA_SAVE(); }
static void os_device_draw(struct lstopo_output *loutput, struct draw_methods *methods, hwloc_obj_t level, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { hwloc_topology_t topology = loutput->topology; int logical = loutput->logical; unsigned gridsize = loutput->gridsize; unsigned fontsize = loutput->fontsize; unsigned myheight = 0, totheight; unsigned mywidth = 0, totwidth; unsigned textwidth = gridsize; struct style style; char text[64]; int n; unsigned nmorelines = 0, i; char morelines[3][64]; DYNA_CHECK(); if (fontsize) { const char *coproctype = level->subtype; if (HWLOC_OBJ_OSDEV_COPROC == level->attr->osdev.type && coproctype) { if (!strcmp(coproctype, "CUDA")) { const char *value, *value2, *value3; value = hwloc_obj_get_info_by_name(level, "CUDAGlobalMemorySize"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10240 ? mb/1024 : mb); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "CUDAL2CacheSize"); if (value) { unsigned long long kb = strtoull(value, NULL, 10); snprintf(morelines[nmorelines], sizeof(morelines[0]), kb >= 10240 ? "L2 (%llu MB)" : "L2 (%llu kB)", kb >= 10240 ? kb/1024 : kb); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "CUDAMultiProcessors"); value2 = hwloc_obj_get_info_by_name(level, "CUDACoresPerMP"); value3 = hwloc_obj_get_info_by_name(level, "CUDASharedMemorySizePerMP"); if (value && value2 && value3) { snprintf(morelines[nmorelines], sizeof(morelines[0]), "%s MP x (%s cores + %s kB)", value, value2, value3); nmorelines++; } } else if (!strcmp(coproctype, "MIC")) { const char *value; value = hwloc_obj_get_info_by_name(level, "MICActiveCores"); if (value) { snprintf(morelines[nmorelines], sizeof(morelines[0]), "%s cores", value); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "MICMemorySize"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10240 ? mb/1024 : mb); nmorelines++; } } else if (!strcmp(coproctype, "OpenCL")) { const char *value; value = hwloc_obj_get_info_by_name(level, "OpenCLComputeUnits"); if (value) { unsigned long long cu = strtoull(value, NULL, 10); snprintf(morelines[nmorelines], sizeof(morelines[0]), "%llu compute units", cu); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "OpenCLGlobalMemorySize"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10240 ? mb/1024 : mb); nmorelines++; } } } else if (HWLOC_OBJ_OSDEV_BLOCK == level->attr->osdev.type) { const char *value; value = hwloc_obj_get_info_by_name(level, "Size"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10485760 ? "%llu TB" : mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10485760 ? mb/1048576 : mb >= 10240 ? mb/1024 : mb); nmorelines++; } } n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(loutput, methods, text, n, fontsize, gridsize); for(i=0; i<nmorelines; i++) { unsigned nn = (unsigned)strlen(morelines[i]); unsigned ntextwidth = get_textwidth(loutput, methods, morelines[i], nn, fontsize, gridsize); if (ntextwidth > textwidth) textwidth = ntextwidth; } myheight = (fontsize + gridsize)*(nmorelines+1); mywidth = 0; } RECURSE_RECT(level, &null_draw_methods, gridsize, gridsize); lstopo_set_object_color(methods, topology, level, 0, &style); methods->box(loutput, style.bg.r, style.bg.g, style.bg.b, depth, x, *retwidth, y, *retheight); if (fontsize) { methods->text(loutput, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + gridsize, text); for(i=0; i<nmorelines; i++) methods->text(loutput, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + (i+2)*gridsize + (i+1)*fontsize, morelines[i]); } RECURSE_RECT(level, methods, gridsize, gridsize); DYNA_SAVE(); }
static void os_device_draw(hwloc_topology_t topology __hwloc_attribute_unused, struct draw_methods *methods, int logical __hwloc_attribute_unused, hwloc_obj_t level, void *output, unsigned depth, unsigned x, unsigned *retwidth, unsigned y, unsigned *retheight) { unsigned textwidth = gridsize; unsigned totheight = gridsize; unsigned totwidth = gridsize; struct style style; char text[64]; int n; unsigned nmorelines = 0, i; char morelines[3][64]; if (fontsize) { const char *coproctype; if (HWLOC_OBJ_OSDEV_COPROC == level->attr->osdev.type && (coproctype = hwloc_obj_get_info_by_name(level, "CoProcType")) != NULL) { if (!strcmp(coproctype, "CUDA")) { const char *value, *value2, *value3; value = hwloc_obj_get_info_by_name(level, "CUDAGlobalMemorySize"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10240 ? mb/1024 : mb); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "CUDAL2CacheSize"); if (value) { unsigned long long kb = strtoull(value, NULL, 10); snprintf(morelines[nmorelines], sizeof(morelines[0]), kb >= 10240 ? "L2 (%llu MB)" : "L2 (%llu kB)", kb >= 10240 ? kb/1024 : kb); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "CUDAMultiProcessors"); value2 = hwloc_obj_get_info_by_name(level, "CUDACoresPerMP"); value3 = hwloc_obj_get_info_by_name(level, "CUDASharedMemorySizePerMP"); if (value && value2 && value3) { snprintf(morelines[nmorelines], sizeof(morelines[0]), "%s MP x (%s cores + %s kB)", value, value2, value3); nmorelines++; } } else if (!strcmp(coproctype, "MIC")) { const char *value; value = hwloc_obj_get_info_by_name(level, "MICActiveCores"); if (value) { snprintf(morelines[nmorelines], sizeof(morelines[0]), "%s cores", value); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "MICMemorySize"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10240 ? mb/1024 : mb); nmorelines++; } } else if (!strcmp(coproctype, "OpenCL")) { const char *value; value = hwloc_obj_get_info_by_name(level, "OpenCLComputeUnits"); if (value) { unsigned long long cu = strtoull(value, NULL, 10); snprintf(morelines[nmorelines], sizeof(morelines[0]), "%llu compute units", cu); nmorelines++; } value = hwloc_obj_get_info_by_name(level, "OpenCLGlobalMemorySize"); if (value) { unsigned long long mb = strtoull(value, NULL, 10) / 1024; snprintf(morelines[nmorelines], sizeof(morelines[0]), mb >= 10240 ? "%llu GB" : "%llu MB", mb >= 10240 ? mb/1024 : mb); nmorelines++; } } } n = lstopo_obj_snprintf(text, sizeof(text), level, logical); textwidth = get_textwidth(output, methods, text, n, fontsize, gridsize); for(i=0; i<nmorelines; i++) { int nn = strlen(morelines[i]); int ntextwidth = get_textwidth(output, methods, morelines[i], nn, fontsize, gridsize); if (ntextwidth > textwidth) textwidth = ntextwidth; } totheight = gridsize + (fontsize + gridsize)*(nmorelines+1); totwidth = gridsize + textwidth; } *retwidth = totwidth; *retheight = totheight; lstopo_set_object_color(methods, topology, level, 0, &style); methods->box(output, style.bg.r, style.bg.g, style.bg.b, depth, x, *retwidth, y, *retheight); if (fontsize) { methods->text(output, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + gridsize, text); for(i=0; i<nmorelines; i++) methods->text(output, style.t.r, style.t.g, style.t.b, fontsize, depth-1, x + gridsize, y + (i+2)*gridsize + (i+1)*fontsize, morelines[i]); } }