Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use CommImpl* for comm_copy callbacks.
[simgrid.git] / src / smpi / internals / smpi_global.cpp
index 3eca3f2..61f16b1 100644 (file)
@@ -59,7 +59,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, "Logging specific to SMPI (ke
  * See https://www.akkadia.org/drepper/dsohowto.pdf
  * and https://lists.freebsd.org/pipermail/freebsd-current/2016-March/060284.html
 */
-#if !defined(RTLD_DEEPBIND) || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD
+#if !RTLD_DEEPBIND || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD
 #define WANT_RTLD_DEEPBIND 0
 #else
 #define WANT_RTLD_DEEPBIND RTLD_DEEPBIND
@@ -102,7 +102,8 @@ static const std::string smpi_default_instance_name("smpirun");
 static simgrid::config::Flag<double> smpi_init_sleep(
   "smpi/init", "Time to inject inside a call to MPI_Init", 0.0);
 
-void (*smpi_comm_copy_data_callback) (smx_activity_t, void*, size_t) = &smpi_comm_copy_buffer_callback;
+void (*smpi_comm_copy_data_callback)(simgrid::kernel::activity::CommImpl*, void*,
+                                     size_t) = &smpi_comm_copy_buffer_callback;
 
 int smpi_process_count()
 {
@@ -151,7 +152,11 @@ int smpi_global_size()
 
 void smpi_comm_set_copy_data_callback(void (*callback) (smx_activity_t, void*, size_t))
 {
-  smpi_comm_copy_data_callback = callback;
+  static void (*saved_callback)(smx_activity_t, void*, size_t);
+  saved_callback               = callback;
+  smpi_comm_copy_data_callback = [](simgrid::kernel::activity::CommImpl* comm, void* buff, size_t size) {
+    saved_callback(smx_activity_t(comm), buff, size);
+  };
 }
 
 static void memcpy_private(void* dest, const void* src, std::vector<std::pair<size_t, size_t>>& private_blocks)
@@ -165,10 +170,8 @@ static void check_blocks(std::vector<std::pair<size_t, size_t>> &private_blocks,
     xbt_assert(block.first <= block.second && block.second <= buff_size, "Oops, bug in shared malloc.");
 }
 
-void smpi_comm_copy_buffer_callback(smx_activity_t synchro, void *buff, size_t buff_size)
+void smpi_comm_copy_buffer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size)
 {
-  simgrid::kernel::activity::CommImplPtr comm =
-      boost::dynamic_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
   int src_shared                        = 0;
   int dst_shared                        = 0;
   size_t src_offset                     = 0;
@@ -184,8 +187,8 @@ void smpi_comm_copy_buffer_callback(smx_activity_t synchro, void *buff, size_t b
     src_private_blocks.clear();
     src_private_blocks.push_back(std::make_pair(0, buff_size));
   }
-  if((dst_shared=smpi_is_shared((char*)comm->dst_buff, dst_private_blocks, &dst_offset))) {
-    XBT_DEBUG("Receiver %p is shared. Let's ignore it.", (char*)comm->dst_buff);
+  if ((dst_shared = smpi_is_shared((char*)comm->dst_buff_, dst_private_blocks, &dst_offset))) {
+    XBT_DEBUG("Receiver %p is shared. Let's ignore it.", (char*)comm->dst_buff_);
     dst_private_blocks = shift_and_frame_private_blocks(dst_private_blocks, dst_offset, buff_size);
   }
   else {
@@ -201,18 +204,19 @@ void smpi_comm_copy_buffer_callback(smx_activity_t synchro, void *buff, size_t b
       (static_cast<char*>(buff) >= smpi_data_exe_start) &&
       (static_cast<char*>(buff) < smpi_data_exe_start + smpi_data_exe_size)) {
     XBT_DEBUG("Privatization : We are copying from a zone inside global memory... Saving data to temp buffer !");
-    smpi_switch_data_segment(comm->src_proc->iface());
+    smpi_switch_data_segment(comm->src_actor_->iface());
     tmpbuff = static_cast<void*>(xbt_malloc(buff_size));
     memcpy_private(tmpbuff, buff, private_blocks);
   }
 
-  if ((smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) && ((char*)comm->dst_buff >= smpi_data_exe_start) &&
-      ((char*)comm->dst_buff < smpi_data_exe_start + smpi_data_exe_size)) {
+  if ((smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) &&
+      ((char*)comm->dst_buff_ >= smpi_data_exe_start) &&
+      ((char*)comm->dst_buff_ < smpi_data_exe_start + smpi_data_exe_size)) {
     XBT_DEBUG("Privatization : We are copying to a zone inside global memory - Switch data segment");
-    smpi_switch_data_segment(comm->dst_proc->iface());
+    smpi_switch_data_segment(comm->dst_actor_->iface());
   }
-  XBT_DEBUG("Copying %zu bytes from %p to %p", buff_size, tmpbuff,comm->dst_buff);
-  memcpy_private(comm->dst_buff, tmpbuff, private_blocks);
+  XBT_DEBUG("Copying %zu bytes from %p to %p", buff_size, tmpbuff, comm->dst_buff_);
+  memcpy_private(comm->dst_buff_, tmpbuff, private_blocks);
 
   if (comm->detached) {
     // if this is a detached send, the source buffer was duplicated by SMPI
@@ -220,13 +224,13 @@ void smpi_comm_copy_buffer_callback(smx_activity_t synchro, void *buff, size_t b
     xbt_free(buff);
     //It seems that the request is used after the call there this should be free somewhere else but where???
     //xbt_free(comm->comm.src_data);// inside SMPI the request is kept inside the user data and should be free
-    comm->src_buff = nullptr;
+    comm->src_buff_ = nullptr;
   }
   if (tmpbuff != buff)
     xbt_free(tmpbuff);
 }
 
-void smpi_comm_null_copy_buffer_callback(smx_activity_t comm, void *buff, size_t buff_size)
+void smpi_comm_null_copy_buffer_callback(simgrid::kernel::activity::CommImpl*, void*, size_t)
 {
   /* nothing done in this version */
 }
@@ -487,7 +491,7 @@ static smpi_entry_point_type smpi_resolve_function(void* handle)
   return smpi_entry_point_type();
 }
 
-static void smpi_copy_file(std::string src, std::string target, off_t fdin_size)
+static void smpi_copy_file(const std::string& src, const std::string& target, off_t fdin_size)
 {
   int fdin = open(src.c_str(), O_RDONLY);
   xbt_assert(fdin >= 0, "Cannot read from %s. Please make sure that the file exists and is executable.", src.c_str());
@@ -495,31 +499,32 @@ static void smpi_copy_file(std::string src, std::string target, off_t fdin_size)
   xbt_assert(fdout >= 0, "Cannot write into %s", target.c_str());
 
   XBT_DEBUG("Copy %" PRIdMAX " bytes into %s", static_cast<intmax_t>(fdin_size), target.c_str());
-  bool slow_copy = true;
 #if SG_HAVE_SENDFILE
   ssize_t sent_size = sendfile(fdout, fdin, NULL, fdin_size);
-  if (sent_size == fdin_size)
-    slow_copy = false;
-  else if (sent_size != -1 || errno != ENOSYS)
+  if (sent_size == fdin_size) {
+    close(fdin);
+    close(fdout);
+    return;
+  } else if (sent_size != -1 || errno != ENOSYS) {
     xbt_die("Error while copying %s: only %zd bytes copied instead of %" PRIdMAX " (errno: %d -- %s)", target.c_str(),
             sent_size, static_cast<intmax_t>(fdin_size), errno, strerror(errno));
+  }
 #endif
-  if (slow_copy) {
-    const int bufsize = 1024 * 1024 * 4;
-    char buf[bufsize];
-    while (int got = read(fdin, buf, bufsize)) {
-      if (got == -1) {
-        xbt_assert(errno == EINTR, "Cannot read from %s", src.c_str());
-      } else {
-        char* p  = buf;
-        int todo = got;
-        while (int done = write(fdout, p, todo)) {
-          if (done == -1) {
-            xbt_assert(errno == EINTR, "Cannot write into %s", target.c_str());
-          } else {
-            p += done;
-            todo -= done;
-          }
+  // If this point is reached, sendfile() actually is not available.  Copy file by hand.
+  const int bufsize = 1024 * 1024 * 4;
+  char buf[bufsize];
+  while (int got = read(fdin, buf, bufsize)) {
+    if (got == -1) {
+      xbt_assert(errno == EINTR, "Cannot read from %s", src.c_str());
+    } else {
+      char* p  = buf;
+      int todo = got;
+      while (int done = write(fdout, p, todo)) {
+        if (done == -1) {
+          xbt_assert(errno == EINTR, "Cannot write into %s", target.c_str());
+        } else {
+          p += done;
+          todo -= done;
         }
       }
     }
@@ -548,7 +553,6 @@ static void smpi_init_privatization_dlopen(const std::string& executable)
   struct stat fdin_stat;
   stat(executable.c_str(), &fdin_stat);
   off_t fdin_size         = fdin_stat.st_size;
-  static std::size_t rank = 0;
 
   std::string libnames = simgrid::config::get_value<std::string>("smpi/privatize-libs");
   if (not libnames.empty()) {
@@ -578,6 +582,7 @@ static void smpi_init_privatization_dlopen(const std::string& executable)
 
   simix_global->default_function = [executable, fdin_size](std::vector<std::string> args) {
     return std::function<void()>([executable, fdin_size, args] {
+      static std::size_t rank = 0;
       // Copy the dynamic library:
       std::string target_executable =
           executable + "_" + std::to_string(getpid()) + "_" + std::to_string(rank) + ".so";