Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'surf++'
[simgrid.git] / src / simgrid / sg_config.c
1 /* Copyright (c) 2009-2010, 2012-2013. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /* sg_config: configuration infrastructure for the simulation world       */
8
9 #include "xbt/misc.h"
10 #include "xbt/config.h"
11 #include "xbt/log.h"
12 #include "xbt/mallocator.h"
13 #include "xbt/str.h"
14 #include "xbt/lib.h"
15 #include "xbt/sysdep.h"
16 #include "surf/surf.h"
17 #include "surf/maxmin.h"
18 #include "instr/instr_interface.h"
19 #include "simgrid/simix.h"
20 #include "simgrid/sg_config.h"
21 #include "smpi/smpi_interface.h"
22 #include "mc/mc.h"
23 #include "instr/instr.h"
24
25 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_config, surf,
26                                 "About the configuration of simgrid");
27
28 xbt_cfg_t _sg_cfg_set = NULL;
29
30 /* 0: beginning of time (config cannot be changed yet);
31  * 1: initialized: cfg_set created (config can now be changed);
32  * 2: configured: command line parsed and config part of platform file was
33  *    integrated also, platform construction ongoing or done.
34  *    (Config cannot be changed anymore!)
35  */
36 int _sg_cfg_init_status = 0;
37
38 /* instruct the upper layer (simix or simdag) to exit as soon as possible
39  */
40 int _sg_cfg_exit_asap = 0;
41
42 #define sg_cfg_exit_early() do { _sg_cfg_exit_asap = 1; return; } while (0)
43
44 /* Parse the command line, looking for options */
45 static void sg_config_cmd_line(int *argc, char **argv)
46 {
47   int shall_exit = 0;
48   int i, j;
49   char *opt;
50
51   for (j = i = 1; i < *argc; i++) {
52     if (!strncmp(argv[i], "--cfg=", strlen("--cfg="))) {
53       opt = strchr(argv[i], '=');
54       opt++;
55
56       xbt_cfg_set_parse(_sg_cfg_set, opt);
57       XBT_DEBUG("Did apply '%s' as config setting", opt);
58     } else if (!strcmp(argv[i], "--version")) {
59       printf("%s\n", SIMGRID_VERSION_STRING);
60       shall_exit = 1;
61     } else if (!strcmp(argv[i], "--cfg-help") || !strcmp(argv[i], "--help")) {
62       printf
63           ("Description of the configuration accepted by this simulator:\n");
64       xbt_cfg_help(_sg_cfg_set);
65       printf(
66 "\n"
67 "Each of these configurations can be used by adding\n"
68 "    --cfg=<option name>:<option value>\n"
69 "to the command line.\n"
70 "You can also use --help-models to see the details of all models known by this simulator.\n"
71 #ifdef HAVE_TRACING
72 "\n"
73 "You can also use --help-tracing to see the details of all tracing options known by this simulator.\n"
74 #endif
75 "\n"
76 "You can also use --help-logs and --help-log-categories to see the details of logging output.\n"
77 "\n"
78 "You can also use --version to get SimGrid version information.\n"
79 "\n"
80         );
81       shall_exit = 1;
82     } else if (!strcmp(argv[i], "--help-models")) {
83       int k;
84
85       model_help("workstation", surf_workstation_model_description);
86       printf("\n");
87       model_help("CPU", surf_cpu_model_description);
88       printf("\n");
89       model_help("network", surf_network_model_description);
90       printf("\nLong description of all optimization levels accepted by the models of this simulator:\n");
91       for (k = 0; surf_optimization_mode_description[k].name; k++)
92         printf("  %s: %s\n",
93                surf_optimization_mode_description[k].name,
94                surf_optimization_mode_description[k].description);
95       printf("Both network and CPU models have 'Lazy' as default optimization level\n\n");
96       shall_exit = 1;
97 #ifdef HAVE_TRACING
98     } else if (!strcmp(argv[i], "--help-tracing")) {
99       TRACE_help (1);
100       shall_exit = 1;
101 #endif
102     } else {
103       argv[j++] = argv[i];
104     }
105   }
106   if (j < *argc) {
107     argv[j] = NULL;
108     *argc = j;
109   }
110   if (shall_exit)
111     sg_cfg_exit_early();
112 }
113
114 /* callback of the workstation/model variable */
115 static void _sg_cfg_cb__workstation_model(const char *name, int pos)
116 {
117   char *val;
118
119   xbt_assert(_sg_cfg_init_status < 2,
120               "Cannot change the model after the initialization");
121
122   val = xbt_cfg_get_string(_sg_cfg_set, name);
123
124   if (!strcmp(val, "help")) {
125     model_help("workstation", surf_workstation_model_description);
126     sg_cfg_exit_early();
127   }
128
129   /* Make sure that the model exists */
130   find_model_description(surf_workstation_model_description, val);
131 }
132
133 /* callback of the vm_workstation/model variable */
134 static void _sg_cfg_cb__vm_workstation_model(const char *name, int pos)
135 {
136   char *val;
137
138   xbt_assert(_sg_cfg_init_status < 2,
139               "Cannot change the model after the initialization");
140
141   val = xbt_cfg_get_string(_sg_cfg_set, name);
142
143   if (!strcmp(val, "help")) {
144     model_help("vm_workstation", surf_vm_workstation_model_description);
145     sg_cfg_exit_early();
146   }
147
148   /* Make sure that the model exists */
149   find_model_description(surf_vm_workstation_model_description, val);
150 }
151
152 /* callback of the cpu/model variable */
153 static void _sg_cfg_cb__cpu_model(const char *name, int pos)
154 {
155   char *val;
156
157   xbt_assert(_sg_cfg_init_status < 2,
158               "Cannot change the model after the initialization");
159
160   val = xbt_cfg_get_string(_sg_cfg_set, name);
161
162   if (!strcmp(val, "help")) {
163     model_help("CPU", surf_cpu_model_description);
164     sg_cfg_exit_early();
165   }
166
167   /* New Module missing */
168   find_model_description(surf_cpu_model_description, val);
169 }
170
171 /* callback of the cpu/model variable */
172 static void _sg_cfg_cb__optimization_mode(const char *name, int pos)
173 {
174   char *val;
175
176   xbt_assert(_sg_cfg_init_status < 2,
177               "Cannot change the model after the initialization");
178
179   val = xbt_cfg_get_string(_sg_cfg_set, name);
180
181   if (!strcmp(val, "help")) {
182     model_help("optimization", surf_optimization_mode_description);
183     sg_cfg_exit_early();
184   }
185
186   /* New Module missing */
187   find_model_description(surf_optimization_mode_description, val);
188 }
189
190 /* callback of the cpu/model variable */
191 static void _sg_cfg_cb__storage_mode(const char *name, int pos)
192 {
193   char *val;
194
195   xbt_assert(_sg_cfg_init_status < 2,
196               "Cannot change the model after the initialization");
197
198   val = xbt_cfg_get_string(_sg_cfg_set, name);
199
200   if (!strcmp(val, "help")) {
201     model_help("storage", surf_storage_model_description);
202     sg_cfg_exit_early();
203   }
204
205   /* New Module missing */
206   find_model_description(surf_storage_model_description, val);
207 }
208
209 /* callback of the workstation_model variable */
210 static void _sg_cfg_cb__network_model(const char *name, int pos)
211 {
212   char *val;
213
214   xbt_assert(_sg_cfg_init_status < 2,
215               "Cannot change the model after the initialization");
216
217   val = xbt_cfg_get_string(_sg_cfg_set, name);
218
219   if (!strcmp(val, "help")) {
220     model_help("network", surf_network_model_description);
221     sg_cfg_exit_early();
222   }
223
224   /* New Module missing */
225   find_model_description(surf_network_model_description, val);
226 }
227
228 /* callbacks of the network models values */
229 static void _sg_cfg_cb__tcp_gamma(const char *name, int pos)
230 {
231   sg_tcp_gamma = xbt_cfg_get_double(_sg_cfg_set, name);
232 }
233
234 static void _sg_cfg_cb__maxmin_precision(const char* name, int pos)
235 {
236   sg_maxmin_precision = xbt_cfg_get_double(_sg_cfg_set, name);
237 }
238
239 static void _sg_cfg_cb__sender_gap(const char* name, int pos)
240 {
241   sg_sender_gap = xbt_cfg_get_double(_sg_cfg_set, name);
242 }
243
244 static void _sg_cfg_cb__latency_factor(const char *name, int pos)
245 {
246   sg_latency_factor = xbt_cfg_get_double(_sg_cfg_set, name);
247 }
248
249 static void _sg_cfg_cb__bandwidth_factor(const char *name, int pos)
250 {
251   sg_bandwidth_factor = xbt_cfg_get_double(_sg_cfg_set, name);
252 }
253
254 static void _sg_cfg_cb__weight_S(const char *name, int pos)
255 {
256   sg_weight_S_parameter = xbt_cfg_get_double(_sg_cfg_set, name);
257 }
258
259 #ifdef HAVE_SMPI
260 /* callback of the mpi collectives */
261 static void _sg_cfg_cb__coll(const char *category,
262                              s_mpi_coll_description_t * table,
263                              const char *name, int pos)
264 {
265   char *val;
266
267   xbt_assert(_sg_cfg_init_status < 2,
268               "Cannot change the model after the initialization");
269
270   val = xbt_cfg_get_string(_sg_cfg_set, name);
271
272   if (!strcmp(val, "help")) {
273     coll_help(category, table);
274     sg_cfg_exit_early();
275   }
276
277   /* New Module missing */
278   find_coll_description(table, val);
279 }
280 static void _sg_cfg_cb__coll_gather(const char *name, int pos){
281   _sg_cfg_cb__coll("gather", mpi_coll_gather_description, name, pos);
282 }
283 static void _sg_cfg_cb__coll_allgather(const char *name, int pos){
284   _sg_cfg_cb__coll("allgather", mpi_coll_allgather_description, name, pos);
285 }
286 static void _sg_cfg_cb__coll_allgatherv(const char *name, int pos){
287   _sg_cfg_cb__coll("allgatherv", mpi_coll_allgatherv_description, name, pos);
288 }
289 static void _sg_cfg_cb__coll_allreduce(const char *name, int pos)
290 {
291   _sg_cfg_cb__coll("allreduce", mpi_coll_allreduce_description, name, pos);
292 }
293 static void _sg_cfg_cb__coll_alltoall(const char *name, int pos)
294 {
295   _sg_cfg_cb__coll("alltoall", mpi_coll_alltoall_description, name, pos);
296 }
297 static void _sg_cfg_cb__coll_alltoallv(const char *name, int pos)
298 {
299   _sg_cfg_cb__coll("alltoallv", mpi_coll_alltoallv_description, name, pos);
300 }
301 static void _sg_cfg_cb__coll_bcast(const char *name, int pos)
302 {
303   _sg_cfg_cb__coll("bcast", mpi_coll_bcast_description, name, pos);
304 }
305 static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
306 {
307   _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);
308 }
309 static void _sg_cfg_cb__coll_reduce_scatter(const char *name, int pos){
310   _sg_cfg_cb__coll("reduce_scatter", mpi_coll_reduce_scatter_description, name, pos);
311 }
312 static void _sg_cfg_cb__coll_scatter(const char *name, int pos){
313   _sg_cfg_cb__coll("scatter", mpi_coll_scatter_description, name, pos);
314 }
315 static void _sg_cfg_cb__coll_barrier(const char *name, int pos){
316   _sg_cfg_cb__coll("barrier", mpi_coll_barrier_description, name, pos);
317 }
318 #endif
319
320 /* callback of the inclusion path */
321 static void _sg_cfg_cb__surf_path(const char *name, int pos)
322 {
323   char *path = xbt_cfg_get_string_at(_sg_cfg_set, name, pos);
324   xbt_dynar_push(surf_path, &path);
325 }
326
327 /* callback to decide if we want to use the model-checking */
328 #include "xbt_modinter.h"
329 #ifdef HAVE_MC
330 extern int _sg_do_model_check;   /* this variable lives in xbt_main until I find a right location for it */
331 #endif
332
333 static void _sg_cfg_cb_model_check(const char *name, int pos)
334 {
335 #ifdef HAVE_MC
336   _sg_do_model_check = xbt_cfg_get_boolean(_sg_cfg_set, name);
337 #else
338   if (xbt_cfg_get_boolean(_sg_cfg_set, name)) {
339     xbt_die("You tried to activate the model-checking from the command line, but it was not compiled in. Change your settings in cmake, recompile and try again");
340   }
341 #endif
342 }
343
344 extern int _sg_do_verbose_exit;
345
346 static void _sg_cfg_cb_verbose_exit(const char *name, int pos)
347 {
348   _sg_do_verbose_exit = xbt_cfg_get_boolean(_sg_cfg_set, name);
349 }
350
351 extern int _sg_do_clean_atexit;
352
353 static void _sg_cfg_cb_clean_atexit(const char *name, int pos)
354 {
355   _sg_do_clean_atexit = xbt_cfg_get_boolean(_sg_cfg_set, name);
356 }
357
358 static void _sg_cfg_cb_context_factory(const char *name, int pos)
359 {
360   smx_context_factory_name = xbt_cfg_get_string(_sg_cfg_set, name);
361 }
362
363 static void _sg_cfg_cb_context_stack_size(const char *name, int pos)
364 {
365   smx_context_stack_size_was_set = 1;
366   smx_context_stack_size = xbt_cfg_get_int(_sg_cfg_set, name) * 1024;
367 }
368
369 static void _sg_cfg_cb_contexts_nthreads(const char *name, int pos)
370 {
371   SIMIX_context_set_nthreads(xbt_cfg_get_int(_sg_cfg_set, name));
372 }
373
374 static void _sg_cfg_cb_contexts_parallel_threshold(const char *name, int pos)
375 {
376   SIMIX_context_set_parallel_threshold(xbt_cfg_get_int(_sg_cfg_set, name));
377 }
378
379 static void _sg_cfg_cb_contexts_parallel_mode(const char *name, int pos)
380 {
381   const char* mode_name = xbt_cfg_get_string(_sg_cfg_set, name);
382   if (!strcmp(mode_name, "posix")) {
383     SIMIX_context_set_parallel_mode(XBT_PARMAP_POSIX);
384   }
385   else if (!strcmp(mode_name, "futex")) {
386     SIMIX_context_set_parallel_mode(XBT_PARMAP_FUTEX);
387   }
388   else if (!strcmp(mode_name, "busy_wait")) {
389     SIMIX_context_set_parallel_mode(XBT_PARMAP_BUSY_WAIT);
390   }
391   else {
392     xbt_die("Command line setting of the parallel synchronization mode should "
393             "be one of \"posix\", \"futex\" or \"busy_wait\"");
394   }
395 }
396
397 static void _sg_cfg_cb__surf_network_coordinates(const char *name,
398                                                  int pos)
399 {
400   int val = xbt_cfg_get_boolean(_sg_cfg_set, name);
401   if (val) {
402     if (!COORD_HOST_LEVEL) {
403       COORD_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_dynar_free_voidp);
404       COORD_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,xbt_dynar_free_voidp);
405     }
406   } else
407     if (COORD_HOST_LEVEL)
408       xbt_die("Setting of whether to use coordinate cannot be disabled once set.");
409 }
410
411 static void _sg_cfg_cb__surf_network_crosstraffic(const char *name,
412                                                   int pos)
413 {
414   sg_network_crosstraffic = xbt_cfg_get_boolean(_sg_cfg_set, name);
415 }
416
417 #ifdef HAVE_GTNETS
418 static void _sg_cfg_cb__gtnets_jitter(const char *name, int pos)
419 {
420   sg_gtnets_jitter = xbt_cfg_get_double(_sg_cfg_set, name);
421 }
422
423 static void _sg_cfg_cb__gtnets_jitter_seed(const char *name, int pos)
424 {
425   sg_gtnets_jitter_seed = xbt_cfg_get_int(_sg_cfg_set, name);
426 }
427 #endif
428
429 /* create the config set, register what should be and parse the command line*/
430 void sg_config_init(int *argc, char **argv)
431 {
432   char *description = xbt_malloc(1024);
433   char *p;
434   int i;
435
436   /* Create the configuration support */
437   if (_sg_cfg_init_status == 0) { /* Only create stuff if not already inited */
438     sprintf(description,
439             "The model to use for the CPU. Possible values: ");
440     p = description;
441     while (*(++p) != '\0');
442     for (i = 0; surf_cpu_model_description[i].name; i++)
443       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
444                    surf_cpu_model_description[i].name);
445     sprintf(p,
446             ".\n       (use 'help' as a value to see the long description of each model)");
447     xbt_cfg_register(&_sg_cfg_set, "cpu/model", description,
448                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
449     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/model", "Cas01");
450
451     while (*(++p) != '\0');
452     for (i = 0; surf_optimization_mode_description[i].name; i++)
453       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
454                    surf_optimization_mode_description[i].name);
455     sprintf(p,
456             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
457     xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description,
458                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
459     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/optim", "Lazy");
460
461     sprintf(description,
462             "The model to use for the storage. Possible values: ");
463     p = description;
464     while (*(++p) != '\0');
465     for (i = 0; surf_storage_model_description[i].name; i++)
466       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
467                    surf_storage_model_description[i].name);
468     sprintf(p,
469             ".\n       (use 'help' as a value to see the long description of each model)");
470     xbt_cfg_register(&_sg_cfg_set, "storage/model", description,
471                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
472     xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
473
474     sprintf(description,
475             "The model to use for the network. Possible values: ");
476     p = description;
477     while (*(++p) != '\0');
478     for (i = 0; surf_network_model_description[i].name; i++)
479       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
480                    surf_network_model_description[i].name);
481     sprintf(p,
482             ".\n       (use 'help' as a value to see the long description of each model)");
483     xbt_cfg_register(&_sg_cfg_set, "network/model", description,
484                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__network_model, NULL);
485     xbt_cfg_setdefault_string(_sg_cfg_set, "network/model", "LV08");
486
487     sprintf(description,
488             "The optimization modes to use for the network. Possible values: ");
489     p = description;
490     while (*(++p) != '\0');
491     for (i = 0; surf_optimization_mode_description[i].name; i++)
492       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
493                    surf_optimization_mode_description[i].name);
494     sprintf(p,
495             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
496     xbt_cfg_register(&_sg_cfg_set, "network/optim", description,
497                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
498     xbt_cfg_setdefault_string(_sg_cfg_set, "network/optim", "Lazy");
499
500     sprintf(description,
501             "The model to use for the workstation. Possible values: ");
502     p = description;
503     while (*(++p) != '\0');
504     for (i = 0; surf_workstation_model_description[i].name; i++)
505       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
506                    surf_workstation_model_description[i].name);
507     sprintf(p,
508             ".\n       (use 'help' as a value to see the long description of each model)");
509     xbt_cfg_register(&_sg_cfg_set, "workstation/model", description,
510                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__workstation_model, NULL);
511     xbt_cfg_setdefault_string(_sg_cfg_set, "workstation/model", "default");
512
513     xbt_cfg_register(&_sg_cfg_set, "vm_workstation/model", description,
514                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__vm_workstation_model, NULL);
515     xbt_cfg_setdefault_string(_sg_cfg_set, "vm_workstation/model", "default");
516
517     xbt_cfg_register(&_sg_cfg_set, "network/TCP_gamma",
518                      "Size of the biggest TCP window (cat /proc/sys/net/ipv4/tcp_[rw]mem for recv/send window; Use the last given value, which is the max window size)",
519                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__tcp_gamma, NULL);
520     xbt_cfg_setdefault_double(_sg_cfg_set, "network/TCP_gamma", 4194304.0);
521
522     xbt_cfg_register(&_sg_cfg_set, "maxmin/precision",
523                      "Numerical precision used when updating simulation models (epsilon in double comparisons)",
524                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__maxmin_precision, NULL);
525     xbt_cfg_setdefault_double(_sg_cfg_set, "maxmin/precision", 0.00001);
526
527     /* The parameters of network models */
528
529     xbt_cfg_register(&_sg_cfg_set, "network/sender_gap",
530                      "Minimum gap between two overlapping sends",
531                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__sender_gap, NULL);
532     /* default for "network/sender_gap" is set in network.c */
533
534     xbt_cfg_register(&_sg_cfg_set, "network/latency_factor",
535                      "Correction factor to apply to the provided latency (default value set by network model)",
536                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__latency_factor, NULL);
537     xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0);
538
539     xbt_cfg_register(&_sg_cfg_set, "network/bandwidth_factor",
540                      "Correction factor to apply to the provided bandwidth (default value set by network model)",
541                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__bandwidth_factor, NULL);
542     xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", 1.0);
543
544     xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
545                      "Correction factor to apply to the weight of competing streams (default value set by network model)",
546                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__weight_S, NULL);
547     /* default for "network/weight_S" is set in network.c */
548
549     /* Inclusion path */
550     xbt_cfg_register(&_sg_cfg_set, "path",
551                      "Lookup path for inclusions in platform and deployment XML files",
552                      xbt_cfgelm_string, 0, 0, _sg_cfg_cb__surf_path, NULL);
553
554     xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
555                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
556                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
557     xbt_cfg_setdefault_boolean(_sg_cfg_set, "cpu/maxmin_selective_update", "no");
558
559     xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
560                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
561                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
562     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/maxmin_selective_update", "no");
563
564 #ifdef HAVE_MC
565     /* do model-checking */
566     xbt_cfg_register(&_sg_cfg_set, "model-check",
567                      "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)",
568                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_model_check, NULL);
569     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", "no");
570
571     /* do stateful model-checking */
572     xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint",
573                      "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => stateless verification). "
574                      "If value=on, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.",
575                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_checkpoint, NULL);
576     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
577
578     /* do liveness model-checking */
579     xbt_cfg_register(&_sg_cfg_set, "model-check/property",
580                      "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
581                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_property, NULL);
582     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
583
584     /* Specify the kind of model-checking reduction */
585     xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
586                      "Specify the kind of exploration reduction (either none or DPOR)",
587                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_reduce, NULL);
588     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
589
590     /* Enable/disable timeout for wait requests with model-checking */
591     xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
592                      "Enable/Disable timeout for wait requests",
593                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
594     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
595
596     /* Set max depth exploration */
597     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
598                      "Specify the max depth of exploration (default : 1000)",
599                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
600     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
601
602     /* Set number of visited state stored for state comparison reduction*/
603     xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
604                      "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
605                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
606     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
607
608     /* Set file name for dot output of graph state */
609     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
610                      "Specify the name of dot file corresponding to graph state",
611                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
612     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
613 #endif
614
615     /* do verbose-exit */
616     xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
617                      "Activate the \"do nothing\" mode in Ctrl-C",
618                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
619     xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
620
621     /* context factory */
622     sprintf(description,
623             "Context factory to use in SIMIX. Possible values: thread");
624     const char *dflt_ctx_fact = "thread";
625 #ifdef CONTEXT_UCONTEXT
626     dflt_ctx_fact = "ucontext";
627     strcat(strcat(description, ", "), dflt_ctx_fact);
628 #endif
629 #ifdef HAVE_RAWCTX
630     dflt_ctx_fact = "raw";
631     strcat(strcat(description, ", "), dflt_ctx_fact);
632 #endif
633     strcat(description, ".");
634     xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
635                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
636     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
637
638     /* stack size of contexts in Ko */
639     xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
640                      "Stack size of contexts in Kib",
641                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
642     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
643     /* No, it was not set yet (the above setdefault() changed this to 1). */
644     smx_context_stack_size_was_set = 0;
645
646     /* number of parallel threads for user processes */
647     xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
648                      "Number of parallel threads used to execute user contexts",
649                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_nthreads, NULL);
650     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/nthreads", 1);
651
652     /* minimal number of user contexts to be run in parallel */
653     xbt_cfg_register(&_sg_cfg_set, "contexts/parallel_threshold",
654                      "Minimal number of user contexts to be run in parallel (raw contexts only)",
655                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_parallel_threshold, NULL);
656     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/parallel_threshold", 2);
657
658     /* synchronization mode for parallel user contexts */
659     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
660                      "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
661                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_contexts_parallel_mode, NULL);
662 #ifdef HAVE_FUTEX_H
663     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "futex");
664 #else //No futex on mac and posix is unimplememted yet
665     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "busy_wait");
666 #endif
667
668     xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
669                      "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
670                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL);
671     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", "no");
672
673     xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
674                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
675                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
676     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
677
678 #ifdef HAVE_GTNETS
679     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
680                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
681                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__gtnets_jitter, NULL);
682     xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
683
684     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
685                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
686                      xbt_cfgelm_int, 0, 1, _sg_cfg_cb__gtnets_jitter_seed, NULL);
687     xbt_cfg_setdefault_int(_sg_cfg_set, "gtnets/jitter_seed", 10);
688 #endif
689 #ifdef HAVE_NS3
690     xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
691                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
692                      xbt_cfgelm_string, 1, 1, NULL, NULL);
693     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
694 #endif
695
696 #ifdef HAVE_SMPI
697     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
698                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
699                      xbt_cfgelm_double, 1, 1, NULL, NULL);
700     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/running_power", 20000.0);
701
702     xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
703                      "Boolean indicating whether we should display the timing after simulation.",
704                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
705     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", "no");
706
707     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
708                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
709                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
710     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", "yes");
711
712     xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
713                      "Minimal computation time (in seconds) not discarded, or -1 for infinity.",
714                      xbt_cfgelm_double, 1, 1, NULL, NULL);
715     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/cpu_threshold", 1e-6);
716
717     xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
718                      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
719                      xbt_cfgelm_int, 1, 1, NULL, NULL);
720     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/async_small_thres", 0);
721
722     xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
723                      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
724                      xbt_cfgelm_int, 1, 1, NULL, NULL);
725     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/send_is_detached_thres", 65536);
726
727     //For smpi/bw_factor and smpi/lat_factor
728     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
729     //test is if( size >= thresholdN ) return valueN;
730     //Values can be modified with command line --cfg=smpi/bw_factor:"threshold0:value0;threshold1:value1;...;thresholdN:valueN"
731     //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
732     xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
733                      "Bandwidth factors for smpi.",
734                      xbt_cfgelm_string, 1, 1, NULL, NULL);
735     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/bw_factor", "65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;1426:0.608902;732:0.341987;257:0.338112;0:0.812084");
736
737     xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
738                      "Latency factors for smpi.",
739                      xbt_cfgelm_string, 1, 1, NULL, NULL);
740     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/lat_factor", "65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;1426:1.61075;732:1.9503;257:1.95341;0:2.01467");
741
742     xbt_cfg_register(&_sg_cfg_set, "smpi/os",
743                      "Small messages timings (MPI_Send minimum time for small messages)",
744                      xbt_cfgelm_string, 1, 1, NULL, NULL);
745     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
746
747     xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
748                      "Small messages timings (MPI_Isend minimum time for small messages)",
749                      xbt_cfgelm_string, 1, 1, NULL, NULL);
750     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
751
752     xbt_cfg_register(&_sg_cfg_set, "smpi/or",
753                      "Small messages timings (MPI_Recv minimum time for small messages)",
754                      xbt_cfgelm_string, 1, 1, NULL, NULL);
755     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
756     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
757                      "Minimum time to inject inside a call to MPI_Iprobe",
758                      xbt_cfgelm_double, 1, 1, NULL, NULL);
759     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/iprobe", 1e-4);
760     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
761                      "Which collective selector to use",
762                      xbt_cfgelm_string, 1, 1, NULL, NULL);
763     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/coll_selector", "default");
764
765     xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
766                      "Which collective to use for gather",
767                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_gather, NULL);
768
769     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
770                      "Which collective to use for allgather",
771                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgather, NULL);
772
773     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
774                      "Which collective to use for barrier",
775                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_barrier, NULL);
776
777     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
778                      "Which collective to use for reduce_scatter",
779                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
780
781     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
782                      "Which collective to use for scatter",
783                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_scatter, NULL);
784
785     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
786                      "Which collective to use for allgatherv",
787                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
788
789     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
790                      "Which collective to use for allreduce",
791                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
792
793     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
794                      "Which collective to use for alltoall",
795                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoall, NULL);
796
797     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
798                      "Which collective to use for alltoallv",
799                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
800
801     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
802                      "Which collective to use for bcast",
803                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
804
805     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
806                      "Which collective to use for reduce",
807                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
808 #endif // HAVE_SMPI
809
810     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
811                      "\"yes\" or \"no\". \"yes\" enables all the cleanups of SimGrid (XBT,SIMIX,MSG) to be registered with atexit. \"no\" may be useful if your code segfaults when calling the exit function.",
812                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_clean_atexit, NULL);
813     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", "yes");
814
815     if (!surf_path) {
816       /* retrieves the current directory of the current process */
817       const char *initial_path = __surf_get_initial_path();
818       xbt_assert((initial_path),
819                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
820
821       surf_path = xbt_dynar_new(sizeof(char *), NULL);
822       xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
823     }
824
825     _sg_cfg_init_status = 1;
826
827     sg_config_cmd_line(argc, argv);
828
829     xbt_mallocator_initialization_is_done(SIMIX_context_is_parallel());
830
831   } else {
832     XBT_WARN("Call to sg_config_init() after initialization ignored");
833   }
834
835   xbt_free(description);
836 }
837
838 void sg_config_finalize(void)
839 {
840   if (!_sg_cfg_init_status)
841     return;                     /* Not initialized yet. Nothing to do */
842
843   xbt_cfg_free(&_sg_cfg_set);
844   _sg_cfg_init_status = 0;
845 }
846
847 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
848 void surf_config_models_setup()
849 {
850   const char *workstation_model_name;
851   const char *vm_workstation_model_name;
852   int workstation_id = -1;
853   int vm_workstation_id = -1;
854   char *network_model_name = NULL;
855   char *cpu_model_name = NULL;
856   int storage_id = -1;
857   char *storage_model_name = NULL;
858
859   workstation_model_name =
860       xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
861   vm_workstation_model_name =
862       xbt_cfg_get_string(_sg_cfg_set, "vm_workstation/model");
863   network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
864   cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
865   storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
866
867   /* Check whether we use a net/cpu model differing from the default ones, in which case
868    * we should switch to the "compound" workstation model to correctly dispatch stuff to
869    * the right net/cpu models.
870    */
871
872   if ((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
873        !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
874       xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model")) {
875     XBT_INFO("Switching workstation model to compound since you changed the network and/or cpu model(s)");
876     workstation_model_name = "compound";
877     xbt_cfg_set_string(_sg_cfg_set, "workstation/model", workstation_model_name);
878   }
879
880   XBT_DEBUG("Workstation model: %s", workstation_model_name);
881   workstation_id =
882       find_model_description(surf_workstation_model_description,
883                              workstation_model_name);
884   if (!strcmp(workstation_model_name, "compound")) {
885     int network_id = -1;
886     int cpu_id = -1;
887
888     xbt_assert(cpu_model_name,
889                 "Set a cpu model to use with the 'compound' workstation model");
890
891     xbt_assert(network_model_name,
892                 "Set a network model to use with the 'compound' workstation model");
893
894     network_id =
895         find_model_description(surf_network_model_description,
896                                network_model_name);
897     cpu_id =
898         find_model_description(surf_cpu_model_description, cpu_model_name);
899
900     surf_cpu_model_description[cpu_id].model_init_preparse();
901     surf_network_model_description[network_id].model_init_preparse();
902   }
903
904   XBT_DEBUG("Call workstation_model_init");
905   surf_workstation_model_description[workstation_id].model_init_preparse();
906
907   XBT_DEBUG("Call vm_workstation_model_init");
908   vm_workstation_id = find_model_description(surf_vm_workstation_model_description,
909                                           vm_workstation_model_name);
910   surf_vm_workstation_model_description[vm_workstation_id].model_init_preparse();
911
912   XBT_DEBUG("Call storage_model_init");
913   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
914   surf_storage_model_description[storage_id].model_init_preparse();
915
916 }
917
918 int sg_cfg_get_int(const char* name)
919 {
920   return xbt_cfg_get_int(_sg_cfg_set,name);
921 }
922
923 double sg_cfg_get_double(const char* name)
924 {
925   return xbt_cfg_get_double(_sg_cfg_set,name);
926 }
927
928 char* sg_cfg_get_string(const char* name)
929 {
930   return xbt_cfg_get_string(_sg_cfg_set,name);
931 }
932
933 int sg_cfg_get_boolean(const char* name)
934 {
935   return xbt_cfg_get_boolean(_sg_cfg_set,name);
936 }
937
938 void sg_cfg_get_peer(const char *name, char **peer, int *port)
939 {
940   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
941 }
942
943 xbt_dynar_t sg_cfg_get_dynar(const char* name)
944 {
945   return xbt_cfg_get_dynar(_sg_cfg_set,name);
946 }