Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / src / smpi / internals / smpi_config.cpp
index d38ea1b..513694b 100644 (file)
@@ -1,36 +1,57 @@
-/* Copyright (c) 2008-2021. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
-#include "smpi_config.hpp"
-#include "include/xbt/config.hpp"
-#include "mc/mc.h"
+
+#if defined(_GNU_SOURCE)
+  #define DEFINED_GNUSOURCE 1
+#else
+  #define _GNU_SOURCE
+#endif
+
+#if defined(__linux__)
+  #include <features.h>
+//inspired by https://stackoverflow.com/a/70211227
+  #if not defined(__USE_GNU)
+    #define __MUSL__
+  #endif
+#endif
+
+#ifndef DEFINED_GNUSOURCE
+  #undef _GNU_SOURCE
+#endif
+
 #include "private.hpp"
 #include "smpi_coll.hpp"
-#include "src/simix/smx_private.hpp"
+#include "smpi_config.hpp"
+#include "src/mc/mc.h"
+#include "xbt/config.hpp"
+#include "xbt/ex.h"
 #include "xbt/parse_units.hpp"
 
 #include <cfloat> /* DBL_MAX */
 #include <boost/algorithm/string.hpp> /* trim */
 #include <boost/tokenizer.hpp>
 
-#if SIMGRID_HAVE_MC
 #include "src/mc/mc_config.hpp"
-#endif
+#include "src/mc/mc_replay.hpp"
 
 #if defined(__APPLE__)
 # include <AvailabilityMacros.h>
 # ifndef MAC_OS_X_VERSION_10_12
 #   define MAC_OS_X_VERSION_10_12 101200
 # endif
-constexpr bool HAVE_WORKING_MMAP = (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12);
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__sun) || defined(__HAIKU__)
+# ifndef __MAC_11_0
+#   define __MAC_11_0 110000
+# endif
+
+constexpr bool HAVE_WORKING_MMAP = ((MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) && (MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_11_0));
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__sun) || defined(__HAIKU__) || defined(__MUSL__)
 constexpr bool HAVE_WORKING_MMAP = false;
 #else
 constexpr bool HAVE_WORKING_MMAP = true;
 #endif
 
-bool _smpi_options_initialized=false;
 SharedMallocType _smpi_cfg_shared_malloc = SharedMallocType::GLOBAL;
 SmpiPrivStrategies _smpi_cfg_privatization = SmpiPrivStrategies::NONE;
 double _smpi_cfg_host_speed;
@@ -38,32 +59,30 @@ double _smpi_cfg_host_speed;
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_config, smpi, "Logging specific to SMPI (config)");
 
 simgrid::config::Flag<std::string> _smpi_cfg_host_speed_string{
-    "smpi/host-speed",
-    "Speed of the host running the simulation (in flop/s). "
-    "Used to bench the operations.",
-    "20000f", [](const std::string& str) {
-      _smpi_cfg_host_speed = xbt_parse_get_speed("smpi/host-speed", 1, str.c_str(), "option", "smpi/host-speed");
+    "smpi/host-speed", "Speed of the host running the simulation (in flop/s). Used to bench the operations.", "20000f",
+    [](const std::string& str) {
+      _smpi_cfg_host_speed = xbt_parse_get_speed("smpi/host-speed", 1, str, "option smpi/host-speed");
       xbt_assert(_smpi_cfg_host_speed > 0.0, "Invalid value (%s) for 'smpi/host-speed': it must be positive.",
-                 _smpi_cfg_host_speed_string.get().c_str());
+                 str.c_str());
     }};
 
 simgrid::config::Flag<bool> _smpi_cfg_simulate_computation{
   "smpi/simulate-computation", "Whether the computational part of the simulated application should be simulated.",
    true};
 simgrid::config::Flag<std::string> _smpi_cfg_shared_malloc_string{
-  "smpi/shared-malloc", "Whether SMPI_SHARED_MALLOC is enabled. Disable it for debugging purposes.", "global", 
-  [](const std::string& val) {   
-    if ((val == "yes") || (val == "1") || (val == "on") || (val == "global")) {
-      _smpi_cfg_shared_malloc = SharedMallocType::GLOBAL;
-    } else if (val == "local") {
-      _smpi_cfg_shared_malloc = SharedMallocType::LOCAL;
-    } else if ((val == "no") || (val == "0") || (val == "off")) {
-      _smpi_cfg_shared_malloc = SharedMallocType::NONE;
-    } else {
-      xbt_die("Invalid value '%s' for option smpi/shared-malloc. Possible values: 'on' or 'global', 'local', 'off'",
-      val.c_str());
-    } 
-  };
+    "smpi/shared-malloc", "Whether SMPI_SHARED_MALLOC is enabled. Disable it for debugging purposes.", "global",
+    [](const std::string& val) {
+      if ((val == "yes") || (val == "1") || (val == "on") || (val == "global")) {
+        _smpi_cfg_shared_malloc = SharedMallocType::GLOBAL;
+      } else if (val == "local") {
+        _smpi_cfg_shared_malloc = SharedMallocType::LOCAL;
+      } else if ((val == "no") || (val == "0") || (val == "off")) {
+        _smpi_cfg_shared_malloc = SharedMallocType::NONE;
+      } else {
+        xbt_die("Invalid value '%s' for option smpi/shared-malloc. Possible values: 'on' or 'global', 'local', 'off'",
+                val.c_str());
+      }
+    }};
 
 simgrid::config::Flag<double> _smpi_cfg_cpu_threshold{
   "smpi/cpu-threshold", "Minimal computation time (in seconds) not discarded, or -1 for infinity.", 1e-6,
@@ -75,9 +94,9 @@ simgrid::config::Flag<double> _smpi_cfg_cpu_threshold{
 simgrid::config::Flag<int> _smpi_cfg_async_small_thresh{"smpi/async-small-thresh",
                                                         "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
                                                         0};
-simgrid::config::Flag<int> _smpi_cfg_detached_send_thresh{"smpi/send-is-detached-thresh",
-                                                          "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend", 
-                                                          65536};
+simgrid::config::Flag<int> _smpi_cfg_detached_send_thresh{
+    "smpi/send-is-detached-thresh",
+    "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend", 65536};
 simgrid::config::Flag<bool> _smpi_cfg_grow_injected_times{"smpi/grow-injected-times",
                                                           "Whether we want to make the injected time in MPI_Iprobe and MPI_Test grow, to "
                                                           "allow faster simulation. This can make simulation less precise, though.",
@@ -92,9 +111,9 @@ simgrid::config::Flag<bool>  _smpi_cfg_trace_call_location{"smpi/trace-call-loca
                                                            "Should filename and linenumber of MPI calls be traced?", false};
 simgrid::config::Flag<bool> _smpi_cfg_trace_call_use_absolute_path{"smpi/trace-call-use-absolute-path",
                                                                    "Should filenames for trace-call tracing be absolute or not?", false};
-simgrid::config::Flag<std::string> _smpi_cfg_comp_adjustment_file{"smpi/comp-adjustment-file",
-    "A file containing speedups or slowdowns for some parts of the code.", 
-    "", [](const std::string& filename){
+simgrid::config::Flag<std::string> _smpi_cfg_comp_adjustment_file{
+    "smpi/comp-adjustment-file", "A file containing speedups or slowdowns for some parts of the code.", "",
+    [](const std::string& filename) {
       if (not filename.empty()) {
         std::ifstream fstream(filename);
         xbt_assert(fstream.is_open(), "Could not open file %s. Does it exist?", filename.c_str());
@@ -103,15 +122,21 @@ simgrid::config::Flag<std::string> _smpi_cfg_comp_adjustment_file{"smpi/comp-adj
         std::getline(fstream, line); // Skip the header line
         while (std::getline(fstream, line)) {
           Tokenizer tok(line);
-          Tokenizer::iterator it  = tok.begin();
-          Tokenizer::iterator end = std::next(tok.begin());
+          auto it              = tok.begin();
+          auto end             = std::next(tok.begin());
           std::string location = *it;
           boost::trim(location);
-          location2speedup.insert(std::pair<std::string, double>(location, std::stod(*end)));
+          location2speedup.try_emplace(location, std::stod(*end));
         }
       }
     }};
-    
+
+simgrid::config::Flag<bool> _smpi_cfg_default_errhandler_is_error{
+  "smpi/errors-are-fatal", "Whether MPI errors are fatal or just return. Default is true", true };
+simgrid::config::Flag<bool> _smpi_cfg_pedantic{
+  "smpi/pedantic", "Activate extra checks that may crash slightly incorrect codes which would not crash on actual implementations", false };
+simgrid::config::Flag<double> _smpi_init_sleep(
+  "smpi/init", "Time to inject inside a call to MPI_Init", 0.0);
 #if HAVE_PAPI
   simgrid::config::Flag<std::string> _smpi_cfg_papi_events_file{"smpi/papi-events",
                                                                 "This switch enables tracking the specified counters with PAPI", ""};
@@ -189,9 +214,22 @@ double smpi_cfg_auto_shared_malloc_thresh(){
   return _smpi_cfg_auto_shared_malloc_thresh;
 }
 
-void smpi_init_options(){
+// public version declared in smpi.h (without parameter, and with C linkage)
+void smpi_init_options()
+{
+  smpi_init_options_internal(false);
+}
+
+void smpi_init_options_internal(bool called_by_smpi_main)
+{
+  static bool smpi_options_initialized = false;
+  static bool running_with_smpi_main   = false;
+
+  if (called_by_smpi_main)
+    running_with_smpi_main = true;
+
   // return if already called
-  if(_smpi_options_initialized)
+  if (smpi_options_initialized)
     return;
   simgrid::config::declare_flag<bool>("smpi/display-timing", "Whether we should display the timing after simulation.", false);
   simgrid::config::declare_flag<bool>("smpi/keep-temps", "Whether we should keep the generated temporary files.", false);
@@ -214,41 +252,40 @@ void smpi_init_options(){
   if (default_privatization == nullptr)
     default_privatization = "no";
 
+  simgrid::config::declare_flag<std::string>(
+      "smpi/privatization", "How we should privatize global variable at runtime (no, yes, mmap, dlopen).",
+      default_privatization, [](const std::string& smpi_privatize_option) {
+        if (smpi_privatize_option == "no" || smpi_privatize_option == "0" || smpi_privatize_option == "OFF")
+          _smpi_cfg_privatization = SmpiPrivStrategies::NONE;
+        else if (smpi_privatize_option == "yes" || smpi_privatize_option == "1" || smpi_privatize_option == "ON")
+          _smpi_cfg_privatization = SmpiPrivStrategies::DEFAULT;
+        else if (smpi_privatize_option == "mmap")
+          _smpi_cfg_privatization = SmpiPrivStrategies::MMAP;
+        else if (smpi_privatize_option == "dlopen")
+          _smpi_cfg_privatization = SmpiPrivStrategies::DLOPEN;
+        else
+          xbt_die("Invalid value for smpi/privatization: '%s'", smpi_privatize_option.c_str());
+
+        if (not running_with_smpi_main) {
+          XBT_DEBUG("Running without smpi_main(); disable smpi/privatization.");
+          _smpi_cfg_privatization = SmpiPrivStrategies::NONE;
+        }
+        if (not HAVE_WORKING_MMAP && _smpi_cfg_privatization == SmpiPrivStrategies::MMAP) {
+          XBT_INFO("mmap privatization is broken on this platform, switching to dlopen privatization instead.");
+          _smpi_cfg_privatization = SmpiPrivStrategies::DLOPEN;
+        }
+      });
 
-  simgrid::config::declare_flag<std::string>( "smpi/privatization", 
-    "How we should privatize global variable at runtime (no, yes, mmap, dlopen).",
-    default_privatization, [](const std::string& smpi_privatize_option){
-      if (smpi_privatize_option == "no" || smpi_privatize_option == "0")
-        _smpi_cfg_privatization = SmpiPrivStrategies::NONE;
-      else if (smpi_privatize_option == "yes" || smpi_privatize_option == "1")
-        _smpi_cfg_privatization = SmpiPrivStrategies::DEFAULT;
-      else if (smpi_privatize_option == "mmap")
-        _smpi_cfg_privatization = SmpiPrivStrategies::MMAP;
-      else if (smpi_privatize_option == "dlopen")
-        _smpi_cfg_privatization = SmpiPrivStrategies::DLOPEN;
-      else
-        xbt_die("Invalid value for smpi/privatization: '%s'", smpi_privatize_option.c_str());
-        
-      if (not SMPI_switch_data_segment) {
-        XBT_DEBUG("Running without smpi_main(); disable smpi/privatization.");
-        _smpi_cfg_privatization = SmpiPrivStrategies::NONE;
-      }
-      if (not HAVE_WORKING_MMAP && _smpi_cfg_privatization == SmpiPrivStrategies::MMAP) {
-        XBT_INFO("mmap privatization is broken on this platform, switching to dlopen privatization instead.");
-        _smpi_cfg_privatization = SmpiPrivStrategies::DLOPEN;
-      }
-    });
-
-  simgrid::config::declare_flag<std::string>("smpi/privatize-libs", 
-                                            "Add libraries (; separated) to privatize (libgfortran for example)."
-                                            "You need to provide the full names of the files (libgfortran.so.4), or its full path", 
-                                            "");
+  simgrid::config::declare_flag<std::string>(
+      "smpi/privatize-libs",
+      "Add libraries (; separated) to privatize (libgfortran for example)."
+      "You need to provide the full names of the files (libgfortran.so.4), or its full path",
+      "");
   simgrid::config::declare_flag<double>("smpi/shared-malloc-blocksize",
-                                        "Size of the bogus file which will be created for global shared allocations", 
+                                        "Size of the bogus file which will be created for global shared allocations",
                                         1UL << 20);
   simgrid::config::declare_flag<std::string>("smpi/shared-malloc-hugepage",
-                                             "Path to a mounted hugetlbfs, to use huge pages with shared malloc.", 
-                                             "");
+                                             "Path to a mounted hugetlbfs, to use huge pages with shared malloc.", "");
 
   simgrid::config::declare_flag<std::string>(
       "smpi/os", "Small messages timings (MPI_Send minimum time for small messages)", "0:0:0:0:0");
@@ -256,13 +293,20 @@ void smpi_init_options(){
       "smpi/ois", "Small messages timings (MPI_Isend minimum time for small messages)", "0:0:0:0:0");
   simgrid::config::declare_flag<std::string>(
       "smpi/or", "Small messages timings (MPI_Recv minimum time for small messages)", "0:0:0:0:0");
-  _smpi_options_initialized=true;
+
+  simgrid::config::declare_flag<bool>("smpi/barrier-finalization", {"smpi/finalization-barrier"},
+                                      "Do we add a barrier in MPI_Finalize or not", false);
+  simgrid::config::declare_flag<bool>("smpi/barrier-collectives",
+                                      "Inject a barrier in each colllective operation, to detect some deadlocks in "
+                                      "incorrect MPI codes, which may not be triggered in all cases",
+                                      false);
+
+  smpi_options_initialized = true;
 }
 
 void smpi_check_options()
 {
-#if SIMGRID_HAVE_MC
-  if (MC_is_active()) {
+  if (MC_is_active() || MC_record_replay_is_active()) {
     if (_sg_mc_buffering == "zero")
       simgrid::config::set_value<int>("smpi/send-is-detached-thresh", 0);
     else if (_sg_mc_buffering == "infty")
@@ -270,7 +314,6 @@ void smpi_check_options()
     else
       THROW_IMPOSSIBLE;
   }
-#endif
 
   xbt_assert(smpi_cfg_async_small_thresh() <= smpi_cfg_detached_send_thresh(),
              "smpi/async-small-thresh (=%d) should be smaller or equal to smpi/send-is-detached-thresh (=%d)",
@@ -289,4 +332,3 @@ void smpi_check_options()
   simgrid::smpi::colls::set_collectives();
   simgrid::smpi::colls::smpi_coll_cleanup_callback = nullptr;
 }
-