/** * \brief Add a "host_link" to the network element list */ static void parse_S_host_link(sg_platf_host_link_cbarg_t host) { sg_routing_edge_t info = NULL; info = xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL); xbt_assert(info, "Host '%s' not found!",host->id); xbt_assert(current_routing->model_desc == &routing_models[SURF_MODEL_CLUSTER] || current_routing->model_desc == &routing_models[SURF_MODEL_VIVALDI], "You have to be in model Cluster to use tag host_link!"); s_surf_parsing_link_up_down_t link_up_down; link_up_down.link_up = xbt_lib_get_or_null(link_lib, host->link_up, SURF_LINK_LEVEL); link_up_down.link_down = xbt_lib_get_or_null(link_lib, host->link_down, SURF_LINK_LEVEL); link_up_down.limiter_link = NULL; link_up_down.loopback_link = NULL; xbt_assert(link_up_down.link_up, "Link '%s' not found!",host->link_up); xbt_assert(link_up_down.link_down, "Link '%s' not found!",host->link_down); if(!current_routing->link_up_down_list) current_routing->link_up_down_list = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL); // If dynar is is greater than edge id and if the host_link is already defined if(xbt_dynar_length(current_routing->link_up_down_list) > info->id && xbt_dynar_get_as(current_routing->link_up_down_list,info->id,void*)) xbt_die("Host_link for '%s' is already defined!",host->id); XBT_DEBUG("Push Host_link for host '%s' to position %d",info->name,info->id); xbt_dynar_set_as(current_routing->link_up_down_list,info->id,s_surf_parsing_link_up_down_t,link_up_down); }
/** * \brief Add a "host_link" to the network element list */ static void parse_S_host_link(sg_platf_host_link_cbarg_t host) { RoutingEdge *info = sg_host_edge(sg_host_by_name(host->id)); xbt_assert(info, "Host '%s' not found!", host->id); xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER] || current_routing->p_modelDesc == &routing_models[SURF_MODEL_VIVALDI], "You have to be in model Cluster to use tag host_link!"); s_surf_parsing_link_up_down_t link_up_down; link_up_down.link_up = Link::byName(host->link_up); link_up_down.link_down = Link::byName(host->link_down); xbt_assert(link_up_down.link_up, "Link '%s' not found!",host->link_up); xbt_assert(link_up_down.link_down, "Link '%s' not found!",host->link_down); if(!current_routing->p_linkUpDownList) current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL); // If dynar is is greater than edge id and if the host_link is already defined if((int)xbt_dynar_length(current_routing->p_linkUpDownList) > info->getId() && xbt_dynar_get_as(current_routing->p_linkUpDownList, info->getId(), void*)) surf_parse_error("Host_link for '%s' is already defined!",host->id); XBT_DEBUG("Push Host_link for host '%s' to position %d", info->getName(), info->getId()); xbt_dynar_set_as(current_routing->p_linkUpDownList, info->getId(), s_surf_parsing_link_up_down_t, link_up_down); }
xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par, bool schedule){ xbt_assert(filename, "Unable to use a null file descriptor\n"); FILE *in_file = fopen(filename, "r"); xbt_assert(in_file != nullptr, "Failed to open file: %s", filename); unsigned int i; SD_task_t root; SD_task_t end; SD_task_t task; xbt_dict_t computers; xbt_dynar_t computer = nullptr; xbt_dict_cursor_t dict_cursor; bool schedule_success = true; xbt_dict_t jobs = xbt_dict_new_homogeneous(nullptr); xbt_dynar_t result = xbt_dynar_new(sizeof(SD_task_t), dot_task_p_free); Agraph_t * dag_dot = agread(in_file, NIL(Agdisc_t *)); if (schedule) computers = xbt_dict_new_homogeneous(nullptr); /* Create all the nodes */ Agnode_t *node = nullptr; for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) { char *name = agnameof(node); double amount = atof(agget(node, (char*)"size")); task = static_cast<SD_task_t>(xbt_dict_get_or_null(jobs, name)); if (task == nullptr) { if (seq_or_par == sequential){ XBT_DEBUG("See <job id=%s amount =%.0f>", name, amount); task = SD_task_create_comp_seq(name, nullptr , amount); } else { double alpha = atof(agget(node, (char *) "alpha")); XBT_DEBUG("See <job id=%s amount =%.0f alpha = %.3f>", name, amount, alpha); task = SD_task_create_comp_par_amdahl(name, nullptr , amount, alpha); } xbt_dict_set(jobs, name, task, nullptr); if (strcmp(name,"root") && strcmp(name,"end")) xbt_dynar_push(result, &task); if((seq_or_par == sequential) && ((schedule && schedule_success) || XBT_LOG_ISENABLED(sd_dotparse, xbt_log_priority_verbose))){ /* try to take the information to schedule the task only if all is right*/ char *char_performer = agget(node, (char *) "performer"); char *char_order = agget(node, (char *) "order"); /* Tasks will execute on in a given "order" on a given set of "performer" hosts */ int performer = ((!char_performer || !strcmp(char_performer,"")) ? -1:atoi(char_performer)); int order = ((!char_order || !strcmp(char_order, ""))? -1:atoi(char_order)); if((performer != -1 && order != -1) && performer < (int) sg_host_count()){ /* required parameters are given and less performers than hosts are required */ XBT_DEBUG ("Task '%s' is scheduled on workstation '%d' in position '%d'", task->name, performer, order); if(!(computer = (xbt_dynar_t) xbt_dict_get_or_null(computers, char_performer))){ computer = xbt_dynar_new(sizeof(SD_task_t), nullptr); xbt_dict_set(computers, char_performer, computer, nullptr); } if((unsigned int)order < xbt_dynar_length(computer)){ SD_task_t *task_test = (SD_task_t *)xbt_dynar_get_ptr(computer,order); if(*task_test && *task_test != task){ /* the user gave the same order to several tasks */ schedule_success = false; XBT_VERB("Task '%s' wants to start on performer '%s' at the same position '%s' as task '%s'", (*task_test)->name, char_performer, char_order, task->name); continue; } } /* the parameter seems to be ok */ xbt_dynar_set_as(computer, order, SD_task_t, task); } else { /* one of required parameters is not given */ schedule_success = false; XBT_VERB("The schedule is ignored, task '%s' can not be scheduled on %d hosts", task->name, performer); } } } else { XBT_WARN("Task '%s' is defined more than once", name); } } /*Check if 'root' and 'end' nodes have been explicitly declared. If not, create them. */ if (!(root = (SD_task_t)xbt_dict_get_or_null(jobs, "root"))) root = (seq_or_par == sequential?SD_task_create_comp_seq("root", nullptr, 0): SD_task_create_comp_par_amdahl("root", nullptr, 0, 0)); SD_task_set_state(root, SD_SCHEDULABLE); /* by design the root task is always SCHEDULABLE */ xbt_dynar_insert_at(result, 0, &root); /* Put it at the beginning of the dynar */ if (!(end = (SD_task_t)xbt_dict_get_or_null(jobs, "end"))) end = (seq_or_par == sequential?SD_task_create_comp_seq("end", nullptr, 0): SD_task_create_comp_par_amdahl("end", nullptr, 0, 0)); /* Create edges */ xbt_dynar_t edges = xbt_dynar_new(sizeof(Agedge_t*), nullptr); for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) { Agedge_t * edge; xbt_dynar_reset(edges); for (edge = agfstout(dag_dot, node); edge; edge = agnxtout(dag_dot, edge)) xbt_dynar_push_as(edges, Agedge_t *, edge); /* Be sure edges are sorted */ xbt_dynar_sort(edges, edge_compare); xbt_dynar_foreach(edges, i, edge) { char *src_name=agnameof(agtail(edge)), *dst_name=agnameof(aghead(edge)); double size = atof(agget(edge, (char *) "size")); SD_task_t src = static_cast<SD_task_t>(xbt_dict_get_or_null(jobs, src_name)); SD_task_t dst = static_cast<SD_task_t>(xbt_dict_get_or_null(jobs, dst_name)); if (size > 0) { char *name = bprintf("%s->%s", src_name, dst_name); XBT_DEBUG("See <transfer id=%s amount = %.0f>", name, size); task = static_cast<SD_task_t>(xbt_dict_get_or_null(jobs, name)); if (task == nullptr) { if (seq_or_par == sequential) task = SD_task_create_comm_e2e(name, nullptr , size); else task = SD_task_create_comm_par_mxn_1d_block(name, nullptr , size); SD_task_dependency_add(nullptr, nullptr, src, task); SD_task_dependency_add(nullptr, nullptr, task, dst); xbt_dict_set(jobs, name, task, nullptr); xbt_dynar_push(result, &task); } else { XBT_WARN("Task '%s' is defined more than once", name); } xbt_free(name); } else { SD_task_dependency_add(nullptr, nullptr, src, dst); } } }