#include <xbt/Extendable.hpp>
namespace simgrid::smpi {
-
+static auto factor_lambda(s_smpi_factor_t const& fact, double size)
+{
+ return fact.values[0] + fact.values[1] * static_cast<size_t>(size);
+}
class Host {
- std::vector<s_smpi_factor_t> orecv_parsed_values;
- std::vector<s_smpi_factor_t> osend_parsed_values;
- std::vector<s_smpi_factor_t> oisend_parsed_values;
+ utils::FactorSet orecv_{"smpi/or", 0.0, factor_lambda};
+ utils::FactorSet osend_{"smpi/os", 0.0, factor_lambda};
+ utils::FactorSet oisend_{"smpi/ois", 0.0, factor_lambda};
s4u::Host* host = nullptr;
/**
* @brief Generates warning message if user's config is conflicting (callback vs command line/xml)
const std::string& name_;
std::vector<s_smpi_factor_t> factors_;
double default_value_;
- const std::function<double(s_smpi_factor_t const&)> lambda_;
+ const std::function<double(s_smpi_factor_t const&, double)> 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) {
+ std::function<double(s_smpi_factor_t const&, double)> const& lambda = [](s_smpi_factor_t const& factor, double) {
return factor.values.front();
});
void parse(const std::string& values);
xbt::Extension<s4u::Host, smpi::Host> Host::EXTENSION_ID;
-static double factor_use(std::vector<s_smpi_factor_t>& factors, const char* name, size_t size)
-{
- /* fallback to smpi/or config */
- double current = factors.empty() ? 0.0 : factors.front().values[0] + factors.front().values[1] * size;
-
- // Iterate over all the sections that were specified and find the right value. (fact.factor represents the interval
- // sizes; we want to find the section that has fact.factor <= size and no other such fact.factor <= size)
- // Note: parse_factor() (used before) already sorts the vector we iterate over!
- for (auto const& fact : factors) {
- if (size <= fact.factor) { // Values already too large, use the previously computed value of current!
- XBT_DEBUG("%s: %zu <= %zu return %.10f", name, size, fact.factor, current);
- return current;
- } else {
- // If the next section is too large, the current section must be used.
- // Hence, save the cost, as we might have to use it.
- current=fact.values[0]+fact.values[1]*size;
- }
- }
- XBT_DEBUG("%s: %zu is larger than largest boundary, return %.10f", name, size, current);
-
- return current;
-}
-
double Host::orecv(size_t size, s4u::Host* src, s4u::Host* dst)
{
/* return user's callback if available */
if (auto it = cost_cbs.find(SmpiOperation::RECV); it != cost_cbs.end())
return it->second(size, src, dst);
- return factor_use(orecv_parsed_values, "smpi/or", size);
+ return orecv_(size);
}
double Host::osend(size_t size, s4u::Host* src, s4u::Host* dst)
if (auto it = cost_cbs.find(SmpiOperation::SEND); it != cost_cbs.end())
return it->second(size, src, dst);
- return factor_use(osend_parsed_values, "smpi/os", size);
+ return osend_(size);
}
double Host::oisend(size_t size, s4u::Host* src, s4u::Host* dst)
if (auto it = cost_cbs.find(SmpiOperation::ISEND); it != cost_cbs.end())
return it->second(size, src, dst);
- return factor_use(oisend_parsed_values, "smpi/ois", size);
+ return oisend_(size);
}
void Host::check_factor_configs(const std::string& op) const
smpi::Host::EXTENSION_ID = s4u::Host::extension_create<Host>();
check_factor_configs("smpi/or");
- if (const char* orecv_string = host->get_property("smpi/or")) {
- orecv_parsed_values = simgrid::smpi::utils::parse_factor(orecv_string);
- } else {
- orecv_parsed_values = simgrid::smpi::utils::parse_factor(config::get_value<std::string>("smpi/or"));
- }
+ if (const char* orecv_string = host->get_property("smpi/or"))
+ orecv_.parse(orecv_string);
+ else
+ orecv_.parse(config::get_value<std::string>("smpi/or"));
check_factor_configs("smpi/os");
- if (const char* osend_string = host->get_property("smpi/os")) {
- osend_parsed_values = simgrid::smpi::utils::parse_factor(osend_string);
- } else {
- osend_parsed_values = simgrid::smpi::utils::parse_factor(config::get_value<std::string>("smpi/os"));
- }
+ if (const char* osend_string = host->get_property("smpi/os"))
+ osend_.parse(osend_string);
+ else
+ osend_.parse(config::get_value<std::string>("smpi/os"));
check_factor_configs("smpi/ois");
- if (const char* oisend_string = host->get_property("smpi/ois")) {
- oisend_parsed_values = simgrid::smpi::utils::parse_factor(oisend_string);
- } else {
- oisend_parsed_values = simgrid::smpi::utils::parse_factor(config::get_value<std::string>("smpi/ois"));
- }
+ if (const char* oisend_string = host->get_property("smpi/ois"))
+ oisend_.parse(oisend_string);
+ else
+ oisend_.parse(config::get_value<std::string>("smpi/ois"));
}
} // namespace simgrid::smpi
}
FactorSet::FactorSet(const std::string& name, double default_value,
- std::function<double(s_smpi_factor_t const&)> const& lambda)
+ std::function<double(s_smpi_factor_t const&, double)> const& lambda)
: name_(name), default_value_(default_value), lambda_(lambda)
{
}
double FactorSet::operator()()
{
- return lambda_(factors_.front());
+ return lambda_(factors_.front(), 0);
}
double FactorSet::operator()(double size)
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]);
+ double val = lambda_(factors_[i - 1], size);
XBT_DEBUG("%s: %f <= %zu return %f", name_.c_str(), size, fact.factor, val);
return val;
}
}
- double val = lambda_(factors_.back());
+ double val = lambda_(factors_.back(), size);
XBT_DEBUG("%s: %f > %zu return %f", name_.c_str(), size, factors_.back().factor, val);
return val;