Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
b812c87d55eb35d231f98cb1e56575cf4df3edc8
[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 cpu/model variable */
134 static void _sg_cfg_cb__cpu_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("CPU", surf_cpu_model_description);
145     sg_cfg_exit_early();
146   }
147
148   /* New Module missing */
149   find_model_description(surf_cpu_model_description, val);
150 }
151
152 /* callback of the cpu/model variable */
153 static void _sg_cfg_cb__optimization_mode(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("optimization", surf_optimization_mode_description);
164     sg_cfg_exit_early();
165   }
166
167   /* New Module missing */
168   find_model_description(surf_optimization_mode_description, val);
169 }
170
171 /* callback of the cpu/model variable */
172 static void _sg_cfg_cb__storage_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("storage", surf_storage_model_description);
183     sg_cfg_exit_early();
184   }
185
186   /* New Module missing */
187   find_model_description(surf_storage_model_description, val);
188 }
189
190 /* callback of the workstation_model variable */
191 static void _sg_cfg_cb__network_model(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("network", surf_network_model_description);
202     sg_cfg_exit_early();
203   }
204
205   /* New Module missing */
206   find_model_description(surf_network_model_description, val);
207 }
208
209 /* callbacks of the network models values */
210 static void _sg_cfg_cb__tcp_gamma(const char *name, int pos)
211 {
212   sg_tcp_gamma = xbt_cfg_get_double(_sg_cfg_set, name);
213 }
214
215 static void _sg_cfg_cb__maxmin_precision(const char* name, int pos)
216 {
217   sg_maxmin_precision = xbt_cfg_get_double(_sg_cfg_set, name);
218 }
219
220 static void _sg_cfg_cb__sender_gap(const char* name, int pos)
221 {
222   sg_sender_gap = xbt_cfg_get_double(_sg_cfg_set, name);
223 }
224
225 static void _sg_cfg_cb__latency_factor(const char *name, int pos)
226 {
227   sg_latency_factor = xbt_cfg_get_double(_sg_cfg_set, name);
228 }
229
230 static void _sg_cfg_cb__bandwidth_factor(const char *name, int pos)
231 {
232   sg_bandwidth_factor = xbt_cfg_get_double(_sg_cfg_set, name);
233 }
234
235 static void _sg_cfg_cb__weight_S(const char *name, int pos)
236 {
237   sg_weight_S_parameter = xbt_cfg_get_double(_sg_cfg_set, name);
238 }
239
240 #ifdef HAVE_SMPI
241 /* callback of the mpi collectives */
242 static void _sg_cfg_cb__coll(const char *category,
243                              s_mpi_coll_description_t * table,
244                              const char *name, int pos)
245 {
246   char *val;
247
248   xbt_assert(_sg_cfg_init_status < 2,
249               "Cannot change the model after the initialization");
250
251   val = xbt_cfg_get_string(_sg_cfg_set, name);
252
253   if (!strcmp(val, "help")) {
254     coll_help(category, table);
255     sg_cfg_exit_early();
256   }
257
258   /* New Module missing */
259   find_coll_description(table, val);
260 }
261 static void _sg_cfg_cb__coll_gather(const char *name, int pos){
262   _sg_cfg_cb__coll("gather", mpi_coll_gather_description, name, pos);
263 }
264 static void _sg_cfg_cb__coll_allgather(const char *name, int pos){
265   _sg_cfg_cb__coll("allgather", mpi_coll_allgather_description, name, pos);
266 }
267 static void _sg_cfg_cb__coll_allgatherv(const char *name, int pos){
268   _sg_cfg_cb__coll("allgatherv", mpi_coll_allgatherv_description, name, pos);
269 }
270 static void _sg_cfg_cb__coll_allreduce(const char *name, int pos)
271 {
272   _sg_cfg_cb__coll("allreduce", mpi_coll_allreduce_description, name, pos);
273 }
274 static void _sg_cfg_cb__coll_alltoall(const char *name, int pos)
275 {
276   _sg_cfg_cb__coll("alltoall", mpi_coll_alltoall_description, name, pos);
277 }
278 static void _sg_cfg_cb__coll_alltoallv(const char *name, int pos)
279 {
280   _sg_cfg_cb__coll("alltoallv", mpi_coll_alltoallv_description, name, pos);
281 }
282 static void _sg_cfg_cb__coll_bcast(const char *name, int pos)
283 {
284   _sg_cfg_cb__coll("bcast", mpi_coll_bcast_description, name, pos);
285 }
286 static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
287 {
288   _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);
289 }
290 static void _sg_cfg_cb__coll_reduce_scatter(const char *name, int pos){
291   _sg_cfg_cb__coll("reduce_scatter", mpi_coll_reduce_scatter_description, name, pos);
292 }
293 static void _sg_cfg_cb__coll_scatter(const char *name, int pos){
294   _sg_cfg_cb__coll("scatter", mpi_coll_scatter_description, name, pos);
295 }
296 static void _sg_cfg_cb__coll_barrier(const char *name, int pos){
297   _sg_cfg_cb__coll("barrier", mpi_coll_barrier_description, name, pos);
298 }
299 #endif
300
301 /* callback of the inclusion path */
302 static void _sg_cfg_cb__surf_path(const char *name, int pos)
303 {
304   char *path = xbt_cfg_get_string_at(_sg_cfg_set, name, pos);
305   xbt_dynar_push(surf_path, &path);
306 }
307
308 /* callback to decide if we want to use the model-checking */
309 #include "xbt_modinter.h"
310 #ifdef HAVE_MC
311 extern int _sg_do_model_check;   /* this variable lives in xbt_main until I find a right location for it */
312 #endif
313
314 static void _sg_cfg_cb_model_check(const char *name, int pos)
315 {
316 #ifdef HAVE_MC
317   _sg_do_model_check = xbt_cfg_get_boolean(_sg_cfg_set, name);
318 #else
319   if (xbt_cfg_get_boolean(_sg_cfg_set, name)) {
320     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");
321   }
322 #endif
323 }
324
325 extern int _sg_do_verbose_exit;
326
327 static void _sg_cfg_cb_verbose_exit(const char *name, int pos)
328 {
329   _sg_do_verbose_exit = xbt_cfg_get_boolean(_sg_cfg_set, name);
330 }
331
332 extern int _sg_do_clean_atexit;
333
334 static void _sg_cfg_cb_clean_atexit(const char *name, int pos)
335 {
336   _sg_do_clean_atexit = xbt_cfg_get_boolean(_sg_cfg_set, name);
337 }
338
339 static void _sg_cfg_cb_context_factory(const char *name, int pos)
340 {
341   smx_context_factory_name = xbt_cfg_get_string(_sg_cfg_set, name);
342 }
343
344 static void _sg_cfg_cb_context_stack_size(const char *name, int pos)
345 {
346   smx_context_stack_size_was_set = 1;
347   smx_context_stack_size = xbt_cfg_get_int(_sg_cfg_set, name) * 1024;
348 }
349
350 static void _sg_cfg_cb_contexts_nthreads(const char *name, int pos)
351 {
352   SIMIX_context_set_nthreads(xbt_cfg_get_int(_sg_cfg_set, name));
353 }
354
355 static void _sg_cfg_cb_contexts_parallel_threshold(const char *name, int pos)
356 {
357   SIMIX_context_set_parallel_threshold(xbt_cfg_get_int(_sg_cfg_set, name));
358 }
359
360 static void _sg_cfg_cb_contexts_parallel_mode(const char *name, int pos)
361 {
362   const char* mode_name = xbt_cfg_get_string(_sg_cfg_set, name);
363   if (!strcmp(mode_name, "posix")) {
364     SIMIX_context_set_parallel_mode(XBT_PARMAP_POSIX);
365   }
366   else if (!strcmp(mode_name, "futex")) {
367     SIMIX_context_set_parallel_mode(XBT_PARMAP_FUTEX);
368   }
369   else if (!strcmp(mode_name, "busy_wait")) {
370     SIMIX_context_set_parallel_mode(XBT_PARMAP_BUSY_WAIT);
371   }
372   else {
373     xbt_die("Command line setting of the parallel synchronization mode should "
374             "be one of \"posix\", \"futex\" or \"busy_wait\"");
375   }
376 }
377
378 static void _sg_cfg_cb__surf_network_coordinates(const char *name,
379                                                  int pos)
380 {
381   int val = xbt_cfg_get_boolean(_sg_cfg_set, name);
382   if (val) {
383     if (!COORD_HOST_LEVEL) {
384       COORD_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_dynar_free_voidp);
385       COORD_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,xbt_dynar_free_voidp);
386     }
387   } else
388     if (COORD_HOST_LEVEL)
389       xbt_die("Setting of whether to use coordinate cannot be disabled once set.");
390 }
391
392 static void _sg_cfg_cb__surf_network_crosstraffic(const char *name,
393                                                   int pos)
394 {
395   sg_network_crosstraffic = xbt_cfg_get_boolean(_sg_cfg_set, name);
396 }
397
398 #ifdef HAVE_GTNETS
399 static void _sg_cfg_cb__gtnets_jitter(const char *name, int pos)
400 {
401   sg_gtnets_jitter = xbt_cfg_get_double(_sg_cfg_set, name);
402 }
403
404 static void _sg_cfg_cb__gtnets_jitter_seed(const char *name, int pos)
405 {
406   sg_gtnets_jitter_seed = xbt_cfg_get_int(_sg_cfg_set, name);
407 }
408 #endif
409
410 /* create the config set, register what should be and parse the command line*/
411 void sg_config_init(int *argc, char **argv)
412 {
413   char *description = xbt_malloc(1024);
414   char *p;
415   int i;
416
417   /* Create the configuration support */
418   if (_sg_cfg_init_status == 0) { /* Only create stuff if not already inited */
419     sprintf(description,
420             "The model to use for the CPU. Possible values: ");
421     p = description;
422     while (*(++p) != '\0');
423     for (i = 0; surf_cpu_model_description[i].name; i++)
424       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
425                    surf_cpu_model_description[i].name);
426     sprintf(p,
427             ".\n       (use 'help' as a value to see the long description of each model)");
428     xbt_cfg_register(&_sg_cfg_set, "cpu/model", description,
429                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
430     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/model", "Cas01");
431
432     while (*(++p) != '\0');
433     for (i = 0; surf_optimization_mode_description[i].name; i++)
434       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
435                    surf_optimization_mode_description[i].name);
436     sprintf(p,
437             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
438     xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description,
439                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
440     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/optim", "Lazy");
441
442     sprintf(description,
443             "The model to use for the storage. Possible values: ");
444     p = description;
445     while (*(++p) != '\0');
446     for (i = 0; surf_storage_model_description[i].name; i++)
447       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
448                    surf_storage_model_description[i].name);
449     sprintf(p,
450             ".\n       (use 'help' as a value to see the long description of each model)");
451     xbt_cfg_register(&_sg_cfg_set, "storage/model", description,
452                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
453     xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
454
455     /* ********************************************************************* */
456     /* TUTORIAL: New model                                                   */
457     sprintf(description,
458             "The model to use for the New model. Possible values: ");
459     p = description;
460     while (*(++p) != '\0');
461     for (i = 0; surf_new_model_description[i].name; i++)
462       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
463                    surf_new_model_description[i].name);
464     sprintf(p,
465             ".\n       (use 'help' as a value to see the long description of each model)");
466     xbt_cfg_register(&_sg_cfg_set, "new_model/model", description,
467                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
468     xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default");
469     /* ********************************************************************* */
470
471     sprintf(description,
472             "The model to use for the network. Possible values: ");
473     p = description;
474     while (*(++p) != '\0');
475     for (i = 0; surf_network_model_description[i].name; i++)
476       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
477                    surf_network_model_description[i].name);
478     sprintf(p,
479             ".\n       (use 'help' as a value to see the long description of each model)");
480     xbt_cfg_register(&_sg_cfg_set, "network/model", description,
481                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__network_model, NULL);
482     xbt_cfg_setdefault_string(_sg_cfg_set, "network/model", "LV08");
483
484     sprintf(description,
485             "The optimization modes to use for the network. Possible values: ");
486     p = description;
487     while (*(++p) != '\0');
488     for (i = 0; surf_optimization_mode_description[i].name; i++)
489       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
490                    surf_optimization_mode_description[i].name);
491     sprintf(p,
492             ".\n       (use 'help' as a value to see the long description of each optimization mode)");
493     xbt_cfg_register(&_sg_cfg_set, "network/optim", description,
494                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
495     xbt_cfg_setdefault_string(_sg_cfg_set, "network/optim", "Lazy");
496
497     sprintf(description,
498             "The model to use for the workstation. Possible values: ");
499     p = description;
500     while (*(++p) != '\0');
501     for (i = 0; surf_workstation_model_description[i].name; i++)
502       p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
503                    surf_workstation_model_description[i].name);
504     sprintf(p,
505             ".\n       (use 'help' as a value to see the long description of each model)");
506     xbt_cfg_register(&_sg_cfg_set, "workstation/model", description,
507                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__workstation_model, NULL);
508     xbt_cfg_setdefault_string(_sg_cfg_set, "workstation/model", "default");
509
510     xbt_cfg_register(&_sg_cfg_set, "network/TCP_gamma",
511                      "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)",
512                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__tcp_gamma, NULL);
513     xbt_cfg_setdefault_double(_sg_cfg_set, "network/TCP_gamma", 4194304.0);
514
515     xbt_cfg_register(&_sg_cfg_set, "maxmin/precision",
516                      "Numerical precision used when updating simulation models (epsilon in double comparisons)",
517                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__maxmin_precision, NULL);
518     xbt_cfg_setdefault_double(_sg_cfg_set, "maxmin/precision", 0.00001);
519
520     /* The parameters of network models */
521
522     xbt_cfg_register(&_sg_cfg_set, "network/sender_gap",
523                      "Minimum gap between two overlapping sends",
524                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__sender_gap, NULL);
525     /* default for "network/sender_gap" is set in network.c */
526
527     xbt_cfg_register(&_sg_cfg_set, "network/latency_factor",
528                      "Correction factor to apply to the provided latency (default value set by network model)",
529                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__latency_factor, NULL);
530     xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0);
531
532     xbt_cfg_register(&_sg_cfg_set, "network/bandwidth_factor",
533                      "Correction factor to apply to the provided bandwidth (default value set by network model)",
534                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__bandwidth_factor, NULL);
535     xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", 1.0);
536
537     xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
538                      "Correction factor to apply to the weight of competing streams (default value set by network model)",
539                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__weight_S, NULL);
540     /* default for "network/weight_S" is set in network.c */
541
542     /* Inclusion path */
543     xbt_cfg_register(&_sg_cfg_set, "path",
544                      "Lookup path for inclusions in platform and deployment XML files",
545                      xbt_cfgelm_string, 0, 0, _sg_cfg_cb__surf_path, NULL);
546
547     xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
548                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
549                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
550     xbt_cfg_setdefault_boolean(_sg_cfg_set, "cpu/maxmin_selective_update", "no");
551
552     xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
553                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
554                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
555     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/maxmin_selective_update", "no");
556
557 #ifdef HAVE_MC
558     /* do model-checking */
559     xbt_cfg_register(&_sg_cfg_set, "model-check",
560                      "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)",
561                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_model_check, NULL);
562     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", "no");
563
564     /* do stateful model-checking */
565     xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint",
566                      "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => stateless verification). "
567                      "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.",
568                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_checkpoint, NULL);
569     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
570
571     /* do liveness model-checking */
572     xbt_cfg_register(&_sg_cfg_set, "model-check/property",
573                      "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
574                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_property, NULL);
575     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
576
577     /* Specify the kind of model-checking reduction */
578     xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
579                      "Specify the kind of exploration reduction (either none or DPOR)",
580                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_reduce, NULL);
581     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
582
583     /* Enable/disable timeout for wait requests with model-checking */
584     xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
585                      "Enable/Disable timeout for wait requests",
586                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
587     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
588
589     /* Set max depth exploration */
590     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
591                      "Specify the max depth of exploration (default : 1000)",
592                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
593     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
594
595     /* Set number of visited state stored for state comparison reduction*/
596     xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
597                      "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
598                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
599     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
600
601     /* Set file name for dot output of graph state */
602     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
603                      "Specify the name of dot file corresponding to graph state",
604                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
605     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
606 #endif
607
608     /* do verbose-exit */
609     xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
610                      "Activate the \"do nothing\" mode in Ctrl-C",
611                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
612     xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
613
614     /* context factory */
615     sprintf(description,
616             "Context factory to use in SIMIX. Possible values: thread");
617     const char *dflt_ctx_fact = "thread";
618 #ifdef CONTEXT_UCONTEXT
619     dflt_ctx_fact = "ucontext";
620     strcat(strcat(description, ", "), dflt_ctx_fact);
621 #endif
622 #ifdef HAVE_RAWCTX
623     dflt_ctx_fact = "raw";
624     strcat(strcat(description, ", "), dflt_ctx_fact);
625 #endif
626     strcat(description, ".");
627     xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
628                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
629     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
630
631     /* stack size of contexts in Ko */
632     xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
633                      "Stack size of contexts in Kib",
634                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
635     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
636     /* No, it was not set yet (the above setdefault() changed this to 1). */
637     smx_context_stack_size_was_set = 0;
638
639     /* number of parallel threads for user processes */
640     xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
641                      "Number of parallel threads used to execute user contexts",
642                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_nthreads, NULL);
643     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/nthreads", 1);
644
645     /* minimal number of user contexts to be run in parallel */
646     xbt_cfg_register(&_sg_cfg_set, "contexts/parallel_threshold",
647                      "Minimal number of user contexts to be run in parallel (raw contexts only)",
648                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_parallel_threshold, NULL);
649     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/parallel_threshold", 2);
650
651     /* synchronization mode for parallel user contexts */
652     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
653                      "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
654                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_contexts_parallel_mode, NULL);
655 #ifdef HAVE_FUTEX_H
656     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "futex");
657 #else //No futex on mac and posix is unimplememted yet
658     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "busy_wait");
659 #endif
660
661     xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
662                      "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
663                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL);
664     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", "no");
665
666     xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
667                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
668                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
669     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
670
671 #ifdef HAVE_GTNETS
672     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
673                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
674                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__gtnets_jitter, NULL);
675     xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
676
677     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
678                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
679                      xbt_cfgelm_int, 0, 1, _sg_cfg_cb__gtnets_jitter_seed, NULL);
680     xbt_cfg_setdefault_int(_sg_cfg_set, "gtnets/jitter_seed", 10);
681 #endif
682 #ifdef HAVE_NS3
683     xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
684                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
685                      xbt_cfgelm_string, 1, 1, NULL, NULL);
686     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
687 #endif
688
689 #ifdef HAVE_SMPI
690     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
691                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
692                      xbt_cfgelm_double, 1, 1, NULL, NULL);
693     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/running_power", 20000.0);
694
695     xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
696                      "Boolean indicating whether we should display the timing after simulation.",
697                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
698     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", "no");
699
700     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
701                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
702                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
703     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", "yes");
704
705     xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
706                      "Minimal computation time (in seconds) not discarded, or -1 for infinity.",
707                      xbt_cfgelm_double, 1, 1, NULL, NULL);
708     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/cpu_threshold", 1e-6);
709
710     xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
711                      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
712                      xbt_cfgelm_int, 1, 1, NULL, NULL);
713     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/async_small_thres", 0);
714
715     xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
716                      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
717                      xbt_cfgelm_int, 1, 1, NULL, NULL);
718     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/send_is_detached_thres", 65536);
719
720     //For smpi/bw_factor and smpi/lat_factor
721     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
722     //test is if( size >= thresholdN ) return valueN;
723     //Values can be modified with command line --cfg=smpi/bw_factor:"threshold0:value0;threshold1:value1;...;thresholdN:valueN"
724     //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
725     xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
726                      "Bandwidth factors for smpi.",
727                      xbt_cfgelm_string, 1, 1, NULL, NULL);
728     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");
729
730     xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
731                      "Latency factors for smpi.",
732                      xbt_cfgelm_string, 1, 1, NULL, NULL);
733     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");
734
735     xbt_cfg_register(&_sg_cfg_set, "smpi/os",
736                      "Small messages timings (MPI_Send minimum time for small messages)",
737                      xbt_cfgelm_string, 1, 1, NULL, NULL);
738     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
739
740     xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
741                      "Small messages timings (MPI_Isend minimum time for small messages)",
742                      xbt_cfgelm_string, 1, 1, NULL, NULL);
743     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
744
745     xbt_cfg_register(&_sg_cfg_set, "smpi/or",
746                      "Small messages timings (MPI_Recv minimum time for small messages)",
747                      xbt_cfgelm_string, 1, 1, NULL, NULL);
748     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
749     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
750                      "Minimum time to inject inside a call to MPI_Iprobe",
751                      xbt_cfgelm_double, 1, 1, NULL, NULL);
752     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/iprobe", 1e-4);
753     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
754                      "Which collective selector to use",
755                      xbt_cfgelm_string, 1, 1, NULL, NULL);
756     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/coll_selector", "default");
757
758     xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
759                      "Which collective to use for gather",
760                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_gather, NULL);
761
762     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
763                      "Which collective to use for allgather",
764                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgather, NULL);
765
766     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
767                      "Which collective to use for barrier",
768                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_barrier, NULL);
769
770     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
771                      "Which collective to use for reduce_scatter",
772                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
773
774     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
775                      "Which collective to use for scatter",
776                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_scatter, NULL);
777
778     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
779                      "Which collective to use for allgatherv",
780                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
781
782     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
783                      "Which collective to use for allreduce",
784                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
785
786     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
787                      "Which collective to use for alltoall",
788                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoall, NULL);
789
790     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
791                      "Which collective to use for alltoallv",
792                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
793
794     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
795                      "Which collective to use for bcast",
796                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
797
798     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
799                      "Which collective to use for reduce",
800                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
801 #endif // HAVE_SMPI
802
803     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
804                      "\"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.",
805                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_clean_atexit, NULL);
806     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", "yes");
807
808     if (!surf_path) {
809       /* retrieves the current directory of the current process */
810       const char *initial_path = __surf_get_initial_path();
811       xbt_assert((initial_path),
812                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
813
814       surf_path = xbt_dynar_new(sizeof(char *), NULL);
815       xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
816     }
817
818     _sg_cfg_init_status = 1;
819
820     sg_config_cmd_line(argc, argv);
821
822     xbt_mallocator_initialization_is_done(SIMIX_context_is_parallel());
823
824   } else {
825     XBT_WARN("Call to sg_config_init() after initialization ignored");
826   }
827
828   xbt_free(description);
829 }
830
831 void sg_config_finalize(void)
832 {
833   if (!_sg_cfg_init_status)
834     return;                     /* Not initialized yet. Nothing to do */
835
836   xbt_cfg_free(&_sg_cfg_set);
837   _sg_cfg_init_status = 0;
838 }
839
840 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
841 void surf_config_models_setup()
842 {
843   const char *workstation_model_name;
844   int workstation_id = -1;
845   char *network_model_name = NULL;
846   char *cpu_model_name = NULL;
847   int storage_id = -1;
848   char *storage_model_name = NULL;
849
850   workstation_model_name =
851       xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
852   network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
853   cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
854   storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
855
856   /* Check whether we use a net/cpu model differing from the default ones, in which case
857    * we should switch to the "compound" workstation model to correctly dispatch stuff to
858    * the right net/cpu models.
859    */
860
861   if ((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
862        !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
863       xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model")) {
864     XBT_INFO("Switching workstation model to compound since you changed the network and/or cpu model(s)");
865     workstation_model_name = "compound";
866     xbt_cfg_set_string(_sg_cfg_set, "workstation/model", workstation_model_name);
867   }
868
869   XBT_DEBUG("Workstation model: %s", workstation_model_name);
870   workstation_id =
871       find_model_description(surf_workstation_model_description,
872                              workstation_model_name);
873   if (!strcmp(workstation_model_name, "compound")) {
874     int network_id = -1;
875     int cpu_id = -1;
876
877     xbt_assert(cpu_model_name,
878                 "Set a cpu model to use with the 'compound' workstation model");
879
880     xbt_assert(network_model_name,
881                 "Set a network model to use with the 'compound' workstation model");
882
883     network_id =
884         find_model_description(surf_network_model_description,
885                                network_model_name);
886     cpu_id =
887         find_model_description(surf_cpu_model_description, cpu_model_name);
888
889     surf_cpu_model_description[cpu_id].model_init_preparse();
890     surf_network_model_description[network_id].model_init_preparse();
891   }
892
893   XBT_DEBUG("Call workstation_model_init");
894   surf_workstation_model_description[workstation_id].model_init_preparse();
895
896   XBT_DEBUG("Call storage_model_init");
897   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
898   surf_storage_model_description[storage_id].model_init_preparse();
899
900   /* ********************************************************************* */
901   /* TUTORIAL: New model                                                   */
902   int new_model_id = -1;
903   char *new_model_name = NULL;
904   new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
905   XBT_DEBUG("Call new model_init");
906   new_model_id = find_model_description(surf_new_model_description, new_model_name);
907   surf_new_model_description[new_model_id].model_init_preparse();
908   /* ********************************************************************* */
909 }
910
911 int sg_cfg_get_int(const char* name)
912 {
913   return xbt_cfg_get_int(_sg_cfg_set,name);
914 }
915
916 double sg_cfg_get_double(const char* name)
917 {
918   return xbt_cfg_get_double(_sg_cfg_set,name);
919 }
920
921 char* sg_cfg_get_string(const char* name)
922 {
923   return xbt_cfg_get_string(_sg_cfg_set,name);
924 }
925
926 int sg_cfg_get_boolean(const char* name)
927 {
928   return xbt_cfg_get_boolean(_sg_cfg_set,name);
929 }
930
931 void sg_cfg_get_peer(const char *name, char **peer, int *port)
932 {
933   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
934 }
935
936 xbt_dynar_t sg_cfg_get_dynar(const char* name)
937 {
938   return xbt_cfg_get_dynar(_sg_cfg_set,name);
939 }