示例#1
0
static void log_action(simgrid::xbt::ReplayAction& action, double date)
{
  if (XBT_LOG_ISENABLED(replay_comm, xbt_log_priority_verbose)) {
    std::string s = boost::algorithm::join(action, " ");
    XBT_VERB("%s %f", s.c_str(), date);
  }
}
示例#2
0
static void log_timed_action (const char *const *action, double clock){
  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }
}
示例#3
0
static char* pointer_to_string(void* pointer) {

  if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
    return bprintf("%p", pointer);

  return xbt_strdup("(verbose only)");
}
示例#4
0
static void action_send(const char *const *action)
{
  int to = atoi(action[2]);
  double size=parse_double(action[3]);
  double clock = smpi_process_simulated_elapsed();
#ifdef HAVE_TRACING
  int rank = smpi_comm_rank(MPI_COMM_WORLD);
  TRACE_smpi_computing_out(rank);
  int dst_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), to);
  TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
  TRACE_smpi_send(rank, rank, dst_traced);
#endif

  smpi_mpi_send(NULL, size, MPI_BYTE, to , 0, MPI_COMM_WORLD);

  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }

  #ifdef HAVE_TRACING
  TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
  TRACE_smpi_computing_in(rank);
#endif

}
示例#5
0
static char* buff_size_to_string(size_t buff_size) {

  if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
    return bprintf("%zu", buff_size);

  return xbt_strdup("(verbose only)");
}
示例#6
0
static void action_Irecv(const char *const *action)
{
  int from = atoi(action[2]);
  double size=parse_double(action[3]);
  double clock = smpi_process_simulated_elapsed();
  MPI_Request request;
  smpi_replay_globals_t globals =
     (smpi_replay_globals_t) smpi_process_get_user_data();

#ifdef HAVE_TRACING
  int rank = smpi_comm_rank(MPI_COMM_WORLD);
  int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from);
  TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
#endif

  request = smpi_mpi_irecv(NULL, size, MPI_BYTE, from, 0, MPI_COMM_WORLD);
#ifdef HAVE_TRACING
  TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
  request->recv = 1;
#endif
  xbt_dynar_push(globals->irecvs,&request);

  //TODO do the asynchronous cleanup
  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }
}
示例#7
0
static void log_action(const char *const *action, double date)
{
  if (XBT_LOG_ISENABLED(storage_actions, xbt_log_priority_verbose)) {
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, date);
    xbt_free(name);
  }
}
示例#8
0
static void action_compute(const char *const *action)
{
  double clock = smpi_process_simulated_elapsed();
  smpi_execute_flops(parse_double(action[2]));

  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }
}
示例#9
0
/** Displays the finger table of a node. */
void Node::printFingerTable()
{
  if (XBT_LOG_ISENABLED(s4u_chord, xbt_log_priority_verbose)) {
    XBT_VERB("My finger table:");
    XBT_VERB("Start | Succ");
    for (int i = 0; i < nb_bits; i++) {
      XBT_VERB(" %3u  | %3d", (id_ + (1U << i)) % nb_keys, fingers_[i]);
    }

    XBT_VERB("Predecessor: %d", pred_id_);
  }
}
示例#10
0
void SIMIX_simcall_answer(smx_simcall_t simcall)
{
  if (simcall->issuer != simix_global->maestro_process){
    XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall->call), (int)simcall->call,
              simcall->issuer->get_cname(), simcall->issuer);
    simcall->issuer->simcall.call = SIMCALL_NONE;
    xbt_assert(not XBT_LOG_ISENABLED(simix_popping, xbt_log_priority_debug) ||
                   std::find(begin(simix_global->actors_to_run), end(simix_global->actors_to_run), simcall->issuer) ==
                       end(simix_global->actors_to_run),
               "Actor %p should not exist in actors_to_run!", simcall->issuer);
    simix_global->actors_to_run.push_back(simcall->issuer);
  }
}
示例#11
0
static void buffer_debug(std::vector<simgrid::instr::PajeEvent*>* buf)
{
  if (not XBT_LOG_ISENABLED(instr_paje_trace, xbt_log_priority_debug))
    return;
  XBT_DEBUG(">>>>>> Dump the state of the buffer. %zu events", buf->size());
  for (auto const& event : *buf) {
    event->print();
    XBT_DEBUG("%p %s", event, event->stream_.str().c_str());
    event->stream_.str("");
    event->stream_.clear();
  }
  XBT_DEBUG("<<<<<<");
}
示例#12
0
/**
 * @brief Dumps the Lua stack if debug logs are enabled.
 * @param msg a message to print
 * @param L a Lua state
 */
void sglua_stack_dump(lua_State* L, const char* msg)
{
  if (XBT_LOG_ISENABLED(lua_debug, xbt_log_priority_debug)) {
    char buff[2048];
    char* p = buff;
    int top = lua_gettop(L);

    fflush(stdout);

    p[0] = '\0';
    for (int i = 1; i <= top; i++) {  /* repeat for each level */
      p += snprintf(p, 2048-(p-buff), "%s ", sglua_tostring(L, i));
    }

    XBT_DEBUG("%s%s", msg, buff);
  }
}
示例#13
0
static void action_barrier(const char *const *action){
  double clock = smpi_process_simulated_elapsed();
#ifdef HAVE_TRACING
  int rank = smpi_comm_rank(MPI_COMM_WORLD);
  TRACE_smpi_computing_out(rank);
  TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
#endif
  smpi_mpi_barrier(MPI_COMM_WORLD);
#ifdef HAVE_TRACING
  TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
  TRACE_smpi_computing_in(rank);
#endif

  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }
}
示例#14
0
static void action_wait(const char *const *action){
  double clock = smpi_process_simulated_elapsed();
  MPI_Request request;
  MPI_Status status;
  smpi_replay_globals_t globals =
      (smpi_replay_globals_t) smpi_process_get_user_data();

  xbt_assert(xbt_dynar_length(globals->irecvs),
      "action wait not preceded by any irecv: %s",
      xbt_str_join_array(action," "));
  request = xbt_dynar_pop_as(globals->irecvs,MPI_Request);
#ifdef HAVE_TRACING
  int rank = request && request->comm != MPI_COMM_NULL
      ? smpi_comm_rank(request->comm)
      : -1;
  TRACE_smpi_computing_out(rank);

  MPI_Group group = smpi_comm_group(request->comm);
  int src_traced = smpi_group_rank(group, request->src);
  int dst_traced = smpi_group_rank(group, request->dst);
  int is_wait_for_receive = request->recv;
  TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__);
#endif
  smpi_mpi_wait(&request, &status);
#ifdef HAVE_TRACING
  TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
  if (is_wait_for_receive) {
    TRACE_smpi_recv(rank, src_traced, dst_traced);
  }
  TRACE_smpi_computing_in(rank);
#endif

  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }
}
示例#15
0
static void action_allReduce(const char *const *action) {
  double comm_size = parse_double(action[2]);
  double comp_size = parse_double(action[3]);
  double clock = smpi_process_simulated_elapsed();
#ifdef HAVE_TRACING
  int rank = smpi_comm_rank(MPI_COMM_WORLD);
  TRACE_smpi_computing_out(rank);
  TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
#endif
  smpi_mpi_reduce(NULL, NULL, comm_size, MPI_BYTE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
  smpi_execute_flops(comp_size);
  smpi_mpi_bcast(NULL, comm_size, MPI_BYTE, 0, MPI_COMM_WORLD);
#ifdef HAVE_TRACING
  TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
  TRACE_smpi_computing_in(rank);
#endif

  if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
    char *name = xbt_str_join_array(action, " ");
    XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
    free(name);
  }
}
示例#16
0
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);
      }
    }
  }
示例#17
0
文件: log.c 项目: Tien-Dat/simgrid
/*
 * This gets called the first time a category is referenced and performs the
 * initialization.
 * Also resets threshold to inherited!
 */
int _xbt_log_cat_init(xbt_log_category_t category,
                      e_xbt_log_priority_t priority)
{
#define _xbt_log_cat_init(a, b) (0)

  if (log_cat_init_mutex != NULL) {
    xbt_os_rmutex_acquire(log_cat_init_mutex);
  }

  if (category->initialized) {
    if (log_cat_init_mutex != NULL) {
      xbt_os_rmutex_release(log_cat_init_mutex);
    }
    return priority >= category->threshold;
  }

  unsigned int cursor;
  xbt_log_setting_t setting = NULL;
  int found = 0;

  XBT_DEBUG("Initializing category '%s' (firstChild=%s, nextSibling=%s)",
         category->name,
         (category->firstChild ? category->firstChild->name : "none"),
         (category->nextSibling ? category->nextSibling->name : "none"));

  if (category == &_XBT_LOGV(XBT_LOG_ROOT_CAT)) {
    category->threshold = xbt_log_priority_info;
    category->appender = xbt_log_default_appender;
    category->layout = xbt_log_default_layout;
  } else {

    if (!category->parent)
      category->parent = &_XBT_LOGV(XBT_LOG_ROOT_CAT);

    XBT_DEBUG("Set %s (%s) as father of %s ",
           category->parent->name,
           (category->parent->initialized ?
            xbt_log_priority_names[category->parent->threshold] : "uninited"),
           category->name);
    xbt_log_parent_set(category, category->parent);

    if (XBT_LOG_ISENABLED(log, xbt_log_priority_debug)) {
      char *buf, *res = NULL;
      xbt_log_category_t cpp = category->parent->firstChild;
      while (cpp) {
        if (res) {
          buf = bprintf("%s %s", res, cpp->name);
          free(res);
          res = buf;
        } else {
          res = xbt_strdup(cpp->name);
        }
        cpp = cpp->nextSibling;
      }

      XBT_DEBUG("Children of %s: %s; nextSibling: %s",
             category->parent->name, res,
             (category->parent->nextSibling ?
              category->parent->nextSibling->name : "none"));

      free(res);
    }

  }

  /* Apply the control */
  if (xbt_log_settings) {
    xbt_assert(category, "NULL category");
    xbt_assert(category->name);

    xbt_dynar_foreach(xbt_log_settings, cursor, setting) {
      xbt_assert(setting, "Damnit, NULL cat in the list");
      xbt_assert(setting->catname, "NULL setting(=%p)->catname",
                 (void *) setting);

      if (!strcmp(setting->catname, category->name)) {
        found = 1;
        _xbt_log_cat_apply_set(category, setting);
        xbt_dynar_cursor_rm(xbt_log_settings, &cursor);
      }
    }

    if (!found)
      XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)",
                category->name, xbt_log_priority_names[category->threshold],
                category->threshold);
  }
示例#18
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;
}
示例#19
0
void simgrid::kernel::lmm::FairBottleneck::bottleneck_solve()
{
  if (not modified_)
    return;

  XBT_DEBUG("Variable set : %zu", variable_set.size());
  for (Variable& var : variable_set) {
    var.value = 0.0;
    XBT_DEBUG("Handling variable %p", &var);
    if (var.sharing_weight > 0.0 && std::find_if(begin(var.cnsts), end(var.cnsts), [](Element const& x) {
                                      return x.consumption_weight != 0.0;
                                    }) != end(var.cnsts)) {
      saturated_variable_set.push_back(var);
    } else {
      XBT_DEBUG("Err, finally, there is no need to take care of variable %p", &var);
      if (var.sharing_weight > 0.0)
        var.value = 1.0;
    }
  }

  XBT_DEBUG("Active constraints : %zu", active_constraint_set.size());
  for (Constraint& cnst : active_constraint_set) {
    saturated_constraint_set.push_back(cnst);
  }
  for (Constraint& cnst : saturated_constraint_set) {
    cnst.remaining = cnst.bound;
    cnst.usage     = 0.0;
  }

  XBT_DEBUG("Fair bottleneck Initialized");

  /*
   * Compute Usage and store the variables that reach the maximum.
   */
  auto& var_list  = saturated_variable_set;
  auto& cnst_list = saturated_constraint_set;
  do {
    if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
      XBT_DEBUG("Fair bottleneck done");
      print();
    }
    XBT_DEBUG("******* Constraints to process: %zu *******", cnst_list.size());
    for (auto iter = std::begin(cnst_list); iter != std::end(cnst_list);) {
      Constraint& cnst = *iter;
      int nb = 0;
      XBT_DEBUG("Processing cnst %p ", &cnst);
      cnst.usage = 0.0;
      for (Element& elem : cnst.enabled_element_set) {
        xbt_assert(elem.variable->sharing_weight > 0);
        if (elem.consumption_weight > 0 && elem.variable->saturated_variable_set_hook.is_linked())
          nb++;
      }
      XBT_DEBUG("\tThere are %d variables", nb);
      if (nb > 0 && cnst.sharing_policy == s4u::Link::SharingPolicy::FATPIPE)
        nb = 1;
      if (nb == 0) {
        cnst.remaining = 0.0;
        cnst.usage     = 0.0;
        iter           = cnst_list.erase(iter);
      } else {
        cnst.usage = cnst.remaining / nb;
        XBT_DEBUG("\tConstraint Usage %p : %f with %d variables", &cnst, cnst.usage, nb);
        iter++;
      }
    }

    for (auto iter = std::begin(var_list); iter != std::end(var_list);) {
      Variable& var  = *iter;
      double min_inc = DBL_MAX;
      for (Element const& elm : var.cnsts) {
        if (elm.consumption_weight > 0)
          min_inc = std::min(min_inc, elm.constraint->usage / elm.consumption_weight);
      }
      if (var.bound > 0)
        min_inc = std::min(min_inc, var.bound - var.value);
      var.mu    = min_inc;
      XBT_DEBUG("Updating variable %p maximum increment: %g", &var, var.mu);
      var.value += var.mu;
      if (var.value == var.bound)
        iter = var_list.erase(iter);
      else
        iter++;
    }

    for (auto iter = std::begin(cnst_list); iter != std::end(cnst_list);) {
      Constraint& cnst = *iter;
      XBT_DEBUG("Updating cnst %p ", &cnst);
      if (cnst.sharing_policy != s4u::Link::SharingPolicy::FATPIPE) {
        for (Element& elem : cnst.enabled_element_set) {
          xbt_assert(elem.variable->sharing_weight > 0);
          XBT_DEBUG("\tUpdate constraint %p (%g) with variable %p by %g", &cnst, cnst.remaining, elem.variable,
                    elem.variable->mu);
          double_update(&cnst.remaining, elem.consumption_weight * elem.variable->mu, sg_maxmin_precision);
        }
      } else {
        for (Element& elem : cnst.enabled_element_set) {
          xbt_assert(elem.variable->sharing_weight > 0);
          XBT_DEBUG("\tNon-Shared variable. Update constraint usage of %p (%g) with variable %p by %g", &cnst,
                    cnst.usage, elem.variable, elem.variable->mu);
          cnst.usage = std::min(cnst.usage, elem.consumption_weight * elem.variable->mu);
        }
        XBT_DEBUG("\tUpdate constraint %p (%g) by %g", &cnst, cnst.remaining, cnst.usage);
        double_update(&cnst.remaining, cnst.usage, sg_maxmin_precision);
      }

      XBT_DEBUG("\tRemaining for %p : %g", &cnst, cnst.remaining);
      if (cnst.remaining <= 0.0) {
        XBT_DEBUG("\tGet rid of constraint %p", &cnst);

        iter = cnst_list.erase(iter);
        for (Element& elem : cnst.enabled_element_set) {
          if (elem.variable->sharing_weight <= 0)
            break;
          if (elem.consumption_weight > 0 && elem.variable->saturated_variable_set_hook.is_linked()) {
            XBT_DEBUG("\t\tGet rid of variable %p", elem.variable);
            simgrid::xbt::intrusive_erase(var_list, *elem.variable);
          }
        }
      } else {
        iter++;
      }
    }
  } while (not var_list.empty());

  cnst_list.clear();
  modified_ = true;
  if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
    XBT_DEBUG("Fair bottleneck done");
    print();
  }
}