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