GCC Code Coverage Report


Directory: src/
File: src/support/options.c
Date: 2026-10-14 08:39:21
Exec Total Coverage
Lines: 418 509 82.1%
Functions: 14 14 100.0%
Branches: 221 294 75.2%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2026 Barcelona Supercomputing Center */
3 /* */
4 /* This file is part of the DLB library. */
5 /* */
6 /* DLB is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU Lesser General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* DLB is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU Lesser General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU Lesser General Public License */
17 /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */
18 /*********************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "support/options.h"
25
26 #include "apis/dlb_types.h"
27 #include "apis/dlb_errors.h"
28 #include "support/types.h"
29 #include "support/mask_utils.h"
30 #include "support/debug.h"
31 #include "LB_core/spd.h"
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stddef.h>
36 #include <ctype.h>
37 #include <stdint.h>
38 #include <limits.h>
39
40 typedef enum OptionFlags {
41 OPT_CLEAR = 0,
42 OPT_READONLY = 1 << 0,
43 OPT_OPTIONAL = 1 << 1,
44 OPT_DEPRECATED = 1 << 2,
45 OPT_ADVANCED = 1 << 3,
46 OPT_HIDDEN = 1 << 4,
47 OPT_UNUSED = 1 << 5,
48 } option_flags_t;
49
50 typedef enum OptionTypes {
51 OPT_BOOL_T,
52 OPT_NEG_BOOL_T,
53 OPT_INT_T,
54 OPT_STR_T,
55 OPT_PTR_PATH_T, // pointer to char[PATH_MAX]
56 OPT_VB_T, // verbose_opts_t
57 OPT_VBFMT_T, // verbose_fmt_t
58 OPT_INST_T, // instrument_items_t
59 OPT_DBG_T, // debug_opts_t
60 OPT_LEWI_AFF_T, // lewi_affinity_t
61 OPT_MASK_T, // cpu_set_t
62 OPT_MODE_T, // interaction_mode_t
63 OPT_MPISET_T, // mpi_set_t
64 OPT_OMPTOPTS_T, // omptool_opts_t
65 OPT_TLPSUM_T, // talp_summary_t
66 OPT_TLPMOD_T, // talp_model_t
67 OPT_TLPCOM_T, // talp_component_t
68 OPT_MNGO_MODE_T,// mngo_mode_t
69 OPT_OMPTM_T // omptm_version_t
70 } option_type_t;
71
72 typedef struct {
73 char var_name[MAX_OPTION_LENGTH]; // LB_OPTION
74 char arg_name[MAX_OPTION_LENGTH]; // --option
75 char default_value[MAX_OPTION_LENGTH];
76 char description[MAX_DESCRIPTION];
77 size_t offset;
78 option_type_t type;
79 option_flags_t flags;
80 } opts_dict_t;
81
82 /* Description is displaced 4 spaces */
83 #define OFFSET " "
84 static const opts_dict_t options_dictionary[] = {
85 // general options
86 {
87 .var_name = "LB_LEWI",
88 .arg_name = "--lewi",
89 .default_value = "no",
90 .description = OFFSET"Enable Lend When Idle. Processes using this mode can use LeWI\n"
91 OFFSET"API to lend and borrow resources.",
92 .offset = offsetof(options_t, lewi),
93 .type = OPT_BOOL_T,
94 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
95 }, {
96 .var_name = "LB_DROM",
97 .arg_name = "--drom",
98 .default_value = "no",
99 .description = OFFSET"Enable the Dynamic Resource Ownership Manager Module. Processes\n"
100 OFFSET"using this mode can receive requests from other processes to\n"
101 OFFSET"change its own process mask.",
102 .offset = offsetof(options_t, drom),
103 .type = OPT_BOOL_T,
104 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
105 }, {
106 .var_name = "LB_TALP",
107 .arg_name = "--talp",
108 .default_value = "none",
109 .description = OFFSET"Enable the TALP (Tracking Application Live Performance) profiler.\n"
110 OFFSET"\n"
111 OFFSET"The option accepts a comma-separated list of profiling components:\n"
112 OFFSET" default Enable profiling for all available components\n"
113 OFFSET" mpi MPI activity\n"
114 OFFSET" openmp OpenMP activity\n"
115 OFFSET" gpu GPU activity\n"
116 OFFSET" hwc Hardware counters\n"
117 OFFSET" none Disable TALP\n"
118 OFFSET"\n"
119 OFFSET"If the option is specified without value (i.e., --talp), it is\n"
120 OFFSET"equivalent to --talp=default.\n"
121 OFFSET"\n"
122 OFFSET"Expected usage is one of:\n"
123 OFFSET" --talp=none\n"
124 OFFSET" --talp or --talp=default\n"
125 OFFSET" --talp=<component>[,<component>...]\n"
126 OFFSET"\n"
127 OFFSET"Examples:\n"
128 OFFSET" --talp\n"
129 OFFSET" Enable profiling for all available components\n"
130 OFFSET" (auto-detected).\n"
131 OFFSET"\n"
132 OFFSET" --talp=gpu\n"
133 OFFSET" Enable GPU profiling.\n"
134 OFFSET"\n"
135 OFFSET" --talp=mpi,openmp\n"
136 OFFSET" Enable profiling of MPI and OpenMP activity.",
137 .offset = offsetof(options_t, talp),
138 .type = OPT_TLPCOM_T,
139 .flags = (option_flags_t)(OPT_OPTIONAL)
140 }, {
141 .var_name = "LB_MNGO",
142 .arg_name = "--mngo",
143 .default_value = "no",
144 .description = OFFSET"Enables the MNGO module. Processes using\n"
145 OFFSET"this module use TALP metrics to enable the usage of other modules\n"
146 OFFSET"like LeWI, and DROM depending on the live performance.",
147 .offset = offsetof(options_t, mngo),
148 .type = OPT_BOOL_T,
149 .flags = (option_flags_t)(OPT_OPTIONAL)
150 }, {
151 .var_name = "LB_BARRIER",
152 .arg_name = "--barrier",
153 .default_value = "yes",
154 .description = OFFSET"Enable the Shared Memory Barrier. Processes can perform\n"
155 OFFSET"intra-node barriers.",
156 .offset = offsetof(options_t, barrier),
157 .type = OPT_BOOL_T,
158 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
159 }, {
160 .var_name = "LB_NULL",
161 .arg_name = "--ompt",
162 .default_value = "yes",
163 .description = OFFSET"Enable OpenMP performance tool. If running with an OMPT capable\n"
164 OFFSET"runtime, DLB can register itself as OpenMP Tool and perform\n"
165 OFFSET"some tasks, like thread pinning reallocation when the process\n"
166 OFFSET"mask changes or some LeWI features if enabled.",
167 .offset = offsetof(options_t, ompt),
168 .type = OPT_BOOL_T,
169 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
170 }, {
171 .var_name = "LB_MODE",
172 .arg_name = "--mode",
173 .default_value = "polling",
174 .description = OFFSET"Set interaction mode between DLB and the application. In polling\n"
175 OFFSET"mode, each process needs to poll DLB to acquire resources. In\n"
176 OFFSET"async mode, DLB creates a helper thread to call back the\n"
177 OFFSET"application when resources become available.",
178 .offset = offsetof(options_t, mode),
179 .type = OPT_MODE_T,
180 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
181 },
182 // verbose
183 {
184 .var_name = "LB_NULL",
185 .arg_name = "--quiet",
186 .default_value = "no",
187 .description = OFFSET"Suppress VERBOSE and INFO messages from DLB, still shows\n"
188 OFFSET"WARNING and PANIC messages.",
189 .offset = offsetof(options_t, quiet),
190 .type = OPT_BOOL_T,
191 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
192 }, {
193 .var_name = "LB_NULL",
194 .arg_name = "--silent",
195 .default_value = "no",
196 .description = OFFSET"Suppress all output from DLB, even error messages.",
197 .offset = offsetof(options_t, silent),
198 .type = OPT_BOOL_T,
199 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
200 }, {
201 .var_name = "LB_VERBOSE",
202 .arg_name = "--verbose",
203 .default_value = "no",
204 .description = OFFSET"Select which verbose components will be printed. Multiple\n"
205 OFFSET"components may be selected.",
206 .offset = offsetof(options_t, verbose),
207 .type = OPT_VB_T,
208 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
209 }, {
210 .var_name = "LB_VERBOSE_FORMAT",
211 .arg_name = "--verbose-format",
212 .default_value = "node:spid",
213 .description = OFFSET"Set the verbose format for the verbose messages. Multiple\n"
214 OFFSET"components may be selected but the order is predefined as\n"
215 OFFSET"shown in the possible values.",
216 .offset = offsetof(options_t, verbose_fmt),
217 .type = OPT_VBFMT_T,
218 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
219 },
220 // instrument
221 {
222 .var_name = "LB_NULL",
223 .arg_name = "--instrument",
224 .default_value = "all",
225 .description = OFFSET"Enable Extrae instrumentation. This option requires the\n"
226 OFFSET"instrumented DLB library and the Extrae library. If both\n"
227 OFFSET"conditions are met, DLB will emit events such as the DLB\n"
228 OFFSET"calls, DLB modes, etc.",
229 .offset = offsetof(options_t, instrument),
230 .type = OPT_INST_T,
231 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
232 }, {
233 .var_name = "LB_NULL",
234 .arg_name = "--instrument-counters",
235 .default_value = "no",
236 .description = OFFSET"Enable counters on DLB events. If this option is enabled, DLB\n"
237 OFFSET"will emit events to Extrae with hardware counters information.\n"
238 OFFSET"This may significantly increase the size of the tracefile.",
239 .offset = offsetof(options_t, instrument_counters),
240 .type = OPT_BOOL_T,
241 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
242 }, {
243 .var_name = "LB_NULL",
244 .arg_name = "--instrument-extrae-nthreads",
245 .default_value = "0",
246 .description = OFFSET"Invoke Extrae_change_num_threads with the provided parameter\n"
247 OFFSET"at the start of the execution to pre-allocate a buffer per\n"
248 OFFSET"thread.",
249 .offset = offsetof(options_t, instrument_extrae_nthreads),
250 .type = OPT_INT_T,
251 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
252 },
253 // LeWI
254 {
255 .var_name = "LB_NULL",
256 .arg_name = "--lewi-keep-one-cpu",
257 .default_value = "no",
258 .description = OFFSET"Whether the CPU of the thread that encounters a blocking call\n"
259 OFFSET"(MPI blocking call or DLB_Barrier) is also lent in the LeWI policy.\n"
260 OFFSET"This flag replaces the option --lewi-mpi, although negated.",
261 .offset = offsetof(options_t, lewi_keep_cpu_on_blocking_call),
262 .type = OPT_BOOL_T,
263 .flags = (option_flags_t)(OPT_OPTIONAL)
264 }, {
265 .var_name = "LB_NULL",
266 .arg_name = "--lewi-respect-cpuset",
267 .default_value = "yes",
268 .description = OFFSET"Whether to respect the set of CPUs registered in DLB to\n"
269 OFFSET"use with LeWI. If disabled, all unknown CPUs are available\n"
270 OFFSET"for any process to borrow.",
271 .offset = offsetof(options_t, lewi_respect_cpuset),
272 .type = OPT_BOOL_T,
273 .flags = (option_flags_t)(OPT_OPTIONAL)
274 }, {
275 .var_name = "LB_NULL",
276 .arg_name = "--lewi-respect-mask",
277 .default_value = "yes",
278 .description = OFFSET"Deprecated in favor of --lewi-respect-cpuset.\n",
279 .offset = SIZE_MAX,
280 .type = OPT_BOOL_T,
281 .flags = (option_flags_t)(OPT_OPTIONAL | OPT_DEPRECATED | OPT_UNUSED)
282 }, {
283 /* This is a deprecated option that overlaps with --lewi-keep-one-cpu.
284 * It must be defined afterwards so that the default value of the
285 * previous option does not overwrite this one */
286 .var_name = "LB_NULL",
287 .arg_name = "--lewi-mpi",
288 .default_value = "no",
289 .description = OFFSET"This option is now deprecated, but its previous behavior is now\n"
290 OFFSET"enabled by default.\n"
291 OFFSET"If you want to lend a CPU when in a blocking call, you may safely\n"
292 OFFSET"remove this option.\n"
293 OFFSET"If you want to keep this CPU, use --lewi-keep-one-cpu instead.",
294 .offset = SIZE_MAX,
295 .type = OPT_NEG_BOOL_T,
296 .flags = (option_flags_t)(OPT_OPTIONAL | OPT_DEPRECATED | OPT_UNUSED)
297 }, {
298 .var_name = "LB_NULL",
299 .arg_name = "--lewi-mpi-calls",
300 .default_value = "all",
301 .description = OFFSET"Select which type of MPI calls will make LeWI to lend their\n"
302 OFFSET"CPUs. If set to all, LeWI will act on all blocking MPI calls,\n"
303 OFFSET"If set to other values, only those types will trigger LeWI.",
304 .offset = offsetof(options_t, lewi_mpi_calls),
305 .type = OPT_MPISET_T,
306 .flags = (option_flags_t)(OPT_OPTIONAL)
307 }, {
308 .var_name = "LB_NULL",
309 .arg_name = "--lewi-barrier",
310 .default_value = "yes",
311 .description = OFFSET"Select whether DLB_Barrier calls (unnamed barriers only) will\n"
312 OFFSET"activate LeWI and lend their CPUs. Named barriers can be\n"
313 OFFSET"configured individually in the source code, or using the\n"
314 OFFSET"--lewi-barrier-select.",
315 .offset = offsetof(options_t, lewi_barrier),
316 .type = OPT_BOOL_T,
317 .flags = (option_flags_t)(OPT_OPTIONAL | OPT_READONLY)
318 }, {
319 .var_name = "LB_NULL",
320 .arg_name = "--lewi-barrier-select",
321 .default_value = "",
322 .description = OFFSET"Comma separated values of barrier names that will activate\n"
323 OFFSET"LeWI. Warning: by setting this option to any non-blank value,\n"
324 OFFSET"the option --lewi-barrier is ignored. Use 'default' to also\n"
325 OFFSET"control the default unnamed barrier.\n"
326 OFFSET"e.g.: --lewi-barrier-select=default,barrier3",
327 .offset = offsetof(options_t, lewi_barrier_select),
328 .type = OPT_STR_T,
329 .flags = (option_flags_t)(OPT_OPTIONAL | OPT_READONLY | OPT_ADVANCED)
330 }, {
331 .var_name = "LB_NULL",
332 .arg_name = "--lewi-affinity",
333 .default_value = "auto",
334 .description = OFFSET"Select which affinity policy to use.\n"
335 OFFSET"With 'auto', DLB will infer the LeWI policy for either classic\n"
336 OFFSET"(no mask support) or LeWI_mask depending on a number of factors.\n"
337 OFFSET"To override the automatic detection, use either 'none' or 'mask'\n"
338 OFFSET"to select the respective policy.\n"
339 OFFSET"The tokens 'nearby-first', 'nearby-only', and 'spread-ifempty'\n"
340 OFFSET"also enforce mask support with extended policies.\n"
341 OFFSET"'nearby-first' is the default policy when LeWI has mask support\n"
342 OFFSET"and will instruct LeWI to assign resources that share the same\n"
343 OFFSET"socket or NUMA node with the current process first, then the\n"
344 OFFSET"rest.\n"
345 OFFSET"'nearby-only' will make LeWI assign only those resources that\n"
346 OFFSET"are near the process.\n"
347 OFFSET"'spread-ifempty' will also prioritise nearby resources, but the\n"
348 OFFSET"rest will only be considered if all CPUs in that socket or NUMA\n"
349 OFFSET"node has been lent to DLB.",
350 .offset = offsetof(options_t, lewi_affinity),
351 .type = OPT_LEWI_AFF_T,
352 .flags = (option_flags_t)(OPT_OPTIONAL)
353 }, {
354 .var_name = "LB_NULL",
355 .arg_name = "--lewi-ompt",
356 .default_value = "borrow",
357 .description = OFFSET"OMPT option flags for LeWI. If OMPT mode is enabled, set when\n"
358 OFFSET"DLB can automatically invoke LeWI functions to lend or borrow\n"
359 OFFSET"CPUs. If 'none' is set, LeWI will not be invoked automatically.\n"
360 OFFSET"If 'borrow' is set, DLB will try to borrow CPUs in certain\n"
361 OFFSET"situations; typically, before non nested parallel constructs if\n"
362 OFFSET"the OMPT thread manager is omp5 and on each task creation and\n"
363 OFFSET"task switch in other thread managers. (This option is the default\n"
364 OFFSET"and should be enough in most of the cases). If the flag 'lend'\n"
365 OFFSET"is set, DLB will lend all non used CPUs after each non nested\n"
366 OFFSET"parallel construct and task completion on external threads.\n"
367 OFFSET"Multiple flags can be selected at the same time.",
368 .offset = offsetof(options_t, lewi_ompt),
369 .type = OPT_OMPTOPTS_T,
370 .flags = (option_flags_t)(OPT_OPTIONAL)
371 }, {
372 .var_name = "LB_NULL",
373 .arg_name = "--lewi-greedy",
374 .default_value = "no",
375 .description = OFFSET"Greedy option for LeWI policy.",
376 .offset = offsetof(options_t, lewi_greedy),
377 .type = OPT_BOOL_T,
378 .flags = (option_flags_t)(OPT_OPTIONAL)
379 }, {
380 .var_name = "LB_NULL",
381 .arg_name = "--lewi-warmup",
382 .default_value = "no",
383 .description = OFFSET"Create as many threads as necessary during the process startup.",
384 .offset = offsetof(options_t, lewi_warmup),
385 .type = OPT_BOOL_T,
386 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
387 }, {
388 .var_name = "LB_NULL",
389 .arg_name = "--lewi-max-parallelism",
390 .default_value = "0",
391 .description = OFFSET"Set the maximum level of parallelism for the LeWI algorithm.",
392 .offset = offsetof(options_t, lewi_max_parallelism),
393 .type = OPT_INT_T,
394 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
395 }, {
396 .var_name = "LB_NULL",
397 .arg_name = "--lewi-color",
398 .default_value = "0",
399 .description = OFFSET"Set the LeWI color of the process, allowing the creation of\n"
400 OFFSET"different disjoint subgroups for resource sharing. Processes\n"
401 OFFSET"will only share resources with other processes of the same color.",
402 .offset = offsetof(options_t, lewi_color),
403 .type = OPT_INT_T,
404 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
405 },
406 // talp
407 {
408 .var_name = "LB_NULL",
409 .arg_name = "--talp-openmp",
410 .default_value = "no",
411 .description = OFFSET"Select whether to measure OpenMP metrics.\n"
412 OFFSET"Deprecated: use --talp=openmp instead.",
413 .offset = offsetof(options_t, deprecated_talp_openmp),
414 .type = OPT_BOOL_T,
415 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_DEPRECATED)
416 },
417 {
418 .var_name = "LB_NULL",
419 .arg_name = "--talp-papi",
420 .default_value = "no",
421 .description = OFFSET"Select whether to collect PAPI counters.\n"
422 OFFSET"Deprecated: use --talp=hwc instead.",
423 .offset = offsetof(options_t, deprecated_talp_papi),
424 .type = OPT_BOOL_T,
425 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_DEPRECATED)
426 },
427 {
428 .var_name = "LB_TALP_SUMM",
429 .arg_name = "--talp-summary",
430 .default_value = "pop-metrics",
431 .description = OFFSET"Report TALP metrics at the end of the execution. If\n"
432 OFFSET"'--talp-output-file' is not specified, a short summary is\n"
433 OFFSET"printed. Otherwise, a more verbose file will be generated\n"
434 OFFSET"with all the metrics collected by TALP, depending on the list\n"
435 OFFSET"of requested summaries, separated by ':':\n"
436 OFFSET"'pop-metrics', the default option, will report a subset of\n"
437 OFFSET"the POP metrics.\n"
438 OFFSET"'process' will report the measurements of each process for\n"
439 OFFSET"each registered region.\n"
440 OFFSET"\n"
441 OFFSET"Deprecated options:\n"
442 OFFSET"'pop-raw' will be removed in the next release. The output \n"
443 OFFSET"will be available using the 'pop-metrics' summary.\n"
444 OFFSET"'node' will be removed in the next release. Its data may\n"
445 OFFSET"be derived from the 'process' report.",
446 .offset = offsetof(options_t, talp_summary),
447 .type = OPT_TLPSUM_T,
448 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
449 },
450 {
451 .var_name = "LB_NULL",
452 .arg_name = "--talp-output-file",
453 .default_value = "",
454 .description = OFFSET"Write extended TALP metrics to a file. If omitted, output is\n"
455 OFFSET"written to stderr.\n"
456 OFFSET"\n"
457 OFFSET"The output format is determined by the file extension:\n"
458 OFFSET" *.json JSON (file is overwritten)\n"
459 OFFSET" *.csv CSV (rows are appended)\n"
460 OFFSET" other Plain text\n"
461 OFFSET"\n"
462 OFFSET"The filename may contain replacement tokens:\n"
463 OFFSET" %h Hostname\n"
464 OFFSET" %p Process ID (PID)\n"
465 OFFSET" %j Job ID from the environment (e.g., Slurm, Flux)\n"
466 OFFSET" %% Literal '%'\n"
467 OFFSET"\n"
468 OFFSET"Deprecated:\n"
469 OFFSET" *.xml XML output format",
470 .offset = offsetof(options_t, talp_output_file),
471 .type = OPT_PTR_PATH_T,
472 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
473 },
474 {
475 .var_name = "LB_NULL",
476 .arg_name = "--talp-partial-output",
477 .default_value = "no",
478 .description = OFFSET"Write one profiling output file per process instead of a single\n"
479 OFFSET"merged file. Only supported when the output format is JSON.",
480 .offset = offsetof(options_t, talp_partial_output),
481 .type = OPT_BOOL_T,
482 .flags = (option_flags_t)(OPT_OPTIONAL)
483 },
484 {
485 /* In the future, consider using an interval update timer instead of a boolean */
486 .var_name = "LB_NULL",
487 .arg_name = "--talp-external-profiler",
488 .default_value = "no",
489 .description = OFFSET"Enable live metrics update to the shared memory. This flag\n"
490 OFFSET"is only needed if there is an external program monitoring\n"
491 OFFSET"the application.",
492 .offset = offsetof(options_t, talp_external_profiler),
493 .type = OPT_BOOL_T,
494 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
495 },
496 {
497 .var_name = "LB_NULL",
498 .arg_name = "--talp-regions-per-proc",
499 .default_value = "100",
500 .description = OFFSET"Number of TALP regions per process to allocate in the shared\n"
501 OFFSET"memory.\n"
502 OFFSET"Deprecated: use --shmem-size-multiplier instead.\n",
503 .offset = SIZE_MAX,
504 .type = OPT_INT_T,
505 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_DEPRECATED | OPT_UNUSED)
506 },
507 {
508 .var_name = "LB_NULL",
509 .arg_name = "--talp-region-select",
510 .default_value = "",
511 .description = OFFSET"Select TALP regions to enable. This option follows the format:\n"
512 OFFSET" --talp-region-select=[(include|exclude):]<region-list>\n"
513 OFFSET"\n"
514 OFFSET"The modifiers 'include:' and 'exclude:' are optional, but only\n"
515 OFFSET"one modifier can be used at a time. If neither is specified,\n"
516 OFFSET"'include:' is assumed by default.\n"
517 OFFSET"\n"
518 OFFSET"The '<region-list>' can be a comma-separated list of regions\n"
519 OFFSET"or a special token 'all' to refer to all regions. The global\n"
520 OFFSET"monitoring region may be specified with the special token\n"
521 OFFSET"'global'. If the modifier 'include:' is used, only the listed\n"
522 OFFSET"regions will be enabled. If 'exclude:' is used, all regions\n"
523 OFFSET"will be enabled except for the ones specified.\n"
524 OFFSET"\n"
525 OFFSET"Note that when using this feature, listed regions must not have\n"
526 OFFSET"spaces in their names.\n"
527 OFFSET"\n"
528 OFFSET"e.g.: --talp-region-select=all (default)\n"
529 OFFSET" --talp-region-select=exclude:all\n"
530 OFFSET" --talp-region-select=include:global,region3\n"
531 OFFSET" --talp-region-select=exclude:region4",
532 .offset = offsetof(options_t, talp_region_select),
533 .type = OPT_STR_T,
534 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
535 },
536 {
537 .var_name = "LB_NULL",
538 .arg_name = "--talp-gpu-backend",
539 .default_value = "",
540 .description = OFFSET"Specifies the GPU backend plugin used by TALP.\n"
541 OFFSET"If unset (default), DLB automatically attempts to load a GPU\n"
542 OFFSET"backend in the following order:\n"
543 OFFSET"'cupti', 'rocprofiler-sdk', and 'rocprofilerv2'.",
544 .offset = offsetof(options_t, talp_gpu_backend),
545 .type = OPT_STR_T,
546 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
547 },
548 {
549 .var_name = "LB_NULL",
550 .arg_name = "--talp-hwc-backend",
551 .default_value = "",
552 .description = OFFSET"Specifies the hardware counter backend plugin used by TALP.\n"
553 OFFSET"If unset (default), DLB automatically attempts to load an HWC\n"
554 OFFSET"backend in the following order:\n"
555 OFFSET"'papi' and 'perf'.",
556 .offset = offsetof(options_t, talp_hwc_backend),
557 .type = OPT_STR_T,
558 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
559 },
560 {
561 .var_name = "LB_NULL",
562 .arg_name = "--talp-model",
563 .default_value = "hybrid-v2",
564 .description = OFFSET"For development use only.\n"
565 OFFSET"Select which version of POP metrics to compute.",
566 .offset = offsetof(options_t, talp_model),
567 .type = OPT_TLPMOD_T,
568 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
569 },
570 // MNGO
571 {
572 .var_name = "LB_NULL",
573 .arg_name = "--mngo-mode",
574 .default_value = "regions",
575 .description = OFFSET"The method used to call the mngo manager.",
576 .offset = offsetof(options_t, mngo_mode),
577 .type = OPT_MNGO_MODE_T,
578 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
579 },
580 {
581 .var_name = "LB_NULL",
582 .arg_name = "--mngo-helper-thread-interval",
583 .default_value = "30",
584 .description = OFFSET"The number of seconds MNGO waits between each event.",
585 .offset = offsetof(options_t, mngo_interval_time),
586 .type = OPT_INT_T,
587 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
588 },
589 {
590 .var_name = "LB_NULL",
591 .arg_name = "--mngo-lb-in-threshold",
592 .default_value = "10",
593 .description = OFFSET"The percentage difference between a process useful computation\n"
594 OFFSET"and its node average useful computation to consider that the\n"
595 OFFSET"process is contributing to load imbalance within the node.\n"
596 OFFSET"\n"
597 OFFSET"Note: This will affect when MNGO redistributes resources inside\n"
598 OFFSET" the node (either with DROM or with LeWI).\n",
599 .offset = offsetof(options_t, mngo_lb_in_threshold),
600 .type = OPT_INT_T,
601 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
602
603 },
604 {
605 .var_name = "LB_NULL",
606 .arg_name = "--mngo-lb-out-threshold",
607 .default_value = "5",
608 .description = OFFSET"The percentage difference between a process useful computation\n"
609 OFFSET"and the global average useful computation to consider that the\n"
610 OFFSET"process is contributing to the imbalance of other nodes.\n"
611 OFFSET"\n"
612 OFFSET"Note: This will change when DROM is used balance nodes across nodes.",
613 .offset = offsetof(options_t, mngo_lb_out_threshold),
614 .type = OPT_INT_T,
615 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
616
617 },
618 // barrier
619 {
620 .var_name = "LB_NULL",
621 .arg_name = "--barrier-id",
622 .default_value = "0",
623 .description = OFFSET"Barrier ID. Use different barrier id numbers for different\n"
624 OFFSET"processes to avoid unwanted synchronization.",
625 .offset = offsetof(options_t, barrier_id),
626 .type = OPT_INT_T,
627 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
628 },
629 // misc
630 {
631 .var_name = "LB_SHM_KEY",
632 .arg_name = "--shm-key",
633 .default_value = "",
634 .description = OFFSET"Shared Memory key. By default, if key is empty, all processes\n"
635 OFFSET"will use a shared memory based on the user ID. If different\n"
636 OFFSET"processes start their execution with different keys, they will\n"
637 OFFSET"use different shared memories and they will not share resources.",
638 .offset = offsetof(options_t, shm_key),
639 .type = OPT_STR_T,
640 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
641 }, {
642 .var_name = "LB_NULL",
643 .arg_name = "--shm-size-multiplier",
644 .default_value = "1",
645 .description = OFFSET"DLB allocates its shared memory at the start of execution, with\n"
646 OFFSET"its size based on the number of CPUs in the node. If you\n"
647 OFFSET"encounter a DLB_ERR_NOMEM error, you can adjust the multiplier\n"
648 OFFSET"to increase the shared memory size. As a reference, with the\n"
649 OFFSET"default multiplier, the typical shared memory size on HPC\n"
650 OFFSET"machines is under 10 megabytes, so keep that in mind if you\n"
651 OFFSET"increase its size to allocate more running processes or TALP\n"
652 OFFSET"regions.",
653 .offset = offsetof(options_t, shm_size_multiplier),
654 .type = OPT_INT_T,
655 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
656 }, {
657 .var_name = "LB_PREINIT_PID",
658 .arg_name = "--preinit-pid",
659 .default_value = "0",
660 .description = OFFSET"Process ID that pre-initializes the DLB process for DROM.",
661 .offset = offsetof(options_t, preinit_pid),
662 .type = OPT_INT_T,
663 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_HIDDEN)
664 }, {
665 .var_name = "LB_NULL",
666 .arg_name = "--ompt-thread-manager",
667 .default_value = "omp5",
668 .description = OFFSET"OMPT Thread Manager version.",
669 .offset = offsetof(options_t, omptm_version),
670 .type = OPT_OMPTM_T,
671 .flags = (option_flags_t)(OPT_OPTIONAL)
672 }, {
673 .var_name = "LB_NULL",
674 .arg_name = "--plugin",
675 .default_value = "",
676 .description = OFFSET"Select plugin to enable.\n"
677 OFFSET"Available options: 'cupti', 'rocprofiler-sdk', or 'rocprofilerv2'.\n"
678 OFFSET"Deprecated: use --talp=gpu or --talp-gpu-backend.",
679 .offset = offsetof(options_t, deprecated_plugins),
680 .type = OPT_STR_T,
681 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_DEPRECATED)
682 }, {
683 .var_name = "LB_DEBUG_OPTS",
684 .arg_name = "--debug-opts",
685 .default_value = "",
686 .description = OFFSET"Debug options.",
687 .offset = offsetof(options_t, debug_opts),
688 .type = OPT_DBG_T,
689 .flags = (option_flags_t)(OPT_OPTIONAL | OPT_ADVANCED)
690 }
691 };
692 #undef OFFSET
693
694 enum { NUM_OPTIONS = sizeof(options_dictionary)/sizeof(opts_dict_t) };
695
696
697 570 static const opts_dict_t* get_entry_by_name(const char *name) {
698 int i;
699
2/2
✓ Branch 0 taken 10588 times.
✓ Branch 1 taken 2 times.
10590 for (i=0; i<NUM_OPTIONS; ++i) {
700 10588 const opts_dict_t *entry = &options_dictionary[i];
701
1/2
✓ Branch 0 taken 10588 times.
✗ Branch 1 not taken.
10588 if (strcasecmp(entry->var_name, name) == 0
702
2/2
✓ Branch 0 taken 568 times.
✓ Branch 1 taken 10020 times.
10588 || strcasecmp(entry->arg_name, name) == 0) {
703 568 return entry;
704 }
705 }
706 2 return NULL;
707 }
708
709 222 static int set_ptr_path_value(void *option, const char *str_value) {
710 222 int path_len = snprintf(NULL, 0, "%s", str_value) + 1;
711
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 221 times.
222 if (path_len > 1) {
712 1 *(char**)option = malloc(sizeof(char) * path_len);
713 1 snprintf(*(char**)option, path_len, "%s", str_value);
714 } else {
715 221 *(char**)option = NULL;
716 }
717 222 return DLB_SUCCESS;
718 }
719
720 10500 static int set_value(option_type_t type, void *option, const char *str_value) {
721
18/20
✓ Branch 0 taken 3915 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2047 times.
✓ Branch 3 taken 1357 times.
✓ Branch 4 taken 222 times.
✓ Branch 5 taken 283 times.
✓ Branch 6 taken 223 times.
✓ Branch 7 taken 223 times.
✓ Branch 8 taken 224 times.
✓ Branch 9 taken 223 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 223 times.
✓ Branch 12 taken 224 times.
✓ Branch 13 taken 223 times.
✓ Branch 14 taken 223 times.
✓ Branch 15 taken 223 times.
✓ Branch 16 taken 222 times.
✓ Branch 17 taken 222 times.
✓ Branch 18 taken 222 times.
✗ Branch 19 not taken.
10500 switch(type) {
722 3915 case OPT_BOOL_T:
723 3915 return parse_bool(str_value, (bool*)option);
724 1 case OPT_NEG_BOOL_T:
725 1 return parse_negated_bool(str_value, (bool*)option);
726 2047 case OPT_INT_T:
727 2047 return parse_int(str_value, (int*)option);
728 1357 case OPT_STR_T:
729 1357 snprintf(option, MAX_OPTION_LENGTH, "%s", str_value);
730 1357 return DLB_SUCCESS;
731 222 case OPT_PTR_PATH_T:
732 222 return set_ptr_path_value(option, str_value);
733 283 case OPT_VB_T:
734 283 return parse_verbose_opts(str_value, (verbose_opts_t*)option);
735 223 case OPT_VBFMT_T:
736 223 return parse_verbose_fmt(str_value, (verbose_fmt_t*)option);
737 223 case OPT_INST_T:
738 223 return parse_instrument_items(str_value, (instrument_items_t*)option);
739 224 case OPT_DBG_T:
740 224 return parse_debug_opts(str_value, (debug_opts_t*)option);
741 223 case OPT_LEWI_AFF_T:
742 223 return parse_lewi_affinity(str_value, (lewi_affinity_t*)option);
743 ✗ case OPT_MASK_T:
744 ✗ mu_parse_mask(str_value, (cpu_set_t*)option);
745 ✗ return DLB_SUCCESS;
746 223 case OPT_MODE_T:
747 223 return parse_mode(str_value, (interaction_mode_t*)option);
748 224 case OPT_MPISET_T:
749 224 return parse_mpiset(str_value, (mpi_set_t*)option);
750 223 case OPT_OMPTOPTS_T:
751 223 return parse_omptool_opts(str_value, (omptool_opts_t*)option);
752 223 case OPT_TLPSUM_T:
753 223 return parse_talp_summary(str_value, (talp_summary_t*)option);
754 223 case OPT_TLPMOD_T:
755 223 return parse_talp_model(str_value, (talp_model_t*)option);
756 222 case OPT_TLPCOM_T:
757 222 return parse_talp_component(str_value, (talp_component_t*)option);
758 222 case OPT_MNGO_MODE_T:
759 222 return parse_mngo_mode(str_value, (mngo_mode_t*)option);
760 222 case OPT_OMPTM_T:
761 222 return parse_omptm_version(str_value, (omptm_version_t*)option);
762 }
763 ✗ return DLB_ERR_NOENT;
764 }
765
766 154 static const char * get_value(option_type_t type, const void *option) {
767 static char int_value[8];
768
17/20
✓ Branch 0 taken 65 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✓ Branch 12 taken 6 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 5 times.
✓ Branch 17 taken 4 times.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
154 switch(type) {
769 65 case OPT_BOOL_T:
770
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 48 times.
65 return *(bool*)option ? "yes" : "no";
771 ✗ case OPT_NEG_BOOL_T:
772 ✗ return *(bool*)option ? "no" : "yes";
773 23 case OPT_INT_T:
774 23 sprintf(int_value, "%d", *(int*)option);
775 23 return int_value;
776 9 case OPT_STR_T:
777 9 return (char*)option;
778 4 case OPT_PTR_PATH_T:
779
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 return *(const char**)option ? *(const char**)option : "";
780 4 case OPT_VB_T:
781 4 return verbose_opts_tostr(*(verbose_opts_t*)option);
782 4 case OPT_VBFMT_T:
783 4 return verbose_fmt_tostr(*(verbose_fmt_t*)option);
784 4 case OPT_INST_T:
785 4 return instrument_items_tostr(*(instrument_items_t*)option);
786 1 case OPT_DBG_T:
787 1 return debug_opts_tostr(*(debug_opts_t*)option);
788 4 case OPT_LEWI_AFF_T:
789 4 return lewi_affinity_tostr(*(lewi_affinity_t*)option);
790 ✗ case OPT_MASK_T:
791 ✗ return mu_to_str((cpu_set_t*)option);
792 8 case OPT_MODE_T:
793 8 return mode_tostr(*(interaction_mode_t*)option);
794 6 case OPT_MPISET_T:
795 6 return mpiset_tostr(*(mpi_set_t*)option);
796 4 case OPT_OMPTOPTS_T:
797 4 return omptool_opts_tostr(*(omptool_opts_t*)option);
798 4 case OPT_TLPSUM_T:
799 4 return talp_summary_tostr(*(talp_summary_t*)option);
800 1 case OPT_TLPMOD_T:
801 1 return talp_model_tostr(*(talp_model_t*)option);
802 5 case OPT_TLPCOM_T:
803 5 return talp_component_tostr(*(talp_component_t*)option);
804 4 case OPT_MNGO_MODE_T:
805 4 return mngo_mode_tostr(*(mngo_mode_t*)option);
806 4 case OPT_OMPTM_T:
807 4 return omptm_version_tostr(*(omptm_version_t*)option);
808 }
809 ✗ return "unknown";
810 }
811
812 5 static bool values_are_equivalent(option_type_t type, const char *value1, const char *value2) {
813
1/20
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
5 switch(type) {
814 5 case OPT_BOOL_T:
815 5 return equivalent_bool(value1, value2);
816 ✗ case OPT_NEG_BOOL_T:
817 ✗ return equivalent_negated_bool(value1, value2);
818 ✗ case OPT_INT_T:
819 ✗ return equivalent_int(value1, value2);
820 ✗ case OPT_STR_T:
821 ✗ return strcmp(value1, value2) == 0;
822 ✗ case OPT_PTR_PATH_T:
823 ✗ return *(const char**)value1 && *(const char**)value2
824 ✗ && strcmp(*(const char**)value1, *(const char**)value2) == 0;
825 ✗ case OPT_VB_T:
826 ✗ return equivalent_verbose_opts(value1, value2);
827 ✗ case OPT_VBFMT_T:
828 ✗ return equivalent_verbose_fmt(value1, value2);
829 ✗ case OPT_INST_T:
830 ✗ return equivalent_instrument_items(value1, value2);
831 ✗ case OPT_DBG_T:
832 ✗ return equivalent_debug_opts(value1, value2);
833 ✗ case OPT_LEWI_AFF_T:
834 ✗ return equivalent_lewi_affinity(value1, value2);
835 ✗ case OPT_MASK_T:
836 ✗ return mu_equivalent_masks(value1, value2);
837 ✗ case OPT_MODE_T:
838 ✗ return equivalent_mode(value1, value2);
839 ✗ case OPT_MPISET_T:
840 ✗ return equivalent_mpiset(value1, value2);
841 ✗ case OPT_OMPTOPTS_T:
842 ✗ return equivalent_omptool_opts(value1, value2);
843 ✗ case OPT_TLPSUM_T:
844 ✗ return equivalent_talp_summary(value1, value2);
845 ✗ case OPT_TLPMOD_T:
846 ✗ return equivalent_talp_model(value1, value2);
847 ✗ case OPT_TLPCOM_T:
848 ✗ return equivalent_talp_component(value1, value2);
849 ✗ case OPT_MNGO_MODE_T:
850 ✗ return equivalent_mngo_mode(value1, value2);
851 ✗ case OPT_OMPTM_T:
852 ✗ return equivalent_omptm_version_opts(value1, value2);
853 }
854 ✗ return false;
855 }
856
857 16 static void copy_value(option_type_t type, void *dest, const char *src) {
858
13/20
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
16 switch(type) {
859 1 case OPT_BOOL_T:
860 1 memcpy(dest, src, sizeof(bool));
861 1 break;
862 1 case OPT_NEG_BOOL_T:
863 1 memcpy(dest, src, sizeof(bool));
864 1 break;
865 3 case OPT_INT_T:
866 3 memcpy(dest, src, sizeof(int));
867 3 break;
868 2 case OPT_STR_T:
869 2 memcpy(dest, src, sizeof(char)*MAX_OPTION_LENGTH);
870 2 break;
871 ✗ case OPT_PTR_PATH_T:
872 ✗ fatal("copy_value of type OPT_PTR_PATH_T not supported");
873 break;
874 1 case OPT_VB_T:
875 1 memcpy(dest, src, sizeof(verbose_opts_t));
876 1 break;
877 1 case OPT_VBFMT_T:
878 1 memcpy(dest, src, sizeof(verbose_fmt_t));
879 1 break;
880 1 case OPT_INST_T:
881 1 memcpy(dest, src, sizeof(instrument_items_t));
882 1 break;
883 ✗ case OPT_DBG_T:
884 ✗ memcpy(dest, src, sizeof(debug_opts_t));
885 ✗ break;
886 1 case OPT_LEWI_AFF_T:
887 1 memcpy(dest, src, sizeof(lewi_affinity_t));
888 1 break;
889 ✗ case OPT_MASK_T:
890 ✗ memcpy(dest, src, sizeof(cpu_set_t));
891 ✗ break;
892 1 case OPT_MODE_T:
893 1 memcpy(dest, src, sizeof(interaction_mode_t));
894 1 break;
895 1 case OPT_MPISET_T:
896 1 memcpy(dest, src, sizeof(mpi_set_t));
897 1 break;
898 1 case OPT_OMPTOPTS_T:
899 1 memcpy(dest, src, sizeof(omptool_opts_t));
900 1 break;
901 1 case OPT_TLPSUM_T:
902 1 memcpy(dest, src, sizeof(talp_summary_t));
903 1 break;
904 1 case OPT_TLPMOD_T:
905 1 memcpy(dest, src, sizeof(talp_model_t));
906 1 break;
907 ✗ case OPT_TLPCOM_T:
908 ✗ memcpy(dest, src, sizeof(talp_component_t));
909 ✗ break;
910 ✗ case OPT_MNGO_MODE_T:
911 ✗ memcpy(dest, src, sizeof(mngo_mode_t));
912 ✗ break;
913 ✗ case OPT_OMPTM_T:
914 ✗ memcpy(dest, src, sizeof(omptm_version_t));
915 ✗ break;
916 }
917 16 }
918
919 /* Parse DLB_ARGS and remove argument if found */
920 17866 static void parse_dlb_args(char *dlb_args, const char *arg_name, char* arg_value, size_t arg_max_len) {
921 17866 *arg_value = 0;
922 /* Tokenize a copy of dlb_args with " "(blank) delimiter */
923 17866 char *progress = dlb_args;
924 17866 char *end_space = NULL;
925 17866 size_t len = strlen(dlb_args) + 1;
926 17866 char *dlb_args_copy = malloc(sizeof(char)*len);
927 17866 strcpy(dlb_args_copy, dlb_args);
928 17866 char *token = strtok_r(dlb_args_copy, " ", &end_space);
929
2/2
✓ Branch 0 taken 13181 times.
✓ Branch 1 taken 17866 times.
31047 while (token) {
930 /* Each token is a complete string representing an option */
931
932 13181 bool remove_token = false;
933 /* token length must be computed before tokenizing into arg=val */
934 13181 size_t token_len = strlen(token);
935 /* progress pointer must be updated each iteration to skip spaces */
936
2/2
✓ Branch 0 taken 18731 times.
✓ Branch 1 taken 13181 times.
31912 while(isspace((unsigned char)*progress)) progress++;
937
938
2/2
✓ Branch 0 taken 11955 times.
✓ Branch 1 taken 1226 times.
13181 if (strchr(token, '=')) {
939 /* Option is of the form --argument=value */
940 11955 char *end_equal = NULL;
941 11955 char *argument = strtok_r(token, "=", &end_equal);
942
2/2
✓ Branch 0 taken 413 times.
✓ Branch 1 taken 11542 times.
11955 if (strcmp(argument, arg_name) == 0) {
943 /* Obtain value */
944 413 char *value = strtok_r(NULL, "=", &end_equal);
945
2/2
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 1 times.
413 if (value) {
946 412 snprintf(arg_value, arg_max_len, "%s", value);
947 } else {
948 1 warning("Bad format parsing of DLB_ARGS. Option %s with empty value", token);
949 }
950 413 remove_token = true;
951 }
952 } else {
953 /* Option is of the form --argument/--no-argument */
954 1226 char *argument = token;
955
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 1020 times.
1226 if (strcmp(argument, arg_name) == 0) {
956 /* Option value is 'yes' */
957 206 strcpy(arg_value, "yes");
958 206 remove_token = true;
959
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1002 times.
1020 } else if (strncmp(argument, "--no-", 5) == 0
960
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 && strcmp(argument+5, arg_name+2) == 0) {
961 /* Option value is 'no' */
962 13 strcpy(arg_value, "no");
963 13 remove_token = true;
964 }
965 }
966
967
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 12549 times.
13181 if (remove_token) {
968 /* Remove token from dlb_args */
969 632 char *dest = progress;
970 632 char *src = progress + token_len;
971 632 size_t n = strlen(src) + 1;
972 632 memmove(dest, src, n);
973 } else {
974 /* Token is not removed, update parsed progress pointer */
975 12549 progress += token_len;
976 }
977
978 /* next token */
979 13181 token = strtok_r(NULL, " ", &end_space);
980 }
981 17866 free(dlb_args_copy);
982 17866 }
983
984 /* Initialize options struct from either argument, or env. variable */
985 222 void options_init(options_t *options, const char *dlb_args) {
986 /* Copy dlb_args into a local buffer */
987 222 char *dlb_args_from_api = NULL;
988
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 44 times.
222 if (dlb_args) {
989 178 size_t len = strlen(dlb_args) + 1;
990 178 dlb_args_from_api = malloc(sizeof(char)*len);
991 178 strcpy(dlb_args_from_api, dlb_args);
992 }
993
994 /* Copy either DLB_ARGS or LB_ARGS into a local buffer */
995 222 char *dlb_args_from_env = NULL;
996 222 const char *env = getenv("DLB_ARGS");
997
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 181 times.
222 if (!env) {
998 41 env = getenv("LB_ARGS");
999
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (env) {
1000 ✗ warning("LB_ARGS is deprecated, please use DLB_ARGS");
1001 }
1002 }
1003
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 41 times.
222 if (env) {
1004 181 size_t len = strlen(env) + 1;
1005 181 dlb_args_from_env = malloc(sizeof(char)*len);
1006 181 strcpy(dlb_args_from_env, env);
1007 }
1008
1009 /* Preallocate two buffers large enough to save any intermediate option value */
1010 222 char *arg_value_from_api = malloc(sizeof(char)*PATH_MAX);
1011 222 char *arg_value_from_env = malloc(sizeof(char)*PATH_MAX);
1012
1013 int i;
1014
2/2
✓ Branch 0 taken 10878 times.
✓ Branch 1 taken 222 times.
11100 for (i=0; i<NUM_OPTIONS; ++i) {
1015 10878 const opts_dict_t *entry = &options_dictionary[i];
1016 10878 const char *rhs = NULL; /* pointer to rhs to be parsed */
1017
1018 /* Set-up specific argument length */
1019 size_t arg_max_len;
1020
2/2
✓ Branch 0 taken 222 times.
✓ Branch 1 taken 10656 times.
10878 switch (entry->type) {
1021 222 case OPT_PTR_PATH_T:
1022 222 arg_max_len = PATH_MAX-1;
1023 222 break;
1024 10656 default:
1025 10656 arg_max_len = MAX_OPTION_LENGTH-1;
1026 10656 break;
1027 }
1028
1029 /* Reset intermediate buffers */
1030 10878 arg_value_from_api[0] = '\0';
1031 10878 arg_value_from_env[0] = '\0';
1032
1033 /* Parse dlb_args from API */
1034
2/2
✓ Branch 0 taken 8722 times.
✓ Branch 1 taken 2156 times.
10878 if (dlb_args_from_api) {
1035 8722 parse_dlb_args(dlb_args_from_api, entry->arg_name, arg_value_from_api, arg_max_len);
1036
2/2
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 8260 times.
8722 if (strlen(arg_value_from_api) > 0) {
1037 462 rhs = arg_value_from_api;
1038 }
1039 }
1040
1041 /* Parse DLB_ARGS from env */
1042
2/2
✓ Branch 0 taken 8869 times.
✓ Branch 1 taken 2009 times.
10878 if (dlb_args_from_env) {
1043 8869 parse_dlb_args(dlb_args_from_env, entry->arg_name, arg_value_from_env, arg_max_len);
1044
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 8745 times.
8869 if (strlen(arg_value_from_env) > 0) {
1045
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 119 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 4 times.
124 if (rhs && !values_are_equivalent(entry->type, rhs, arg_value_from_env)) {
1046 1 warning("Overwriting option %s = %s",
1047 1 entry->arg_name, arg_value_from_env);
1048 }
1049 124 rhs = arg_value_from_env;
1050 }
1051 }
1052
1053 /* Parse LB_option (to be deprecated soon) */
1054 10878 const char *arg_value = getenv(entry->var_name);
1055
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10878 times.
10878 if (arg_value) {
1056 ✗ if (rhs) {
1057 ✗ warning("Ignoring option %s = %s due to DLB_ARGS precedence",
1058 ✗ entry->var_name, arg_value);
1059 } else {
1060 ✗ warning("Option %s is to be deprecated in the near future, please use DLB_ARGS",
1061 ✗ entry->var_name);
1062 ✗ rhs = arg_value;
1063 }
1064 }
1065
1066 /* Warn if option is deprecated and has rhs */
1067
4/4
✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 9546 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1323 times.
10878 if (entry->flags & OPT_DEPRECATED && rhs) {
1068 9 warning("Option %s is deprecated:\n%s", entry->arg_name, entry->description);
1069 }
1070
1071 /* Skip iteration if option is not used anymore */
1072
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 10212 times.
10878 if (entry->flags & OPT_UNUSED) {
1073 666 continue;
1074 }
1075
1076 /* Check offset is valid at this point */
1077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10212 times.
10212 ensure(entry->offset < sizeof(options_t), "Offset value in options directory not valid");
1078
1079 /* Assign option = rhs, and nullify rhs if error */
1080
2/2
✓ Branch 0 taken 579 times.
✓ Branch 1 taken 9633 times.
10212 if (rhs) {
1081 579 int error = set_value(entry->type, (char*)options+entry->offset, rhs);
1082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 579 times.
579 if (error) {
1083 ✗ warning("Unrecognized %s value: %s. Setting default %s",
1084 ✗ entry->arg_name, rhs, entry->default_value);
1085 ✗ rhs = NULL;
1086 }
1087 }
1088
1089 /* Set default value if needed */
1090
2/2
✓ Branch 0 taken 9633 times.
✓ Branch 1 taken 579 times.
10212 if (rhs == NULL) {
1091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9633 times.
9633 fatal_cond(!(entry->flags & OPT_OPTIONAL),
1092 "Variable %s must be defined", entry->arg_name);
1093 9633 int error = set_value(entry->type, (char*)options+entry->offset, entry->default_value);
1094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9633 times.
9633 fatal_cond(error, "Internal error parsing default value %s=%s. Please, report bug at %s.",
1095 entry->arg_name, entry->default_value, PACKAGE_BUGREPORT);
1096 }
1097 }
1098
1099 /* Temporarily support deprecated TALP options */
1100
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 219 times.
222 if (options->deprecated_talp_openmp) {
1101 3 options->talp |= TALP_COMPONENT_OPENMP;
1102 }
1103
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 220 times.
222 if (options->deprecated_talp_papi) {
1104 2 options->talp |= TALP_COMPONENT_HWC;
1105 }
1106
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 220 times.
222 if (options->deprecated_plugins[0] != '\0' &&
1107
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 (strncmp(options->deprecated_plugins, "cupti", MAX_OPTION_LENGTH-1) == 0
1108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 || strncmp(options->deprecated_plugins, "rocprofiler-sdk", MAX_OPTION_LENGTH-1) == 0
1109 ✗ || strncmp(options->deprecated_plugins, "rocprofilerv2", MAX_OPTION_LENGTH-1) == 0)) {
1110 2 options->talp |= TALP_COMPONENT_GPU;
1111
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (options->talp_gpu_backend[0] == '\0') {
1112 2 strcpy(options->talp_gpu_backend, options->deprecated_plugins);
1113 }
1114 }
1115
1116 /* MNGO required options */
1117
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 208 times.
222 if (options->mngo){
1118
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
14 if ( (!options->lewi) && (!options->drom) ) {
1119 ✗ warning("MNGO without LeWI nor DROM won't be able to take any"
1120 " action.");
1121 }
1122
1123 // Enable the TALP MPI component in external mode
1124 14 options->talp |= TALP_COMPONENT_MPI;
1125 14 options->talp_external_profiler = true;
1126 }
1127
1128 /* Free intermediate buffers */
1129 222 free(arg_value_from_api);
1130 222 free(arg_value_from_env);
1131
1132 /* Safety checks and free local buffers */
1133
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 44 times.
222 if (dlb_args_from_api) {
1134 178 char *str = dlb_args_from_api;
1135
2/2
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 178 times.
486 while(isspace((unsigned char)*str)) str++;
1136
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 176 times.
178 if (strlen(str) > 0) {
1137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (options->debug_opts & DBG_WERROR) {
1138 ✗ fatal("Unrecognized flags from DLB_Init: %s", str);
1139 } else {
1140 2 warning("Unrecognized flags from DLB_Init: %s", str);
1141 }
1142 }
1143 178 free(dlb_args_from_api);
1144 }
1145
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 41 times.
222 if (dlb_args_from_env) {
1146 181 char *str = dlb_args_from_env;
1147
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 181 times.
461 while(isspace((unsigned char)*str)) str++;
1148
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 180 times.
181 if (strlen(str) > 0) {
1149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (options->debug_opts & DBG_WERROR) {
1150 ✗ fatal("Unrecognized flags from DLB_ARGS: %s", str);
1151 } else {
1152 1 warning("Unrecognized flags from DLB_ARGS: %s", str);
1153 }
1154 }
1155 181 free(dlb_args_from_env);
1156 }
1157 222 }
1158
1159 121 void options_finalize(options_t *options) {
1160
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 120 times.
121 if (options->talp_output_file) {
1161 1 free(options->talp_output_file);
1162 1 options->talp_output_file = NULL;
1163 }
1164 121 }
1165
1166 /* Obtain value of specific entry, either from DLB_ARGS or from thread_spd->options */
1167 300 void options_parse_entry(const char *var_name, void *option) {
1168 300 const opts_dict_t *entry = get_entry_by_name(var_name);
1169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 300 times.
300 ensure(entry, "%s: bad variable name '%s'", __func__, var_name);
1170
1171
4/4
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 46 times.
300 if (thread_spd && thread_spd->dlb_initialized) {
1172 16 copy_value(entry->type, option, (char*)&thread_spd->options + entry->offset);
1173 } else {
1174 /* Simplified options_init just for this entry */
1175
1176 /* Copy DLB_ARGS into a local buffer */
1177 284 char *dlb_args_from_env = NULL;
1178 284 const char *env = getenv("DLB_ARGS");
1179
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 9 times.
284 if (env) {
1180 275 size_t len = strlen(env) + 1;
1181 275 dlb_args_from_env = malloc(sizeof(char)*len);
1182 275 strcpy(dlb_args_from_env, env);
1183 }
1184
1185 /* Pointer to rhs to be parsed */
1186 284 const char *rhs = NULL;
1187
1188 /* Set-up specific argument length */
1189 size_t arg_max_len;
1190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 284 times.
284 switch (entry->type) {
1191 ✗ case OPT_PTR_PATH_T:
1192 ✗ arg_max_len = PATH_MAX-1;
1193 ✗ break;
1194 284 default:
1195 284 arg_max_len = MAX_OPTION_LENGTH-1;
1196 284 break;
1197 }
1198
1199 /* Preallocate a buffer large enough to save the option value */
1200 284 char *arg_value_from_env = malloc(sizeof(char)*(arg_max_len+1));
1201 284 arg_value_from_env[0] = '\0';
1202
1203 /* Parse DLB_ARGS from env */
1204
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 9 times.
284 if (dlb_args_from_env) {
1205 275 parse_dlb_args(dlb_args_from_env, entry->arg_name, arg_value_from_env, arg_max_len);
1206
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 245 times.
275 if (strlen(arg_value_from_env) > 0) {
1207 30 rhs = arg_value_from_env;
1208 }
1209 }
1210
1211 /* Assign option = rhs, and nullify rhs if error */
1212
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 254 times.
284 if (rhs) {
1213 30 int error = set_value(entry->type, option, rhs);
1214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (error) {
1215 ✗ rhs = NULL;
1216 }
1217 }
1218
1219 /* Set default value if needed */
1220
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 30 times.
284 if (!rhs) {
1221 254 set_value(entry->type, option, entry->default_value);
1222 }
1223
1224 /* Free buffers */
1225 284 free(arg_value_from_env);
1226
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 9 times.
284 if (dlb_args_from_env) {
1227 275 free(dlb_args_from_env);
1228 }
1229 }
1230 300 }
1231
1232 /* API Setter */
1233 8 int options_set_variable(options_t *options, const char *var_name, const char *value) {
1234 int error;
1235 8 const opts_dict_t *entry = get_entry_by_name(var_name);
1236
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (entry) {
1237
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (entry->flags & OPT_READONLY) {
1238 3 error = DLB_ERR_PERM;
1239 } else {
1240 4 error = set_value(entry->type, (char*)options+entry->offset, value);
1241 }
1242 } else {
1243 1 error = DLB_ERR_NOENT;
1244 }
1245
1246 8 return error;
1247 }
1248
1249 /* API Getter */
1250 14 int options_get_variable(const options_t *options, const char *var_name, char *value) {
1251 int error;
1252 14 const opts_dict_t *entry = get_entry_by_name(var_name);
1253
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 if (entry) {
1254 13 sprintf(value, "%s", get_value(entry->type, (char*)options+entry->offset));
1255 13 error = DLB_SUCCESS;
1256 } else {
1257 1 error = DLB_ERR_NOENT;
1258 }
1259
1260 14 return error;
1261 }
1262
1263 /* API Printer. Also, dlb -h/-hh output */
1264 4 void options_print_variables(const options_t *options, bool print_extended) {
1265
1266 /* Initialize buffer */
1267 print_buffer_t buffer;
1268 4 printbuffer_init(&buffer);
1269
1270 /* Set up intermediate buffer per entry */
1271 enum { MAX_ENTRY_LEN = 256 };
1272 char entry_buffer[MAX_ENTRY_LEN];
1273
1274 /* Header (last \n is not needed) */
1275 4 printbuffer_append(&buffer,
1276 "DLB Options:\n\n"
1277 "DLB is configured by setting these flags in the DLB_ARGS environment variable.\n"
1278 "Possible options are listed below:\n\n"
1279 "Option Current value Possible value (type) / [choice] / {val1:val2}\n"
1280 "--------------------------------------------------------------------------------------"
1281 );
1282
1283 int i;
1284
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 4 times.
200 for (i=0; i<NUM_OPTIONS; ++i) {
1285 196 const opts_dict_t *entry = &options_dictionary[i];
1286
1287 /* Skip if deprecated */
1288
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 172 times.
196 if (entry->flags & OPT_DEPRECATED) continue;
1289
1290 /* Skip if hidden */
1291
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 168 times.
172 if (entry->flags & OPT_HIDDEN) continue;
1292
1293 /* Skip if advanced (unless print_extended) */
1294
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 132 times.
168 if (entry->flags & OPT_ADVANCED
1295
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 9 times.
36 && !print_extended) continue;
1296
1297 /* Reset entry buffer */
1298 141 entry_buffer[0] = '\0';
1299 141 char *b = entry_buffer;
1300 141 size_t max_entry_len = MAX_ENTRY_LEN;
1301
1302 /* Name */
1303 141 size_t name_len = strlen(entry->arg_name) + 1;
1304
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 13 times.
141 if (name_len < 24) {
1305 /* Option + tabs until column 24 */
1306
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 24 times.
232 b += snprintf(b, max_entry_len, "%s:%s",
1307 128 entry->arg_name,
1308
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 52 times.
104 name_len < 8 ? "\t\t\t" : name_len < 16 ? "\t\t" : "\t");
1309 } else {
1310 /* Long option, break line */
1311 13 b += snprintf(b, max_entry_len, "%s:\n\t\t\t",
1312 13 entry->arg_name);
1313 }
1314
1315 /* Check if output was truncated, and update remaining entry length */
1316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 fatal_cond((b - entry_buffer) >= MAX_ENTRY_LEN,
1317 "Output truncated in in %s. Please report bug at %s",
1318 __func__, PACKAGE_BUGREPORT);
1319 141 max_entry_len = MAX_ENTRY_LEN - (b - entry_buffer);
1320
1321 /* Value */
1322 141 const char *value = get_value(entry->type, (char*)options+entry->offset);
1323 141 size_t value_len = strlen(value) + 1;
1324
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 124 times.
158 b += snprintf(b, max_entry_len, "%s %s",
1325 value,
1326
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 value_len < 8 ? "\t\t" : value_len < 16 ? "\t" : "");
1327
1328 /* Check if output was truncated, and update remaining entry length */
1329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 fatal_cond((b - entry_buffer) >= MAX_ENTRY_LEN,
1330 "Output truncated in in %s. Please report bug at %s",
1331 __func__, PACKAGE_BUGREPORT);
1332 141 max_entry_len = MAX_ENTRY_LEN - (b - entry_buffer);
1333
1334 /* Choices */
1335
17/20
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 4 times.
✓ Branch 14 taken 4 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 4 times.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
141 switch(entry->type) {
1336 60 case OPT_BOOL_T:
1337 60 b += snprintf(b, max_entry_len, "(bool)");
1338 60 break;
1339 ✗ case OPT_NEG_BOOL_T:
1340 ✗ b += snprintf(b, max_entry_len, "(bool)");
1341 ✗ break;
1342 23 case OPT_INT_T:
1343 23 b += snprintf(b, max_entry_len, "(int)");
1344 23 break;
1345 8 case OPT_STR_T:
1346 8 b += snprintf(b, max_entry_len, "(string)");
1347 8 break;
1348 4 case OPT_PTR_PATH_T:
1349 4 b += snprintf(b, max_entry_len, "(path)");
1350 4 break;
1351 4 case OPT_VB_T:
1352 4 b += snprintf(b, max_entry_len, "{%s}", get_verbose_opts_choices());
1353 4 break;
1354 4 case OPT_VBFMT_T:
1355 4 b += snprintf(b, max_entry_len, "{%s}", get_verbose_fmt_choices());
1356 4 break;
1357 4 case OPT_INST_T:
1358 4 b += snprintf(b, max_entry_len, "{%s}", get_instrument_items_choices());
1359 4 break;
1360 1 case OPT_DBG_T:
1361 1 b += snprintf(b, max_entry_len, "{%s}", get_debug_opts_choices());
1362 1 break;
1363 4 case OPT_LEWI_AFF_T:
1364 4 b += snprintf(b, max_entry_len, "[%s]", get_lewi_affinity_choices());
1365 4 break;
1366 ✗ case OPT_MASK_T:
1367 ✗ b += snprintf(b, max_entry_len, "(cpuset)");
1368 ✗ break;
1369 4 case OPT_MODE_T:
1370 4 b += snprintf(b, max_entry_len, "[%s]", get_mode_choices());
1371 4 break;
1372 4 case OPT_MPISET_T:
1373 4 b += snprintf(b, max_entry_len, "[%s]", get_mpiset_choices());
1374 4 break;
1375 4 case OPT_OMPTOPTS_T:
1376 4 b += snprintf(b, max_entry_len, "[%s]", get_omptool_opts_choices());
1377 4 break;
1378 4 case OPT_TLPSUM_T:
1379 4 b += snprintf(b, max_entry_len, "{%s}", get_talp_summary_choices());
1380 4 break;
1381 1 case OPT_TLPMOD_T:
1382 1 b += snprintf(b, max_entry_len, "[%s]", get_talp_model_choices());
1383 1 break;
1384 4 case OPT_TLPCOM_T:
1385 4 b += snprintf(b, max_entry_len, "{%s}", get_talp_component_choices());
1386 4 break;
1387 4 case OPT_MNGO_MODE_T:
1388 4 b += snprintf(b, max_entry_len, "{%s}", get_mngo_mode_choices());
1389 4 break;
1390 4 case OPT_OMPTM_T:
1391 4 b += snprintf(b, max_entry_len, "[%s]", get_omptm_version_choices());
1392 4 break;
1393 }
1394
1395 /* Check if output was truncated */
1396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 fatal_cond((b - entry_buffer) >= MAX_ENTRY_LEN,
1397 "Buffer overflow in %s. Please report bug at %s",
1398 __func__, PACKAGE_BUGREPORT);
1399
1400 /* Append entry listing */
1401 141 printbuffer_append(&buffer, entry_buffer);
1402
1403 /* Append long description if print_extended */
1404
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 99 times.
141 if (print_extended) {
1405 42 printbuffer_append(&buffer, entry->description);
1406 42 printbuffer_append(&buffer, "");
1407 }
1408
1409 }
1410
1411 /* Footer (last \n is not needed) */
1412 4 printbuffer_append(&buffer,
1413 "\n"
1414 "Boolean options accept both standalone flags and 'yes'/'no' parameters.\n"
1415 "These are equivalent flags:\n"
1416 " export DLB_ARGS=\"--lewi --no-drom\"\n"
1417 " export DLB_ARGS=\"--lewi=yes --drom=no\"");
1418
1419 /* This function must print always and ignore options --quiet and --silent */
1420 4 info0_force_print("%s", buffer.addr);
1421
1422 4 printbuffer_destroy(&buffer);
1423 4 }
1424
1425 /* Print which LeWI flags are enabled during DLB_Init */
1426 62 void options_print_lewi_flags(const options_t *options) {
1427 const opts_dict_t *entry;
1428
1429 // --lewi-mpi
1430 bool default_lewi_keep_one_cpu;
1431 62 entry = get_entry_by_name("--lewi-keep-one-cpu");
1432 62 parse_bool(entry->default_value, &default_lewi_keep_one_cpu);
1433
1434 // --lewi-mpi-calls
1435 mpi_set_t default_lewi_mpi_calls;
1436 62 entry = get_entry_by_name("--lewi-mpi-calls");
1437 62 parse_mpiset(entry->default_value, &default_lewi_mpi_calls);
1438
1439 // --lewi-affinity
1440 lewi_affinity_t default_lewi_affinity;
1441 62 entry = get_entry_by_name("--lewi-affinity");
1442 62 parse_lewi_affinity(entry->default_value, &default_lewi_affinity);
1443
1444 // --lewi-ompt
1445 omptool_opts_t default_lewi_ompt;
1446 62 entry = get_entry_by_name("--lewi-ompt");
1447 62 parse_omptool_opts(entry->default_value, &default_lewi_ompt);
1448
1449
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 if (options->lewi_keep_cpu_on_blocking_call != default_lewi_keep_one_cpu
1450
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 || options->lewi_mpi_calls != default_lewi_mpi_calls
1451
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
62 || options->lewi_affinity != default_lewi_affinity
1452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 || options->lewi_ompt != default_lewi_ompt) {
1453 30 info0("LeWI options:");
1454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (options->lewi_keep_cpu_on_blocking_call != default_lewi_keep_one_cpu) {
1455 ✗ info0(" --lewi-keep-one-cpu");
1456 }
1457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (options->lewi_mpi_calls != default_lewi_mpi_calls) {
1458 ✗ info0(" --lewi-mpi-calls=%s", mpiset_tostr(options->lewi_mpi_calls));
1459 }
1460
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (options->lewi_affinity != default_lewi_affinity) {
1461 30 info0(" --lewi-affinity=%s", lewi_affinity_tostr(options->lewi_affinity));
1462 }
1463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (options->lewi_ompt != default_lewi_ompt) {
1464 ✗ info0(" --lewi-ompt=%s", omptool_opts_tostr(options->lewi_ompt));
1465 }
1466 }
1467 62 }
1468