int main(int argc, char **argv) { unsigned int ctr; SD_task_t task; xbt_dynar_t changed_tasks; SD_init(&argc, argv); SD_create_environment(argv[1]); const sg_host_t *hosts = sg_host_list(); SD_task_t t1 = SD_task_create_comp_seq("t1", NULL, 25000000); SD_task_t c1 = SD_task_create_comm_e2e("c1", NULL, 125000000); SD_task_t t2 = SD_task_create_comp_seq("t2", NULL, 25000000); SD_task_t c2 = SD_task_create_comm_e2e("c2", NULL, 62500000); SD_task_t t3 = SD_task_create_comp_seq("t3", NULL, 25000000); SD_task_t c3 = SD_task_create_comm_e2e("c3", NULL, 31250000); SD_task_t t4 = SD_task_create_comp_seq("t4", NULL, 25000000); /* Add dependencies: t1->c1->t2->c2->t3 */ SD_task_dependency_add(NULL, NULL, t1, c1); SD_task_dependency_add(NULL, NULL, c1, t2); SD_task_dependency_add(NULL, NULL, t2, c2); SD_task_dependency_add(NULL, NULL, c2, t3); SD_task_dependency_add(NULL, NULL, t3, c3); SD_task_dependency_add(NULL, NULL, c3, t4); /* Schedule tasks t1 and w3 on first host, t2 on second host */ /* Transfers are auto-scheduled */ SD_task_schedulel(t1, 1, hosts[0]); SD_task_schedulel(t2, 1, hosts[1]); SD_task_schedulel(t3, 1, hosts[0]); SD_task_schedulel(t4, 1, hosts[1]); /* Add some watchpoint upon task completion */ SD_task_watch(t1, SD_DONE); SD_task_watch(c1, SD_DONE); SD_task_watch(t2, SD_DONE); SD_task_watch(c2, SD_DONE); SD_task_watch(t3, SD_DONE); SD_task_watch(c3, SD_DONE); SD_task_watch(t4, SD_DONE); while (!xbt_dynar_is_empty((changed_tasks = SD_simulate(-1.0)))) { XBT_INFO("link1: bw=%.0f, lat=%f", SD_route_get_bandwidth(hosts[0], hosts[1]), SD_route_get_latency(hosts[0], hosts[1])); XBT_INFO("Jupiter: speed=%.0f", sg_host_speed(hosts[0])* sg_host_get_available_speed(hosts[0])); XBT_INFO("Tremblay: speed=%.0f", sg_host_speed(hosts[1])* sg_host_get_available_speed(hosts[1])); xbt_dynar_foreach(changed_tasks, ctr, task) { XBT_INFO("Task '%s' start time: %f, finish time: %f", SD_task_get_name(task), SD_task_get_start_time(task), SD_task_get_finish_time(task)); if (SD_task_get_state(task)==SD_DONE) SD_task_destroy(task); } }
int main(int argc, char **argv) { unsigned int ctr; SD_task_t task; xbt_dynar_t changed_tasks; SD_init(&argc, argv); xbt_assert(argc > 1, "Usage: %s platform_file\n\nExample: %s two_clusters.xml", argv[0], argv[0]); SD_create_environment(argv[1]); sg_host_t *hosts = sg_host_list(); /* creation of some typed tasks and their dependencies */ /* chain of five tasks, three compute tasks with two data transfers in between */ SD_task_t taskA = SD_task_create_comp_seq("Task A", NULL, 5e9); SD_task_t taskB = SD_task_create_comm_e2e("Task B", NULL, 1e7); SD_task_t taskC = SD_task_create_comp_seq("Task C", NULL, 5e9); SD_task_t taskD = SD_task_create_comm_e2e("Task D", NULL, 1e7); SD_task_t taskE = SD_task_create_comp_seq("Task E", NULL, 5e9); SD_task_dependency_add(NULL, NULL, taskA, taskB); SD_task_dependency_add(NULL, NULL, taskB, taskC); SD_task_dependency_add(NULL, NULL, taskC, taskD); SD_task_dependency_add(NULL, NULL, taskD, taskE); /* Add watchpoints on completion of compute tasks */ SD_task_watch(taskA, SD_DONE); SD_task_watch(taskC, SD_DONE); SD_task_watch(taskE, SD_DONE); /* Auto-schedule the compute tasks on three different workstations */ /* Data transfer tasks taskB and taskD are automagically scheduled */ SD_task_schedulel(taskA, 1, hosts[0]); SD_task_schedulel(taskC, 1, hosts[1]); SD_task_schedulel(taskE, 1, hosts[0]); while (!xbt_dynar_is_empty((changed_tasks = SD_simulate(-1.0)))) { XBT_INFO("Simulation stopped after %.4f seconds", SD_get_clock()); xbt_dynar_foreach(changed_tasks, ctr, task) { XBT_INFO("Task '%s' start time: %f, finish time: %f", SD_task_get_name(task), SD_task_get_start_time(task), SD_task_get_finish_time(task)); } /* let throttle the communication for taskD if its parent is SD_DONE */ /* the bandwidth is 1.25e8, the data size is 1e7, and we want to throttle the bandwidth by a factor 2. * The rate is then 1.25e8/(2*1e7)=6.25 * Changing the rate is possible before the task execution starts (in SD_RUNNING state). */ if (SD_task_get_state(taskC) == SD_DONE && SD_task_get_state(taskD) < SD_RUNNING) SD_task_set_rate(taskD, 6.25); }
static void send_one(int from, int to) { //XBT_DEBUG("send_one(%d, %d)",from,to); if (count %100000 == 0) XBT_INFO("Sending task #%d",count); count++; bcast_task_t bt; if (!xbt_dynar_is_empty(reclaimed)) { bt = xbt_dynar_pop_as(reclaimed,bcast_task_t); } else { bt = xbt_new(s_bcast_task_t,1); } bt->i=from; bt->j=(from+to)/2; bt->k=to; SD_task_t task = SD_task_create_comm_e2e(NULL,bt,424242); XBT_DEBUG("Schedule task between %d and %d",bt->i,bt->j); SD_task_schedulel(task,2,ws_list[bt->i],ws_list[bt->j]); SD_task_watch(task,SD_DONE); }
int main(int argc, char **argv) { int i; const char *platform_file; const SD_workstation_t *workstations; int kind; SD_task_t task, taskA, taskB, taskC; xbt_dynar_t changed_tasks; SD_workstation_t workstation_list[2]; double computation_amount[2]; double communication_amount[4] = { 0 }; double rate = -1.0; SD_workstation_t w1, w2; /* SD initialization */ SD_init(&argc, argv); /* xbt_log_control_set("sd.thres=debug"); */ if (argc < 2) { XBT_INFO("Usage: %s platform_file", argv[0]); XBT_INFO("example: %s sd_platform.xml", argv[0]); exit(1); } /* creation of the environment */ platform_file = argv[1]; SD_create_environment(platform_file); /* Change the access mode of the workstations */ workstations = SD_workstation_get_list(); w1 = workstations[0]; w2 = workstations[1]; for (i = 0; i < 2; i++) { SD_workstation_set_access_mode(workstations[i], SD_WORKSTATION_SEQUENTIAL_ACCESS); XBT_INFO("Access mode of %s is %s", SD_workstation_get_name(workstations[i]), (SD_workstation_get_access_mode(workstations[i]) == SD_WORKSTATION_SEQUENTIAL_ACCESS) ? "sequential" : "shared"); } /* creation of the tasks and their dependencies */ taskA = SD_task_create_comp_seq("Task A", NULL, 2e9); taskB = SD_task_create_comm_e2e("Task B", NULL, 2e9); taskC = SD_task_create_comp_seq("Task C", NULL, 1e9); TRACE_category ("taskA"); TRACE_category ("taskB"); TRACE_category ("taskC"); TRACE_sd_set_task_category (taskA, "taskA"); TRACE_sd_set_task_category (taskB, "taskB"); TRACE_sd_set_task_category (taskC, "taskC"); /* if everything is ok, no exception is forwarded or rethrown by main() */ /* watch points */ SD_task_watch(taskA, SD_RUNNING); SD_task_watch(taskB, SD_RUNNING); SD_task_watch(taskC, SD_RUNNING); SD_task_watch(taskC, SD_DONE); /* scheduling parameters */ workstation_list[0] = w1; workstation_list[1] = w2; computation_amount[0] = SD_task_get_amount(taskA); computation_amount[1] = SD_task_get_amount(taskB); communication_amount[1] = SD_task_get_amount(taskC); communication_amount[2] = 0.0; SD_task_schedule(taskA, 1, &w1, &(computation_amount[0]), SD_SCHED_NO_COST, rate); SD_task_schedule(taskB, 2, workstation_list, SD_SCHED_NO_COST, communication_amount, rate); SD_task_schedule(taskC, 1, &w1, &(computation_amount[1]), SD_SCHED_NO_COST, rate); /* let's launch the simulation! */ while (!xbt_dynar_is_empty(changed_tasks = SD_simulate(-1.0))) { for (i = 0; i < 2; i++) { task = SD_workstation_get_current_task(workstations[i]); if (task) kind = SD_task_get_kind(task); else { XBT_INFO("There is no task running on %s", SD_workstation_get_name(workstations[i])); continue; } switch (kind) { case SD_TASK_COMP_SEQ: XBT_INFO("%s is currently running on %s (SD_TASK_COMP_SEQ)", SD_task_get_name(task), SD_workstation_get_name(workstations[i])); break; case SD_TASK_COMM_E2E: XBT_INFO("%s is currently running on %s (SD_TASK_COMM_E2E)", SD_task_get_name(task), SD_workstation_get_name(workstations[i])); break; case SD_TASK_NOT_TYPED: XBT_INFO("Task running on %s has no type", SD_workstation_get_name(workstations[i])); break; default: XBT_ERROR("Shouldn't be here"); } } xbt_dynar_free_container(&changed_tasks); } xbt_dynar_free_container(&changed_tasks); XBT_DEBUG("Destroying tasks..."); SD_task_destroy(taskA); SD_task_destroy(taskB); SD_task_destroy(taskC); XBT_DEBUG("Tasks destroyed. Exiting SimDag..."); SD_exit(); return 0; }
int main(int argc, char **argv) { int i; const char *platform_file; const SD_workstation_t *workstations; SD_task_t taskA, taskB, taskC, taskD; xbt_dynar_t changed_tasks; /* initialization of SD */ SD_init(&argc, argv); /* xbt_log_control_set("sd.thres=debug"); */ if (argc < 2) { XBT_INFO("Usage: %s platform_file", argv[0]); XBT_INFO("example: %s sd_platform.xml", argv[0]); exit(1); } /* creation of the environment */ platform_file = argv[1]; SD_create_environment(platform_file); /* Change the access mode of the workstations */ workstations = SD_workstation_get_list(); for (i = 0; i < 2; i++) { SD_workstation_dump(workstations[i]); SD_workstation_set_access_mode(workstations[i], SD_WORKSTATION_SEQUENTIAL_ACCESS); XBT_INFO(" Change access mode of %s to %s", SD_workstation_get_name(workstations[i]), (SD_workstation_get_access_mode(workstations[i]) == SD_WORKSTATION_SEQUENTIAL_ACCESS) ? "sequential" : "shared"); } /* Well I changed my mind, I want the second workstation to be shared */ SD_workstation_set_access_mode(workstations[1], SD_WORKSTATION_SHARED_ACCESS); XBT_INFO(" Change access mode of %s to %s", SD_workstation_get_name(workstations[1]), (SD_workstation_get_access_mode(workstations[1]) == SD_WORKSTATION_SEQUENTIAL_ACCESS) ? "sequential" : "shared"); /* creation of the tasks and their dependencies */ taskA = SD_task_create_comp_seq("Task A", NULL, 2e10); taskB = SD_task_create_comm_e2e("Task B", NULL, 2e8); taskC = SD_task_create_comp_seq("Task C", NULL, 1e10); taskD = SD_task_create_comp_seq("Task D", NULL, 1e11); SD_task_dependency_add("B->C", NULL,taskB, taskC); /* watch points */ SD_task_watch(taskA, SD_RUNNING); SD_task_watch(taskB, SD_RUNNING); SD_task_watch(taskC, SD_RUNNING); SD_task_watch(taskC, SD_DONE); SD_task_watch(taskD, SD_DONE); /* scheduling parameters */ SD_task_schedulel(taskA, 1, workstations[0]); SD_task_schedulel(taskB, 2, workstations[0], workstations[1]); SD_task_schedulel(taskC, 1, workstations[1]); SD_task_schedulel(taskD, 1, workstations[1]); /* let's launch the simulation! */ while (!xbt_dynar_is_empty(changed_tasks = SD_simulate(-1.0))) { XBT_INFO(" Simulation was suspended, check workstation states"); for (i = 0; i < 2; i++) { SD_workstation_dump(workstations[i]); } xbt_dynar_free(&changed_tasks); } xbt_dynar_free(&changed_tasks); XBT_DEBUG("Destroying tasks..."); SD_task_destroy(taskA); SD_task_destroy(taskB); SD_task_destroy(taskC); SD_task_destroy(taskD); XBT_DEBUG("Tasks destroyed. Exiting SimDag..."); SD_exit(); return 0; }
int main(int argc, char **argv) { unsigned int ctr; const char *platform_file; const SD_workstation_t *workstations; SD_task_t task, taskA, taskB, taskC, taskD, taskE; xbt_dynar_t changed_tasks; /* initialization of SD */ SD_init(&argc, argv); /* xbt_log_control_set("sd.thres=debug"); */ if (argc < 2) { XBT_INFO("Usage: %s platform_file", argv[0]); XBT_INFO("example: %s sd_platform.xml", argv[0]); exit(1); } /* creation of the environment */ platform_file = argv[1]; SD_create_environment(platform_file); workstations = SD_workstation_get_list(); /* creation of some typed tasks and their dependencies */ /* chain of five tasks, three compute tasks with two data transfers */ /* in between */ taskA = SD_task_create_comp_seq("Task A", NULL, 5e9); taskB = SD_task_create_comm_e2e("Task B", NULL, 1e7); taskC = SD_task_create_comp_seq("Task C", NULL, 5e9); taskD = SD_task_create_comm_e2e("Task D", NULL, 1e7); taskE = SD_task_create_comp_seq("Task E", NULL, 5e9); SD_task_dependency_add(NULL, NULL, taskA, taskB); SD_task_dependency_add(NULL, NULL, taskB, taskC); SD_task_dependency_add(NULL, NULL, taskC, taskD); SD_task_dependency_add(NULL, NULL, taskD, taskE); /* Add watchpoints on completion of compute tasks */ SD_task_watch(taskA, SD_DONE); SD_task_watch(taskC, SD_DONE); SD_task_watch(taskE, SD_DONE); /* Auto-schedule the compute tasks on three different workstations */ /* Data transfer tasks taskB and taskD are automagically scheduled */ SD_task_schedulel(taskA, 1, workstations[0]); SD_task_schedulel(taskC, 1, workstations[1]); SD_task_schedulel(taskE, 1, workstations[0]); while (!xbt_dynar_is_empty((changed_tasks = SD_simulate(-1.0)))) { XBT_INFO("Simulation stopped after %.4f seconds", SD_get_clock()); xbt_dynar_foreach(changed_tasks, ctr, task) { XBT_INFO("Task '%s' start time: %f, finish time: %f", SD_task_get_name(task), SD_task_get_start_time(task), SD_task_get_finish_time(task)); } /* let throttle the communication for taskD if its parent is SD_DONE */ /* the bandwidth is 1.25e8, the data size is 1e7, and we want to throttle * the bandwidth by a factor 2. the rate is then 1.25e8/(2*1e7)=6.25 * Changing the rate is possible before the task execution starts (in SD_RUNNING * state). */ if (SD_task_get_state(taskC) == SD_DONE && SD_task_get_state(taskD) < SD_RUNNING) SD_task_set_rate(taskD, 6.25); xbt_dynar_free_container(&changed_tasks); }
xbt_dynar_t SD_dotload_generic(const char* filename, bool sequential, 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); SD_task_t root; SD_task_t end; SD_task_t task; std::vector<SD_task_t>* computer; std::unordered_map<std::string, std::vector<SD_task_t>*> computers; bool schedule_success = true; std::unordered_map<std::string, SD_task_t> jobs; 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 *)); /* 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")); if (jobs.find(name) == jobs.end()) { if (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); } jobs.insert({std::string(name), task}); if (strcmp(name,"root") && strcmp(name,"end")) xbt_dynar_push(result, &task); if ((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 = ((not char_performer || not strcmp(char_performer, "")) ? -1 : atoi(char_performer)); int order = ((not char_order || not strcmp(char_order, "")) ? -1 : atoi(char_order)); if ((performer != -1 && order != -1) && performer < static_cast<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); auto comp = computers.find(char_performer); if (comp != computers.end()) { computer = comp->second; } else { computer = new std::vector<SD_task_t>; computers.insert({char_performer, computer}); } if (static_cast<unsigned int>(order) < computer->size()) { SD_task_t task_test = computer->at(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; } } else computer->resize(order); computer->insert(computer->begin() + order, 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 (jobs.find("root") == jobs.end()) root = (sequential ? SD_task_create_comp_seq("root", nullptr, 0) : SD_task_create_comp_par_amdahl("root", nullptr, 0, 0)); else root = jobs.at("root"); 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 (jobs.find("end") == jobs.end()) end = (sequential ? SD_task_create_comp_seq("end", nullptr, 0) : SD_task_create_comp_par_amdahl("end", nullptr, 0, 0)); else end = jobs.at("end"); /* Create edges */ std::vector<Agedge_t*> edges; for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) { edges.clear(); for (Agedge_t* edge = agfstout(dag_dot, node); edge; edge = agnxtout(dag_dot, edge)) edges.push_back(edge); /* Be sure edges are sorted */ std::sort(edges.begin(), edges.end(), [](const Agedge_t* a, const Agedge_t* b) { return AGSEQ(a) < AGSEQ(b); }); for (Agedge_t* edge : edges) { char *src_name=agnameof(agtail(edge)); char *dst_name=agnameof(aghead(edge)); double size = atof(agget(edge, (char *) "size")); SD_task_t src = jobs.at(src_name); SD_task_t dst = jobs.at(dst_name); if (size > 0) { std::string name = std::string(src_name) + "->" + dst_name; XBT_DEBUG("See <transfer id=%s amount = %.0f>", name.c_str(), size); if (jobs.find(name) == jobs.end()) { if (sequential) task = SD_task_create_comm_e2e(name.c_str(), nullptr, size); else task = SD_task_create_comm_par_mxn_1d_block(name.c_str(), nullptr, size); SD_task_dependency_add(src, task); SD_task_dependency_add(task, dst); jobs.insert({name, task}); xbt_dynar_push(result, &task); } else { XBT_WARN("Task '%s' is defined more than once", name.c_str()); } } else { SD_task_dependency_add(src, dst); } } } XBT_DEBUG("All tasks have been created, put %s at the end of the dynar", end->name); xbt_dynar_push(result, &end); /* Connect entry tasks to 'root', and exit tasks to 'end'*/ unsigned i; xbt_dynar_foreach (result, i, task){ if (task->predecessors->empty() && task->inputs->empty() && task != root) { XBT_DEBUG("Task '%s' has no source. Add dependency from 'root'", task->name); SD_task_dependency_add(root, task); } if (task->successors->empty() && task->outputs->empty() && task != end) { XBT_DEBUG("Task '%s' has no destination. Add dependency to 'end'", task->name); SD_task_dependency_add(task, end); } } agclose(dag_dot); fclose(in_file); if(schedule){ if (schedule_success) { std::vector<simgrid::s4u::Host*> hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts(); for (auto const& elm : computers) { SD_task_t previous_task = nullptr; for (auto const& cur_task : *elm.second) { /* add dependency between the previous and the task to avoid parallel execution */ if (cur_task) { if (previous_task && not SD_task_dependency_exists(previous_task, cur_task)) SD_task_dependency_add(previous_task, cur_task); SD_task_schedulel(cur_task, 1, hosts[std::stod(elm.first)]); previous_task = cur_task; } } delete elm.second; } } else { XBT_WARN("The scheduling is ignored"); for (auto const& elm : computers) delete elm.second; xbt_dynar_free(&result); result = nullptr; } } if (result && not acyclic_graph_detail(result)) { std::string base = simgrid::xbt::Path(filename).get_base_name(); XBT_ERROR("The DOT described in %s is not a DAG. It contains a cycle.", base.c_str()); xbt_dynar_free(&result); result = nullptr; } return result; }
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); } } }