1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2021 Inria. All rights reserved.
4 * Copyright © 2009-2010, 2012, 2015 Université Bordeaux
5 * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
6 * Copyright © 2020 Hewlett Packard Enterprise. All rights reserved.
7 * See COPYING in top-level directory.
8 */
9
10 #ifndef UTILS_LSTOPO_H
11 #define UTILS_LSTOPO_H
12
13 #include "private/autogen/config.h"
14 #include "hwloc.h"
15 #include "misc.h"
16
17 enum lstopo_drawing_e {
18 LSTOPO_DRAWING_PREPARE,
19 LSTOPO_DRAWING_DRAW
20 };
21
22 enum lstopo_orient_e {
23 LSTOPO_ORIENT_NONE = 0,
24 LSTOPO_ORIENT_HORIZ,
25 LSTOPO_ORIENT_VERT,
26 LSTOPO_ORIENT_RECT
27 };
28
29 enum lstopo_index_type_e {
30 LSTOPO_INDEX_TYPE_DEFAULT,
31 LSTOPO_INDEX_TYPE_PHYSICAL,
32 LSTOPO_INDEX_TYPE_LOGICAL,
33 LSTOPO_INDEX_TYPE_NONE /* only used during the interactive display */
34 };
35
36 enum lstopo_show_legend_e {
37 LSTOPO_SHOW_LEGEND_ALL,
38 LSTOPO_SHOW_LEGEND_NONE,
39 LSTOPO_SHOW_LEGEND_NO_DEFAULT
40 };
41
42 FILE *open_output(const char *filename, int overwrite) __hwloc_attribute_malloc;
43
44 struct draw_methods;
45
46 /* if embedded in backend-specific output structure, must be at the beginning */
47 struct lstopo_output {
48 hwloc_topology_t topology;
49 unsigned depth;
50
51 /* when an interactive backends want a refresh of the topology */
52 int needs_topology_refresh;
53 /* when actually doing a refresh */
54 int refreshing;
55
56 /* file config */
57 FILE *file;
58 int overwrite;
59
60 /* misc config */
61 enum lstopo_index_type_e index_type;
62 int verbose_mode;
63 int ignore_pus;
64 int ignore_numanodes;
65 int pci_collapse_enabled; /* global toggle for PCI collapsing */
66 int pid_number;
67 hwloc_pid_t pid;
68 hwloc_bitmap_t cpubind_set, membind_set;
69
70 /* misc cached data */
71 int need_pci_domain;
72 unsigned nr_cpukind_styles;
73
74 /* export config */
75 unsigned long export_synthetic_flags;
76 unsigned long export_xml_flags;
77 uint64_t shmem_output_addr;
78
79 /* legend */
80 enum lstopo_show_legend_e show_legend;
81 #define LSTOPO_LEGEND_DEFAULT_LINES 3 /* hostname + index + date */
82 char legend_default_lines[LSTOPO_LEGEND_DEFAULT_LINES][128];
83 unsigned legend_default_lines_nr;
84 unsigned legend_info_lines_nr;
85 char ** legend_append;
86 unsigned legend_append_nr;
87 unsigned legend_maxtextwidth;
88
89 /* text config */
90 int show_distances_only;
91 int show_memattrs_only;
92 int show_cpukinds_only;
93 int show_windows_processor_groups_only;
94 hwloc_obj_type_t show_only;
95 int show_cpuset;
96 int show_taskset;
97 int transform_distances;
98
99 /* draw config */
100 char title[256];
101 unsigned plain_children_order;
102 unsigned int gridsize, fontsize, linespacing, thickness;
103 float text_xscale;
104 enum lstopo_orient_e force_orient[HWLOC_OBJ_TYPE_MAX]; /* orientation of children within an object of the given type */
105 unsigned no_half_lines; /* set by ASCII backend because it cannot write between lines of the terminal */
106 int show_indexes[HWLOC_OBJ_TYPE_MAX]; /* enabled by global toggle index_type */
107 int show_text_enabled; /* global toggle for interactive keyboard shortcuts */
108 int show_text[HWLOC_OBJ_TYPE_MAX];
109 int show_attrs_enabled; /* global toggle for interactive keyboard shortcuts */
110 int show_attrs[HWLOC_OBJ_TYPE_MAX];
111 int show_binding;
112 int show_disallowed;
113 int show_cpukinds;
114 int factorize_enabled; /* global toggle for interactive keyboard shortcuts */
115 unsigned factorize_min[HWLOC_OBJ_TYPE_MAX]; /* minimum number of object before factorizing (parent->arity must be strictly higher) */
116 #define FACTORIZE_MIN_DEFAULT 4
117 #define FACTORIZE_MIN_DISABLED UINT_MAX
118 unsigned factorize_first[HWLOC_OBJ_TYPE_MAX]; /* number of first children to keep before factorizing */
119 unsigned factorize_last[HWLOC_OBJ_TYPE_MAX]; /* number of last children to keep after factorizing */
120
121 /* draw internal data */
122 void *backend_data;
123 struct draw_methods *methods;
124 enum lstopo_drawing_e drawing;
125 unsigned width, height; /* total output size */
126 };
127
128 struct lstopo_color {
129 /* these variables must be initialized before passing the structure to declare_color() */
130 int r, g, b;
131 int free; /* 1 if lstopo should free() this structure at exit */
132
133 /* these variable are initialized by declare_color() */
134 /* backend specific private data */
135 union lstopo_color_private_u {
136 struct lstopo_color_private_ascii_s {
137 int color;
138 } ascii;
139 struct lstopo_color_private_fig_s {
140 int color;
141 } fig;
142 #ifdef HWLOC_WIN_SYS
143 struct lstopo_color_private_windows_s {
144 HGDIOBJ brush;
145 COLORREF color;
146 } windows;
147 #endif
148 } private;
149 /* list of colors */
150 struct lstopo_color *next;
151 };
152
153 struct lstopo_style {
154 struct lstopo_color
155 *bg, /* main box background color */
156 *t, /* main text color */
157 *t2; /* other text color */
158 };
159
160 #define LSTOPO_CHILD_KIND_NORMAL 0x1
161 #define LSTOPO_CHILD_KIND_MEMORY 0x2
162 #define LSTOPO_CHILD_KIND_IO 0x4
163 #define LSTOPO_CHILD_KIND_MISC 0x8
164 #define LSTOPO_CHILD_KIND_ALL 0xf
165
166 struct lstopo_obj_userdata {
167 /* original common userdata (we replace the first one with this extended structure) */
168 struct hwloc_utils_userdata common;
169
170 /* PCI collapsing */
171 int pci_collapsed; /* 0 if no collapsing, -1 if collapsed with a previous one, >1 if collapsed with several next */
172 int factorized; /* 0 if no factorizing, -1 if hidden, 1 if replaced with dots */
173
174 /* custom style */
175 struct lstopo_style style;
176 #define LSTOPO_STYLE_BG 0x1
177 #define LSTOPO_STYLE_T 0x2
178 #define LSTOPO_STYLE_T2 0x4
179 unsigned style_set; /* OR'ed LSTOPO_STYLE_* */
180
181 /* PU style for CPU kind */
182 unsigned cpukind_style;
183
184 /* object size (including children if they are outside of it, not including borders) */
185 unsigned width;
186 unsigned height;
187
188 /* a child position is: its parent position + parent->children_*rel + child->*rel */
189 /* relative position of first child with respect to top-left corner of this object */
190 struct lstopo_children_position {
191 unsigned kinds;
192 unsigned width;
193 unsigned height;
194 unsigned xrel;
195 unsigned yrel;
196 unsigned box;
197 struct lstopo_color *boxcolor;
198 } children;
199 /* relative position of first memory child */
200 struct lstopo_children_position above_children;
201
202 /* relative position of this object within its parent children zone */
203 unsigned xrel;
204 unsigned yrel;
205
206 /* children orientation */
207 enum lstopo_orient_e orient;
208
209 /* text lines within object */
210 #define LSTOPO_OBJ_TEXT_MAX 4 /* current max number of lines is osdev name + 3 cuda attributes */
211 struct lstopo_text_line {
212 char text[128];
213 unsigned width;
214 unsigned xoffset;
215 } text[LSTOPO_OBJ_TEXT_MAX];
216 unsigned ntext;
217 unsigned textwidth; /* required width for all lines of text,
218 * max of above text[].width + optional padding
219 */
220 };
221
222 typedef int output_method (struct lstopo_output *output, const char *filename);
223 extern output_method output_console, output_synthetic, output_ascii, output_tikz, output_fig, output_png, output_pdf, output_ps, output_nativesvg, output_cairosvg, output_x11, output_windows, output_xml, output_android, output_shmem;
224
225 extern int lstopo_shmem_adopt(const char *input, hwloc_topology_t *topologyp);
226
227 struct draw_methods {
228 int (*declare_color) (struct lstopo_output *loutput, struct lstopo_color *lcolor);
229 void (*destroy_color) (struct lstopo_output *loutput, struct lstopo_color *lcolor);
230 /* only called when loutput->draw_methods == LSTOPO_DRAWING_DRAW */
231 void (*box) (struct lstopo_output *loutput, const struct lstopo_color *lcolor, unsigned depth, unsigned x, unsigned width, unsigned y, unsigned height, hwloc_obj_t obj, unsigned box_id);
232 void (*line) (struct lstopo_output *loutput, const struct lstopo_color *lcolor, unsigned depth, unsigned x1, unsigned y1, unsigned x2, unsigned y2, hwloc_obj_t obj, unsigned line_id);
233 void (*text) (struct lstopo_output *loutput, const struct lstopo_color *lcolor, int size, unsigned depth, unsigned x, unsigned y, const char *text, hwloc_obj_t obj, unsigned text_id);
234 /* may be called when loutput->drawing == LSTOPO_DRAWING_PREPARE */
235 void (*textsize) (struct lstopo_output *loutput, const char *text, unsigned textlength, unsigned fontsize, unsigned *width);
236 };
237
238 extern void output_draw(struct lstopo_output *output);
239
240 extern void lstopo_prepare_custom_styles(struct lstopo_output *loutput);
241 extern void declare_colors(struct lstopo_output *output);
242 extern void destroy_colors(struct lstopo_output *output);
243
lstopo_pu_disallowed(struct lstopo_output * loutput,hwloc_obj_t l)244 static __hwloc_inline int lstopo_pu_disallowed(struct lstopo_output *loutput, hwloc_obj_t l)
245 {
246 hwloc_topology_t topology = loutput->topology;
247 return !hwloc_bitmap_isset(hwloc_topology_get_allowed_cpuset(topology), l->os_index);
248 }
249
lstopo_pu_binding(struct lstopo_output * loutput,hwloc_obj_t l)250 static __hwloc_inline int lstopo_pu_binding(struct lstopo_output *loutput, hwloc_obj_t l)
251 {
252 return loutput->pid_number != -1 && hwloc_bitmap_isset(loutput->cpubind_set, l->os_index);
253 }
254
lstopo_numa_disallowed(struct lstopo_output * loutput,hwloc_obj_t l)255 static __hwloc_inline int lstopo_numa_disallowed(struct lstopo_output *loutput, hwloc_obj_t l)
256 {
257 hwloc_topology_t topology = loutput->topology;
258 return !hwloc_bitmap_isset(hwloc_topology_get_allowed_nodeset(topology), l->os_index);
259 }
260
lstopo_numa_binding(struct lstopo_output * loutput,hwloc_obj_t l)261 static __hwloc_inline int lstopo_numa_binding(struct lstopo_output *loutput, hwloc_obj_t l)
262 {
263 return loutput->pid_number != -1 && hwloc_bitmap_isset(loutput->membind_set, l->os_index);
264 }
265
lstopo_busid_snprintf(struct lstopo_output * loutput,char * text,size_t textlen,hwloc_obj_t firstobj,int collapse,unsigned needdomain)266 static __hwloc_inline int lstopo_busid_snprintf(struct lstopo_output *loutput, char *text, size_t textlen, hwloc_obj_t firstobj, int collapse, unsigned needdomain)
267 {
268 hwloc_obj_t lastobj;
269 char domain[10] = "";
270 unsigned i;
271
272 if (needdomain)
273 snprintf(domain, sizeof(domain), "%04x:", firstobj->attr->pcidev.domain);
274
275 /* single busid */
276 if (!loutput->pci_collapse_enabled || collapse <= 1) {
277 return snprintf(text, textlen, "%s%02x:%02x.%01x",
278 domain,
279 firstobj->attr->pcidev.bus,
280 firstobj->attr->pcidev.dev,
281 firstobj->attr->pcidev.func);
282 }
283
284 assert(collapse >= 0); /* should be called on the first object of a collapsed range */
285
286 for(lastobj=firstobj, i=1; i<(unsigned)collapse; i++)
287 lastobj = lastobj->next_cousin;
288
289 /* multiple busid functions for same busid device */
290 if (firstobj->attr->pcidev.dev == lastobj->attr->pcidev.dev)
291 return snprintf(text, textlen, "%s%02x:%02x.%01x-%01x",
292 domain,
293 firstobj->attr->pcidev.bus,
294 firstobj->attr->pcidev.dev,
295 firstobj->attr->pcidev.func,
296 lastobj->attr->pcidev.func);
297
298 /* multiple busid devices */
299 return snprintf(text, textlen, "%s%02x:%02x.%01x-%02x.%01x",
300 domain,
301 firstobj->attr->pcidev.bus,
302 firstobj->attr->pcidev.dev,
303 firstobj->attr->pcidev.func,
304 lastobj->attr->pcidev.dev,
305 lastobj->attr->pcidev.func);
306 }
307
308 extern void lstopo_show_interactive_cli_options(const struct lstopo_output *loutput);
309 extern void lstopo_show_interactive_help(void);
310
311 #endif /* UTILS_LSTOPO_H */
312