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);
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;
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