1 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011. The SimGrid Team.
2 * All rights reserved. */
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. */
9 #include "surf_private.h"
10 #include "xbt/module.h"
12 #include "surf/surf_resource.h"
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
15 "Logging specific to SURF (kernel)");
17 /* Additional declarations for Windows potability. */
25 static const char *disk_drives_letter_table[MAX_DRIVE] = {
53 #endif /* #ifdef _XBT_WIN32 */
56 * Returns the initial path. On Windows the initial path is
57 * the current directory for the current process in the other
58 * case the function returns "./" that represents the current
59 * directory on Unix/Linux platforms.
62 const char *__surf_get_initial_path(void)
67 char current_directory[MAX_PATH + 1] = { 0 };
68 unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
74 strncpy(root, current_directory, 3);
76 for (i = 0; i < MAX_DRIVE; i++) {
77 if (toupper(root[0]) == disk_drives_letter_table[i][0])
78 return disk_drives_letter_table[i];
87 /* The __surf_is_absolute_file_path() returns 1 if
88 * file_path is a absolute file path, in the other
89 * case the function returns 0.
91 int __surf_is_absolute_file_path(const char *file_path)
94 WIN32_FIND_DATA wfd = { 0 };
95 HANDLE hFile = FindFirstFile(file_path, &wfd);
97 if (INVALID_HANDLE_VALUE == hFile)
103 return (file_path[0] == '/');
109 xbt_dynar_t model_list = NULL;
110 tmgr_history_t history = NULL;
111 lmm_system_t maxmin_system = NULL;
112 xbt_dynar_t surf_path = NULL;
114 /* Don't forget to update the option description in smx_config when you change this */
115 s_surf_model_description_t surf_network_model_description[] = {
117 "Simplistic network model where all communication take a constant time (one second)",
118 surf_network_model_init_Constant},
120 "Legacy network model with lmm_solve (slow-start and bottleneck sharing with small bandwidth poorly modeled).",
121 surf_network_model_init_CM02},
123 "Realistic network model (slow-start modeled by multiplying latency by 10.4, bandwidth by .92 and bottleneck sharing uses a payload of S=8775 for evaluating RTT). Uses partial invalidation optimization of lmm system and a heap for action management by default (option --cfg=network/optim:Lazy)",
124 surf_network_model_init_LegrandVelho},
126 "Realistic network model (see LV08) [Deprecated. Use LV08 with option --cfg=network/optim:Full. The Full option updates all actions at every step, which may be useful for debug.]",
127 surf_network_model_init_LegrandVelho},
129 "Realistic network model with lmm_solve specifically tailored for HPC setting (accurate modeling of slow start with correction factors on three intervals (< 1KiB, < 64 KiB, >= 64 KiB))",
130 surf_network_model_init_SMPI},
133 "Network Pseudo-model using the GTNets simulator instead of an analytic model",
134 surf_network_model_init_GTNETS},
139 surf_network_model_init_NS3},
142 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info)",
143 surf_network_model_init_Reno},
145 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info)",
146 surf_network_model_init_Reno2},
148 "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info)",
149 surf_network_model_init_Vegas},
150 {NULL, NULL, NULL} /* this array must be NULL terminated */
153 s_surf_model_description_t surf_cpu_model_description[] = {
154 {"Cas01_fullupdate", "CPU classical model time=size/power (Cas01). [Deprecated. Use Cas01 with option --cfg=cpu/optim:Full. The Full option updates all actions at every step, which may be useful for debug.]",
155 surf_cpu_model_init_Cas01},
157 "CPU classical model time=size/power. Default version uses partial invalidation optimization of lmm system and a heap for action management (default option is --cfg=cpu/optim:Lazy)",
158 surf_cpu_model_init_Cas01},
160 "CPU classical model time=size/power (Cas01). [Deprecated. Use Cas01 with option --cfg=cpu/optim:TI. The TI optimization is highly optimized when using traces]",
161 surf_cpu_model_init_ti},
162 {NULL, NULL, NULL} /* this array must be NULL terminated */
165 s_surf_model_description_t surf_workstation_model_description[] = {
167 "Curent default workstation model (may change with versions of SimGrid). Currently Cas01 and LV08 (with full duplex support) as CPU and Network",
168 surf_workstation_model_init_current_default},
170 "Default workstation model, using Cas01 and CM02 as CPU and Network",
171 surf_workstation_model_init_CLM03},
173 "Workstation model allowing you to use other network and CPU models",
174 surf_workstation_model_init_compound},
175 {"ptask_L07", "Workstation model with better parallel task modeling",
176 surf_workstation_model_init_ptask_L07},
177 {NULL, NULL, NULL} /* this array must be NULL terminated */
180 s_surf_model_description_t surf_optimization_mode_description[] = {
182 "Lazy action management (partial invalidation in lmm + heap in action remaining).",
185 "Trace integration. Highly optimized mode for the Cas01 model when using availability traces.",
188 "Full update of remaining and variables. Slow but may be useful when debugging.",
190 {NULL, NULL, NULL} /* this array must be NULL terminated */
193 /** Displays the long description of all registered models, and quit */
194 void model_help(const char *category, s_surf_model_description_t * table)
197 printf("Long description of the %s models accepted by this simulator:\n",
199 for (i = 0; table[i].name; i++)
200 printf(" %s: %s\n", table[i].name, table[i].description);
203 int find_model_description(s_surf_model_description_t * table,
207 char *name_list = NULL;
209 for (i = 0; table[i].name; i++)
210 if (!strcmp(name, table[i].name)) {
213 name_list = strdup(table[0].name);
214 for (i = 1; table[i].name; i++) {
216 xbt_realloc(name_list,
217 strlen(name_list) + strlen(table[i].name) + 3);
218 strcat(name_list, ", ");
219 strcat(name_list, table[i].name);
221 xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
225 double generic_maxmin_share_resources(xbt_swag_t running_actions,
228 void (*solve) (lmm_system_t))
230 surf_action_t action = NULL;
233 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + (offset))))
237 xbt_swag_foreach(action, running_actions) {
238 value = lmm_variable_getvalue(VARIABLE(action));
239 if ((value > 0) || (action->max_duration >= 0))
247 if (action->remains > 0)
248 min = action->remains / value;
251 if ((action->max_duration >= 0) && (action->max_duration < min))
252 min = action->max_duration;
254 min = action->max_duration;
257 for (action = xbt_swag_getNext(action, running_actions->offset);
259 action = xbt_swag_getNext(action, running_actions->offset)) {
260 value = lmm_variable_getvalue(VARIABLE(action));
262 if (action->remains > 0)
263 value = action->remains / value;
268 XBT_DEBUG("Updating min (value) with %p: %f", action, min);
271 if ((action->max_duration >= 0) && (action->max_duration < min)) {
272 min = action->max_duration;
273 XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
276 XBT_DEBUG("min value : %f", min);
282 XBT_LOG_EXTERNAL_CATEGORY(surf_cpu);
283 XBT_LOG_EXTERNAL_CATEGORY(surf_kernel);
284 XBT_LOG_EXTERNAL_CATEGORY(surf_lagrange);
285 XBT_LOG_EXTERNAL_CATEGORY(surf_lagrange_dichotomy);
286 XBT_LOG_EXTERNAL_CATEGORY(surf_maxmin);
287 XBT_LOG_EXTERNAL_CATEGORY(surf_network);
288 XBT_LOG_EXTERNAL_CATEGORY(surf_trace);
289 XBT_LOG_EXTERNAL_CATEGORY(surf_parse);
290 XBT_LOG_EXTERNAL_CATEGORY(surf_timer);
291 XBT_LOG_EXTERNAL_CATEGORY(surf_workstation);
292 XBT_LOG_EXTERNAL_CATEGORY(surf_config);
293 XBT_LOG_EXTERNAL_CATEGORY(surf_route);
296 XBT_LOG_EXTERNAL_CATEGORY(surf_network_gtnets);
299 void surf_init(int *argc, char **argv)
301 XBT_DEBUG("Create all Libs");
302 host_lib = xbt_lib_new();
303 link_lib = xbt_lib_new();
304 as_router_lib = xbt_lib_new();
306 XBT_DEBUG("ADD ROUTING LEVEL");
307 ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_free);
308 ROUTING_ASR_LEVEL = xbt_lib_add_level(as_router_lib,xbt_free);
310 XBT_DEBUG("ADD SURF LEVELS");
311 SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
312 SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
313 SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_resource_free);
315 /* Connect our log channels: that must be done manually under windows */
316 XBT_LOG_CONNECT(surf_cpu, surf);
317 XBT_LOG_CONNECT(surf_kernel, surf);
318 XBT_LOG_CONNECT(surf_lagrange, surf);
319 XBT_LOG_CONNECT(surf_lagrange_dichotomy, surf_lagrange);
320 XBT_LOG_CONNECT(surf_maxmin, surf);
321 XBT_LOG_CONNECT(surf_network, surf);
322 XBT_LOG_CONNECT(surf_trace, surf);
323 XBT_LOG_CONNECT(surf_parse, surf);
324 XBT_LOG_CONNECT(surf_timer, surf);
325 XBT_LOG_CONNECT(surf_workstation, surf);
326 XBT_LOG_CONNECT(surf_config, surf);
327 XBT_LOG_CONNECT(surf_route, surf);
330 XBT_LOG_CONNECT(surf_network_gtnets, surf);
333 xbt_init(argc, argv);
335 model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
337 history = tmgr_history_new();
339 surf_config_init(argc, argv);
346 # define FILE_DELIM "\\"
348 # define FILE_DELIM "/" /* FIXME: move to better location */
351 FILE *surf_fopen(const char *name, const char *mode)
354 char *path_elm = NULL;
360 if (__surf_is_absolute_file_path(name)) /* don't mess with absolute file names */
361 return fopen(name, mode);
363 /* search relative files in the path */
364 xbt_dynar_foreach(surf_path, cpt, path_elm) {
365 buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
366 file = fopen(buff, mode);
378 surf_model_t model = NULL;
380 surf_config_finalize();
382 xbt_dynar_foreach(model_list, iter, model)
383 model->model_private->finalize();
384 xbt_dynar_free(&model_list);
388 lmm_system_free(maxmin_system);
389 maxmin_system = NULL;
392 tmgr_history_free(history);
397 xbt_dynar_free(&surf_path);
399 xbt_lib_free(&host_lib);
400 xbt_lib_free(&link_lib);
401 xbt_lib_free(&as_router_lib);
405 surf_parse_lex_destroy();
406 surf_parse_free_callbacks();
408 NOW = 0; /* Just in case the user plans to restart the simulation afterward */
411 void surf_presolve(void)
413 double next_event_date = -1.0;
414 tmgr_trace_event_t event = NULL;
416 surf_resource_t resource = NULL;
417 surf_model_t model = NULL;
421 ("First Run! Let's \"purge\" events and put models in the right state");
422 while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
423 if (next_event_date > NOW)
426 tmgr_history_get_next_event_leq(history, next_event_date,
428 (void **) &resource))) {
429 resource->model->model_private->update_resource_state(resource,
434 xbt_dynar_foreach(model_list, iter, model)
435 model->model_private->update_actions_state(NOW, 0.0);
438 double surf_solve(double max_date)
440 double min = -1.0; /* duration */
441 double next_event_date = -1.0;
442 double model_next_action_end = -1.0;
444 surf_resource_t resource = NULL;
445 surf_model_t model = NULL;
446 tmgr_trace_event_t event = NULL;
449 if (max_date != -1.0 && max_date != NOW) {
450 min = max_date - NOW;
453 XBT_DEBUG("Looking for next action end for all models except NS3");
454 xbt_dynar_foreach(model_list, iter, model) {
455 if(strcmp(model->name,"network NS3") ){
456 XBT_DEBUG("Running for Resource [%s]", model->name);
457 model_next_action_end = model->model_private->share_resources(NOW);
458 XBT_DEBUG("Resource [%s] : next action end = %f",
459 model->name, model_next_action_end);
460 if (((min < 0.0) || (model_next_action_end < min))
461 && (model_next_action_end >= 0.0))
462 min = model_next_action_end;
466 XBT_DEBUG("Min for resources (except NS3) : %f", min);
468 XBT_DEBUG("Looking for next trace event");
471 XBT_DEBUG("Next TRACE event : %f", next_event_date);
473 next_event_date = tmgr_history_next_date(history);
475 if(surf_network_model->name && !strcmp(surf_network_model->name,"network NS3")){
476 if(next_event_date!=-1.0 && min!=-1.0) {
477 min = MIN(next_event_date - NOW, min);
479 min = MAX(next_event_date - NOW, min);
482 XBT_DEBUG("Run for NS3 at most %f", min);
483 // run until min or next flow
484 model_next_action_end = surf_network_model->model_private->share_resources(min);
486 XBT_DEBUG("Min for NS3 : %f", model_next_action_end);
487 if(model_next_action_end>=0.0)
488 min = model_next_action_end;
491 if (next_event_date == -1.0) break;
493 if ((min != -1.0) && (next_event_date > NOW + min)) break;
495 XBT_DEBUG("Updating models");
497 tmgr_history_get_next_event_leq(history, next_event_date,
499 (void **) &resource))) {
500 if (resource->model->model_private->resource_used(resource)) {
501 min = next_event_date - NOW;
503 ("This event will modify model state. Next event set to %f",
506 /* update state of model_obj according to new value. Does not touch lmm.
507 It will be modified if needed when updating actions */
508 XBT_DEBUG("Calling update_resource_state for resource %s with min %lf",
509 resource->model->name, min);
510 resource->model->model_private->update_resource_state(resource,
516 /* FIXME: Moved this test to here to avoid stoping simulation if there are actions running on cpus and all cpus are with availability = 0.
517 * This may cause an infinite loop if one cpu has a trace with periodicity = 0 and the other a trace with periodicity > 0.
518 * The options are: all traces with same periodicity(0 or >0) or we need to change the way how the events are managed */
522 XBT_DEBUG("Duration set to %f", min);
526 xbt_dynar_foreach(model_list, iter, model)
527 model->model_private->update_actions_state(NOW, min);
530 TRACE_paje_dump_buffer (0);
536 XBT_INLINE double surf_get_clock(void)