: Exception(XBT_THROW_POINT, xbt::string_printf("Parse error at %s:%d: %s", file.c_str(), line, msg.c_str()))
{
}
+ ParseError(const std::string& msg) : Exception(XBT_THROW_POINT, xbt::string_printf("Parse error: %s", msg.c_str())) {}
ParseError(const ParseError&) = default;
ParseError(ParseError&&) noexcept = default;
~ParseError();
--- /dev/null
+/* Copyright (c) 2007-2020. 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 SIMGRID_XBT_PARSE_UNITS_HPP
+#define SIMGRID_XBT_PARSE_UNITS_HPP
+
+double xbt_parse_get_time(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name);
+double surf_parse_get_size(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name);
+double xbt_parse_get_bandwidth(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name);
+std::vector<double> xbt_parse_get_bandwidths(const std::string& filename, int lineno, const char* string,
+ const char* entity_kind, const std::string& name);
+double xbt_parse_get_speed(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name);
+std::vector<double> xbt_parse_get_all_speeds(const std::string& filename, int lineno, char* speeds,
+ const char* entity_kind, const std::string& id);
+
+#endif
#include "src/surf/network_interface.hpp"
#include "src/surf/surf_private.hpp"
#include "src/surf/xml/platf_private.hpp"
+#include "xbt/parse_units.hpp"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
int console_add_backbone(lua_State *L) {
simgrid::kernel::routing::LinkCreationArgs link;
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
link.properties = nullptr;
type = lua_gettable(L, -2);
lua_ensure(type == LUA_TSTRING || type == LUA_TNUMBER,
"Attribute 'bandwidth' must be specified for backbone and must either be a string (in the right format; see docs) or a number.");
- link.bandwidths.push_back(surf_parse_get_bandwidth(lua_tostring(L, -1), "bandwidth of backbone", link.id.c_str()));
+ link.bandwidths.push_back(xbt_parse_get_bandwidth(ar.short_src, ar.currentline, lua_tostring(L, -1),
+ "bandwidth of backbone", link.id.c_str()));
lua_pop(L, 1);
lua_pushstring(L, "lat");
type = lua_gettable(L, -2);
lua_ensure(type == LUA_TSTRING || type == LUA_TNUMBER,
"Attribute 'lat' must be specified for backbone and must either be a string (in the right format; see docs) or a number.");
- link.latency = surf_parse_get_time(lua_tostring(L, -1), "latency of backbone", link.id.c_str());
+ link.latency =
+ xbt_parse_get_time(ar.short_src, ar.currentline, lua_tostring(L, -1), "latency of backbone", link.id.c_str());
lua_pop(L, 1);
lua_pushstring(L, "sharing_policy");
int console_add_host(lua_State *L) {
simgrid::kernel::routing::HostCreationArgs host;
int type;
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
// we get values from the table passed as argument
lua_ensure(lua_istable(L, -1),
if (type == LUA_TNUMBER)
host.speed_per_pstate.push_back(lua_tointeger(L, -1));
else // LUA_TSTRING
- host.speed_per_pstate.push_back(surf_parse_get_speed(lua_tostring(L, -1), "speed of host", host.id));
+ host.speed_per_pstate.push_back(
+ xbt_parse_get_speed(ar.short_src, ar.currentline, lua_tostring(L, -1), "speed of host", host.id));
lua_pop(L, 1);
// get core
int console_add_link(lua_State *L) {
simgrid::kernel::routing::LinkCreationArgs link;
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
const char* policy;
if (type == LUA_TNUMBER)
link.bandwidths.push_back(lua_tonumber(L, -1));
else // LUA_TSTRING
- link.bandwidths.push_back(surf_parse_get_bandwidth(lua_tostring(L, -1), "bandwidth of link", link.id.c_str()));
+ link.bandwidths.push_back(xbt_parse_get_bandwidth(ar.short_src, ar.currentline, lua_tostring(L, -1),
+ "bandwidth of link", link.id.c_str()));
lua_pop(L, 1);
//get latency value
if (type == LUA_TNUMBER)
link.latency = lua_tonumber(L, -1);
else // LUA_TSTRING
- link.latency = surf_parse_get_time(lua_tostring(L, -1), "latency of link", link.id.c_str());
+ link.latency =
+ xbt_parse_get_time(ar.short_src, ar.currentline, lua_tostring(L, -1), "latency of link", link.id.c_str());
lua_pop(L, 1);
/*Optional Arguments */
#include "src/surf/HostImpl.hpp"
#include "src/surf/xml/platf_private.hpp"
#include "xbt/config.hpp"
+#include "xbt/parse_units.hpp"
#include <algorithm>
#include <boost/algorithm/string.hpp>
FileSystemDiskExt::FileSystemDiskExt(const Disk* ptr)
{
const char* size_str = ptr->get_property("size");
+ std::string dummyfile;
if (size_str)
- size_ = surf_parse_get_size(size_str, "disk size", ptr->get_name());
+ size_ = surf_parse_get_size(dummyfile, -1, size_str, "disk size", ptr->get_name());
const char* current_mount_str = ptr->get_property("mount");
if (current_mount_str)
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "smpi_utils.hpp"
+
+#include "src/surf/xml/platf_private.hpp"
#include "xbt/log.h"
+#include "xbt/parse_units.hpp"
#include "xbt/sysdep.h"
#include <boost/tokenizer.hpp>
-#include "src/surf/xml/platf_private.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_utils, smpi, "Logging specific to SMPI (utils)");
+extern std::string& surf_parsed_filename;
+extern int surf_parse_lineno;
+
std::vector<s_smpi_factor_t> parse_factor(const std::string& smpi_coef_string)
{
std::vector<s_smpi_factor_t> smpi_factor;
}
} else {
try {
- fact.values.push_back(surf_parse_get_time((*factor_iter).c_str(), "smpi factor", ""));
+ fact.values.push_back(
+ xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, (*factor_iter).c_str(), "smpi factor", ""));
} catch (const std::invalid_argument&) {
throw std::invalid_argument(std::string("Invalid factor value ") + std::to_string(iteration) + " in chunk " +
std::to_string(smpi_factor.size() + 1) + ": " + *factor_iter);
StorageModel& operator=(const StorageModel&) = delete;
~StorageModel();
- virtual StorageImpl* createStorage(const std::string& id, const std::string& type_id, const std::string& content_name,
+ virtual StorageImpl* createStorage(std::string& filename, int lineno, const std::string& id,
+ const std::string& type_id, const std::string& content_name,
const std::string& attach) = 0;
};
storage->id.c_str(), stype->model.c_str(), stype->id.c_str(), storage->content.c_str(),
storage->properties);
- auto s = surf_storage_model->createStorage(storage->id, stype->id, storage->content, storage->attach);
+ auto s = surf_storage_model->createStorage(storage->filename, storage->lineno, storage->id, stype->id,
+ storage->content, storage->attach);
if (storage->properties) {
s->set_properties(*storage->properties);
#include "src/kernel/lmm/maxmin.hpp"
#include "src/surf/xml/platf.hpp"
#include "surf/surf.hpp"
+#include "xbt/parse_units.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_storage);
all_existing_models.push_back(this);
}
-StorageImpl* StorageN11Model::createStorage(const std::string& id, const std::string& type_id,
- const std::string& content_name, const std::string& attach)
+StorageImpl* StorageN11Model::createStorage(std::string& filename, int lineno, const std::string& id,
+ const std::string& type_id, const std::string& content_name,
+ const std::string& attach)
{
const StorageType* storage_type = storage_types.at(type_id);
- double Bread =
- surf_parse_get_bandwidth(storage_type->model_properties->at("Bread").c_str(), "property Bread, storage", type_id);
- double Bwrite = surf_parse_get_bandwidth(storage_type->model_properties->at("Bwrite").c_str(),
- "property Bwrite, storage", type_id);
+ double Bread = xbt_parse_get_bandwidth(filename, lineno, storage_type->model_properties->at("Bread").c_str(),
+ "property Bread, storage", type_id);
+ double Bwrite = xbt_parse_get_bandwidth(filename, lineno, storage_type->model_properties->at("Bwrite").c_str(),
+ "property Bwrite, storage", type_id);
XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s'\n\t\tBread '%f'\n", id.c_str(), type_id.c_str(),
Bread);
class StorageN11Model : public StorageModel {
public:
StorageN11Model();
- StorageImpl* createStorage(const std::string& id, const std::string& type_id, const std::string& content_name,
- const std::string& attach) override;
+ StorageImpl* createStorage(std::string& filename, int lineno, const std::string& id, const std::string& type_id,
+ const std::string& content_name, const std::string& attach) override;
double next_occurring_event(double now) override;
void update_actions_state(double now, double delta) override;
};
XBT_PUBLIC double surf_parse_get_double(const std::string& s);
XBT_PUBLIC int surf_parse_get_int(const std::string& s);
-XBT_PUBLIC double surf_parse_get_time(const char* string, const char* entity_kind, const std::string& name);
-XBT_PUBLIC double surf_parse_get_size(const char* string, const char* entity_kind, const std::string& name);
-XBT_PUBLIC double surf_parse_get_bandwidth(const char* string, const char* entity_kind, const std::string& name);
-XBT_PUBLIC std::vector<double> surf_parse_get_bandwidths(const char* string, const char* entity_kind,
- const std::string& name);
-XBT_PUBLIC double surf_parse_get_speed(const char* string, const char* entity_kind, const std::string& name);
XBT_PUBLIC void surf_parse(); /* Entry-point to the parser */
class StorageCreationArgs {
public:
+ std::string filename;
+ int lineno;
std::string id;
std::string type_id;
std::string content;
#include "src/surf/xml/platf_private.hpp"
#include "surf/surf.hpp"
#include "xbt/file.hpp"
+#include "xbt/parse_units.hpp"
-#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <string>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_parse, surf, "Logging specific to the SURF parsing module");
-static std::string surf_parsed_filename; // Currently parsed file (for the error messages)
+std::string surf_parsed_filename; // Currently parsed file (for the error messages)
std::vector<simgrid::kernel::resource::LinkImpl*>
parsed_link_list; /* temporary store of current link list of a route */
std::vector<simgrid::kernel::resource::DiskImpl*> parsed_disk_list; /* temporary store of current disk list of a host */
}
}
-namespace {
-
/* Turn something like "1-4,6,9-11" into the vector {1,2,3,4,6,9,10,11} */
-std::vector<int>* explodesRadical(const std::string& radicals)
+static std::vector<int>* explodesRadical(const std::string& radicals)
{
std::vector<int>* exploded = new std::vector<int>();
return exploded;
}
-class unit_scale : public std::unordered_map<std::string, double> {
-public:
- using std::unordered_map<std::string, double>::unordered_map;
- // tuples are : <unit, value for unit, base (2 or 10), true if abbreviated>
- explicit unit_scale(std::initializer_list<std::tuple<const std::string, double, int, bool>> generators);
-};
-
-unit_scale::unit_scale(std::initializer_list<std::tuple<const std::string, double, int, bool>> generators)
-{
- for (const auto& gen : generators) {
- const std::string& unit = std::get<0>(gen);
- double value = std::get<1>(gen);
- const int base = std::get<2>(gen);
- const bool abbrev = std::get<3>(gen);
- double mult;
- std::vector<std::string> prefixes;
- switch (base) {
- case 2:
- mult = 1024.0;
- prefixes = abbrev ? std::vector<std::string>{"Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"}
- : std::vector<std::string>{"kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"};
- break;
- case 10:
- mult = 1000.0;
- prefixes = abbrev ? std::vector<std::string>{"k", "M", "G", "T", "P", "E", "Z", "Y"}
- : std::vector<std::string>{"kilo", "mega", "giga", "tera", "peta", "exa", "zeta", "yotta"};
- break;
- default:
- THROW_IMPOSSIBLE;
- }
- emplace(unit, value);
- for (const auto& prefix : prefixes) {
- value *= mult;
- emplace(prefix + unit, value);
- }
- }
-}
-
-/* Note: no warning is issued for unit-less values when `name' is empty. */
-double surf_parse_get_value_with_unit(const char* string, const unit_scale& units, const char* entity_kind,
- const std::string& name, const char* error_msg, const char* default_unit)
-{
- char* endptr;
- errno = 0;
- double res = strtod(string, &endptr);
- const char* ptr = endptr; // for const-correctness
- if (errno == ERANGE)
- surf_parse_error(std::string("value out of range: ") + string);
- if (ptr == string)
- surf_parse_error(std::string("cannot parse number:") + string);
- if (ptr[0] == '\0') {
- // Ok, 0 can be unit-less
- if (res != 0 && not name.empty())
- XBT_WARN("Deprecated unit-less value '%s' for %s %s. %s", string, entity_kind, name.c_str(), error_msg);
- ptr = default_unit;
- }
- auto u = units.find(ptr);
- if (u == units.end())
- surf_parse_error(std::string("unknown unit: ") + ptr);
- return res * u->second;
-}
-}
-
-double surf_parse_get_time(const char* string, const char* entity_kind, const std::string& name)
-{
- static const unit_scale units{std::make_pair("w", 7 * 24 * 60 * 60),
- std::make_pair("d", 24 * 60 * 60),
- std::make_pair("h", 60 * 60),
- std::make_pair("m", 60),
- std::make_pair("s", 1.0),
- std::make_pair("ms", 1e-3),
- std::make_pair("us", 1e-6),
- std::make_pair("ns", 1e-9),
- std::make_pair("ps", 1e-12)};
- return surf_parse_get_value_with_unit(string, units, entity_kind, name,
- "Append 's' to your time to get seconds", "s");
-}
-
-double surf_parse_get_size(const char* string, const char* entity_kind, const std::string& name)
-{
- static const unit_scale units{std::make_tuple("b", 0.125, 2, true), std::make_tuple("b", 0.125, 10, true),
- std::make_tuple("B", 1.0, 2, true), std::make_tuple("B", 1.0, 10, true)};
- return surf_parse_get_value_with_unit(string, units, entity_kind, name,
- "Append 'B' to get bytes (or 'b' for bits but 1B = 8b).", "B");
-}
-
-double surf_parse_get_bandwidth(const char* string, const char* entity_kind, const std::string& name)
-{
- static const unit_scale units{std::make_tuple("bps", 0.125, 2, true), std::make_tuple("bps", 0.125, 10, true),
- std::make_tuple("Bps", 1.0, 2, true), std::make_tuple("Bps", 1.0, 10, true)};
- return surf_parse_get_value_with_unit(string, units, entity_kind, name,
- "Append 'Bps' to get bytes per second (or 'bps' for bits but 1Bps = 8bps)", "Bps");
-}
-
-std::vector<double> surf_parse_get_bandwidths(const char* string, const char* entity_kind, const std::string& name)
-{
- static const unit_scale units{std::make_tuple("bps", 0.125, 2, true), std::make_tuple("bps", 0.125, 10, true),
- std::make_tuple("Bps", 1.0, 2, true), std::make_tuple("Bps", 1.0, 10, true)};
-
- std::vector<double> bandwidths;
- std::vector<std::string> tokens;
- boost::split(tokens, string, boost::is_any_of(";"));
- for (auto token : tokens) {
- bandwidths.push_back(surf_parse_get_value_with_unit(
- token.c_str(), units, entity_kind, name,
- "Append 'Bps' to get bytes per second (or 'bps' for bits but 1Bps = 8bps)", "Bps"));
- }
-
- return bandwidths;
-}
-
-double surf_parse_get_speed(const char* string, const char* entity_kind, const std::string& name)
-{
- static const unit_scale units{std::make_tuple("f", 1.0, 10, true), std::make_tuple("flops", 1.0, 10, false)};
- return surf_parse_get_value_with_unit(string, units, entity_kind, name,
- "Append 'f' or 'flops' to your speed to get flop per second", "f");
-}
-
-static std::vector<double> surf_parse_get_all_speeds(char* speeds, const char* entity_kind, const std::string& id)
-{
- std::vector<double> speed_per_pstate;
-
- if (strchr(speeds, ',') == nullptr){
- double speed = surf_parse_get_speed(speeds, entity_kind, id);
- speed_per_pstate.push_back(speed);
- } else {
- std::vector<std::string> pstate_list;
- boost::split(pstate_list, speeds, boost::is_any_of(","));
- for (auto speed_str : pstate_list) {
- boost::trim(speed_str);
- double speed = surf_parse_get_speed(speed_str.c_str(), entity_kind, id);
- speed_per_pstate.push_back(speed);
- XBT_DEBUG("Speed value: %f", speed);
- }
- }
- return speed_per_pstate;
-}
/*
* All the callback lists that can be overridden anywhere.
storage.properties = property_sets.back();
property_sets.pop_back();
+ storage.filename = surf_parsed_filename;
+ storage.lineno = surf_parse_lineno;
storage.id = A_surfxml_storage_id;
storage.type_id = A_surfxml_storage_typeId;
storage.content = A_surfxml_storage_content;
storage_type.content = A_surfxml_storage___type_content;
storage_type.id = A_surfxml_storage___type_id;
storage_type.model = A_surfxml_storage___type_model;
- storage_type.size =
- surf_parse_get_size(A_surfxml_storage___type_size, "size of storage type", storage_type.id.c_str());
+ storage_type.size = surf_parse_get_size(surf_parsed_filename, surf_parse_lineno, A_surfxml_storage___type_size,
+ "size of storage type", storage_type.id.c_str());
sg_platf_new_storage_type(&storage_type);
}
host.id = A_surfxml_host_id;
- host.speed_per_pstate = surf_parse_get_all_speeds(A_surfxml_host_speed, "speed of host", host.id);
+ host.speed_per_pstate =
+ xbt_parse_get_all_speeds(surf_parsed_filename, surf_parse_lineno, A_surfxml_host_speed, "speed of host", host.id);
XBT_DEBUG("pstate: %s", A_surfxml_host_pstate);
host.core_amount = surf_parse_get_int(A_surfxml_host_core);
property_sets.pop_back();
disk.id = A_surfxml_disk_id;
- disk.read_bw = surf_parse_get_bandwidth(A_surfxml_disk_read___bw, "read_bw of disk ", disk.id);
- disk.write_bw = surf_parse_get_bandwidth(A_surfxml_disk_write___bw, "write_bw of disk ", disk.id);
+ disk.read_bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_disk_read___bw,
+ "read_bw of disk ", disk.id);
+ disk.write_bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_disk_write___bw,
+ "write_bw of disk ", disk.id);
parsed_disk_list.push_back(sg_platf_new_disk(&disk));
}
cluster.prefix = A_surfxml_cluster_prefix;
cluster.suffix = A_surfxml_cluster_suffix;
cluster.radicals = explodesRadical(A_surfxml_cluster_radical);
- cluster.speeds = surf_parse_get_all_speeds(A_surfxml_cluster_speed, "speed of cluster", cluster.id);
+ cluster.speeds = xbt_parse_get_all_speeds(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_speed,
+ "speed of cluster", cluster.id);
cluster.core_amount = surf_parse_get_int(A_surfxml_cluster_core);
- cluster.bw = surf_parse_get_bandwidth(A_surfxml_cluster_bw, "bw of cluster", cluster.id);
- cluster.lat = surf_parse_get_time(A_surfxml_cluster_lat, "lat of cluster", cluster.id);
+ cluster.bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_bw, "bw of cluster",
+ cluster.id);
+ cluster.lat =
+ xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_lat, "lat of cluster", cluster.id);
if(strcmp(A_surfxml_cluster_bb___bw,""))
- cluster.bb_bw = surf_parse_get_bandwidth(A_surfxml_cluster_bb___bw, "bb_bw of cluster", cluster.id);
+ cluster.bb_bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_bb___bw,
+ "bb_bw of cluster", cluster.id);
if(strcmp(A_surfxml_cluster_bb___lat,""))
- cluster.bb_lat = surf_parse_get_time(A_surfxml_cluster_bb___lat, "bb_lat of cluster", cluster.id);
+ cluster.bb_lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_bb___lat,
+ "bb_lat of cluster", cluster.id);
if(strcmp(A_surfxml_cluster_limiter___link,""))
- cluster.limiter_link = surf_parse_get_bandwidth(A_surfxml_cluster_limiter___link, "limiter_link of cluster", cluster.id);
+ cluster.limiter_link =
+ xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_limiter___link,
+ "limiter_link of cluster", cluster.id);
if(strcmp(A_surfxml_cluster_loopback___bw,""))
- cluster.loopback_bw = surf_parse_get_bandwidth(A_surfxml_cluster_loopback___bw, "loopback_bw of cluster", cluster.id);
+ cluster.loopback_bw = xbt_parse_get_bandwidth(
+ surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_loopback___bw, "loopback_bw of cluster", cluster.id);
if(strcmp(A_surfxml_cluster_loopback___lat,""))
- cluster.loopback_lat = surf_parse_get_time(A_surfxml_cluster_loopback___lat, "loopback_lat of cluster", cluster.id);
+ cluster.loopback_lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_loopback___lat,
+ "loopback_lat of cluster", cluster.id);
switch(AX_surfxml_cluster_topology){
case A_surfxml_cluster_topology_FLAT:
cabinet.id = A_surfxml_cabinet_id;
cabinet.prefix = A_surfxml_cabinet_prefix;
cabinet.suffix = A_surfxml_cabinet_suffix;
- cabinet.speed = surf_parse_get_speed(A_surfxml_cabinet_speed, "speed of cabinet", cabinet.id.c_str());
- cabinet.bw = surf_parse_get_bandwidth(A_surfxml_cabinet_bw, "bw of cabinet", cabinet.id.c_str());
- cabinet.lat = surf_parse_get_time(A_surfxml_cabinet_lat, "lat of cabinet", cabinet.id.c_str());
+ cabinet.speed = xbt_parse_get_speed(surf_parsed_filename, surf_parse_lineno, A_surfxml_cabinet_speed,
+ "speed of cabinet", cabinet.id.c_str());
+ cabinet.bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cabinet_bw, "bw of cabinet",
+ cabinet.id.c_str());
+ cabinet.lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cabinet_lat, "lat of cabinet",
+ cabinet.id.c_str());
cabinet.radicals = explodesRadical(A_surfxml_cabinet_radical);
sg_platf_new_cabinet(&cabinet);
simgrid::kernel::routing::PeerCreationArgs peer;
peer.id = std::string(A_surfxml_peer_id);
- peer.speed = surf_parse_get_speed(A_surfxml_peer_speed, "speed of peer", peer.id.c_str());
- peer.bw_in = surf_parse_get_bandwidth(A_surfxml_peer_bw___in, "bw_in of peer", peer.id.c_str());
- peer.bw_out = surf_parse_get_bandwidth(A_surfxml_peer_bw___out, "bw_out of peer", peer.id.c_str());
+ peer.speed = xbt_parse_get_speed(surf_parsed_filename, surf_parse_lineno, A_surfxml_peer_speed, "speed of peer",
+ peer.id.c_str());
+ peer.bw_in = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_peer_bw___in, "bw_in of peer",
+ peer.id.c_str());
+ peer.bw_out = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_peer_bw___out,
+ "bw_out of peer", peer.id.c_str());
peer.coord = A_surfxml_peer_coordinates;
peer.speed_trace = nullptr;
if (A_surfxml_peer_availability___file[0] != '\0') {
property_sets.pop_back();
link.id = std::string(A_surfxml_link_id);
- link.bandwidths = surf_parse_get_bandwidths(A_surfxml_link_bandwidth, "bandwidth of link", link.id.c_str());
+ link.bandwidths = xbt_parse_get_bandwidths(surf_parsed_filename, surf_parse_lineno, A_surfxml_link_bandwidth,
+ "bandwidth of link", link.id.c_str());
link.bandwidth_trace = A_surfxml_link_bandwidth___file[0]
? simgrid::kernel::profile::Profile::from_file(A_surfxml_link_bandwidth___file)
: nullptr;
- link.latency = surf_parse_get_time(A_surfxml_link_latency, "latency of link", link.id.c_str());
+ link.latency = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_link_latency, "latency of link",
+ link.id.c_str());
link.latency_trace = A_surfxml_link_latency___file[0]
? simgrid::kernel::profile::Profile::from_file(A_surfxml_link_latency___file)
: nullptr;
link.properties = nullptr;
link.id = std::string(A_surfxml_backbone_id);
- link.bandwidths.push_back(
- surf_parse_get_bandwidth(A_surfxml_backbone_bandwidth, "bandwidth of backbone", link.id.c_str()));
- link.latency = surf_parse_get_time(A_surfxml_backbone_latency, "latency of backbone", link.id.c_str());
+ link.bandwidths.push_back(xbt_parse_get_bandwidth(
+ surf_parsed_filename, surf_parse_lineno, A_surfxml_backbone_bandwidth, "bandwidth of backbone", link.id.c_str()));
+ link.latency = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_backbone_latency,
+ "latency of backbone", link.id.c_str());
link.policy = simgrid::s4u::Link::SharingPolicy::SHARED;
sg_platf_new_link(&link);
--- /dev/null
+#include "simgrid/Exception.hpp"
+#include "xbt/ex.h"
+#include "xbt/log.h"
+
+#include "xbt/parse_units.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(parse, xbt, "Parsing functions");
+
+class unit_scale : public std::unordered_map<std::string, double> {
+public:
+ using std::unordered_map<std::string, double>::unordered_map;
+ // tuples are : <unit, value for unit, base (2 or 10), true if abbreviated>
+ explicit unit_scale(std::initializer_list<std::tuple<const std::string, double, int, bool>> generators);
+};
+
+unit_scale::unit_scale(std::initializer_list<std::tuple<const std::string, double, int, bool>> generators)
+{
+ for (const auto& gen : generators) {
+ const std::string& unit = std::get<0>(gen);
+ double value = std::get<1>(gen);
+ const int base = std::get<2>(gen);
+ const bool abbrev = std::get<3>(gen);
+ double mult;
+ std::vector<std::string> prefixes;
+ switch (base) {
+ case 2:
+ mult = 1024.0;
+ prefixes = abbrev ? std::vector<std::string>{"Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"}
+ : std::vector<std::string>{"kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"};
+ break;
+ case 10:
+ mult = 1000.0;
+ prefixes = abbrev ? std::vector<std::string>{"k", "M", "G", "T", "P", "E", "Z", "Y"}
+ : std::vector<std::string>{"kilo", "mega", "giga", "tera", "peta", "exa", "zeta", "yotta"};
+ break;
+ default:
+ THROW_IMPOSSIBLE;
+ }
+ emplace(unit, value);
+ for (const auto& prefix : prefixes) {
+ value *= mult;
+ emplace(prefix + unit, value);
+ }
+ }
+}
+
+/* Note: no warning is issued for unit-less values when `name' is empty. */
+static double surf_parse_get_value_with_unit(const std::string& filename, int lineno, const char* string,
+ const unit_scale& units, const char* entity_kind, const std::string& name,
+ const char* error_msg, const char* default_unit)
+{
+ char* endptr;
+ errno = 0;
+ double res = strtod(string, &endptr);
+ const char* ptr = endptr; // for const-correctness
+ if (errno == ERANGE)
+ throw simgrid::ParseError(filename, lineno, std::string("value out of range: ") + string);
+ if (ptr == string)
+ throw simgrid::ParseError(filename, lineno, std::string("cannot parse number:") + string);
+ if (ptr[0] == '\0') {
+ // Ok, 0 can be unit-less
+ if (res != 0 && not name.empty())
+ XBT_WARN("Deprecated unit-less value '%s' for %s %s. %s", string, entity_kind, name.c_str(), error_msg);
+ ptr = default_unit;
+ }
+ auto u = units.find(ptr);
+ if (u == units.end())
+ throw simgrid::ParseError(filename, lineno, std::string("unknown unit: ") + ptr);
+ return res * u->second;
+}
+
+double xbt_parse_get_time(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name)
+{
+ static const unit_scale units{std::make_pair("w", 7 * 24 * 60 * 60),
+ std::make_pair("d", 24 * 60 * 60),
+ std::make_pair("h", 60 * 60),
+ std::make_pair("m", 60),
+ std::make_pair("s", 1.0),
+ std::make_pair("ms", 1e-3),
+ std::make_pair("us", 1e-6),
+ std::make_pair("ns", 1e-9),
+ std::make_pair("ps", 1e-12)};
+ return surf_parse_get_value_with_unit(filename, lineno, string, units, entity_kind, name,
+ "Append 's' to your time to get seconds", "s");
+}
+
+double surf_parse_get_size(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name)
+{
+ static const unit_scale units{std::make_tuple("b", 0.125, 2, true), std::make_tuple("b", 0.125, 10, true),
+ std::make_tuple("B", 1.0, 2, true), std::make_tuple("B", 1.0, 10, true)};
+ return surf_parse_get_value_with_unit(filename, lineno, string, units, entity_kind, name,
+ "Append 'B' to get bytes (or 'b' for bits but 1B = 8b).", "B");
+}
+
+double xbt_parse_get_bandwidth(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name)
+{
+ static const unit_scale units{std::make_tuple("bps", 0.125, 2, true), std::make_tuple("bps", 0.125, 10, true),
+ std::make_tuple("Bps", 1.0, 2, true), std::make_tuple("Bps", 1.0, 10, true)};
+ return surf_parse_get_value_with_unit(filename, lineno, string, units, entity_kind, name,
+ "Append 'Bps' to get bytes per second (or 'bps' for bits but 1Bps = 8bps)",
+ "Bps");
+}
+
+std::vector<double> xbt_parse_get_bandwidths(const std::string& filename, int lineno, const char* string,
+ const char* entity_kind, const std::string& name)
+{
+ static const unit_scale units{std::make_tuple("bps", 0.125, 2, true), std::make_tuple("bps", 0.125, 10, true),
+ std::make_tuple("Bps", 1.0, 2, true), std::make_tuple("Bps", 1.0, 10, true)};
+
+ std::vector<double> bandwidths;
+ std::vector<std::string> tokens;
+ boost::split(tokens, string, boost::is_any_of(";"));
+ for (auto token : tokens) {
+ bandwidths.push_back(surf_parse_get_value_with_unit(
+ filename, lineno, token.c_str(), units, entity_kind, name,
+ "Append 'Bps' to get bytes per second (or 'bps' for bits but 1Bps = 8bps)", "Bps"));
+ }
+
+ return bandwidths;
+}
+
+double xbt_parse_get_speed(const std::string& filename, int lineno, const char* string, const char* entity_kind,
+ const std::string& name)
+{
+ static const unit_scale units{std::make_tuple("f", 1.0, 10, true), std::make_tuple("flops", 1.0, 10, false)};
+ return surf_parse_get_value_with_unit(filename, lineno, string, units, entity_kind, name,
+ "Append 'f' or 'flops' to your speed to get flop per second", "f");
+}
+
+std::vector<double> xbt_parse_get_all_speeds(const std::string& filename, int lineno, char* speeds,
+ const char* entity_kind, const std::string& id)
+{
+ std::vector<double> speed_per_pstate;
+
+ if (strchr(speeds, ',') == nullptr) {
+ double speed = xbt_parse_get_speed(filename, lineno, speeds, entity_kind, id);
+ speed_per_pstate.push_back(speed);
+ } else {
+ std::vector<std::string> pstate_list;
+ boost::split(pstate_list, speeds, boost::is_any_of(","));
+ for (auto speed_str : pstate_list) {
+ boost::trim(speed_str);
+ double speed = xbt_parse_get_speed(filename, lineno, speed_str.c_str(), entity_kind, id);
+ speed_per_pstate.push_back(speed);
+ XBT_DEBUG("Speed value: %f", speed);
+ }
+ }
+ return speed_per_pstate;
+}
src/xbt/xbt_main.cpp
src/xbt/xbt_os_file.cpp
src/xbt/xbt_os_time.c
+ src/xbt/xbt_parse_units.cpp
src/xbt/xbt_replay.cpp
src/xbt/xbt_str.cpp
src/xbt/xbt_virtu.cpp
include/xbt/module.h
include/xbt/PropertyHolder.hpp
include/xbt/parmap.h
+ include/xbt/parse_units.hpp
include/xbt/range.hpp
include/xbt/random.hpp
include/xbt/replay.hpp