Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move SMPI config to smpi_config.cpp file.
authorAugustin Degomme <adegomme@gmail.com>
Wed, 4 Dec 2019 17:55:45 +0000 (18:55 +0100)
committerAugustin Degomme <adegomme@gmail.com>
Wed, 4 Dec 2019 17:56:14 +0000 (18:56 +0100)
Store values for most used values, which can be used millions of times.
In some tests I saw up to 5% of the time spent reading them.

15 files changed:
src/simgrid/sg_config.cpp
src/simix/smx_global.cpp
src/smpi/include/private.hpp
src/smpi/include/smpi_config.hpp [new file with mode: 0644]
src/smpi/internals/smpi_actor.cpp
src/smpi/internals/smpi_bench.cpp
src/smpi/internals/smpi_config.cpp [new file with mode: 0644]
src/smpi/internals/smpi_global.cpp
src/smpi/internals/smpi_replay.cpp
src/smpi/internals/smpi_shared.cpp
src/smpi/mpi/smpi_comm.cpp
src/smpi/mpi/smpi_datatype.cpp
src/smpi/mpi/smpi_op.cpp
src/smpi/mpi/smpi_request.cpp
tools/cmake/DefinePackages.cmake

index 2b8cdc2..57d1311 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/kernel/lmm/maxmin.hpp"
 #include "src/mc/mc_config.hpp"
 #include "src/mc/mc_replay.hpp"
+#include "src/smpi/include/smpi_config.hpp"
 #include "src/surf/surf_interface.hpp"
 #include "surf/surf.hpp"
 #include "xbt/config.hpp"
@@ -365,111 +366,6 @@ void sg_config_init(int *argc, char **argv)
                                              "contention (default value based on Stampede cluster profiling)",
                                              "0.965;0.925;1.35");
   simgrid::config::alias("smpi/IB-penalty-factors", {"smpi/IB_penalty_factors"});
-
-#if HAVE_SMPI
-  simgrid::config::declare_flag<double>("smpi/host-speed", "Speed of the host running the simulation (in flop/s). "
-                                                           "Used to bench the operations.",
-                                        20000.0, [](const double& val) {
-      xbt_assert(val > 0.0, "Invalid value (%f) for 'smpi/host-speed': it must be positive.", val);
-    });
-  simgrid::config::alias("smpi/host-speed", {"smpi/running_power", "smpi/running-power"});
-
-  simgrid::config::declare_flag<bool>("smpi/keep-temps", "Whether we should keep the generated temporary files.",
-                                      false);
-
-  simgrid::config::declare_flag<bool>("smpi/display-timing", "Whether we should display the timing after simulation.",
-                                      false);
-  simgrid::config::alias("smpi/display-timing", {"smpi/display_timing"});
-
-  simgrid::config::declare_flag<bool>(
-      "smpi/simulate-computation", "Whether the computational part of the simulated application should be simulated.",
-      true);
-  simgrid::config::alias("smpi/simulate-computation", {"smpi/simulate_computation"});
-
-  simgrid::config::declare_flag<std::string>(
-      "smpi/shared-malloc", "Whether SMPI_SHARED_MALLOC is enabled. Disable it for debugging purposes.", "global");
-  simgrid::config::alias("smpi/shared-malloc", {"smpi/use_shared_malloc", "smpi/use-shared-malloc"});
-  simgrid::config::declare_flag<double>("smpi/shared-malloc-blocksize",
-                                        "Size of the bogus file which will be created for global shared allocations",
-                                        1UL << 20);
-  simgrid::config::declare_flag<double>("smpi/auto-shared-malloc-thresh",
-                                        "Threshold size for the automatic sharing of memory",
-                                        0);
-
-  simgrid::config::declare_flag<std::string>("smpi/shared-malloc-hugepage",
-                                             "Path to a mounted hugetlbfs, to use huge pages with shared malloc.", "");
-
-  simgrid::config::declare_flag<double>(
-      "smpi/cpu-threshold", "Minimal computation time (in seconds) not discarded, or -1 for infinity.", 1e-6);
-  simgrid::config::alias("smpi/cpu-threshold", {"smpi/cpu_threshold"});
-
-  simgrid::config::declare_flag<int>(
-      "smpi/async-small-thresh",
-      "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver", 0);
-  simgrid::config::alias("smpi/async-small-thresh", {"smpi/async_small_thres", "smpi/async_small_thresh"});
-
-  simgrid::config::declare_flag<bool>("smpi/trace-call-location",
-                                      "Should filename and linenumber of MPI calls be traced?", false);
-  simgrid::config::declare_flag<bool>("smpi/trace-call-use-absolute-path",
-                                      "Should filenames for trace-call tracing be absolute or not?", false);
-  simgrid::config::declare_flag<int>(
-      "smpi/send-is-detached-thresh",
-      "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend", 65536);
-  simgrid::config::alias("smpi/send-is-detached-thresh",
-                         {"smpi/send_is_detached_thres", "smpi/send_is_detached_thresh"});
-
-  const char* default_privatization = std::getenv("SMPI_PRIVATIZATION");
-  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);
-  simgrid::config::alias("smpi/privatization", {"smpi/privatize_global_variables", "smpi/privatize-global-variables"});
-
-  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<bool>("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.",
-                                      true);
-
-#if HAVE_PAPI
-  simgrid::config::declare_flag<std::string>("smpi/papi-events",
-                                             "This switch enables tracking the specified counters with PAPI", "");
-#endif
-  simgrid::config::declare_flag<std::string>("smpi/comp-adjustment-file",
-                                             "A file containing speedups or slowdowns for some parts of the code.", "");
-  simgrid::config::declare_flag<std::string>(
-      "smpi/os", "Small messages timings (MPI_Send minimum time for small messages)", "0:0:0:0:0");
-  simgrid::config::declare_flag<std::string>(
-      "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");
-
-  simgrid::config::declare_flag<double>("smpi/iprobe-cpu-usage",
-                                        "Maximum usage of CPUs by MPI_Iprobe() calls. We've observed that MPI_Iprobes "
-                                        "consume significantly less power than the maximum of a specific application. "
-                                        "This value is then (Iprobe_Usage/Max_Application_Usage).",
-                                        1.0);
-
-  simgrid::config::declare_flag<std::string>("smpi/coll-selector", "Which collective selector to use", "default");
-  simgrid::config::alias("smpi/coll-selector", {"smpi/coll_selector"});
-  simgrid::config::declare_flag<std::string>("smpi/gather", "Which collective to use for gather", "");
-  simgrid::config::declare_flag<std::string>("smpi/allgather", "Which collective to use for allgather", "");
-  simgrid::config::declare_flag<std::string>("smpi/barrier", "Which collective to use for barrier", "");
-  simgrid::config::declare_flag<std::string>("smpi/reduce_scatter", "Which collective to use for reduce_scatter", "");
-  simgrid::config::alias("smpi/reduce_scatter", {"smpi/reduce-scatter"});
-  simgrid::config::declare_flag<std::string>("smpi/scatter", "Which collective to use for scatter", "");
-  simgrid::config::declare_flag<std::string>("smpi/allgatherv", "Which collective to use for allgatherv", "");
-  simgrid::config::declare_flag<std::string>("smpi/allreduce", "Which collective to use for allreduce", "");
-  simgrid::config::declare_flag<std::string>("smpi/alltoall", "Which collective to use for alltoall", "");
-  simgrid::config::declare_flag<std::string>("smpi/alltoallv", "Which collective to use for alltoallv", "");
-  simgrid::config::declare_flag<std::string>("smpi/bcast", "Which collective to use for bcast", "");
-  simgrid::config::declare_flag<std::string>("smpi/reduce", "Which collective to use for reduce", "");
-#endif // HAVE_SMPI
-
   /* Others */
 
   simgrid::config::declare_flag<bool>(
index 916eeca..48b3dca 100644 (file)
@@ -72,7 +72,7 @@ static void segvhandler(int signum, siginfo_t* siginfo, void* /*context*/)
   } else  if (siginfo->si_signo == SIGSEGV) {
     fprintf(stderr, "Segmentation fault.\n");
 #if HAVE_SMPI
-    if (smpi_enabled() && smpi_privatize_global_variables == SmpiPrivStrategies::NONE) {
+    if (smpi_enabled() && smpi_cfg_privatization() == SmpiPrivStrategies::NONE) {
 #if HAVE_PRIVATIZATION
       fprintf(stderr, "Try to enable SMPI variable privatization with --cfg=smpi/privatization:yes.\n");
 #else
index ca7e3ab..d3b4943 100644 (file)
@@ -93,15 +93,30 @@ XBT_PRIVATE int smpi_enabled();
 XBT_PRIVATE double smpi_mpi_wtime();
 XBT_PRIVATE void smpi_mpi_init();
 
+enum class SharedMallocType { NONE, LOCAL, GLOBAL };
+enum class SmpiPrivStrategies { NONE = 0, MMAP = 1, DLOPEN = 2, DEFAULT = DLOPEN };
+
+XBT_PRIVATE void smpi_init_options();
+XBT_PRIVATE void smpi_check_options();
+XBT_PRIVATE double smpi_cfg_host_speed();
+XBT_PRIVATE bool smpi_cfg_simulate_computation();
+XBT_PRIVATE SharedMallocType smpi_cfg_shared_malloc();
+XBT_PRIVATE double smpi_cfg_cpu_thresh();
+XBT_PRIVATE SmpiPrivStrategies smpi_cfg_privatization();
+XBT_PRIVATE int smpi_cfg_async_small_thresh();
+XBT_PRIVATE int smpi_cfg_detached_send_thresh();
+XBT_PRIVATE bool smpi_cfg_grow_injected_times();
+XBT_PRIVATE double smpi_cfg_iprobe_cpu_usage();
+XBT_PRIVATE bool smpi_cfg_trace_call_location();
+XBT_PRIVATE bool smpi_cfg_trace_call_use_absolute_path();
+XBT_PRIVATE std::string smpi_cfg_comp_adjustment_file();
+XBT_PRIVATE std::string smpi_cfg_papi_events_file();
+XBT_PRIVATE double smpi_cfg_auto_shared_malloc_thresh();
+
 // utilities
-extern XBT_PRIVATE double smpi_cpu_threshold;
-extern XBT_PRIVATE double smpi_host_speed;
 extern XBT_PRIVATE char* smpi_data_exe_start; // start of the data+bss segment of the executable
 extern XBT_PRIVATE int smpi_data_exe_size;    // size of the data+bss segment of the executable
 
-enum class SharedMallocType { NONE, LOCAL, GLOBAL };
-extern XBT_PRIVATE SharedMallocType smpi_cfg_shared_malloc; // Whether to activate shared malloc
-
 XBT_PRIVATE void smpi_switch_data_segment(simgrid::s4u::ActorPtr actor);
 
 XBT_PRIVATE void smpi_prepare_global_memory_segment();
@@ -480,10 +495,6 @@ extern std::unordered_map<std::string, double> location2speedup;
 /** @brief Returns the last call location (filename, linenumber). Process-specific. */
 XBT_PUBLIC smpi_trace_call_location_t* smpi_trace_get_call_location();
 
-enum class SmpiPrivStrategies { NONE = 0, MMAP = 1, DLOPEN = 2, DEFAULT = DLOPEN };
-
-extern XBT_PRIVATE SmpiPrivStrategies smpi_privatize_global_variables;
-
 XBT_PRIVATE void private_execute_flops(double flops);
 
 #endif
diff --git a/src/smpi/include/smpi_config.hpp b/src/smpi/include/smpi_config.hpp
new file mode 100644 (file)
index 0000000..26cfad8
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018-2019. 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. */
+
+#ifndef SMPI_CONFIG_HPP
+#define SMPI_CONFIG_HPP
+
+#include <xbt/config.hpp>
+
+/********************************** Configuration of SMPI **************************************/
+extern XBT_PRIVATE simgrid::config::Flag<double> _smpi_cfg_host_speed;
+extern XBT_PRIVATE simgrid::config::Flag<bool> _smpi_cfg_simulate_computation;
+extern XBT_PRIVATE simgrid::config::Flag<std::string> _smpi_cfg_shared_malloc_string;
+extern XBT_PRIVATE simgrid::config::Flag<double> _smpi_cfg_cpu_thresh;
+extern XBT_PRIVATE simgrid::config::Flag<std::string> _smpi_cfg_privatization_string;
+extern XBT_PRIVATE simgrid::config::Flag<int> _smpi_cfg_async_small_thresh;
+extern XBT_PRIVATE simgrid::config::Flag<int> _smpi_cfg_detached_send_thresh;
+extern XBT_PRIVATE simgrid::config::Flag<bool> _smpi_cfg_grow_injected_times;
+extern XBT_PRIVATE simgrid::config::Flag<double> _smpi_cfg_iprobe_cpu_usage;
+extern XBT_PRIVATE simgrid::config::Flag<bool> _smpi_cfg_trace_call_use_absolute_path;
+extern XBT_PRIVATE simgrid::config::Flag<bool> _smpi_cfg_trace_call_location;
+extern XBT_PRIVATE simgrid::config::Flag<std::string> _smpi_cfg_comp_adjustment_file;
+#if HAVE_PAPI
+extern XBT_PRIVATE simgrid::config::Flag<std::string> _smpi_cfg_papi_events_file;
+#endif
+extern XBT_PRIVATE simgrid::config::Flag<double> _smpi_cfg_auto_shared_malloc_thresh;
+#endif
index eae4244..da0e96c 100644 (file)
@@ -36,7 +36,7 @@ ActorExt::ActorExt(s4u::Actor* actor) : actor_(actor)
     MC_ignore_heap(timer_, xbt_os_timer_size());
 
 #if HAVE_PAPI
-  if (not simgrid::config::get_value<std::string>("smpi/papi-events").empty()) {
+  if (not smpi_cfg_papi_events_file().empty()) {
     // TODO: Implement host/process/thread based counters. This implementation
     // just always takes the values passed via "default", like this:
     // "default:COUNTER1:COUNTER2:COUNTER3;".
@@ -221,7 +221,7 @@ void ActorExt::init()
   if (ext->initialized())
     return;
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     /* Now using the segment index of this process  */
     ext->set_privatized_region(smpi_init_global_memory_segment_process());
     /* Done at the process's creation */
index 6380f77..6c326fa 100644 (file)
@@ -33,10 +33,6 @@ static simgrid::config::Flag<double>
                      "Minimum time to inject inside a call to MPI_Wtime(), gettimeofday() and clock_gettime()",
                      1e-8 /* Documented to be 10 ns */);
 
-double smpi_cpu_threshold = -1;
-double smpi_host_speed;
-
-SharedMallocType smpi_cfg_shared_malloc = SharedMallocType::GLOBAL;
 double smpi_total_benched_time = 0;
 
 // Private execute_flops used by smpi_execute and smpi_execute_benched
@@ -62,9 +58,9 @@ void smpi_execute_flops(double flops) {
 
 void smpi_execute(double duration)
 {
-  if (duration >= smpi_cpu_threshold) {
+  if (duration >= smpi_cfg_cpu_thresh()) {
     XBT_DEBUG("Sleep for %g to handle real computation time", duration);
-    double flops = duration * smpi_host_speed;
+    double flops = duration * smpi_cfg_host_speed();
     int rank     = simgrid::s4u::this_actor::get_pid();
     TRACE_smpi_computing_in(rank, flops);
 
@@ -74,7 +70,7 @@ void smpi_execute(double duration)
 
   } else {
     XBT_DEBUG("Real computation took %g while option smpi/cpu-threshold is set to %g => ignore it", duration,
-              smpi_cpu_threshold);
+              smpi_cfg_cpu_thresh());
   }
 }
 
@@ -88,7 +84,7 @@ void smpi_execute_benched(double duration)
 
 void smpi_bench_begin()
 {
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     smpi_switch_data_segment(simgrid::s4u::Actor::self());
   }
 
@@ -96,7 +92,7 @@ void smpi_bench_begin()
     return;
 
 #if HAVE_PAPI
-  if (not simgrid::config::get_value<std::string>("smpi/papi-events").empty()) {
+  if (not smpi_cfg_papi_events_file().empty()) {
     int event_set = smpi_process()->papi_event_set();
     // PAPI_start sets everything to 0! See man(3) PAPI_start
     if (PAPI_LOW_LEVEL_INITED == PAPI_is_initialized() && PAPI_start(event_set) != PAPI_OK) {
@@ -111,7 +107,7 @@ void smpi_bench_begin()
 
 double smpi_adjust_comp_speed(){
   double speedup=1;
-  if (simgrid::config::get_value<std::string>("smpi/comp-adjustment-file")[0] != '\0') {
+  if (smpi_cfg_comp_adjustment_file()[0] != '\0') {
 
     smpi_trace_call_location_t* loc                            = smpi_process()->call_location();
     std::string key                                            = loc->get_composed_key();
@@ -136,7 +132,7 @@ void smpi_bench_end()
    * An MPI function has been called and now is the right time to update
    * our PAPI counters for this process.
    */
-  if (not simgrid::config::get_value<std::string>("smpi/papi-events").empty()) {
+  if (not smpi_cfg_papi_events_file().empty()) {
     papi_counter_t& counter_data        = smpi_process()->papi_counters();
     int event_set                       = smpi_process()->papi_event_set();
     std::vector<long long> event_values = std::vector<long long>(counter_data.size());
@@ -161,12 +157,12 @@ void smpi_bench_end()
 
   // Maybe we need to artificially speed up or slow down our computation based on our statistical analysis.
   // Simulate the benchmarked computation unless disabled via command-line argument
-  if (simgrid::config::get_value<bool>("smpi/simulate-computation")) {
+  if (smpi_cfg_simulate_computation()) {
     smpi_execute(xbt_os_timer_elapsed(timer)/smpi_adjust_comp_speed());
   }
 
 #if HAVE_PAPI
-  if (not simgrid::config::get_value<std::string>("smpi/papi-events").empty() && TRACE_smpi_is_enabled()) {
+  if (not smpi_cfg_papi_events_file().empty() && TRACE_smpi_is_enabled()) {
     container_t container =
         simgrid::instr::Container::by_name(std::string("rank-") + std::to_string(simgrid::s4u::this_actor::get_pid()));
     papi_counter_t& counter_data = smpi_process()->papi_counters();
@@ -471,7 +467,7 @@ void smpi_trace_set_call_location(const char* file, const int line)
 
   loc->previous_filename   = loc->filename;
   loc->previous_linenumber = loc->linenumber;
-  if(not simgrid::config::get_value<bool>("smpi/trace-call-use-absolute-path"))
+  if(not smpi_cfg_trace_call_use_absolute_path())
     loc->filename = simgrid::xbt::Path(file).get_base_name();
   else
     loc->filename = file;
diff --git a/src/smpi/internals/smpi_config.cpp b/src/smpi/internals/smpi_config.cpp
new file mode 100644 (file)
index 0000000..68f3b67
--- /dev/null
@@ -0,0 +1,278 @@
+/* Copyright (c) 2008-2019. 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 "mc/mc.h"
+#include "include/xbt/config.hpp"
+#include "private.hpp"
+#include "smpi_coll.hpp"
+#include "src/simix/smx_private.hpp"
+#include <cfloat> /* DBL_MAX */
+#include <boost/algorithm/string.hpp> /* trim */
+#include <boost/tokenizer.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__)
+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;
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_config, smpi, "Logging specific to SMPI (config)");
+
+simgrid::config::Flag<double> _smpi_cfg_host_speed{
+  "smpi/host-speed", "Speed of the host running the simulation (in flop/s). "
+  "Used to bench the operations.",  20000.0,
+  [](const double& val) { xbt_assert(val > 0.0, "Invalid value (%f) for 'smpi/host-speed': it must be positive.", val); }};
+
+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());
+    } 
+  } };
+
+simgrid::config::Flag<double> _smpi_cfg_cpu_threshold{
+  "smpi/cpu-threshold", "Minimal computation time (in seconds) not discarded, or -1 for infinity.", 1e-6,
+  [](const double& val){
+    if (val < 0)
+      _smpi_cfg_cpu_threshold = DBL_MAX;
+  }};
+
+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<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.",
+                                                          true};
+simgrid::config::Flag<double> _smpi_cfg_iprobe_cpu_usage{"smpi/iprobe-cpu-usage",
+                                                        "Maximum usage of CPUs by MPI_Iprobe() calls. We've observed that MPI_Iprobes "
+                                                        "consume significantly less power than the maximum of a specific application. "
+                                                        "This value is then (Iprobe_Usage/Max_Application_Usage).",
+                                                        1.0};
+
+simgrid::config::Flag<bool>  _smpi_cfg_trace_call_location{"smpi/trace-call-location",
+                                                           "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){
+      if (not filename.empty()) {
+        std::ifstream fstream(filename);
+        xbt_assert(fstream.is_open(), "Could not open file %s. Does it exist?", filename.c_str());
+        std::string line;
+        typedef boost::tokenizer<boost::escaped_list_separator<char>> Tokenizer;
+        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());
+          std::string location = *it;
+          boost::trim(location);
+          location2speedup.insert(std::pair<std::string, double>(location, std::stod(*end)));
+        }
+      }
+    }};
+    
+#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", ""};
+#endif
+
+simgrid::config::Flag<double> _smpi_cfg_auto_shared_malloc_thresh("smpi/auto-shared-malloc-thresh",
+                                                                  "Threshold size for the automatic sharing of memory", 
+                                                                  0);
+
+double smpi_cfg_host_speed(){
+  return _smpi_cfg_host_speed;
+}
+
+bool smpi_cfg_simulate_computation(){
+  return _smpi_cfg_simulate_computation;
+}
+
+SharedMallocType smpi_cfg_shared_malloc(){
+  return _smpi_cfg_shared_malloc;
+}
+
+double smpi_cfg_cpu_thresh(){
+  return _smpi_cfg_cpu_threshold;
+}
+
+SmpiPrivStrategies smpi_cfg_privatization(){
+  return _smpi_cfg_privatization;
+}
+
+int smpi_cfg_async_small_thresh(){
+  return _smpi_cfg_async_small_thresh;
+}
+
+int smpi_cfg_detached_send_thresh(){
+  return _smpi_cfg_detached_send_thresh;
+}
+
+bool smpi_cfg_grow_injected_times(){
+  return _smpi_cfg_grow_injected_times;
+}
+
+double smpi_cfg_iprobe_cpu_usage(){
+  return _smpi_cfg_iprobe_cpu_usage;
+}
+
+bool smpi_cfg_trace_call_location(){
+  return _smpi_cfg_trace_call_location;
+}
+
+bool smpi_cfg_trace_call_use_absolute_path(){
+  return _smpi_cfg_trace_call_use_absolute_path;
+}
+
+std::string smpi_cfg_comp_adjustment_file(){
+  return _smpi_cfg_comp_adjustment_file;
+}
+#if HAVE_PAPI
+std::string smpi_cfg_papi_events_file(){
+  return _smpi_cfg_papi_events_file;
+}
+#endif
+double smpi_cfg_auto_shared_malloc_thresh(){
+  return _smpi_cfg_auto_shared_malloc_thresh;
+}
+
+void smpi_init_options(){
+  // return if already called
+  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);
+
+  simgrid::config::declare_flag<std::string>("smpi/coll-selector", "Which collective selector to use", "default");
+  simgrid::config::declare_flag<std::string>("smpi/gather", "Which collective to use for gather", "");
+  simgrid::config::declare_flag<std::string>("smpi/allgather", "Which collective to use for allgather", "");
+  simgrid::config::declare_flag<std::string>("smpi/barrier", "Which collective to use for barrier", "");
+  simgrid::config::declare_flag<std::string>("smpi/reduce_scatter", "Which collective to use for reduce_scatter", "");
+  simgrid::config::declare_flag<std::string>("smpi/scatter", "Which collective to use for scatter", "");
+  simgrid::config::declare_flag<std::string>("smpi/allgatherv", "Which collective to use for allgatherv", "");
+  simgrid::config::declare_flag<std::string>("smpi/allreduce", "Which collective to use for allreduce", "");
+  simgrid::config::declare_flag<std::string>("smpi/alltoall", "Which collective to use for alltoall", "");
+  simgrid::config::declare_flag<std::string>("smpi/alltoallv", "Which collective to use for alltoallv", "");
+  simgrid::config::declare_flag<std::string>("smpi/bcast", "Which collective to use for bcast", "");
+  simgrid::config::declare_flag<std::string>("smpi/reduce", "Which collective to use for reduce", "");
+
+  const char* default_privatization = std::getenv("SMPI_PRIVATIZATION");
+  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_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<double>("smpi/shared-malloc-blocksize",
+                                        "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.", 
+                                             "");
+
+  simgrid::config::declare_flag<std::string>(
+      "smpi/os", "Small messages timings (MPI_Send minimum time for small messages)", "0:0:0:0:0");
+  simgrid::config::declare_flag<std::string>(
+      "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");
+  simgrid::config::alias("smpi/display-timing", {"smpi/display_timing"});
+  simgrid::config::alias("smpi/coll-selector", {"smpi/coll_selector"});
+  simgrid::config::alias("smpi/simulate-computation", {"smpi/simulate_computation"});
+  simgrid::config::alias("smpi/shared-malloc", {"smpi/use_shared_malloc", "smpi/use-shared-malloc"});
+  simgrid::config::alias("smpi/host-speed", {"smpi/running_power", "smpi/running-power"});
+  simgrid::config::alias("smpi/cpu-threshold", {"smpi/cpu_threshold"});
+  simgrid::config::alias("smpi/async-small-thresh", {"smpi/async_small_thres", "smpi/async_small_thresh"});
+  simgrid::config::alias("smpi/send-is-detached-thresh", {"smpi/send_is_detached_thres", "smpi/send_is_detached_thresh"});
+  simgrid::config::alias("smpi/privatization", {"smpi/privatize_global_variables", "smpi/privatize-global-variables"});
+  simgrid::config::alias("smpi/reduce_scatter", {"smpi/reduce-scatter"});
+  _smpi_options_initialized=true;
+
+}
+
+void smpi_check_options()
+{
+#if SIMGRID_HAVE_MC
+  if (MC_is_active()) {
+    if (_sg_mc_buffering == "zero")
+      simgrid::config::set_value<int>("smpi/send-is-detached-thresh", 0);
+    else if (_sg_mc_buffering == "infty")
+      simgrid::config::set_value<int>("smpi/send-is-detached-thresh", INT_MAX);
+    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)",
+             smpi_cfg_async_small_thresh(),
+             smpi_cfg_detached_send_thresh());
+
+  if (simgrid::config::is_default("smpi/host-speed") && not MC_is_active()) {
+    XBT_INFO("You did not set the power of the host running the simulation.  "
+             "The timings will certainly not be accurate.  "
+             "Use the option \"--cfg=smpi/host-speed:<flops>\" to set its value.  "
+             "Check "
+             "https://simgrid.org/doc/latest/Configuring_SimGrid.html#automatic-benchmarking-of-smpi-code for more "
+             "information.");
+  }
+
+  simgrid::smpi::colls::set_collectives();
+  simgrid::smpi::colls::smpi_coll_cleanup_callback = nullptr;
+}
+
index a2d7e50..9955d92 100644 (file)
@@ -15,9 +15,8 @@
 #include "xbt/config.hpp"
 
 #include <algorithm>
-#include <boost/algorithm/string.hpp> /* trim_right / trim_left */
+#include <boost/algorithm/string.hpp> /* split */
 #include <boost/tokenizer.hpp>
-#include <cfloat> /* DBL_MAX */
 #include <cinttypes>
 #include <cstdint> /* intmax_t */
 #include <dlfcn.h>
 #include <link.h>
 #endif
 
-#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__)
-constexpr bool HAVE_WORKING_MMAP = false;
-#else
-constexpr bool HAVE_WORKING_MMAP = true;
-#endif
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, "Logging specific to SMPI (kernel)");
 
 #if SMPI_IFORT
@@ -206,7 +193,7 @@ void smpi_comm_copy_buffer_callback(simgrid::kernel::activity::CommImpl* comm, v
   auto private_blocks = merge_private_blocks(src_private_blocks, dst_private_blocks);
   check_blocks(private_blocks, buff_size);
   void* tmpbuff=buff;
-  if ((smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) &&
+  if ((smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) &&
       (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 !");
@@ -215,7 +202,7 @@ void smpi_comm_copy_buffer_callback(simgrid::kernel::activity::CommImpl* comm, v
     memcpy_private(tmpbuff, buff, private_blocks);
   }
 
-  if ((smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) &&
+  if ((smpi_cfg_privatization() == 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");
@@ -234,39 +221,6 @@ void smpi_comm_null_copy_buffer_callback(simgrid::kernel::activity::CommImpl*, v
   /* nothing done in this version */
 }
 
-static void smpi_check_options()
-{
-#if SIMGRID_HAVE_MC
-  if (MC_is_active()) {
-    if (_sg_mc_buffering == "zero")
-      simgrid::config::set_value<int>("smpi/send-is-detached-thresh", 0);
-    else if (_sg_mc_buffering == "infty")
-      simgrid::config::set_value<int>("smpi/send-is-detached-thresh", INT_MAX);
-    else
-      THROW_IMPOSSIBLE;
-  }
-#endif
-
-  xbt_assert(simgrid::config::get_value<int>("smpi/async-small-thresh") <=
-                 simgrid::config::get_value<int>("smpi/send-is-detached-thresh"),
-             "smpi/async-small-thresh (=%d) should be smaller or equal to smpi/send-is-detached-thresh (=%d)",
-             simgrid::config::get_value<int>("smpi/async-small-thresh"),
-             simgrid::config::get_value<int>("smpi/send-is-detached-thresh"));
-
-  if (simgrid::config::is_default("smpi/host-speed") && not MC_is_active()) {
-    XBT_INFO("You did not set the power of the host running the simulation.  "
-             "The timings will certainly not be accurate.  "
-             "Use the option \"--cfg=smpi/host-speed:<flops>\" to set its value.  "
-             "Check "
-             "https://simgrid.org/doc/latest/Configuring_SimGrid.html#automatic-benchmarking-of-smpi-code for more "
-             "information.");
-  }
-
-  xbt_assert(simgrid::config::get_value<double>("smpi/cpu-threshold") >= 0,
-             "The 'smpi/cpu-threshold' option cannot have negative values [anymore]. If you want to discard "
-             "the simulation of any computation, please use 'smpi/simulate-computation:no' instead.");
-}
-
 int smpi_enabled() {
   return MPI_COMM_WORLD != MPI_COMM_UNINITIALIZED;
 }
@@ -278,14 +232,14 @@ static void smpi_init_papi()
   // the configuration as given by the user (counter data as a pair of (counter_name, counter_counter))
   // and the (computed) event_set.
 
-  if (not simgrid::config::get_value<std::string>("smpi/papi-events").empty()) {
+  if (not smpi_cfg_papi_events_file().empty()) {
     if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT)
       XBT_ERROR("Could not initialize PAPI library; is it correctly installed and linked?"
                 " Expected version is %u", PAPI_VER_CURRENT);
 
     typedef boost::tokenizer<boost::char_separator<char>> Tokenizer;
     boost::char_separator<char> separator_units(";");
-    std::string str = simgrid::config::get_value<std::string>("smpi/papi-events");
+    std::string str = smpi_cfg_papi_events_file();
     Tokenizer tokens(str, separator_units);
 
     // Iterate over all the computational units. This could be processes, hosts, threads, ranks... You name it.
@@ -338,50 +292,7 @@ static void smpi_init_papi()
 #endif
 }
 
-static void smpi_init_options(){
-  // return if already called
-  if (smpi_cpu_threshold > -1)
-    return;
-  simgrid::smpi::colls::set_collectives();
-  simgrid::smpi::colls::smpi_coll_cleanup_callback = nullptr;
-  smpi_cpu_threshold                               = simgrid::config::get_value<double>("smpi/cpu-threshold");
-  if (smpi_cpu_threshold < 0)
-    smpi_cpu_threshold = DBL_MAX;
-
-  smpi_host_speed                   = simgrid::config::get_value<double>("smpi/host-speed");
-  std::string smpi_privatize_option = simgrid::config::get_value<std::string>("smpi/privatization");
-  if (smpi_privatize_option == "no" || smpi_privatize_option == "0")
-    smpi_privatize_global_variables = SmpiPrivStrategies::NONE;
-  else if (smpi_privatize_option == "yes" || smpi_privatize_option == "1")
-    smpi_privatize_global_variables = SmpiPrivStrategies::DEFAULT;
-  else if (smpi_privatize_option == "mmap")
-    smpi_privatize_global_variables = SmpiPrivStrategies::MMAP;
-  else if (smpi_privatize_option == "dlopen")
-    smpi_privatize_global_variables = 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_privatize_global_variables = SmpiPrivStrategies::NONE;
-  }
-  if (not HAVE_WORKING_MMAP && smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
-    XBT_INFO("mmap privatization is broken on this platform, switching to dlopen privatization instead.");
-    smpi_privatize_global_variables = SmpiPrivStrategies::DLOPEN;
-  }
 
-  std::string val = simgrid::config::get_value<std::string>("smpi/shared-malloc");
-  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());
-  }
-}
 
 typedef std::function<int(int argc, char *argv[])> smpi_entry_point_type;
 typedef int (* smpi_c_entry_point_type)(int argc, char **argv);
@@ -600,7 +511,7 @@ static void smpi_init_privatization_dlopen(const std::string& executable)
 
 static void smpi_init_privatization_no_dlopen(const std::string& executable)
 {
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP)
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP)
     smpi_prepare_global_memory_segment();
 
   // Load the dynamic library and resolve the entry point:
@@ -610,7 +521,7 @@ static void smpi_init_privatization_no_dlopen(const std::string& executable)
   smpi_entry_point_type entry_point = smpi_resolve_function(handle);
   xbt_assert(entry_point, "main not found in %s", executable.c_str());
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP)
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP)
     smpi_backup_global_memory_segment();
 
   // Execute the same entry point for each simulated process:
@@ -627,23 +538,27 @@ int smpi_main(const char* executable, int argc, char* argv[])
      * configuration tools */
     return 0;
   }
-
+  
+  SMPI_switch_data_segment = &smpi_switch_data_segment;
+  smpi_init_options();
   TRACE_global_init();
   SIMIX_global_init(&argc, argv);
 
   auto engine              = simgrid::s4u::Engine::get_instance();
-  SMPI_switch_data_segment = &smpi_switch_data_segment;
+
   sg_storage_file_system_init();
   // parse the platform file: get the host list
   engine->load_platform(argv[1]);
   SIMIX_comm_set_copy_data_callback(smpi_comm_copy_buffer_callback);
 
-  smpi_init_options();
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::DLOPEN)
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::DLOPEN)
     smpi_init_privatization_dlopen(executable);
   else
     smpi_init_privatization_no_dlopen(executable);
 
+  simgrid::smpi::colls::set_collectives();
+  simgrid::smpi::colls::smpi_coll_cleanup_callback = nullptr;
+  
   SMPI_init();
 
   /* This is a ... heavy way to count the MPI ranks */
@@ -687,6 +602,7 @@ int smpi_main(const char* executable, int argc, char* argv[])
 
 // Called either directly from the user code, or from the code called by smpirun
 void SMPI_init(){
+  smpi_init_options();
   simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::Actor& actor) {
     if (not actor.is_daemon())
       actor.extension_set<simgrid::smpi::ActorExt>(new simgrid::smpi::ActorExt(&actor));
@@ -696,30 +612,10 @@ void SMPI_init(){
   for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
     host->extension_set(new simgrid::smpi::Host(host));
 
-  smpi_init_options();
   if (not MC_is_active()) {
     global_timer = xbt_os_timer_new();
     xbt_os_walltimer_start(global_timer);
   }
-
-  std::string filename = simgrid::config::get_value<std::string>("smpi/comp-adjustment-file");
-  if (not filename.empty()) {
-    std::ifstream fstream(filename);
-    xbt_assert(fstream.is_open(), "Could not open file %s. Does it exist?", filename.c_str());
-
-    std::string line;
-    typedef boost::tokenizer<boost::escaped_list_separator<char>> Tokenizer;
-    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());
-
-      std::string location = *it;
-      boost::trim(location);
-      location2speedup.insert(std::pair<std::string, double>(location, std::stod(*end)));
-    }
-  }
   smpi_init_papi();
   smpi_check_options();
 }
@@ -739,7 +635,7 @@ void SMPI_finalize()
     xbt_os_timer_free(global_timer);
   }
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP)
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP)
     smpi_destroy_global_memory_segments();
   if (simgrid::smpi::F2C::lookup() != nullptr)
     simgrid::smpi::F2C::delete_lookup();
index b0c8bd9..5d2619c 100644 (file)
@@ -489,7 +489,7 @@ void RecvAction::kernel(simgrid::xbt::ReplayAction&)
 
 void ComputeAction::kernel(simgrid::xbt::ReplayAction&)
 {
-  if (simgrid::config::get_value<bool>("smpi/simulate-computation")) {
+  if (smpi_cfg_simulate_computation()) {
     smpi_execute_flops(args.flops/smpi_adjust_comp_speed());
   }
 }
index 29f3b27..2e406e3 100644 (file)
@@ -344,14 +344,14 @@ void* smpi_shared_malloc_partial(size_t size, size_t* shared_block_offsets, int
 
 
 void *smpi_shared_malloc_intercept(size_t size, const char *file, int line) {
-  if( simgrid::config::get_value<double>("smpi/auto-shared-malloc-thresh") == 0 || size < simgrid::config::get_value<double>("smpi/auto-shared-malloc-thresh"))
+  if( smpi_cfg_auto_shared_malloc_thresh() == 0 || size < smpi_cfg_auto_shared_malloc_thresh())
     return ::operator new(size);
   else
     return smpi_shared_malloc(size, file, line);
 }
 
 void* smpi_shared_calloc_intercept(size_t num_elm, size_t elem_size, const char* file, int line){
-  if( simgrid::config::get_value<double>("smpi/auto-shared-malloc-thresh") == 0 || elem_size*num_elm < simgrid::config::get_value<double>("smpi/auto-shared-malloc-thresh")){
+  if( smpi_cfg_auto_shared_malloc_thresh() == 0 || elem_size*num_elm < smpi_cfg_auto_shared_malloc_thresh()){
     void* ptr = ::operator new(elem_size*num_elm);
     memset(ptr, 0, elem_size*num_elm);
     return ptr;
@@ -361,9 +361,9 @@ void* smpi_shared_calloc_intercept(size_t num_elm, size_t elem_size, const char*
 }
 
 void *smpi_shared_malloc(size_t size, const char *file, int line) {
-  if (size > 0 && smpi_cfg_shared_malloc == SharedMallocType::LOCAL) {
+  if (size > 0 && smpi_cfg_shared_malloc() == SharedMallocType::LOCAL) {
     return smpi_shared_malloc_local(size, file, line);
-  } else if (smpi_cfg_shared_malloc == SharedMallocType::GLOBAL) {
+  } else if (smpi_cfg_shared_malloc() == SharedMallocType::GLOBAL) {
     int nb_shared_blocks = 1;
     size_t shared_block_offsets[2] = {0, size};
     return smpi_shared_malloc_partial(size, shared_block_offsets, nb_shared_blocks);
@@ -376,7 +376,7 @@ int smpi_is_shared(const void* ptr, std::vector<std::pair<size_t, size_t>> &priv
   private_blocks.clear(); // being paranoid
   if (allocs_metadata.empty())
     return 0;
-  if (smpi_cfg_shared_malloc == SharedMallocType::LOCAL || smpi_cfg_shared_malloc == SharedMallocType::GLOBAL) {
+  if (smpi_cfg_shared_malloc() == SharedMallocType::LOCAL || smpi_cfg_shared_malloc() == SharedMallocType::GLOBAL) {
     auto low = allocs_metadata.lower_bound(ptr);
     if (low != allocs_metadata.end() && low->first == ptr) {
       private_blocks = low->second.private_blocks;
@@ -440,7 +440,7 @@ std::vector<std::pair<size_t, size_t>> merge_private_blocks(const std::vector<st
 
 void smpi_shared_free(void *ptr)
 {
-  if (smpi_cfg_shared_malloc == SharedMallocType::LOCAL) {
+  if (smpi_cfg_shared_malloc() == SharedMallocType::LOCAL) {
     char loc[PTR_STRLEN];
     snprintf(loc, PTR_STRLEN, "%p", ptr);
     auto meta = allocs_metadata.find(ptr);
@@ -462,7 +462,7 @@ void smpi_shared_free(void *ptr)
       XBT_DEBUG("Shared free - Local - no removal - of %p, count = %d", ptr, data->count);
     }
 
-  } else if (smpi_cfg_shared_malloc == SharedMallocType::GLOBAL) {
+  } else if (smpi_cfg_shared_malloc() == SharedMallocType::GLOBAL) {
     auto meta = allocs_metadata.find(ptr);
     if (meta != allocs_metadata.end()){
       meta->second.data->second.count--;
index 3507333..6c2bacc 100644 (file)
@@ -66,7 +66,7 @@ void Comm::destroy(Comm* comm)
 }
 
 int Comm::dup(MPI_Comm* newcomm){
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
     smpi_switch_data_segment(s4u::Actor::self());
   }
@@ -380,7 +380,7 @@ void Comm::init_smp(){
     smpi_process()->set_replaying(false);
   }
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
     smpi_switch_data_segment(s4u::Actor::self());
   }
@@ -395,7 +395,7 @@ void Comm::init_smp(){
 
   allgather__ring(&leader, 1, MPI_INT , leaders_map, 1, MPI_INT, this);
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
     smpi_switch_data_segment(s4u::Actor::self());
   }
@@ -468,7 +468,7 @@ void Comm::init_smp(){
   }
   bcast__scatter_LR_allgather(&(is_uniform_),1, MPI_INT, 0, comm_intra );
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
     smpi_switch_data_segment(s4u::Actor::self());
   }
index b82b801..eabb154 100644 (file)
@@ -275,7 +275,7 @@ int Datatype::copy(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
 
 // FIXME Handle the case of a partial shared malloc.
 
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     smpi_switch_data_segment(simgrid::s4u::Actor::self());
   }
   /* First check if we really have something to do */
index 24c9eb6..9b755c7 100644 (file)
@@ -240,7 +240,7 @@ namespace smpi{
 
 void Op::apply(const void* invec, void* inoutvec, const int* len, MPI_Datatype datatype)
 {
-  if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
+  if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
     XBT_DEBUG("Applying operation, switch to the right data frame ");
     smpi_switch_data_segment(simgrid::s4u::Actor::self());
index d34a031..d99290b 100644 (file)
@@ -376,15 +376,13 @@ void Request::start()
 
     simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(dst_));
 
-    int async_small_thresh = simgrid::config::get_value<int>("smpi/async-small-thresh");
-
     simgrid::s4u::MutexPtr mut = process->mailboxes_mutex();
-    if (async_small_thresh != 0 || (flags_ & MPI_REQ_RMA) != 0)
+    if (smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0)
       mut->lock();
 
-    if (async_small_thresh == 0 && (flags_ & MPI_REQ_RMA) == 0) {
+    if (smpi_cfg_async_small_thresh() == 0 && (flags_ & MPI_REQ_RMA) == 0) {
       mailbox = process->mailbox();
-    } else if (((flags_ & MPI_REQ_RMA) != 0) || static_cast<int>(size_) < async_small_thresh) {
+    } else if (((flags_ & MPI_REQ_RMA) != 0) || static_cast<int>(size_) < smpi_cfg_async_small_thresh()) {
       //We have to check both mailboxes (because SSEND messages are sent to the large mbox).
       //begin with the more appropriate one : the small one.
       mailbox = process->mailbox_small();
@@ -423,7 +421,7 @@ void Request::start()
         process->replaying() ? &smpi_comm_null_copy_buffer_callback : smpi_comm_copy_data_callback, this, -1.0);
     XBT_DEBUG("recv simcall posted");
 
-    if (async_small_thresh != 0 || (flags_ & MPI_REQ_RMA) != 0)
+    if (smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0)
       mut->unlock();
   } else { /* the RECV flag was not set, so this is a send */
     simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(dst_));
@@ -437,7 +435,7 @@ void Request::start()
     void* buf = buf_;
     if ((flags_ & MPI_REQ_SSEND) == 0 &&
         ((flags_ & MPI_REQ_RMA) != 0 || (flags_ & MPI_REQ_BSEND) != 0 ||
-         static_cast<int>(size_) < simgrid::config::get_value<int>("smpi/send-is-detached-thresh"))) {
+         static_cast<int>(size_) < smpi_cfg_detached_send_thresh())) {
       void *oldbuf = nullptr;
       detached_    = true;
       XBT_DEBUG("Send request %p is detached", this);
@@ -445,7 +443,7 @@ void Request::start()
       if (not(old_type_->flags() & DT_FLAG_DERIVED)) {
         oldbuf = buf_;
         if (not process->replaying() && oldbuf != nullptr && size_ != 0) {
-          if ((smpi_privatize_global_variables != SmpiPrivStrategies::NONE) &&
+          if ((smpi_cfg_privatization() != SmpiPrivStrategies::NONE) &&
               (static_cast<char*>(buf_) >= smpi_data_exe_start) &&
               (static_cast<char*>(buf_) < smpi_data_exe_start + smpi_data_exe_size)) {
             XBT_DEBUG("Privatization : We are sending from a zone inside global memory. Switch data segment ");
@@ -474,16 +472,14 @@ void Request::start()
       XBT_DEBUG("sending size of %zu : sleep %f ", size_, sleeptime);
     }
 
-    int async_small_thresh = simgrid::config::get_value<int>("smpi/async-small-thresh");
-
     simgrid::s4u::MutexPtr mut = process->mailboxes_mutex();
 
-    if (async_small_thresh != 0 || (flags_ & MPI_REQ_RMA) != 0)
+    if (smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0)
       mut->lock();
 
-    if (not(async_small_thresh != 0 || (flags_ & MPI_REQ_RMA) != 0)) {
+    if (not(smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0)) {
       mailbox = process->mailbox();
-    } else if (((flags_ & MPI_REQ_RMA) != 0) || static_cast<int>(size_) < async_small_thresh) { // eager mode
+    } else if (((flags_ & MPI_REQ_RMA) != 0) || static_cast<int>(size_) < smpi_cfg_async_small_thresh()) { // eager mode
       mailbox = process->mailbox();
       XBT_DEBUG("Is there a corresponding recv already posted in the large mailbox %s?", mailbox->get_cname());
       smx_activity_t action = mailbox->iprobe(1, &match_send, static_cast<void*>(this));
@@ -526,7 +522,7 @@ void Request::start()
           smpi_process()->get_tracing_category());
     }
 
-    if (async_small_thresh != 0 || ((flags_ & MPI_REQ_RMA) != 0))
+    if (smpi_cfg_async_small_thresh() != 0 || ((flags_ & MPI_REQ_RMA) != 0))
       mut->unlock();
   }
 }
@@ -605,7 +601,7 @@ int Request::test(MPI_Request * request, MPI_Status * status, int* flag) {
       nsleeps=1;//reset the number of sleeps we will do next time
       if (*request != MPI_REQUEST_NULL && ((*request)->flags_ & MPI_REQ_PERSISTENT) == 0)
         *request = MPI_REQUEST_NULL;
-    } else if (simgrid::config::get_value<bool>("smpi/grow-injected-times")) {
+    } else if (smpi_cfg_grow_injected_times()) {
       nsleeps++;
     }
   }
@@ -763,7 +759,7 @@ void Request::iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status*
   // This can speed up the execution of certain applications by an order of magnitude, such as HPL
   static int nsleeps = 1;
   double speed        = s4u::this_actor::get_host()->get_speed();
-  double maxrate      = simgrid::config::get_value<double>("smpi/iprobe-cpu-usage");
+  double maxrate      = smpi_cfg_iprobe_cpu_usage();
   MPI_Request request = new Request(nullptr, 0, MPI_CHAR,
                                     source == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(source)->get_pid(),
                                     simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_PERSISTENT | MPI_REQ_RECV);
@@ -786,7 +782,7 @@ void Request::iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status*
 
   request->print_request("New iprobe");
   // We have to test both mailboxes as we don't know if we will receive one or another
-  if (simgrid::config::get_value<int>("smpi/async-small-thresh") > 0) {
+  if (smpi_cfg_async_small_thresh() > 0) {
     mailbox = smpi_process()->mailbox_small();
     XBT_DEBUG("Trying to probe the perm recv mailbox");
     request->action_ = mailbox->iprobe(0, &match_recv, static_cast<void*>(request));
@@ -812,7 +808,7 @@ void Request::iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status*
   }
   else {
     *flag = 0;
-    if (simgrid::config::get_value<bool>("smpi/grow-injected-times"))
+    if (smpi_cfg_grow_injected_times())
       nsleeps++;
   }
   unref(&request);
@@ -851,7 +847,7 @@ void Request::finish_wait(MPI_Request* request, MPI_Status * status)
       if (((req->flags_ & MPI_REQ_ACCUMULATE) != 0) ||
           (datatype->flags() & DT_FLAG_DERIVED)) { // && (not smpi_is_shared(req->old_buf_))){
 
-        if (not smpi_process()->replaying() && smpi_privatize_global_variables != SmpiPrivStrategies::NONE &&
+        if (not smpi_process()->replaying() && smpi_cfg_privatization() != SmpiPrivStrategies::NONE &&
             static_cast<char*>(req->old_buf_) >= smpi_data_exe_start &&
             static_cast<char*>(req->old_buf_) < smpi_data_exe_start + smpi_data_exe_size) {
           XBT_VERB("Privatization : We are unserializing to a zone in global memory  Switch data segment ");
index bbafaa5..a709fd7 100644 (file)
@@ -100,6 +100,7 @@ set(SMPI_SRC
   src/smpi/internals/smpi_replay.cpp
   src/smpi/internals/smpi_actor.cpp
   src/smpi/internals/smpi_utils.cpp
+  src/smpi/internals/smpi_config.cpp
   src/smpi/mpi/smpi_comm.cpp
   src/smpi/mpi/smpi_datatype.cpp
   src/smpi/mpi/smpi_datatype_derived.cpp
@@ -117,6 +118,7 @@ set(SMPI_SRC
   src/smpi/include/smpi_actor.hpp
   src/smpi/include/smpi_coll.hpp
   src/smpi/include/smpi_comm.hpp
+  src/smpi/include/smpi_config.hpp
   src/smpi/include/smpi_datatype_derived.hpp
   src/smpi/include/smpi_datatype.hpp
   src/smpi/include/smpi_errhandler.hpp