示例#1
0
/**
 * \brief Remove a dependency between two tasks
 *
 * \param src a task
 * \param dst a task depending on \a src
 * \see SD_task_dependency_add()
 */
void SD_task_dependency_remove(SD_task_t src, SD_task_t dst)
{
  XBT_DEBUG("SD_task_dependency_remove: src = %s, dst = %s", SD_task_get_name(src), SD_task_get_name(dst));

  if (src->successors->find(dst) == src->successors->end() &&
      src->outputs->find(dst) == src->outputs->end())
    THROWF(arg_error, 0, "No dependency found between task '%s' and '%s': task '%s' is not a successor of task '%s'",
           SD_task_get_name(src), SD_task_get_name(dst), SD_task_get_name(dst), SD_task_get_name(src));

  e_SD_task_kind_t src_kind = SD_task_get_kind(src);
  e_SD_task_kind_t dst_kind = SD_task_get_kind(dst);
  if (src_kind == SD_TASK_COMM_E2E || src_kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){
    if (dst_kind == SD_TASK_COMP_SEQ || dst_kind == SD_TASK_COMP_PAR_AMDAHL){
      dst->inputs->erase(src);
    } else {
      dst->predecessors->erase(src);
    }
    src->successors->erase(dst);
  } else {
    if (dst_kind == SD_TASK_COMM_E2E|| dst_kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){
      src->outputs->erase(dst);
    } else {
      src->successors->erase(dst);
    }
    dst->predecessors->erase(src);
  }

  /* if the task was scheduled and dependencies are satisfied, we can make it runnable */
  if (dst->predecessors->empty() && dst->inputs->empty() && SD_task_get_state(dst) == SD_SCHEDULED)
    SD_task_set_state(dst, SD_RUNNABLE);
}
示例#2
0
 xbt_dynar_foreach(dax, cursor, task) {
   int kind = SD_task_get_kind(task);
   SD_workstation_t *wsl = SD_task_get_workstation_list(task);
   switch (kind) {
   case SD_TASK_COMP_SEQ:
     fprintf(out, "[%f] %s compute %f # %s\n",
             SD_task_get_start_time(task),
             SD_workstation_get_name(wsl[0]), SD_task_get_amount(task),
             SD_task_get_name(task));
     break;
   case SD_TASK_COMM_E2E:
     fprintf(out, "[%f] %s send %s %f # %s\n",
             SD_task_get_start_time(task),
             SD_workstation_get_name(wsl[0]),
             SD_workstation_get_name(wsl[1]), SD_task_get_amount(task),
             SD_task_get_name(task));
     fprintf(out, "[%f] %s recv %s %f # %s\n",
             SD_task_get_finish_time(task),
             SD_workstation_get_name(wsl[1]),
             SD_workstation_get_name(wsl[0]), SD_task_get_amount(task),
             SD_task_get_name(task));
     break;
   default:
     xbt_die("Task %s is of unknown kind %d", SD_task_get_name(task),
             SD_task_get_kind(task));
   }
   SD_task_destroy(task);
 }
示例#3
0
/**
 * \brief Adds a dependency between two tasks
 *
 * \a dst will depend on \a src, ie \a dst will not start before \a src is finished.
 * Their \ref e_SD_task_state_t "state" must be #SD_NOT_SCHEDULED, #SD_SCHEDULED or #SD_RUNNABLE.
 *
 * \param name the name of the new dependency (can be \c nullptr)
 * \param data the user data you want to associate with this dependency (can be \c nullptr)
 * \param src the task which must be executed first
 * \param dst the task you want to make depend on \a src
 * \see SD_task_dependency_remove()
 */
void SD_task_dependency_add(const char *name, void *data, SD_task_t src, SD_task_t dst)
{

  if (src == dst)
    THROWF(arg_error, 0, "Cannot add a dependency between task '%s' and itself", SD_task_get_name(src));

  e_SD_task_state_t state = SD_task_get_state(src);
  if (state == SD_DONE || state == SD_FAILED)
    THROWF(arg_error, 0, "Task '%s' must be SD_NOT_SCHEDULED, SD_SCHEDULABLE, SD_SCHEDULED, SD_RUNNABLE, or SD_RUNNING",
           SD_task_get_name(src));

  state = SD_task_get_state(dst);
  if (state == SD_DONE || state == SD_FAILED || state == SD_RUNNING)
    THROWF(arg_error, 0, "Task '%s' must be SD_NOT_SCHEDULED, SD_SCHEDULABLE, SD_SCHEDULED, or SD_RUNNABLE",
           SD_task_get_name(dst));

  if (src->successors->find(dst) != src->successors->end() ||
      dst->predecessors->find(src) != dst->predecessors->end() ||
      dst->inputs->find(src) != dst->inputs->end() ||
      src->outputs->find(dst) != src->outputs->end())
    THROWF(arg_error, 0, "A dependency already exists between task '%s' and task '%s'",
           SD_task_get_name(src), SD_task_get_name(dst));

  XBT_DEBUG("SD_task_dependency_add: src = %s, dst = %s", SD_task_get_name(src), SD_task_get_name(dst));

  e_SD_task_kind_t src_kind = SD_task_get_kind(src);
  e_SD_task_kind_t dst_kind = SD_task_get_kind(dst);

  if (src_kind == SD_TASK_COMM_E2E || src_kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){
    if (dst_kind == SD_TASK_COMP_SEQ || dst_kind == SD_TASK_COMP_PAR_AMDAHL){
        dst->inputs->insert(src);
    } else {
      dst->predecessors->insert(src);
    }
    src->successors->insert(dst);
  } else {
    if (dst_kind == SD_TASK_COMM_E2E|| dst_kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){
      src->outputs->insert(dst);
    } else {
      src->successors->insert(dst);
    }
    dst->predecessors->insert(src);
  }

  /* if the task was runnable, the task goes back to SD_SCHEDULED because of the new dependency*/
  if (SD_task_get_state(dst) == SD_RUNNABLE) {
    XBT_DEBUG("SD_task_dependency_add: %s was runnable and becomes scheduled!", SD_task_get_name(dst));
    SD_task_set_state(dst, SD_SCHEDULED);
  }
}
示例#4
0
static double finish_on_at(SD_task_t task, sg_host_t host)
{
  double result;
  unsigned int i;
  double data_available = 0.;
  double redist_time = 0;
  double last_data_available;

  xbt_dynar_t parents = SD_task_get_parents(task);

  if (!xbt_dynar_is_empty(parents)) {
    /* compute last_data_available */
    SD_task_t parent;
    last_data_available = -1.0;
    xbt_dynar_foreach(parents, i, parent) {
      /* normal case */
      if (SD_task_get_kind(parent) == SD_TASK_COMM_E2E) {
        xbt_dynar_t grand_parents = SD_task_get_parents(parent);
        SD_task_t grand_parent;

        xbt_assert(xbt_dynar_length(grand_parents) <2, "Error: transfer %s has 2 parents", SD_task_get_name(parent));

        xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);

        sg_host_t * grand_parent_host_list = SD_task_get_workstation_list(grand_parent);
        /* Estimate the redistribution time from this parent */
        if (SD_task_get_amount(parent) <= 1e-6){
          redist_time= 0;
        } else {
          redist_time = SD_route_get_latency(grand_parent_host_list[0], host) +
                        SD_task_get_amount(parent) / SD_route_get_bandwidth(grand_parent_host_list[0], host);
        }
        data_available = SD_task_get_finish_time(grand_parent) + redist_time;

        xbt_dynar_free_container(&grand_parents);
      }

      /* no transfer, control dependency */
      if (SD_task_get_kind(parent) == SD_TASK_COMP_SEQ) {
        data_available = SD_task_get_finish_time(parent);
      }

      if (last_data_available < data_available)
        last_data_available = data_available;
    }

    xbt_dynar_free_container(&parents);

    result = MAX(sg_host_get_available_at(host), last_data_available) + SD_task_get_amount(task)/sg_host_speed(host);
  } else {
示例#5
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]);
      }
    }
  }
}
示例#6
0
文件: task.c 项目: frs69wq/biCPA
/*
 * Estimate the time at which all the input data of a task are available (i.e.,
 * have been transfered to) on its current allocation. This estimation
 * corresponds to the maximum value among the compute parents of the task of
 * the sum of the estimated finish time of the parent and estimated transfer
 * time of the data sent by this parent. For control dependencies, the second
 * part is obviously discarded.
 */
double SD_task_estimate_last_data_arrival_time (SD_task_t task){
  unsigned int i;
  double last_data_arrival = -1., data_availability, estimated_transfer_time;
  SD_task_t parent, grand_parent;
  xbt_dynar_t parents, grand_parents;

  parents = SD_task_get_parents(task);

  xbt_dynar_foreach(parents, i, parent){
    if (SD_task_get_kind(parent) == SD_TASK_COMM_PAR_MXN_1D_BLOCK) {
      grand_parents = SD_task_get_parents(parent);
      xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);
      estimated_transfer_time =
          SD_task_estimate_transfer_time_from(grand_parent, task,
              SD_task_get_amount(parent));
      data_availability = SD_task_get_estimated_finish_time(grand_parent)+
          estimated_transfer_time;
      xbt_dynar_free_container(&grand_parents);
    } else {
      data_availability = SD_task_get_estimated_finish_time(parent);
    }

    if (last_data_arrival < data_availability)
      last_data_arrival = data_availability;
  }
  xbt_dynar_free_container(&parents);
  return last_data_arrival;
}
示例#7
0
文件: task.c 项目: frs69wq/biCPA
/* This function is actually not used by biCPA */
double top_level_recursive_computation(SD_task_t task){
  unsigned int i;
  double max_top_level = 0.0, my_top_level, current_parent_top_level = 0.0;
  SD_task_t parent, grand_parent=NULL;
  xbt_dynar_t parents, grand_parents;

  max_top_level = -1.0;

  if (!strcmp(SD_task_get_name(task),"root")){
    XBT_DEBUG("root's top level is 0.0");
    SD_task_mark(task);
    SD_task_set_top_level(task, 0.0);
    return 0.0;
  }

  parents = SD_task_get_parents(task);

  xbt_dynar_foreach(parents, i, parent){
    if (SD_task_get_kind(parent) == SD_TASK_COMM_PAR_MXN_1D_BLOCK) {
      grand_parents = SD_task_get_parents(parent);
      xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);
      if (SD_task_is_marked(grand_parent)){
        current_parent_top_level = SD_task_get_top_level(grand_parent) +
            SD_task_estimate_execution_time(grand_parent,
                SD_task_get_allocation_size(grand_parent));
      } else {
        current_parent_top_level =
            top_level_recursive_computation(grand_parent) +
            SD_task_estimate_execution_time(grand_parent,
                SD_task_get_allocation_size(grand_parent));
      }
      xbt_dynar_free_container(&grand_parents);
    } else {
      if (SD_task_is_marked(parent)){
        current_parent_top_level = SD_task_get_top_level(parent) +
            SD_task_estimate_execution_time(parent,
                SD_task_get_allocation_size(parent));
      } else {
        current_parent_top_level =
            top_level_recursive_computation(parent) +
            SD_task_estimate_execution_time(parent,
                SD_task_get_allocation_size(parent));
      }
    }

    if (max_top_level < current_parent_top_level)
      max_top_level = current_parent_top_level;
  }

  my_top_level = max_top_level;

  SD_task_set_top_level(task, my_top_level);
  SD_task_mark(task);
  XBT_DEBUG("%s's top level is %f", SD_task_get_name(task), my_top_level);

  xbt_dynar_free_container(&parents);

  return my_top_level;
}
示例#8
0
/* Build the set of the compute successors of a task that are ready (i.e., with all parents already scheduled). Both
 * data and control dependencies are checked. As more than one transfer may exist between two compute tasks, it is
 * mandatory to check whether the successor is not already in the set.
 */
xbt_dynar_t SD_task_get_ready_children(SD_task_t t){
  unsigned int i;
  xbt_dynar_t children=NULL, ready_children;
  xbt_dynar_t output_transfers = SD_task_get_children(t);
  SD_task_t output, child;

  ready_children = xbt_dynar_new(sizeof(SD_task_t), NULL);

  xbt_dynar_foreach(output_transfers, i, output){
    if (SD_task_get_kind(output) == SD_TASK_COMM_E2E) {
      /* Data dependency case: a compute task is followed by a data transfer. Its child (in a scheduling sense) is
       * then the grand child
       */
      children = SD_task_get_children(output);
      xbt_dynar_get_cpy(children, 0, &child);

      /* check if this child is already in the set */
      if (xbt_dynar_member(ready_children, &child)){
        XBT_DEBUG("%s already seen, ignore", SD_task_get_name(child));
        xbt_dynar_free_container(&children); /* avoid memory leaks */
        continue;
      }

      if (SD_task_get_kind(child) == SD_TASK_COMP_SEQ && (SD_task_get_state(child) == SD_NOT_SCHEDULED ||
           SD_task_get_state(child) == SD_SCHEDULABLE) && SD_task_is_ready(child)){
        xbt_dynar_push(ready_children, &child);
      }
      xbt_dynar_free_container(&children); /* avoid memory leaks */
    } else {
      /* Control dependency case: a compute task successor is another compute task. */
      /* check if this child is already in the set */
      if (xbt_dynar_member(ready_children, &output)){
        XBT_DEBUG("%s already seen, ignore", SD_task_get_name(output));
        continue;
      }
      if (SD_task_get_kind(output) == SD_TASK_COMP_SEQ && (SD_task_get_state(output) == SD_NOT_SCHEDULED ||
           SD_task_get_state(output) == SD_SCHEDULABLE)&& SD_task_is_ready(output)){
        xbt_dynar_push(ready_children, &output);
      }
    }
  }

  xbt_dynar_free_container(&output_transfers); /* avoid memory leaks */

  return ready_children;
}
示例#9
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]);
   }
 }
示例#10
0
 xbt_dynar_foreach(dot, cursor, task) {
   int kind = SD_task_get_kind(task);
   sg_host_t *wsl = SD_task_get_workstation_list(task);
   switch (kind) {
   case SD_TASK_COMP_SEQ:
     fprintf(out, "[%f->%f] %s compute %f flops # %s\n",
         SD_task_get_start_time(task), SD_task_get_finish_time(task),
         sg_host_get_name(wsl[0]), SD_task_get_amount(task), SD_task_get_name(task));
     break;
   case SD_TASK_COMM_E2E:
     fprintf(out, "[%f -> %f] %s -> %s transfer of %.0f bytes # %s\n",
         SD_task_get_start_time(task), SD_task_get_finish_time(task),
         sg_host_get_name(wsl[0]), sg_host_get_name(wsl[1]), SD_task_get_amount(task), SD_task_get_name(task));
     break;
   default:
     xbt_die("Task %s is of unknown kind %d", SD_task_get_name(task), SD_task_get_kind(task));
   }
   SD_task_destroy(task);
 }
示例#11
0
文件: task.c 项目: frs69wq/biCPA
double bottom_level_recursive_computation(SD_task_t task){
  unsigned int i;
  double my_bottom_level = 0.0, max_bottom_level,
      current_child_bottom_level = 0.0;
  SD_task_t child, grand_child;
  xbt_dynar_t children, grand_children;

  my_bottom_level = SD_task_estimate_execution_time(task,
      SD_task_get_allocation_size(task));

  max_bottom_level = -1.0;
  if (!strcmp(SD_task_get_name(task),"end")){
    XBT_DEBUG("end's bottom level is 0.0");
    SD_task_mark(task);
    SD_task_set_bottom_level(task, 0.0);
    return 0.0;
  }

  children = SD_task_get_children(task);

  xbt_dynar_foreach(children, i, child){
    if (SD_task_get_kind(child) == SD_TASK_COMM_PAR_MXN_1D_BLOCK) {
      grand_children = SD_task_get_children(child);
      xbt_dynar_get_cpy(grand_children, 0, &grand_child);
      if (SD_task_is_marked(grand_child)){
        current_child_bottom_level = SD_task_get_bottom_level(grand_child);
      } else {
        current_child_bottom_level =
            bottom_level_recursive_computation(grand_child);
      }
      xbt_dynar_free_container(&grand_children);
    } else {
      if (SD_task_is_marked(child)){
        current_child_bottom_level = SD_task_get_bottom_level(child);
      } else {
        current_child_bottom_level =
            bottom_level_recursive_computation(child);
      }
    }

    if (max_bottom_level < current_child_bottom_level)
      max_bottom_level = current_child_bottom_level;
  }

  my_bottom_level += max_bottom_level;

  SD_task_set_bottom_level(task, my_bottom_level);
  SD_task_mark(task);
  XBT_DEBUG("%s's bottom level is %f", SD_task_get_name(task), my_bottom_level);

  xbt_dynar_free_container(&children);
  return my_bottom_level ;
}
示例#12
0
文件: task.c 项目: frs69wq/biCPA
/* This function is actually not used by biCPA */
int precedence_level_recursive_computation(SD_task_t task){
  unsigned int i;
  int my_prec_level = -1, current_parent_prec_level = 0;
  SD_task_t parent, grand_parent=NULL;
  xbt_dynar_t parents, grand_parents;

  if (!strcmp(SD_task_get_name(task),"root")){
    XBT_DEBUG("root's precedence level is 0.0");
    SD_task_mark(task);
    SD_task_set_precedence_level(task, 0);
    return 0;
  }

  parents = SD_task_get_parents(task);

  xbt_dynar_foreach(parents, i, parent){
    if (SD_task_get_kind(parent) == SD_TASK_COMM_PAR_MXN_1D_BLOCK) {
      grand_parents = SD_task_get_parents(parent);
      xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);
      if (SD_task_is_marked(grand_parent)){
        current_parent_prec_level =
            SD_task_get_precedence_level(grand_parent) + 1;
      } else {
        current_parent_prec_level =
            precedence_level_recursive_computation(grand_parent) + 1;
      }
      xbt_dynar_free_container(&grand_parents);
    } else {
      if (SD_task_is_marked(parent)){
        current_parent_prec_level =
            SD_task_get_precedence_level(parent) + 1;
      } else {
        current_parent_prec_level =
            precedence_level_recursive_computation(parent) + 1;
      }
    }

    if (my_prec_level < current_parent_prec_level)
      my_prec_level = current_parent_prec_level;
  }

  SD_task_set_precedence_level(task, my_prec_level);
  SD_task_mark(task);
  XBT_DEBUG("%s's precedence level is %d", SD_task_get_name(task),
      my_prec_level);

  xbt_dynar_free_container(&parents);

  return my_prec_level;
}
示例#13
0
static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax)
{
  unsigned int i;
  xbt_dynar_t ready_tasks;
  SD_task_t task;

  ready_tasks = xbt_dynar_new(sizeof(SD_task_t), NULL);
  xbt_dynar_foreach(dax, i, task) {
    if (SD_task_get_kind(task) == SD_TASK_COMP_SEQ && SD_task_get_state(task) == SD_SCHEDULABLE) {
      xbt_dynar_push(ready_tasks, &task);
    }
  }
  XBT_DEBUG("There are %lu ready tasks", xbt_dynar_length(ready_tasks));

  return ready_tasks;
}
示例#14
0
文件: task.c 项目: frs69wq/biCPA
/*
 * Return an estimation of the minimal time before which a task can start. This
 * time depends on the estimated finished time of the compute ancestors of the
 * task, as set when they have been scheduled. Two cases are considered,
 * depending on whether an ancestor is 'linked' to the task through a flow or
 * control dependency. Flow dependencies imply to look at the grand parents of
 * the task, while control dependencies look at the parent tasks directly.
 */
double SD_task_estimate_minimal_start_time(SD_task_t task){
  unsigned int i;
  double min_start_time=0.0;
  xbt_dynar_t parents, grand_parents;
  SD_task_t parent, grand_parent;

  parents = SD_task_get_parents(task);
  xbt_dynar_foreach(parents, i, parent){
    if (SD_task_get_kind(parent) == SD_TASK_COMM_PAR_MXN_1D_BLOCK) {
      grand_parents = SD_task_get_parents(parent);
      xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);
        if (SD_task_get_estimated_finish_time(grand_parent) > min_start_time)
          min_start_time = SD_task_get_estimated_finish_time(grand_parent);
      xbt_dynar_free_container(&grand_parents);
    }
    else{
      if (SD_task_get_estimated_finish_time(parent) > min_start_time)
        min_start_time = SD_task_get_estimated_finish_time(parent);
    }
  }
  xbt_dynar_free_container(&parents);
  return min_start_time;
}
示例#15
0
/* Determine if a task is ready. The condition to meet is that all its compute predecessors have to be in one of the
 * following state:
 *  - SD_RUNNABLE
 *  - SD_RUNNING
 *  - SD_DONE
 */
int SD_task_is_ready(SD_task_t task){
  unsigned int i;
  int is_ready = 1;
  xbt_dynar_t parents, grand_parents;
  SD_task_t parent, grand_parent;

  parents = SD_task_get_parents(task);

  if (xbt_dynar_length(parents)) {
    xbt_dynar_foreach(parents, i, parent){
      if (SD_task_get_kind(parent) == SD_TASK_COMM_E2E) {
        /* Data dependency case: a compute task is preceded by a data transfer. Its parent (in a scheduling sense) is
         * then the grand parent
         */
        grand_parents = SD_task_get_parents(parent);
        xbt_dynar_get_cpy(grand_parents, 0, &grand_parent);
        if (SD_task_get_state(grand_parent) < SD_SCHEDULED) {
          is_ready =0;
          xbt_dynar_free_container(&grand_parents); /* avoid memory leaks */
          break;
        } else {
          xbt_dynar_free_container(&grand_parents); /* avoid memory leaks */
        }
      } else {
        /* Control dependency case: a compute task predecessor is another compute task. */
        if (SD_task_get_state(parent) < SD_SCHEDULED) {
         is_ready =0;
         break;
        }
      }
    }
  }
  xbt_dynar_free_container(&parents); /* avoid memory leaks */

  return is_ready;
}
示例#16
0
/** @brief Auto-schedules a task.
 *
 * Auto-scheduling mean that the task can be used with SD_task_schedulev(). This allows to specify the task costs at
 * creation, and decouple them from the scheduling process where you just specify which resource should deliver the
 * mandatory power.
 *
 * To be auto-schedulable, a task must be type and created with one of the specialized creation functions.
 *
 * @todo
 * We should create tasks kind for the following categories:
 *  - Point to point communication (done)
 *  - Sequential computation       (done)
 *  - group communication (redistribution, several kinds)
 *  - parallel tasks with no internal communication (one kind per speedup    model such as Amdahl)
 *  - idem+ internal communication. Task type not enough since we cannot store comm cost alongside to comp one)
 */
void SD_task_schedulev(SD_task_t task, int count, const sg_host_t * list)
{
  int i;
  int j;
  xbt_assert(task->kind != 0, "Task %s is not typed. Cannot automatically schedule it.", SD_task_get_name(task));
  switch (task->kind) {
  case SD_TASK_COMP_PAR_AMDAHL:
    SD_task_distribute_comp_amdahl(task, count);
    /* no break */
  case SD_TASK_COMM_E2E:
  case SD_TASK_COMP_SEQ:
    xbt_assert(task->host_count == count, "Got %d locations, but were expecting %d locations", count,task->host_count);
    for (i = 0; i < count; i++)
      task->host_list[i] = list[i];
    if (SD_task_get_kind(task)== SD_TASK_COMP_SEQ && !task->flops_amount){
      /*This task has failed and is rescheduled. Reset the flops_amount*/
      task->flops_amount = xbt_new0(double, 1);
      task->flops_amount[0] = task->remains;
    }
    SD_task_do_schedule(task);
    break;
  default:
    xbt_die("Kind of task %s not supported by SD_task_schedulev()", SD_task_get_name(task));
  }
示例#17
0
/**
 * \brief Returns the alpha parameter of a SD_TASK_COMP_PAR_AMDAHL task
 *
 * \param task a parallel task assuming Amdahl's law as speedup model
 * \return the alpha parameter (serial part of a task in percent) for this task
 */
double SD_task_get_alpha(SD_task_t task)
{
  xbt_assert(SD_task_get_kind(task) == SD_TASK_COMP_PAR_AMDAHL, "Alpha parameter is not defined for this kind of task");
  return task->alpha;
}
示例#18
0
int main(int argc, char **argv) {
  unsigned int flag, cursor, cursor2;
  char *platform_file = NULL, *daxname = NULL, *priority=NULL;
  int total_nworkstations = 0;
  const SD_workstation_t *workstations = NULL;
  xbt_dynar_t daxes = NULL, current_dax = NULL;
  int completed_daxes = 0;
  SD_task_t task;
  scheduling_globals_t globals;
  WorkstationAttribute attr;
  double total_cost = 0.0, score = 0.0;

  SD_init(&argc, argv);

  /* get rid off some logs that are useless */
  xbt_log_control_set("sd_daxparse.thresh:critical");
  xbt_log_control_set("surf_workstation.thresh:critical");
  xbt_log_control_set("root.fmt:[%9.3r]%e[%13c/%7p]%e%m%n");

  globals = new_scheduling_globals();

  daxes = xbt_dynar_new(sizeof(xbt_dynar_t), NULL);
  opterr = 0;

  while (1){
    static struct option long_options[] = {
        {"alg", 1, 0, 'a'},
        {"platform", 1, 0, 'b'},
        {"dax", 1, 0, 'c'},
        {"priority", 1, 0, 'd'},
        {"deadline", 1, 0, 'e'},
        {"budget", 1, 0, 'f'},
        {"price", 1, 0, 'g'},
        {"period", 1, 0, 'h'},
        {"uh", 1, 0, 'i'},
        {"ul", 1, 0, 'j'},
        {"provisioning_delay", 1, 0, 'k'},
        {"silent", 0, 0, 'y'},
        {"dump", 1, 0, 'z'},
        {0, 0, 0, 0}
    };

    int option_index = 0;
    flag = getopt_long (argc, argv, "",
                        long_options, &option_index);

    /* Detect the end of the options. */
    if (flag == -1)
      break;

    switch (flag) {
    case 0:
      /* If this option set a flag, do nothing else now. */
      if (long_options[option_index].flag != 0)
        break;
      printf ("option %s", long_options[option_index].name);
      if (optarg)
        printf (" with arg %s", optarg);
        printf ("\n");
      break;
    case 'a': /* Algorithm name */
      /* DPDS, WA-DPDS, SPSS, Ours*/
      globals->alg = getAlgorithmByName(optarg);
      break;
    case 'b':
      platform_file = optarg;
      SD_create_environment(platform_file);
      total_nworkstations = SD_workstation_get_number();
      workstations = SD_workstation_get_list();

      /* Sort the hosts by name for sake of simplicity */
      qsort((void *)workstations,total_nworkstations, sizeof(SD_workstation_t),
          nameCompareWorkstations);

      for(cursor=0; cursor<total_nworkstations; cursor++){
        SD_workstation_allocate_attribute(workstations[cursor]);
      }
      break;
    case 'c':
      /* List of DAGs to schedule concurrently (just file names here) */
      daxname = optarg;
      XBT_DEBUG("Loading %s", daxname);
      current_dax = SD_daxload(daxname);
      xbt_dynar_foreach(current_dax,cursor,task) {
        if (SD_task_get_kind(task) == SD_TASK_COMP_SEQ){
          SD_task_watch(task, SD_DONE);
        }
        SD_task_allocate_attribute(task);
        SD_task_set_dax_name(task, daxname);
      }
      xbt_dynar_push(daxes,&current_dax);
      break;
    case 'd':
      priority = optarg;
      if (!strcmp(priority,"random"))
        globals->priority_method = RANDOM;
      else if (!strcmp(priority, "sorted"))
        globals->priority_method = SORTED;
      else {
        XBT_ERROR("Unknown priority setting method.");
        exit(1);
      }
      break;
    case 'e':
      globals->deadline = atof(optarg);
      break;
    case 'f':
      globals->budget = atof(optarg);
      break;
    case 'g':
      globals->price = atof(optarg);
      break;
    case 'h':
      globals->period = atof(optarg);
      break;
    case 'i':
      globals->uh = atof(optarg);
      break;
    case 'j':
      globals->ul = atof(optarg);
      break;
    case 'k':
      globals->provisioning_delay = atof(optarg);
      break;
    case 'y':
      xbt_log_control_set("root.thresh:critical");
      break;
    case 'z':
      break;
    }
  }
  /* Display some information about the current run */
  XBT_INFO("Algorithm: %s",getAlgorithmName(globals->alg));
  XBT_INFO("  Priority method: %s",
      globals->priority_method ? "SORTED" : "RANDOM");
  XBT_INFO("  Dynamic provisioning period: %.0fs", globals->period);
  XBT_INFO("  Lower utilization threshold: %.2f%%", globals->ul);
  XBT_INFO("  Upper utilization threshold: %.2f%%", globals->uh);

  XBT_INFO("Platform: %s (%d potential VMs)", platform_file,
      SD_workstation_get_number());
  XBT_INFO("  VM hourly cost: $%f", globals->price);
  XBT_INFO("  VM provisioning delay: %.0fs", globals->provisioning_delay);
  if (ceil(globals->budget/((globals->deadline/3600.)*globals->price))>
      SD_workstation_get_number()){
    XBT_ERROR("The platform file doesn't have enough nodes. Stop here");
    exit(1);
  }
  /* Assign price and provisioning delay to workstation/VM (for the sake of
   * simplicity) */
  for(cursor=0; cursor<total_nworkstations; cursor++){
    SD_workstation_set_price(workstations[cursor], globals->price);
    SD_workstation_set_provisioning_delay(workstations[cursor],
        globals->provisioning_delay);
  }

  XBT_INFO("Ensemble: %lu DAXes", xbt_dynar_length(daxes));
  /* Assign priorities to the DAXes composing the ensemble according to the
   * chosen method: RANDOM (default) or SORTED.
   * Then display the result.
   */
  assign_dax_priorities(daxes, globals->priority_method);
  xbt_dynar_foreach(daxes, cursor, current_dax){
     task = get_root(current_dax);
     XBT_INFO("  %s", SD_task_get_dax_name(task));
     XBT_INFO("    Priority: %d", SD_task_get_dax_priority(task));
  }
示例#19
0
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;
}
示例#20
0
 xbt_dynar_foreach(dot, cursor, task) {
   if (SD_task_get_kind(task) == SD_TASK_COMP_PAR_AMDAHL) {
       SD_task_schedulev(task, count, ws_list);
   }
 }