Beispiel #1
0
static void scheduleDAX(xbt_dynar_t dax)
{
  unsigned int cursor;
  SD_task_t task;

  const SD_workstation_t *ws_list = SD_workstation_get_list();
  int totalHosts = SD_workstation_get_number();
  qsort((void *) ws_list, totalHosts, sizeof(SD_workstation_t),
        name_compare_hosts);

  int count = SD_workstation_get_number();
  //fprintf(stdout, "No. workstations: %d, %d\n", count, (dax != NULL));

  xbt_dynar_foreach(dax, cursor, task) {
    if (SD_task_get_kind(task) == SD_TASK_COMP_SEQ) {
      if (!strcmp(SD_task_get_name(task), "end")
          || !strcmp(SD_task_get_name(task), "root")) {
        fprintf(stdout, "Scheduling %s to node: %s\n", SD_task_get_name(task),
                SD_workstation_get_name(ws_list[0]));
        SD_task_schedulel(task, 1, ws_list[0]);
      } else {
        fprintf(stdout, "Scheduling %s to node: %s\n", SD_task_get_name(task),
                SD_workstation_get_name(ws_list[(cursor) % count]));
        SD_task_schedulel(task, 1, ws_list[(cursor) % count]);
      }
    }
  }
}
Beispiel #2
0
 xbt_dynar_foreach(dax, cursor, task) {
   if (SD_task_get_kind(task) == SD_TASK_COMP_SEQ) {
     if (!strcmp(SD_task_get_name(task), "end"))
       SD_task_schedulel(task, 1, ws_list[0]);
     else
       SD_task_schedulel(task, 1, ws_list[cursor % hosts_count]);
   }
 }
Beispiel #3
0
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);
  }
Beispiel #5
0
/* Activate a resource, i.e., act as if a VM is started on a host. This amounts to :
 * - setting attributes to 'ON' and 'idle'
 * - Resetting the start time of the host to the current time
 * - bill at least the first hour
 * If a provisioning delay is needed before a VM is actually available for executing task, this function :
 * - creates a task whose name is "Booting " followed by the host name
 * - schedules this task on the host
 * - Ensures that no compute task can be executed before the completion of this booting task.
 */
void sg_host_start(sg_host_t host){
  HostAttribute attr = (HostAttribute) sg_host_user(host);
  char name[1024];

  attr->on_off = 1;
  attr->idle_busy = 0;
  attr->start_time = SD_get_clock();
  attr->total_cost += attr->price;
  if (attr->provisioning_delay){
    sprintf(name,"Booting %s", sg_host_get_name(host));

    attr->booting = SD_task_create_comp_seq(name, NULL, attr->provisioning_delay*sg_host_speed(host));
    SD_task_schedulel(attr->booting, 1, host);
    attr->available_at += attr->provisioning_delay;
    handle_resource_dependency(host, attr->booting);
  }
  XBT_DEBUG("VM started on %s: Total cost is now $%f for this host", sg_host_get_name(host), attr->total_cost);
  sg_host_user_set(host, attr);
}
Beispiel #6
0
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);
}
Beispiel #7
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;
}
Beispiel #8
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);
  }
Beispiel #9
0
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;
}
Beispiel #10
0
int main(int argc, char **argv)
{
  double computation_amount[1];
  double communication_amount[2] = { 0 };
  sg_host_t hosts[1];

  /* initialization of SD */
  SD_init(&argc, argv);

  /* creation of the environment */
  SD_create_environment(argv[1]);

  /* creation of a single task that will poorly fail when the workstation will stop */
  XBT_INFO("First test: COMP_SEQ task");
  SD_task_t task = SD_task_create_comp_seq("Poor task", NULL, 2e10);
  SD_task_watch(task, SD_FAILED);
  SD_task_watch(task, SD_DONE);

  XBT_INFO("Schedule task '%s' on 'Faulty Host'", SD_task_get_name(task));

  SD_task_schedulel(task, 1, sg_host_by_name("Faulty Host"));

  xbt_dynar_t tasks = SD_simulate(-1.0);
  xbt_dynar_free(&tasks);

  SD_task_dump(task);

  XBT_INFO("Task '%s' has failed. %.f flops remain to be done", SD_task_get_name(task),
           SD_task_get_remaining_amount(task));

  XBT_INFO("let's unschedule task '%s' and reschedule it on the 'Safe Host'", SD_task_get_name(task));
  SD_task_unschedule(task);
  SD_task_schedulel(task, 1, sg_host_by_name("Safe Host"));

  XBT_INFO("Run the simulation again");
  tasks = SD_simulate(-1.0);
  xbt_dynar_free(&tasks);

  SD_task_dump(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));

  SD_task_destroy(task);
  task=NULL;

  XBT_INFO("Second test: NON TYPED task");

  task = SD_task_create("Poor parallel task", NULL, 2e10);
  SD_task_watch(task, SD_FAILED);
  SD_task_watch(task, SD_DONE);

  computation_amount[0] = 2e10;

  XBT_INFO("Schedule task '%s' on 'Faulty Host'", SD_task_get_name(task));

  hosts[0] = sg_host_by_name("Faulty Host");
  SD_task_schedule(task, 1, hosts, computation_amount, communication_amount,-1);

  tasks = SD_simulate(-1.0);
  xbt_dynar_free(&tasks);

  SD_task_dump(task);

  XBT_INFO("Task '%s' has failed. %.f flops remain to be done", SD_task_get_name(task),
            SD_task_get_remaining_amount(task));

  XBT_INFO("let's unschedule task '%s' and reschedule it on the 'Safe Host'", SD_task_get_name(task));
  SD_task_unschedule(task);

  hosts[0] = sg_host_by_name("Safe Host");

  SD_task_schedule(task, 1, hosts, computation_amount, communication_amount,-1);

  XBT_INFO("Run the simulation again");
  tasks = SD_simulate(-1.0);
  xbt_dynar_free(&tasks);

  SD_task_dump(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));

  SD_task_destroy(task);
  SD_exit();
  return 0;
}