Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'mc' into mc++
[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=1, 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     /* do communications determinism model-checking */
578     xbt_cfg_register(&_sg_cfg_set, "model-check/communications_determinism",
579                      "Enable/disable the detection of determinism in the communications schemes",
580                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_comms_determinism, NULL);
581     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/communications_determinism", "no");
582
583     /* do send determinism model-checking */
584     xbt_cfg_register(&_sg_cfg_set, "model-check/send_determinism",
585                      "Enable/disable the detection of send-determinism in the communications schemes",
586                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_send_determinism, NULL);
587     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/send_determinism", "no");
588
589     /* Specify the kind of model-checking reduction */
590     xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
591                      "Specify the kind of exploration reduction (either none or DPOR)",
592                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_reduce, NULL);
593     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
594
595     /* Enable/disable timeout for wait requests with model-checking */
596     xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
597                      "Enable/Disable timeout for wait requests",
598                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
599     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
600
601     /* Enable/disable global hash computation with model-checking */
602     xbt_cfg_register(&_sg_cfg_set, "model-check/hash",
603                      "Enable/Disable state hash for state comparison",
604                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_hash, NULL);
605     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/hash", "no");
606
607     /* Set max depth exploration */
608     xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
609                      "Specify the max depth of exploration (default : 1000)",
610                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
611     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
612
613     /* Set number of visited state stored for state comparison reduction*/
614     xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
615                      "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
616                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
617     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
618
619     /* Set file name for dot output of graph state */
620     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
621                      "Specify the name of dot file corresponding to graph state",
622                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
623     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
624 #endif
625
626     /* do verbose-exit */
627     xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
628                      "Activate the \"do nothing\" mode in Ctrl-C",
629                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
630     xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
631
632     /* context factory */
633     sprintf(description,
634             "Context factory to use in SIMIX. Possible values: thread");
635     const char *dflt_ctx_fact = "thread";
636 #ifdef CONTEXT_UCONTEXT
637     dflt_ctx_fact = "ucontext";
638     strcat(strcat(description, ", "), dflt_ctx_fact);
639 #endif
640 #ifdef HAVE_RAWCTX
641     dflt_ctx_fact = "raw";
642     strcat(strcat(description, ", "), dflt_ctx_fact);
643 #endif
644     strcat(description, ".");
645     xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
646                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
647     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
648
649     /* stack size of contexts in Ko */
650     xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
651                      "Stack size of contexts in Kib",
652                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
653     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
654     /* No, it was not set yet (the above setdefault() changed this to 1). */
655     smx_context_stack_size_was_set = 0;
656
657     /* number of parallel threads for user processes */
658     xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
659                      "Number of parallel threads used to execute user contexts",
660                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_nthreads, NULL);
661     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/nthreads", 1);
662
663     /* minimal number of user contexts to be run in parallel */
664     xbt_cfg_register(&_sg_cfg_set, "contexts/parallel_threshold",
665                      "Minimal number of user contexts to be run in parallel (raw contexts only)",
666                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_parallel_threshold, NULL);
667     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/parallel_threshold", 2);
668
669     /* synchronization mode for parallel user contexts */
670     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
671                      "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
672                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_contexts_parallel_mode, NULL);
673 #ifdef HAVE_FUTEX_H
674     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "futex");
675 #else //No futex on mac and posix is unimplememted yet
676     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "busy_wait");
677 #endif
678
679     xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
680                      "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
681                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL);
682     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", "no");
683
684     xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
685                      "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
686                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
687     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
688
689 #ifdef HAVE_GTNETS
690     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
691                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
692                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__gtnets_jitter, NULL);
693     xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
694
695     xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
696                      "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
697                      xbt_cfgelm_int, 0, 1, _sg_cfg_cb__gtnets_jitter_seed, NULL);
698     xbt_cfg_setdefault_int(_sg_cfg_set, "gtnets/jitter_seed", 10);
699 #endif
700 #ifdef HAVE_NS3
701     xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
702                      "The ns3 tcp model can be : NewReno or Reno or Tahoe",
703                      xbt_cfgelm_string, 1, 1, NULL, NULL);
704     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
705 #endif
706
707 #ifdef HAVE_SMPI
708     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
709                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
710                      xbt_cfgelm_double, 1, 1, NULL, NULL);
711     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/running_power", 20000.0);
712
713     xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
714                      "Boolean indicating whether we should display the timing after simulation.",
715                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
716     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", "no");
717
718     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
719                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
720                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
721     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", "yes");
722
723     xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
724                      "Minimal computation time (in seconds) not discarded, or -1 for infinity.",
725                      xbt_cfgelm_double, 1, 1, NULL, NULL);
726     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/cpu_threshold", 1e-6);
727
728     xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
729                      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
730                      xbt_cfgelm_int, 1, 1, NULL, NULL);
731     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/async_small_thres", 0);
732
733     xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
734                      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
735                      xbt_cfgelm_int, 1, 1, NULL, NULL);
736     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/send_is_detached_thres", 65536);
737
738     //For smpi/bw_factor and smpi/lat_factor
739     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
740     //test is if( size >= thresholdN ) return valueN;
741     //Values can be modified with command line --cfg=smpi/bw_factor:"threshold0:value0;threshold1:value1;...;thresholdN:valueN"
742     //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
743     xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
744                      "Bandwidth factors for smpi.",
745                      xbt_cfgelm_string, 1, 1, NULL, NULL);
746     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");
747
748     xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
749                      "Latency factors for smpi.",
750                      xbt_cfgelm_string, 1, 1, NULL, NULL);
751     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");
752
753     xbt_cfg_register(&_sg_cfg_set, "smpi/os",
754                      "Small messages timings (MPI_Send minimum time for small messages)",
755                      xbt_cfgelm_string, 1, 1, NULL, NULL);
756     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
757
758     xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
759                      "Small messages timings (MPI_Isend minimum time for small messages)",
760                      xbt_cfgelm_string, 1, 1, NULL, NULL);
761     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
762
763     xbt_cfg_register(&_sg_cfg_set, "smpi/or",
764                      "Small messages timings (MPI_Recv minimum time for small messages)",
765                      xbt_cfgelm_string, 1, 1, NULL, NULL);
766     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
767     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
768                      "Minimum time to inject inside a call to MPI_Iprobe",
769                      xbt_cfgelm_double, 1, 1, NULL, NULL);
770     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/iprobe", 1e-4);
771     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
772                      "Which collective selector to use",
773                      xbt_cfgelm_string, 1, 1, NULL, NULL);
774     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/coll_selector", "default");
775
776     xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
777                      "Which collective to use for gather",
778                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_gather, NULL);
779
780     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
781                      "Which collective to use for allgather",
782                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgather, NULL);
783
784     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
785                      "Which collective to use for barrier",
786                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_barrier, NULL);
787
788     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
789                      "Which collective to use for reduce_scatter",
790                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce_scatter, NULL);
791
792     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
793                      "Which collective to use for scatter",
794                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_scatter, NULL);
795
796     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
797                      "Which collective to use for allgatherv",
798                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
799
800     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
801                      "Which collective to use for allreduce",
802                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
803
804     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
805                      "Which collective to use for alltoall",
806                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoall, NULL);
807
808     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
809                      "Which collective to use for alltoallv",
810                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
811
812     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
813                      "Which collective to use for bcast",
814                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
815
816     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
817                      "Which collective to use for reduce",
818                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
819 #endif // HAVE_SMPI
820
821     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
822                      "\"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.",
823                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_clean_atexit, NULL);
824     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", "yes");
825
826     if (!surf_path) {
827       /* retrieves the current directory of the current process */
828       const char *initial_path = __surf_get_initial_path();
829       xbt_assert((initial_path),
830                   "__surf_get_initial_path() failed! Can't resolves current Windows directory");
831
832       surf_path = xbt_dynar_new(sizeof(char *), NULL);
833       xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
834     }
835
836     _sg_cfg_init_status = 1;
837
838     sg_config_cmd_line(argc, argv);
839
840     xbt_mallocator_initialization_is_done(SIMIX_context_is_parallel());
841
842   } else {
843     XBT_WARN("Call to sg_config_init() after initialization ignored");
844   }
845
846   xbt_free(description);
847 }
848
849 void sg_config_finalize(void)
850 {
851   if (!_sg_cfg_init_status)
852     return;                     /* Not initialized yet. Nothing to do */
853
854   xbt_cfg_free(&_sg_cfg_set);
855   _sg_cfg_init_status = 0;
856 }
857
858 /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
859 void surf_config_models_setup()
860 {
861   const char *workstation_model_name;
862   int workstation_id = -1;
863   char *network_model_name = NULL;
864   char *cpu_model_name = NULL;
865   int storage_id = -1;
866   char *storage_model_name = NULL;
867
868   workstation_model_name =
869       xbt_cfg_get_string(_sg_cfg_set, "workstation/model");
870   network_model_name = xbt_cfg_get_string(_sg_cfg_set, "network/model");
871   cpu_model_name = xbt_cfg_get_string(_sg_cfg_set, "cpu/model");
872   storage_model_name = xbt_cfg_get_string(_sg_cfg_set, "storage/model");
873
874   /* Check whether we use a net/cpu model differing from the default ones, in which case
875    * we should switch to the "compound" workstation model to correctly dispatch stuff to
876    * the right net/cpu models.
877    */
878
879   if ((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
880        !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
881       xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model")) {
882     XBT_INFO("Switching workstation model to compound since you changed the network and/or cpu model(s)");
883     workstation_model_name = "compound";
884     xbt_cfg_set_string(_sg_cfg_set, "workstation/model", workstation_model_name);
885   }
886
887   XBT_DEBUG("Workstation model: %s", workstation_model_name);
888   workstation_id =
889       find_model_description(surf_workstation_model_description,
890                              workstation_model_name);
891   if (!strcmp(workstation_model_name, "compound")) {
892     int network_id = -1;
893     int cpu_id = -1;
894
895     xbt_assert(cpu_model_name,
896                 "Set a cpu model to use with the 'compound' workstation model");
897
898     xbt_assert(network_model_name,
899                 "Set a network model to use with the 'compound' workstation model");
900
901     network_id =
902         find_model_description(surf_network_model_description,
903                                network_model_name);
904     cpu_id =
905         find_model_description(surf_cpu_model_description, cpu_model_name);
906
907     surf_cpu_model_description[cpu_id].model_init_preparse();
908     surf_network_model_description[network_id].model_init_preparse();
909   }
910
911   XBT_DEBUG("Call workstation_model_init");
912   surf_workstation_model_description[workstation_id].model_init_preparse();
913
914   XBT_DEBUG("Call storage_model_init");
915   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
916   surf_storage_model_description[storage_id].model_init_preparse();
917
918   /* ********************************************************************* */
919   /* TUTORIAL: New model                                                   */
920   int new_model_id = -1;
921   char *new_model_name = NULL;
922   new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
923   XBT_DEBUG("Call new model_init");
924   new_model_id = find_model_description(surf_new_model_description, new_model_name);
925   surf_new_model_description[new_model_id].model_init_preparse();
926   /* ********************************************************************* */
927 }
928
929 int sg_cfg_get_int(const char* name)
930 {
931   return xbt_cfg_get_int(_sg_cfg_set,name);
932 }
933
934 double sg_cfg_get_double(const char* name)
935 {
936   return xbt_cfg_get_double(_sg_cfg_set,name);
937 }
938
939 char* sg_cfg_get_string(const char* name)
940 {
941   return xbt_cfg_get_string(_sg_cfg_set,name);
942 }
943
944 int sg_cfg_get_boolean(const char* name)
945 {
946   return xbt_cfg_get_boolean(_sg_cfg_set,name);
947 }
948
949 void sg_cfg_get_peer(const char *name, char **peer, int *port)
950 {
951   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
952 }
953
954 xbt_dynar_t sg_cfg_get_dynar(const char* name)
955 {
956   return xbt_cfg_get_dynar(_sg_cfg_set,name);
957 }