GCC Code Coverage Report


Directory: src/
File: src/support/options.c
Date: 2026-09-15 07:37:49
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-model",
551 .default_value = "hybrid-v2",
552 .description = OFFSET"For development use only.\n"
553 OFFSET"Select which version of POP metrics to compute.",
554 .offset = offsetof(options_t, talp_model),
555 .type = OPT_TLPMOD_T,
556 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
557 },
558 // MNGO
559 {
560 .var_name = "LB_NULL",
561 .arg_name = "--mngo-mode",
562 .default_value = "regions",
563 .description = OFFSET"The method used to call the mngo manager.",
564 .offset = offsetof(options_t, mngo_mode),
565 .type = OPT_MNGO_MODE_T,
566 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
567 },
568 {
569 .var_name = "LB_NULL",
570 .arg_name = "--mngo-helper-thread-interval",
571 .default_value = "30",
572 .description = OFFSET"The number of seconds MNGO waits between each event.",
573 .offset = offsetof(options_t, mngo_interval_time),
574 .type = OPT_INT_T,
575 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
576 },
577 {
578 .var_name = "LB_NULL",
579 .arg_name = "--mngo-lb-in-threshold",
580 .default_value = "10",
581 .description = OFFSET"The percentage difference between a process useful computation\n"
582 OFFSET"and its node average useful computation to consider that the\n"
583 OFFSET"process is contributing to load imbalance within the node.\n"
584 OFFSET"\n"
585 OFFSET"Note: This will affect when MNGO redistributes resources inside\n"
586 OFFSET" the node (either with DROM or with LeWI).\n",
587 .offset = offsetof(options_t, mngo_lb_in_threshold),
588 .type = OPT_INT_T,
589 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
590
591 },
592 {
593 .var_name = "LB_NULL",
594 .arg_name = "--mngo-lb-out-threshold",
595 .default_value = "5",
596 .description = OFFSET"The percentage difference between a process useful computation\n"
597 OFFSET"and the global average useful computation to consider that the\n"
598 OFFSET"process is contributing to the imbalance of other nodes.\n"
599 OFFSET"\n"
600 OFFSET"Note: This will change when DROM is used balance nodes across nodes.",
601 .offset = offsetof(options_t, mngo_lb_out_threshold),
602 .type = OPT_INT_T,
603 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL)
604
605 },
606 // barrier
607 {
608 .var_name = "LB_NULL",
609 .arg_name = "--barrier-id",
610 .default_value = "0",
611 .description = OFFSET"Barrier ID. Use different barrier id numbers for different\n"
612 OFFSET"processes to avoid unwanted synchronization.",
613 .offset = offsetof(options_t, barrier_id),
614 .type = OPT_INT_T,
615 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
616 },
617 // misc
618 {
619 .var_name = "LB_SHM_KEY",
620 .arg_name = "--shm-key",
621 .default_value = "",
622 .description = OFFSET"Shared Memory key. By default, if key is empty, all processes\n"
623 OFFSET"will use a shared memory based on the user ID. If different\n"
624 OFFSET"processes start their execution with different keys, they will\n"
625 OFFSET"use different shared memories and they will not share resources.",
626 .offset = offsetof(options_t, shm_key),
627 .type = OPT_STR_T,
628 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
629 }, {
630 .var_name = "LB_NULL",
631 .arg_name = "--shm-size-multiplier",
632 .default_value = "1",
633 .description = OFFSET"DLB allocates its shared memory at the start of execution, with\n"
634 OFFSET"its size based on the number of CPUs in the node. If you\n"
635 OFFSET"encounter a DLB_ERR_NOMEM error, you can adjust the multiplier\n"
636 OFFSET"to increase the shared memory size. As a reference, with the\n"
637 OFFSET"default multiplier, the typical shared memory size on HPC\n"
638 OFFSET"machines is under 10 megabytes, so keep that in mind if you\n"
639 OFFSET"increase its size to allocate more running processes or TALP\n"
640 OFFSET"regions.",
641 .offset = offsetof(options_t, shm_size_multiplier),
642 .type = OPT_INT_T,
643 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_ADVANCED)
644 }, {
645 .var_name = "LB_PREINIT_PID",
646 .arg_name = "--preinit-pid",
647 .default_value = "0",
648 .description = OFFSET"Process ID that pre-initializes the DLB process for DROM.",
649 .offset = offsetof(options_t, preinit_pid),
650 .type = OPT_INT_T,
651 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_HIDDEN)
652 }, {
653 .var_name = "LB_NULL",
654 .arg_name = "--ompt-thread-manager",
655 .default_value = "omp5",
656 .description = OFFSET"OMPT Thread Manager version.",
657 .offset = offsetof(options_t, omptm_version),
658 .type = OPT_OMPTM_T,
659 .flags = (option_flags_t)(OPT_OPTIONAL)
660 }, {
661 .var_name = "LB_NULL",
662 .arg_name = "--plugin",
663 .default_value = "",
664 .description = OFFSET"Select plugin to enable.\n"
665 OFFSET"Available options: 'cupti', 'rocprofiler-sdk', or 'rocprofilerv2'.\n"
666 OFFSET"Deprecated: use --talp=gpu or --talp-gpu-backend.",
667 .offset = offsetof(options_t, deprecated_plugins),
668 .type = OPT_STR_T,
669 .flags = (option_flags_t)(OPT_READONLY | OPT_OPTIONAL | OPT_DEPRECATED)
670 }, {
671 .var_name = "LB_DEBUG_OPTS",
672 .arg_name = "--debug-opts",
673 .default_value = "",
674 .description = OFFSET"Debug options.",
675 .offset = offsetof(options_t, debug_opts),
676 .type = OPT_DBG_T,
677 .flags = (option_flags_t)(OPT_OPTIONAL | OPT_ADVANCED)
678 }
679 };
680 #undef OFFSET
681
682 enum { NUM_OPTIONS = sizeof(options_dictionary)/sizeof(opts_dict_t) };
683
684
685 570 static const opts_dict_t* get_entry_by_name(const char *name) {
686 int i;
687
2/2
✓ Branch 0 taken 10526 times.
✓ Branch 1 taken 2 times.
10528 for (i=0; i<NUM_OPTIONS; ++i) {
688 10526 const opts_dict_t *entry = &options_dictionary[i];
689
1/2
✓ Branch 0 taken 10526 times.
✗ Branch 1 not taken.
10526 if (strcasecmp(entry->var_name, name) == 0
690
2/2
✓ Branch 0 taken 568 times.
✓ Branch 1 taken 9958 times.
10526 || strcasecmp(entry->arg_name, name) == 0) {
691 568 return entry;
692 }
693 }
694 2 return NULL;
695 }
696
697 222 static int set_ptr_path_value(void *option, const char *str_value) {
698 222 int path_len = snprintf(NULL, 0, "%s", str_value) + 1;
699
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 221 times.
222 if (path_len > 1) {
700 1 *(char**)option = malloc(sizeof(char) * path_len);
701 1 snprintf(*(char**)option, path_len, "%s", str_value);
702 } else {
703 221 *(char**)option = NULL;
704 }
705 222 return DLB_SUCCESS;
706 }
707
708 10278 static int set_value(option_type_t type, void *option, const char *str_value) {
709
18/20
✓ Branch 0 taken 3915 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2047 times.
✓ Branch 3 taken 1135 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.
10278 switch(type) {
710 3915 case OPT_BOOL_T:
711 3915 return parse_bool(str_value, (bool*)option);
712 1 case OPT_NEG_BOOL_T:
713 1 return parse_negated_bool(str_value, (bool*)option);
714 2047 case OPT_INT_T:
715 2047 return parse_int(str_value, (int*)option);
716 1135 case OPT_STR_T:
717 1135 snprintf(option, MAX_OPTION_LENGTH, "%s", str_value);
718 1135 return DLB_SUCCESS;
719 222 case OPT_PTR_PATH_T:
720 222 return set_ptr_path_value(option, str_value);
721 283 case OPT_VB_T:
722 283 return parse_verbose_opts(str_value, (verbose_opts_t*)option);
723 223 case OPT_VBFMT_T:
724 223 return parse_verbose_fmt(str_value, (verbose_fmt_t*)option);
725 223 case OPT_INST_T:
726 223 return parse_instrument_items(str_value, (instrument_items_t*)option);
727 224 case OPT_DBG_T:
728 224 return parse_debug_opts(str_value, (debug_opts_t*)option);
729 223 case OPT_LEWI_AFF_T:
730 223 return parse_lewi_affinity(str_value, (lewi_affinity_t*)option);
731 case OPT_MASK_T:
732 mu_parse_mask(str_value, (cpu_set_t*)option);
733 return DLB_SUCCESS;
734 223 case OPT_MODE_T:
735 223 return parse_mode(str_value, (interaction_mode_t*)option);
736 224 case OPT_MPISET_T:
737 224 return parse_mpiset(str_value, (mpi_set_t*)option);
738 223 case OPT_OMPTOPTS_T:
739 223 return parse_omptool_opts(str_value, (omptool_opts_t*)option);
740 223 case OPT_TLPSUM_T:
741 223 return parse_talp_summary(str_value, (talp_summary_t*)option);
742 223 case OPT_TLPMOD_T:
743 223 return parse_talp_model(str_value, (talp_model_t*)option);
744 222 case OPT_TLPCOM_T:
745 222 return parse_talp_component(str_value, (talp_component_t*)option);
746 222 case OPT_MNGO_MODE_T:
747 222 return parse_mngo_mode(str_value, (mngo_mode_t*)option);
748 222 case OPT_OMPTM_T:
749 222 return parse_omptm_version(str_value, (omptm_version_t*)option);
750 }
751 return DLB_ERR_NOENT;
752 }
753
754 153 static const char * get_value(option_type_t type, const void *option) {
755 static char int_value[8];
756
17/20
✓ Branch 0 taken 65 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 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.
153 switch(type) {
757 65 case OPT_BOOL_T:
758
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 48 times.
65 return *(bool*)option ? "yes" : "no";
759 case OPT_NEG_BOOL_T:
760 return *(bool*)option ? "no" : "yes";
761 23 case OPT_INT_T:
762 23 sprintf(int_value, "%d", *(int*)option);
763 23 return int_value;
764 8 case OPT_STR_T:
765 8 return (char*)option;
766 4 case OPT_PTR_PATH_T:
767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 return *(const char**)option ? *(const char**)option : "";
768 4 case OPT_VB_T:
769 4 return verbose_opts_tostr(*(verbose_opts_t*)option);
770 4 case OPT_VBFMT_T:
771 4 return verbose_fmt_tostr(*(verbose_fmt_t*)option);
772 4 case OPT_INST_T:
773 4 return instrument_items_tostr(*(instrument_items_t*)option);
774 1 case OPT_DBG_T:
775 1 return debug_opts_tostr(*(debug_opts_t*)option);
776 4 case OPT_LEWI_AFF_T:
777 4 return lewi_affinity_tostr(*(lewi_affinity_t*)option);
778 case OPT_MASK_T:
779 return mu_to_str((cpu_set_t*)option);
780 8 case OPT_MODE_T:
781 8 return mode_tostr(*(interaction_mode_t*)option);
782 6 case OPT_MPISET_T:
783 6 return mpiset_tostr(*(mpi_set_t*)option);
784 4 case OPT_OMPTOPTS_T:
785 4 return omptool_opts_tostr(*(omptool_opts_t*)option);
786 4 case OPT_TLPSUM_T:
787 4 return talp_summary_tostr(*(talp_summary_t*)option);
788 1 case OPT_TLPMOD_T:
789 1 return talp_model_tostr(*(talp_model_t*)option);
790 5 case OPT_TLPCOM_T:
791 5 return talp_component_tostr(*(talp_component_t*)option);
792 4 case OPT_MNGO_MODE_T:
793 4 return mngo_mode_tostr(*(mngo_mode_t*)option);
794 4 case OPT_OMPTM_T:
795 4 return omptm_version_tostr(*(omptm_version_t*)option);
796 }
797 return "unknown";
798 }
799
800 5 static bool values_are_equivalent(option_type_t type, const char *value1, const char *value2) {
801
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) {
802 5 case OPT_BOOL_T:
803 5 return equivalent_bool(value1, value2);
804 case OPT_NEG_BOOL_T:
805 return equivalent_negated_bool(value1, value2);
806 case OPT_INT_T:
807 return equivalent_int(value1, value2);
808 case OPT_STR_T:
809 return strcmp(value1, value2) == 0;
810 case OPT_PTR_PATH_T:
811 return *(const char**)value1 && *(const char**)value2
812 && strcmp(*(const char**)value1, *(const char**)value2) == 0;
813 case OPT_VB_T:
814 return equivalent_verbose_opts(value1, value2);
815 case OPT_VBFMT_T:
816 return equivalent_verbose_fmt(value1, value2);
817 case OPT_INST_T:
818 return equivalent_instrument_items(value1, value2);
819 case OPT_DBG_T:
820 return equivalent_debug_opts(value1, value2);
821 case OPT_LEWI_AFF_T:
822 return equivalent_lewi_affinity(value1, value2);
823 case OPT_MASK_T:
824 return mu_equivalent_masks(value1, value2);
825 case OPT_MODE_T:
826 return equivalent_mode(value1, value2);
827 case OPT_MPISET_T:
828 return equivalent_mpiset(value1, value2);
829 case OPT_OMPTOPTS_T:
830 return equivalent_omptool_opts(value1, value2);
831 case OPT_TLPSUM_T:
832 return equivalent_talp_summary(value1, value2);
833 case OPT_TLPMOD_T:
834 return equivalent_talp_model(value1, value2);
835 case OPT_TLPCOM_T:
836 return equivalent_talp_component(value1, value2);
837 case OPT_MNGO_MODE_T:
838 return equivalent_mngo_mode(value1, value2);
839 case OPT_OMPTM_T:
840 return equivalent_omptm_version_opts(value1, value2);
841 }
842 return false;
843 }
844
845 16 static void copy_value(option_type_t type, void *dest, const char *src) {
846
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) {
847 1 case OPT_BOOL_T:
848 1 memcpy(dest, src, sizeof(bool));
849 1 break;
850 1 case OPT_NEG_BOOL_T:
851 1 memcpy(dest, src, sizeof(bool));
852 1 break;
853 3 case OPT_INT_T:
854 3 memcpy(dest, src, sizeof(int));
855 3 break;
856 2 case OPT_STR_T:
857 2 memcpy(dest, src, sizeof(char)*MAX_OPTION_LENGTH);
858 2 break;
859 case OPT_PTR_PATH_T:
860 fatal("copy_value of type OPT_PTR_PATH_T not supported");
861 break;
862 1 case OPT_VB_T:
863 1 memcpy(dest, src, sizeof(verbose_opts_t));
864 1 break;
865 1 case OPT_VBFMT_T:
866 1 memcpy(dest, src, sizeof(verbose_fmt_t));
867 1 break;
868 1 case OPT_INST_T:
869 1 memcpy(dest, src, sizeof(instrument_items_t));
870 1 break;
871 case OPT_DBG_T:
872 memcpy(dest, src, sizeof(debug_opts_t));
873 break;
874 1 case OPT_LEWI_AFF_T:
875 1 memcpy(dest, src, sizeof(lewi_affinity_t));
876 1 break;
877 case OPT_MASK_T:
878 memcpy(dest, src, sizeof(cpu_set_t));
879 break;
880 1 case OPT_MODE_T:
881 1 memcpy(dest, src, sizeof(interaction_mode_t));
882 1 break;
883 1 case OPT_MPISET_T:
884 1 memcpy(dest, src, sizeof(mpi_set_t));
885 1 break;
886 1 case OPT_OMPTOPTS_T:
887 1 memcpy(dest, src, sizeof(omptool_opts_t));
888 1 break;
889 1 case OPT_TLPSUM_T:
890 1 memcpy(dest, src, sizeof(talp_summary_t));
891 1 break;
892 1 case OPT_TLPMOD_T:
893 1 memcpy(dest, src, sizeof(talp_model_t));
894 1 break;
895 case OPT_TLPCOM_T:
896 memcpy(dest, src, sizeof(talp_component_t));
897 break;
898 case OPT_MNGO_MODE_T:
899 memcpy(dest, src, sizeof(mngo_mode_t));
900 break;
901 case OPT_OMPTM_T:
902 memcpy(dest, src, sizeof(omptm_version_t));
903 break;
904 }
905 16 }
906
907 /* Parse DLB_ARGS and remove argument if found */
908 17507 static void parse_dlb_args(char *dlb_args, const char *arg_name, char* arg_value, size_t arg_max_len) {
909 17507 *arg_value = 0;
910 /* Tokenize a copy of dlb_args with " "(blank) delimiter */
911 17507 char *progress = dlb_args;
912 17507 char *end_space = NULL;
913 17507 size_t len = strlen(dlb_args) + 1;
914 17507 char *dlb_args_copy = malloc(sizeof(char)*len);
915 17507 strcpy(dlb_args_copy, dlb_args);
916 17507 char *token = strtok_r(dlb_args_copy, " ", &end_space);
917
2/2
✓ Branch 0 taken 12958 times.
✓ Branch 1 taken 17507 times.
30465 while (token) {
918 /* Each token is a complete string representing an option */
919
920 12958 bool remove_token = false;
921 /* token length must be computed before tokenizing into arg=val */
922 12958 size_t token_len = strlen(token);
923 /* progress pointer must be updated each iteration to skip spaces */
924
2/2
✓ Branch 0 taken 18328 times.
✓ Branch 1 taken 12958 times.
31286 while(isspace((unsigned char)*progress)) progress++;
925
926
2/2
✓ Branch 0 taken 11735 times.
✓ Branch 1 taken 1223 times.
12958 if (strchr(token, '=')) {
927 /* Option is of the form --argument=value */
928 11735 char *end_equal = NULL;
929 11735 char *argument = strtok_r(token, "=", &end_equal);
930
2/2
✓ Branch 0 taken 413 times.
✓ Branch 1 taken 11322 times.
11735 if (strcmp(argument, arg_name) == 0) {
931 /* Obtain value */
932 413 char *value = strtok_r(NULL, "=", &end_equal);
933
2/2
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 1 times.
413 if (value) {
934 412 snprintf(arg_value, arg_max_len, "%s", value);
935 } else {
936 1 warning("Bad format parsing of DLB_ARGS. Option %s with empty value", token);
937 }
938 413 remove_token = true;
939 }
940 } else {
941 /* Option is of the form --argument/--no-argument */
942 1223 char *argument = token;
943
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 1017 times.
1223 if (strcmp(argument, arg_name) == 0) {
944 /* Option value is 'yes' */
945 206 strcpy(arg_value, "yes");
946 206 remove_token = true;
947
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 999 times.
1017 } else if (strncmp(argument, "--no-", 5) == 0
948
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 5 times.
18 && strcmp(argument+5, arg_name+2) == 0) {
949 /* Option value is 'no' */
950 13 strcpy(arg_value, "no");
951 13 remove_token = true;
952 }
953 }
954
955
2/2
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 12326 times.
12958 if (remove_token) {
956 /* Remove token from dlb_args */
957 632 char *dest = progress;
958 632 char *src = progress + token_len;
959 632 size_t n = strlen(src) + 1;
960 632 memmove(dest, src, n);
961 } else {
962 /* Token is not removed, update parsed progress pointer */
963 12326 progress += token_len;
964 }
965
966 /* next token */
967 12958 token = strtok_r(NULL, " ", &end_space);
968 }
969 17507 free(dlb_args_copy);
970 17507 }
971
972 /* Initialize options struct from either argument, or env. variable */
973 222 void options_init(options_t *options, const char *dlb_args) {
974 /* Copy dlb_args into a local buffer */
975 222 char *dlb_args_from_api = NULL;
976
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 44 times.
222 if (dlb_args) {
977 178 size_t len = strlen(dlb_args) + 1;
978 178 dlb_args_from_api = malloc(sizeof(char)*len);
979 178 strcpy(dlb_args_from_api, dlb_args);
980 }
981
982 /* Copy either DLB_ARGS or LB_ARGS into a local buffer */
983 222 char *dlb_args_from_env = NULL;
984 222 const char *env = getenv("DLB_ARGS");
985
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 181 times.
222 if (!env) {
986 41 env = getenv("LB_ARGS");
987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (env) {
988 warning("LB_ARGS is deprecated, please use DLB_ARGS");
989 }
990 }
991
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 41 times.
222 if (env) {
992 181 size_t len = strlen(env) + 1;
993 181 dlb_args_from_env = malloc(sizeof(char)*len);
994 181 strcpy(dlb_args_from_env, env);
995 }
996
997 /* Preallocate two buffers large enough to save any intermediate option value */
998 222 char *arg_value_from_api = malloc(sizeof(char)*PATH_MAX);
999 222 char *arg_value_from_env = malloc(sizeof(char)*PATH_MAX);
1000
1001 int i;
1002
2/2
✓ Branch 0 taken 10656 times.
✓ Branch 1 taken 222 times.
10878 for (i=0; i<NUM_OPTIONS; ++i) {
1003 10656 const opts_dict_t *entry = &options_dictionary[i];
1004 10656 const char *rhs = NULL; /* pointer to rhs to be parsed */
1005
1006 /* Set-up specific argument length */
1007 size_t arg_max_len;
1008
2/2
✓ Branch 0 taken 222 times.
✓ Branch 1 taken 10434 times.
10656 switch (entry->type) {
1009 222 case OPT_PTR_PATH_T:
1010 222 arg_max_len = PATH_MAX-1;
1011 222 break;
1012 10434 default:
1013 10434 arg_max_len = MAX_OPTION_LENGTH-1;
1014 10434 break;
1015 }
1016
1017 /* Reset intermediate buffers */
1018 10656 arg_value_from_api[0] = '\0';
1019 10656 arg_value_from_env[0] = '\0';
1020
1021 /* Parse dlb_args from API */
1022
2/2
✓ Branch 0 taken 8544 times.
✓ Branch 1 taken 2112 times.
10656 if (dlb_args_from_api) {
1023 8544 parse_dlb_args(dlb_args_from_api, entry->arg_name, arg_value_from_api, arg_max_len);
1024
2/2
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 8082 times.
8544 if (strlen(arg_value_from_api) > 0) {
1025 462 rhs = arg_value_from_api;
1026 }
1027 }
1028
1029 /* Parse DLB_ARGS from env */
1030
2/2
✓ Branch 0 taken 8688 times.
✓ Branch 1 taken 1968 times.
10656 if (dlb_args_from_env) {
1031 8688 parse_dlb_args(dlb_args_from_env, entry->arg_name, arg_value_from_env, arg_max_len);
1032
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 8564 times.
8688 if (strlen(arg_value_from_env) > 0) {
1033
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)) {
1034 1 warning("Overwriting option %s = %s",
1035 1 entry->arg_name, arg_value_from_env);
1036 }
1037 124 rhs = arg_value_from_env;
1038 }
1039 }
1040
1041 /* Parse LB_option (to be deprecated soon) */
1042 10656 const char *arg_value = getenv(entry->var_name);
1043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10656 times.
10656 if (arg_value) {
1044 if (rhs) {
1045 warning("Ignoring option %s = %s due to DLB_ARGS precedence",
1046 entry->var_name, arg_value);
1047 } else {
1048 warning("Option %s is to be deprecated in the near future, please use DLB_ARGS",
1049 entry->var_name);
1050 rhs = arg_value;
1051 }
1052 }
1053
1054 /* Warn if option is deprecated and has rhs */
1055
4/4
✓ Branch 0 taken 1332 times.
✓ Branch 1 taken 9324 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1323 times.
10656 if (entry->flags & OPT_DEPRECATED && rhs) {
1056 9 warning("Option %s is deprecated:\n%s", entry->arg_name, entry->description);
1057 }
1058
1059 /* Skip iteration if option is not used anymore */
1060
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 9990 times.
10656 if (entry->flags & OPT_UNUSED) {
1061 666 continue;
1062 }
1063
1064 /* Check offset is valid at this point */
1065
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9990 times.
9990 ensure(entry->offset < sizeof(options_t), "Offset value in options directory not valid");
1066
1067 /* Assign option = rhs, and nullify rhs if error */
1068
2/2
✓ Branch 0 taken 579 times.
✓ Branch 1 taken 9411 times.
9990 if (rhs) {
1069 579 int error = set_value(entry->type, (char*)options+entry->offset, rhs);
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 579 times.
579 if (error) {
1071 warning("Unrecognized %s value: %s. Setting default %s",
1072 entry->arg_name, rhs, entry->default_value);
1073 rhs = NULL;
1074 }
1075 }
1076
1077 /* Set default value if needed */
1078
2/2
✓ Branch 0 taken 9411 times.
✓ Branch 1 taken 579 times.
9990 if (rhs == NULL) {
1079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9411 times.
9411 fatal_cond(!(entry->flags & OPT_OPTIONAL),
1080 "Variable %s must be defined", entry->arg_name);
1081 9411 int error = set_value(entry->type, (char*)options+entry->offset, entry->default_value);
1082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9411 times.
9411 fatal_cond(error, "Internal error parsing default value %s=%s. Please, report bug at %s.",
1083 entry->arg_name, entry->default_value, PACKAGE_BUGREPORT);
1084 }
1085 }
1086
1087 /* Temporarily support deprecated TALP options */
1088
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 219 times.
222 if (options->deprecated_talp_openmp) {
1089 3 options->talp |= TALP_COMPONENT_OPENMP;
1090 }
1091
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 220 times.
222 if (options->deprecated_talp_papi) {
1092 2 options->talp |= TALP_COMPONENT_HWC;
1093 }
1094
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 220 times.
222 if (options->deprecated_plugins[0] != '\0' &&
1095
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 (strncmp(options->deprecated_plugins, "cupti", MAX_OPTION_LENGTH-1) == 0
1096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 || strncmp(options->deprecated_plugins, "rocprofiler-sdk", MAX_OPTION_LENGTH-1) == 0
1097 || strncmp(options->deprecated_plugins, "rocprofilerv2", MAX_OPTION_LENGTH-1) == 0)) {
1098 2 options->talp |= TALP_COMPONENT_GPU;
1099
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (options->talp_gpu_backend[0] == '\0') {
1100 2 strcpy(options->talp_gpu_backend, options->deprecated_plugins);
1101 }
1102 }
1103
1104 /* MNGO required options */
1105
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 208 times.
222 if (options->mngo){
1106
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) ) {
1107 warning("MNGO without LeWI nor DROM won't be able to take any"
1108 " action.");
1109 }
1110
1111 // Enable the TALP MPI component in external mode
1112 14 options->talp |= TALP_COMPONENT_MPI;
1113 14 options->talp_external_profiler = true;
1114 }
1115
1116 /* Free intermediate buffers */
1117 222 free(arg_value_from_api);
1118 222 free(arg_value_from_env);
1119
1120 /* Safety checks and free local buffers */
1121
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 44 times.
222 if (dlb_args_from_api) {
1122 178 char *str = dlb_args_from_api;
1123
2/2
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 178 times.
486 while(isspace((unsigned char)*str)) str++;
1124
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 176 times.
178 if (strlen(str) > 0) {
1125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (options->debug_opts & DBG_WERROR) {
1126 fatal("Unrecognized flags from DLB_Init: %s", str);
1127 } else {
1128 2 warning("Unrecognized flags from DLB_Init: %s", str);
1129 }
1130 }
1131 178 free(dlb_args_from_api);
1132 }
1133
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 41 times.
222 if (dlb_args_from_env) {
1134 181 char *str = dlb_args_from_env;
1135
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 181 times.
461 while(isspace((unsigned char)*str)) str++;
1136
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 180 times.
181 if (strlen(str) > 0) {
1137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (options->debug_opts & DBG_WERROR) {
1138 fatal("Unrecognized flags from DLB_ARGS: %s", str);
1139 } else {
1140 1 warning("Unrecognized flags from DLB_ARGS: %s", str);
1141 }
1142 }
1143 181 free(dlb_args_from_env);
1144 }
1145 222 }
1146
1147 121 void options_finalize(options_t *options) {
1148
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 120 times.
121 if (options->talp_output_file) {
1149 1 free(options->talp_output_file);
1150 1 options->talp_output_file = NULL;
1151 }
1152 121 }
1153
1154 /* Obtain value of specific entry, either from DLB_ARGS or from thread_spd->options */
1155 300 void options_parse_entry(const char *var_name, void *option) {
1156 300 const opts_dict_t *entry = get_entry_by_name(var_name);
1157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 300 times.
300 ensure(entry, "%s: bad variable name '%s'", __func__, var_name);
1158
1159
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) {
1160 16 copy_value(entry->type, option, (char*)&thread_spd->options + entry->offset);
1161 } else {
1162 /* Simplified options_init just for this entry */
1163
1164 /* Copy DLB_ARGS into a local buffer */
1165 284 char *dlb_args_from_env = NULL;
1166 284 const char *env = getenv("DLB_ARGS");
1167
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 9 times.
284 if (env) {
1168 275 size_t len = strlen(env) + 1;
1169 275 dlb_args_from_env = malloc(sizeof(char)*len);
1170 275 strcpy(dlb_args_from_env, env);
1171 }
1172
1173 /* Pointer to rhs to be parsed */
1174 284 const char *rhs = NULL;
1175
1176 /* Set-up specific argument length */
1177 size_t arg_max_len;
1178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 284 times.
284 switch (entry->type) {
1179 case OPT_PTR_PATH_T:
1180 arg_max_len = PATH_MAX-1;
1181 break;
1182 284 default:
1183 284 arg_max_len = MAX_OPTION_LENGTH-1;
1184 284 break;
1185 }
1186
1187 /* Preallocate a buffer large enough to save the option value */
1188 284 char *arg_value_from_env = malloc(sizeof(char)*(arg_max_len+1));
1189 284 arg_value_from_env[0] = '\0';
1190
1191 /* Parse DLB_ARGS from env */
1192
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 9 times.
284 if (dlb_args_from_env) {
1193 275 parse_dlb_args(dlb_args_from_env, entry->arg_name, arg_value_from_env, arg_max_len);
1194
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 245 times.
275 if (strlen(arg_value_from_env) > 0) {
1195 30 rhs = arg_value_from_env;
1196 }
1197 }
1198
1199 /* Assign option = rhs, and nullify rhs if error */
1200
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 254 times.
284 if (rhs) {
1201 30 int error = set_value(entry->type, option, rhs);
1202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (error) {
1203 rhs = NULL;
1204 }
1205 }
1206
1207 /* Set default value if needed */
1208
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 30 times.
284 if (!rhs) {
1209 254 set_value(entry->type, option, entry->default_value);
1210 }
1211
1212 /* Free buffers */
1213 284 free(arg_value_from_env);
1214
2/2
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 9 times.
284 if (dlb_args_from_env) {
1215 275 free(dlb_args_from_env);
1216 }
1217 }
1218 300 }
1219
1220 /* API Setter */
1221 8 int options_set_variable(options_t *options, const char *var_name, const char *value) {
1222 int error;
1223 8 const opts_dict_t *entry = get_entry_by_name(var_name);
1224
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (entry) {
1225
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (entry->flags & OPT_READONLY) {
1226 3 error = DLB_ERR_PERM;
1227 } else {
1228 4 error = set_value(entry->type, (char*)options+entry->offset, value);
1229 }
1230 } else {
1231 1 error = DLB_ERR_NOENT;
1232 }
1233
1234 8 return error;
1235 }
1236
1237 /* API Getter */
1238 14 int options_get_variable(const options_t *options, const char *var_name, char *value) {
1239 int error;
1240 14 const opts_dict_t *entry = get_entry_by_name(var_name);
1241
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 if (entry) {
1242 13 sprintf(value, "%s", get_value(entry->type, (char*)options+entry->offset));
1243 13 error = DLB_SUCCESS;
1244 } else {
1245 1 error = DLB_ERR_NOENT;
1246 }
1247
1248 14 return error;
1249 }
1250
1251 /* API Printer. Also, dlb -h/-hh output */
1252 4 void options_print_variables(const options_t *options, bool print_extended) {
1253
1254 /* Initialize buffer */
1255 print_buffer_t buffer;
1256 4 printbuffer_init(&buffer);
1257
1258 /* Set up intermediate buffer per entry */
1259 enum { MAX_ENTRY_LEN = 256 };
1260 char entry_buffer[MAX_ENTRY_LEN];
1261
1262 /* Header (last \n is not needed) */
1263 4 printbuffer_append(&buffer,
1264 "DLB Options:\n\n"
1265 "DLB is configured by setting these flags in the DLB_ARGS environment variable.\n"
1266 "Possible options are listed below:\n\n"
1267 "Option Current value Possible value (type) / [choice] / {val1:val2}\n"
1268 "--------------------------------------------------------------------------------------"
1269 );
1270
1271 int i;
1272
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 4 times.
196 for (i=0; i<NUM_OPTIONS; ++i) {
1273 192 const opts_dict_t *entry = &options_dictionary[i];
1274
1275 /* Skip if deprecated */
1276
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 168 times.
192 if (entry->flags & OPT_DEPRECATED) continue;
1277
1278 /* Skip if hidden */
1279
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 164 times.
168 if (entry->flags & OPT_HIDDEN) continue;
1280
1281 /* Skip if advanced (unless print_extended) */
1282
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 132 times.
164 if (entry->flags & OPT_ADVANCED
1283
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 && !print_extended) continue;
1284
1285 /* Reset entry buffer */
1286 140 entry_buffer[0] = '\0';
1287 140 char *b = entry_buffer;
1288 140 size_t max_entry_len = MAX_ENTRY_LEN;
1289
1290 /* Name */
1291 140 size_t name_len = strlen(entry->arg_name) + 1;
1292
2/2
✓ Branch 0 taken 127 times.
✓ Branch 1 taken 13 times.
140 if (name_len < 24) {
1293 /* Option + tabs until column 24 */
1294
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 24 times.
230 b += snprintf(b, max_entry_len, "%s:%s",
1295 127 entry->arg_name,
1296
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 51 times.
103 name_len < 8 ? "\t\t\t" : name_len < 16 ? "\t\t" : "\t");
1297 } else {
1298 /* Long option, break line */
1299 13 b += snprintf(b, max_entry_len, "%s:\n\t\t\t",
1300 13 entry->arg_name);
1301 }
1302
1303 /* Check if output was truncated, and update remaining entry length */
1304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 fatal_cond((b - entry_buffer) >= MAX_ENTRY_LEN,
1305 "Output truncated in in %s. Please report bug at %s",
1306 __func__, PACKAGE_BUGREPORT);
1307 140 max_entry_len = MAX_ENTRY_LEN - (b - entry_buffer);
1308
1309 /* Value */
1310 140 const char *value = get_value(entry->type, (char*)options+entry->offset);
1311 140 size_t value_len = strlen(value) + 1;
1312
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 123 times.
157 b += snprintf(b, max_entry_len, "%s %s",
1313 value,
1314
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 value_len < 8 ? "\t\t" : value_len < 16 ? "\t" : "");
1315
1316 /* Check if output was truncated, and update remaining entry length */
1317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 fatal_cond((b - entry_buffer) >= MAX_ENTRY_LEN,
1318 "Output truncated in in %s. Please report bug at %s",
1319 __func__, PACKAGE_BUGREPORT);
1320 140 max_entry_len = MAX_ENTRY_LEN - (b - entry_buffer);
1321
1322 /* Choices */
1323
17/20
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 7 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.
140 switch(entry->type) {
1324 60 case OPT_BOOL_T:
1325 60 b += snprintf(b, max_entry_len, "(bool)");
1326 60 break;
1327 case OPT_NEG_BOOL_T:
1328 b += snprintf(b, max_entry_len, "(bool)");
1329 break;
1330 23 case OPT_INT_T:
1331 23 b += snprintf(b, max_entry_len, "(int)");
1332 23 break;
1333 7 case OPT_STR_T:
1334 7 b += snprintf(b, max_entry_len, "(string)");
1335 7 break;
1336 4 case OPT_PTR_PATH_T:
1337 4 b += snprintf(b, max_entry_len, "(path)");
1338 4 break;
1339 4 case OPT_VB_T:
1340 4 b += snprintf(b, max_entry_len, "{%s}", get_verbose_opts_choices());
1341 4 break;
1342 4 case OPT_VBFMT_T:
1343 4 b += snprintf(b, max_entry_len, "{%s}", get_verbose_fmt_choices());
1344 4 break;
1345 4 case OPT_INST_T:
1346 4 b += snprintf(b, max_entry_len, "{%s}", get_instrument_items_choices());
1347 4 break;
1348 1 case OPT_DBG_T:
1349 1 b += snprintf(b, max_entry_len, "{%s}", get_debug_opts_choices());
1350 1 break;
1351 4 case OPT_LEWI_AFF_T:
1352 4 b += snprintf(b, max_entry_len, "[%s]", get_lewi_affinity_choices());
1353 4 break;
1354 case OPT_MASK_T:
1355 b += snprintf(b, max_entry_len, "(cpuset)");
1356 break;
1357 4 case OPT_MODE_T:
1358 4 b += snprintf(b, max_entry_len, "[%s]", get_mode_choices());
1359 4 break;
1360 4 case OPT_MPISET_T:
1361 4 b += snprintf(b, max_entry_len, "[%s]", get_mpiset_choices());
1362 4 break;
1363 4 case OPT_OMPTOPTS_T:
1364 4 b += snprintf(b, max_entry_len, "[%s]", get_omptool_opts_choices());
1365 4 break;
1366 4 case OPT_TLPSUM_T:
1367 4 b += snprintf(b, max_entry_len, "{%s}", get_talp_summary_choices());
1368 4 break;
1369 1 case OPT_TLPMOD_T:
1370 1 b += snprintf(b, max_entry_len, "[%s]", get_talp_model_choices());
1371 1 break;
1372 4 case OPT_TLPCOM_T:
1373 4 b += snprintf(b, max_entry_len, "{%s}", get_talp_component_choices());
1374 4 break;
1375 4 case OPT_MNGO_MODE_T:
1376 4 b += snprintf(b, max_entry_len, "{%s}", get_mngo_mode_choices());
1377 4 break;
1378 4 case OPT_OMPTM_T:
1379 4 b += snprintf(b, max_entry_len, "[%s]", get_omptm_version_choices());
1380 4 break;
1381 }
1382
1383 /* Check if output was truncated */
1384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 fatal_cond((b - entry_buffer) >= MAX_ENTRY_LEN,
1385 "Buffer overflow in %s. Please report bug at %s",
1386 __func__, PACKAGE_BUGREPORT);
1387
1388 /* Append entry listing */
1389 140 printbuffer_append(&buffer, entry_buffer);
1390
1391 /* Append long description if print_extended */
1392
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 99 times.
140 if (print_extended) {
1393 41 printbuffer_append(&buffer, entry->description);
1394 41 printbuffer_append(&buffer, "");
1395 }
1396
1397 }
1398
1399 /* Footer (last \n is not needed) */
1400 4 printbuffer_append(&buffer,
1401 "\n"
1402 "Boolean options accept both standalone flags and 'yes'/'no' parameters.\n"
1403 "These are equivalent flags:\n"
1404 " export DLB_ARGS=\"--lewi --no-drom\"\n"
1405 " export DLB_ARGS=\"--lewi=yes --drom=no\"");
1406
1407 /* This function must print always and ignore options --quiet and --silent */
1408 4 info0_force_print("%s", buffer.addr);
1409
1410 4 printbuffer_destroy(&buffer);
1411 4 }
1412
1413 /* Print which LeWI flags are enabled during DLB_Init */
1414 62 void options_print_lewi_flags(const options_t *options) {
1415 const opts_dict_t *entry;
1416
1417 // --lewi-mpi
1418 bool default_lewi_keep_one_cpu;
1419 62 entry = get_entry_by_name("--lewi-keep-one-cpu");
1420 62 parse_bool(entry->default_value, &default_lewi_keep_one_cpu);
1421
1422 // --lewi-mpi-calls
1423 mpi_set_t default_lewi_mpi_calls;
1424 62 entry = get_entry_by_name("--lewi-mpi-calls");
1425 62 parse_mpiset(entry->default_value, &default_lewi_mpi_calls);
1426
1427 // --lewi-affinity
1428 lewi_affinity_t default_lewi_affinity;
1429 62 entry = get_entry_by_name("--lewi-affinity");
1430 62 parse_lewi_affinity(entry->default_value, &default_lewi_affinity);
1431
1432 // --lewi-ompt
1433 omptool_opts_t default_lewi_ompt;
1434 62 entry = get_entry_by_name("--lewi-ompt");
1435 62 parse_omptool_opts(entry->default_value, &default_lewi_ompt);
1436
1437
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
1438
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 || options->lewi_mpi_calls != default_lewi_mpi_calls
1439
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
62 || options->lewi_affinity != default_lewi_affinity
1440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 || options->lewi_ompt != default_lewi_ompt) {
1441 30 info0("LeWI options:");
1442
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) {
1443 info0(" --lewi-keep-one-cpu");
1444 }
1445
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (options->lewi_mpi_calls != default_lewi_mpi_calls) {
1446 info0(" --lewi-mpi-calls=%s", mpiset_tostr(options->lewi_mpi_calls));
1447 }
1448
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (options->lewi_affinity != default_lewi_affinity) {
1449 30 info0(" --lewi-affinity=%s", lewi_affinity_tostr(options->lewi_affinity));
1450 }
1451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (options->lewi_ompt != default_lewi_ompt) {
1452 info0(" --lewi-ompt=%s", omptool_opts_tostr(options->lewi_ompt));
1453 }
1454 }
1455 62 }
1456