Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Introduce class simgrid::smpi::utils::FactorSet to reduce code dupplication
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sat, 22 Oct 2022 16:59:39 +0000 (18:59 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sat, 22 Oct 2022 16:59:39 +0000 (18:59 +0200)
src/smpi/include/smpi_utils.hpp
src/smpi/internals/smpi_utils.cpp
src/surf/network_smpi.cpp

index 99ff9c7..cf44119 100644 (file)
@@ -23,6 +23,27 @@ struct s_smpi_factor_t {
 
 namespace simgrid::smpi::utils {
 
+class FactorSet {
+  const std::string& name_;
+  std::vector<s_smpi_factor_t> factors_;
+  double default_value_;
+  const std::function<double(s_smpi_factor_t const&)> lambda_;
+  bool initialized_ = false;
+
+public:
+  // Parse the factor from a string
+  FactorSet(
+      const std::string& name, double default_value = 1,
+      std::function<double(s_smpi_factor_t const&)> const& lambda = [](s_smpi_factor_t const& factor) {
+        return factor.values.front();
+      });
+  void parse(const std::string& values);
+  bool is_initialized() const { return initialized_; }
+  // Get the default factor, the one that is not a function of the size
+  double operator()();
+  // Get the factor to use for the provided size
+  double operator()(double size);
+};
 XBT_PUBLIC std::vector<s_smpi_factor_t> parse_factor(const std::string& smpi_coef_string);
 XBT_PUBLIC void add_benched_time(double time);
 XBT_PUBLIC void account_malloc_size(size_t size, std::string_view file, int line, const void* ptr);
index 967e729..b7f5a80 100644 (file)
@@ -49,6 +49,48 @@ std::unordered_map<const void*, alloc_metadata_t> allocs;
 
 std::unordered_map<int, std::vector<std::string>> collective_calls;
 
+void FactorSet::parse(const std::string& values)
+{
+  factors_     = parse_factor(values);
+  initialized_ = true;
+}
+
+FactorSet::FactorSet(const std::string& name, double default_value,
+                     std::function<double(s_smpi_factor_t const&)> const& lambda)
+    : name_(name), default_value_(default_value), lambda_(lambda)
+{
+}
+
+double FactorSet::operator()()
+{
+  return lambda_(factors_.front());
+}
+
+double FactorSet::operator()(double size)
+{
+  if (factors_.empty())
+    return default_value_;
+
+  for (long unsigned i = 0; i < factors_.size(); i++) {
+    auto const& fact = factors_[i];
+
+    if (size <= fact.factor) { // Too large already, use the previous value
+
+      if (i == 0) { // Before the first boundary: use the default value
+        XBT_DEBUG("%s: %f <= %zu return default %f", name_.c_str(), size, fact.factor, default_value_);
+        return default_value_;
+      }
+      double val = lambda_(factors_[i - 1]);
+      XBT_DEBUG("%s: %f <= %zu return %f", name_.c_str(), size, fact.factor, val);
+      return val;
+    }
+  }
+  double val = lambda_(factors_.back());
+
+  XBT_DEBUG("%s: %f > %zu return %f", name_.c_str(), size, factors_.back().factor, val);
+  return val;
+}
+
 std::vector<s_smpi_factor_t> parse_factor(const std::string& smpi_coef_string)
 {
   std::vector<s_smpi_factor_t> smpi_factor;
index 02d6a00..3e47a60 100644 (file)
@@ -59,39 +59,19 @@ void NetworkSmpiModel::check_bw_factor_cb()
 
 double NetworkSmpiModel::get_bandwidth_factor(double size)
 {
-  static std::vector<s_smpi_factor_t> smpi_bw_factor;
-  if (smpi_bw_factor.empty())
-    smpi_bw_factor = smpi::utils::parse_factor(config::get_value<std::string>("smpi/bw-factor"));
+  static smpi::utils::FactorSet smpi_bw_factor("smpi/bw-factor");
+  if (not smpi_bw_factor.is_initialized())
+    smpi_bw_factor.parse(config::get_value<std::string>("smpi/bw-factor"));
 
-  double current = 1.0;
-  for (auto const& fact : smpi_bw_factor) {
-    if (size <= fact.factor) {
-      XBT_DEBUG("%f <= %zu return %f", size, fact.factor, current);
-      return current;
-    } else
-      current = fact.values.front();
-  }
-  XBT_DEBUG("%f > %zu return %f", size, smpi_bw_factor.back().factor, current);
-
-  return current;
+  return smpi_bw_factor(size);
 }
 
 double NetworkSmpiModel::get_latency_factor(double size)
 {
-  static std::vector<s_smpi_factor_t> smpi_lat_factor;
-  if (smpi_lat_factor.empty())
-    smpi_lat_factor = smpi::utils::parse_factor(config::get_value<std::string>("smpi/lat-factor"));
-
-  double current = 1.0;
-  for (auto const& fact : smpi_lat_factor) {
-    if (size <= fact.factor) {
-      XBT_DEBUG("%f <= %zu return %f", size, fact.factor, current);
-      return current;
-    } else
-      current = fact.values.front();
-  }
-  XBT_DEBUG("%f > %zu return %f", size, smpi_lat_factor.back().factor, current);
+  static smpi::utils::FactorSet smpi_lat_factor("smpi/lat-factor");
+  if (not smpi_lat_factor.is_initialized())
+    smpi_lat_factor.parse(config::get_value<std::string>("smpi/lat-factor"));
 
-  return current;
+  return smpi_lat_factor(size);
 }
 } // namespace simgrid::kernel::resource