- Actor: Merge signals on_migration_start/end into on_host_change
- Actor: Rename migrate() into set_host()
+XML:
+- Parse errors now raise a simgrid::ParseError that you may want to catch.
+
Kernel:
- In simgrid::kernel::resource::Model, the methods next_occuring_event*() have
been renamed to fix a spelling error. As usual, the previous definitions are
#include <xbt/backtrace.hpp>
#include <xbt/ex.h>
+#include <xbt/string.hpp>
#include <atomic>
#include <functional>
}
};
+class XBT_PUBLIC ParseError : public Exception, public std::invalid_argument {
+ int line_;
+ std::string file_;
+ std::string msg_;
+
+public:
+ ParseError(int line, std::string& file, std::string&& msg)
+ : Exception(XBT_THROW_POINT, std::move(msg)), std::invalid_argument(msg), line_(line), file_(file), msg_(msg)
+ {
+ }
+
+ const char* what() const noexcept override
+ {
+ return bprintf("Parse error at %s:%d: %s", file_.c_str(), line_, msg_.c_str());
+ }
+};
+
class XBT_PUBLIC ForcefulKillException {
/** @brief Exception launched to kill an actor; DO NOT BLOCK IT!
*
XBT_PUBLIC_DATA const MPI_Datatype MPI_COUNT;
//defines for fortran compatibility
-#if defined(__alpha__) || defined(__sparc64__) || defined(__x86_64__) || defined(__ia64__)
+#if defined(__alpha__) || defined(__sparc64__) || defined(__x86_64__) || defined(__ia64__) || defined(__aarch64__)
#define MPI_INTEGER MPI_INT
#define MPI_2INTEGER MPI_2INT
#define MPI_LOGICAL MPI_INT
sg_platf_init();
surf_parse_open(file);
- try {
- int parse_status = surf_parse();
- surf_parse_close();
- xbt_assert(not parse_status, "Parse error at %s:%d", file.c_str(), surf_parse_lineno);
- } catch (const Exception&) {
- xbt_die(
- "Unrecoverable error at %s:%d. The full exception stack follows, in case it helps you to diagnose the problem.",
- file.c_str(), surf_parse_lineno);
- throw;
- }
+ surf_parse();
+ surf_parse_close();
}
void EngineImpl::register_function(const std::string& name, xbt_main_func_t code)
{
std::vector<std::string> parameters;
std::vector<std::string> tmp;
boost::split(parameters, cluster->topo_parameters, boost::is_any_of(";"));
- const std::string error_msg {"Fat trees are defined by the levels number and 3 vectors, see the documentation for more information"};
// TODO : we have to check for zeros and negative numbers, or it might crash
- if (parameters.size() != 4) {
- surf_parse_error(error_msg);
- }
+ surf_parse_assert(
+ parameters.size() == 4,
+ "Fat trees are defined by the levels number and 3 vectors, see the documentation for more information.");
// The first parts of topo_parameters should be the levels number
try {
this->levels_ = std::stoi(parameters[0]);
} catch (const std::invalid_argument&) {
- throw std::invalid_argument(std::string("First parameter is not the amount of levels:") + parameters[0]);
+ surf_parse_error(std::string("First parameter is not the amount of levels: ") + parameters[0]);
}
// Then, a l-sized vector standing for the children number by level
boost::split(tmp, parameters[1], boost::is_any_of(","));
- if (tmp.size() != this->levels_) {
- surf_parse_error(error_msg);
- }
+ surf_parse_assert(tmp.size() == this->levels_, std::string("You specified ") + std::to_string(this->levels_) +
+ " levels but the child count vector (the first one) contains " +
+ std::to_string(tmp.size()) + " levels.");
+
for (size_t i = 0; i < tmp.size(); i++) {
try {
this->num_children_per_node_.push_back(std::stoi(tmp[i]));
} catch (const std::invalid_argument&) {
- throw std::invalid_argument(std::string("Invalid lower level node number:") + tmp[i]);
+ surf_parse_error(std::string("Invalid child count: ") + tmp[i]);
}
}
// Then, a l-sized vector standing for the parents number by level
boost::split(tmp, parameters[2], boost::is_any_of(","));
- if (tmp.size() != this->levels_) {
- surf_parse_error(error_msg);
- }
+ surf_parse_assert(tmp.size() == this->levels_, std::string("You specified ") + std::to_string(this->levels_) +
+ " levels but the parent count vector (the second one) contains " +
+ std::to_string(tmp.size()) + " levels.");
for (size_t i = 0; i < tmp.size(); i++) {
try {
this->num_parents_per_node_.push_back(std::stoi(tmp[i]));
} catch (const std::invalid_argument&) {
- throw std::invalid_argument(std::string("Invalid upper level node number:") + tmp[i]);
+ surf_parse_error(std::string("Invalid parent count: ") + tmp[i]);
}
}
// Finally, a l-sized vector standing for the ports number with the lower level
boost::split(tmp, parameters[3], boost::is_any_of(","));
- if (tmp.size() != this->levels_) {
- surf_parse_error(error_msg);
- }
+ surf_parse_assert(tmp.size() == this->levels_, std::string("You specified ") + std::to_string(this->levels_) +
+ " levels but the port count vector (the third one) contains " +
+ std::to_string(tmp.size()) + " levels.");
for (size_t i = 0; i < tmp.size(); i++) {
try {
this->num_port_lower_level_.push_back(std::stoi(tmp[i]));
if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
return;
- // TODO Trace: set to zero the energy variable associated to host->getName()
+ // TODO Trace: set to zero the energy variable associated to host->get_name()
host.extension_set(new HostEnergy(&host));
}
});
}
+static void ensure_plugin_inited()
+{
+ if (not HostEnergy::EXTENSION_ID.valid())
+ throw std::logic_error("The Energy plugin is not active. Please call sg_host_energy_plugin_init() before calling "
+ "any function related to that plugin.");
+}
+
/** @ingroup plugin_host_energy
* @brief Returns the total energy consumed by the host so far (in Joules)
*
*/
double sg_host_get_consumed_energy(sg_host_t host)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_consumed_energy();
}
*/
double sg_host_get_idle_consumption(sg_host_t host)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_watt_idle_at(0);
}
*/
double sg_host_get_idle_consumption_at(sg_host_t host, int pstate)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_watt_idle_at(pstate);
}
*/
double sg_host_get_wattmin_at(sg_host_t host, int pstate)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_watt_min_at(pstate);
}
/** @ingroup plugin_host_energy
*/
double sg_host_get_wattmax_at(sg_host_t host, int pstate)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_watt_max_at(pstate);
}
/** @ingroup plugin_host_energy
*/
double sg_host_get_power_range_slope_at(sg_host_t host, int pstate)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_power_range_slope_at(pstate);
}
/** @ingroup plugin_host_energy
*/
double sg_host_get_current_consumption(sg_host_t host)
{
- xbt_assert(HostEnergy::EXTENSION_ID.valid(),
- "The Energy plugin is not active. Please call sg_host_energy_plugin_init() during initialization.");
+ ensure_plugin_inited();
return host->extension<HostEnergy>()->get_current_watts_value();
}
*/
double sg_link_get_consumed_energy(sg_link_t link)
{
+ if (not LinkEnergy::EXTENSION_ID.valid())
+ throw std::logic_error("The Energy plugin is not active. Please call sg_link_energy_plugin_init() before calling "
+ "sg_link_get_consumed_energy().");
return link->extension<LinkEnergy>()->get_consumed_energy();
}
void Engine::load_platform(const std::string& platf)
{
double start = xbt_os_time();
- try {
- parse_platform_file(platf);
- } catch (const Exception& e) {
- xbt_die("Error while loading %s: %s", platf.c_str(), e.what());
- }
+ parse_platform_file(platf);
double end = xbt_os_time();
XBT_DEBUG("PARSE TIME: %g", (end - start));
MPI_COMM_WORLD->add_f();
MPI_BYTE->add_f();//MPI_BYTE
MPI_CHAR->add_f();//MPI_CHARACTER
-#if defined(__alpha__) || defined(__sparc64__) || defined(__x86_64__) || defined(__ia64__)
- MPI_C_BOOL->add_f();//MPI_LOGICAL
- MPI_INT->add_f();//MPI_INTEGER
-#else
- MPI_C_BOOL->add_f();//MPI_LOGICAL
- MPI_LONG->add_f();//MPI_INTEGER
-#endif
+ if(sizeof(void*)==8) {
+ MPI_C_BOOL->add_f();//MPI_LOGICAL
+ MPI_INT->add_f();//MPI_INTEGER
+ } else {
+ MPI_C_BOOL->add_f();//MPI_LOGICAL
+ MPI_LONG->add_f();//MPI_INTEGER
+ }
MPI_INT8_T->add_f();//MPI_INTEGER1
MPI_INT16_T->add_f();//MPI_INTEGER2
MPI_INT32_T->add_f();//MPI_INTEGER4
MPI_DOUBLE->add_f();//MPI_DOUBLE_PRECISION
MPI_COMPLEX8->add_f();//MPI_COMPLEX
MPI_COMPLEX16->add_f();//MPI_DOUBLE_COMPLEX
-#if defined(__alpha__) || defined(__sparc64__) || defined(__x86_64__) || defined(__ia64__)
- MPI_2INT->add_f();//MPI_2INTEGER
-#else
- MPI_2LONG->add_f();//MPI_2INTEGER
-#endif
+ if(sizeof(void*)==8)
+ MPI_2INT->add_f();//MPI_2INTEGER
+ else
+ MPI_2LONG->add_f();//MPI_2INTEGER
MPI_UINT8_T->add_f();//MPI_LOGICAL1
MPI_UINT16_T->add_f();//MPI_LOGICAL2
MPI_UINT32_T->add_f();//MPI_LOGICAL4
XBT_PUBLIC void surf_parse_open(const std::string& file);
XBT_PUBLIC void surf_parse_close();
-XBT_PUBLIC void surf_parse_assert(bool cond, const std::string& msg);
-XBT_ATTRIB_NORETURN XBT_PUBLIC void surf_parse_error(const std::string& msg);
+XBT_PUBLIC void surf_parse_assert(bool cond, std::string&& msg);
+XBT_ATTRIB_NORETURN XBT_PUBLIC void surf_parse_error(std::string&& msg);
XBT_PUBLIC void surf_parse_assert_netpoint(const std::string& hostname, const std::string& pre,
const std::string& post);
const std::string& name);
XBT_PUBLIC double surf_parse_get_speed(const char* string, const char* entity_kind, const std::string& name);
-XBT_PUBLIC int surf_parse(); /* Entry-point to the parser */
+XBT_PUBLIC void surf_parse(); /* Entry-point to the parser */
#endif
void sg_platf_trace_connect(simgrid::kernel::routing::TraceConnectCreationArgs* trace_connect)
{
- xbt_assert(traces_set_list.find(trace_connect->trace) != traces_set_list.end(),
- "Cannot connect trace %s to %s: trace unknown", trace_connect->trace.c_str(),
- trace_connect->element.c_str());
+ surf_parse_assert(traces_set_list.find(trace_connect->trace) != traces_set_list.end(),
+ std::string("Cannot connect trace ")+ trace_connect->trace+ " to "+trace_connect->element+": trace unknown");
switch (trace_connect->kind) {
case simgrid::kernel::routing::TraceConnectKind::HOST_AVAIL:
// Use XML parser
- int parse_status;
-
/* init the flex parser */
surf_parse_open(file);
/* Do the actual parsing */
- parse_status = surf_parse();
+ surf_parse();
/* connect all profiles relative to hosts */
for (auto const& elm : trace_connect_list_host_avail) {
- xbt_assert(traces_set_list.find(elm.first) != traces_set_list.end(), "Trace %s undefined", elm.first.c_str());
- simgrid::kernel::profile::Profile* profile = traces_set_list.at(elm.first);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"HOST_AVAIL\">: Trace ")+elm.first+" undefined.");
+ auto profile = traces_set_list.at(elm.first);
- simgrid::s4u::Host* host = simgrid::s4u::Host::by_name_or_null(elm.second);
- xbt_assert(host, "Host %s undefined", elm.second.c_str());
+ auto host = simgrid::s4u::Host::by_name_or_null(elm.second);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"HOST_AVAIL\">: Host ")+elm.second+" undefined.");
host->set_state_profile(profile);
}
for (auto const& elm : trace_connect_list_host_speed) {
- xbt_assert(traces_set_list.find(elm.first) != traces_set_list.end(), "Trace %s undefined", elm.first.c_str());
- simgrid::kernel::profile::Profile* profile = traces_set_list.at(elm.first);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"SPEED\">: Trace ")+elm.first+" undefined.");
+ auto profile = traces_set_list.at(elm.first);
- simgrid::s4u::Host* host = simgrid::s4u::Host::by_name_or_null(elm.second);
- xbt_assert(host, "Host %s undefined", elm.second.c_str());
+ auto host = simgrid::s4u::Host::by_name_or_null(elm.second);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"SPEED\">: Host ")+elm.second+" undefined.");
host->set_speed_profile(profile);
}
for (auto const& elm : trace_connect_list_link_avail) {
- xbt_assert(traces_set_list.find(elm.first) != traces_set_list.end(), "Trace %s undefined", elm.first.c_str());
- simgrid::kernel::profile::Profile* profile = traces_set_list.at(elm.first);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"LINK_AVAIL\">: Trace ")+elm.first+" undefined.");
+ auto profile = traces_set_list.at(elm.first);
- sg_link_t link = simgrid::s4u::Link::by_name(elm.second);
- xbt_assert(link, "Link %s undefined", elm.second.c_str());
+ auto link = simgrid::s4u::Link::by_name(elm.second);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"LINK_AVAIL\">: Link ")+elm.second+" undefined.");
link->set_state_profile(profile);
}
for (auto const& elm : trace_connect_list_link_bw) {
- xbt_assert(traces_set_list.find(elm.first) != traces_set_list.end(), "Trace %s undefined", elm.first.c_str());
- simgrid::kernel::profile::Profile* profile = traces_set_list.at(elm.first);
- sg_link_t link = simgrid::s4u::Link::by_name(elm.second);
- xbt_assert(link, "Link %s undefined", elm.second.c_str());
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"BANDWIDTH\">: Trace ")+elm.first+" undefined.");
+ auto profile = traces_set_list.at(elm.first);
+
+ auto link = simgrid::s4u::Link::by_name(elm.second);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"BANDWIDTH\">: Link ")+elm.second+" undefined.");
link->set_bandwidth_profile(profile);
}
for (auto const& elm : trace_connect_list_link_lat) {
- xbt_assert(traces_set_list.find(elm.first) != traces_set_list.end(), "Trace %s undefined", elm.first.c_str());
- simgrid::kernel::profile::Profile* profile = traces_set_list.at(elm.first);
- sg_link_t link = simgrid::s4u::Link::by_name(elm.second);
- xbt_assert(link, "Link %s undefined", elm.second.c_str());
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"LATENCY\">: Trace ")+elm.first+" undefined.");
+ auto profile = traces_set_list.at(elm.first);
+
+ auto link = simgrid::s4u::Link::by_name(elm.second);
+ surf_parse_assert(traces_set_list.find(elm.first) != traces_set_list.end(), std::string("<trace_connect kind=\"LATENCY\">: Link ")+elm.second+" undefined.");
link->set_latency_profile(profile);
}
surf_parse_close();
-
- if (parse_status)
- surf_parse_error(std::string("Parse error in ") + file);
}
/* 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 "simgrid/Exception.hpp"
#include "simgrid/kernel/routing/NetPoint.hpp"
#include "simgrid/s4u/Engine.hpp"
#include "simgrid/sg_config.hpp"
/*
* Helping functions
*/
-void surf_parse_assert(bool cond, const std::string& msg)
+void surf_parse_assert(bool cond, std::string&& msg)
{
- if (not cond) {
- int lineno = surf_parse_lineno;
- cleanup();
- XBT_ERROR("Parse error at %s:%d: %s", surf_parsed_filename.c_str(), lineno, msg.c_str());
- surf_exit();
- xbt_die("Exiting now");
- }
+ if (not cond)
+ surf_parse_error(std::move(msg));
}
-void surf_parse_error(const std::string& msg)
+void surf_parse_error(std::string&& msg)
{
- int lineno = surf_parse_lineno;
- cleanup();
- XBT_ERROR("Parse error at %s:%d: %s", surf_parsed_filename.c_str(), lineno, msg.c_str());
- surf_exit();
- xbt_die("Exiting now");
+ throw simgrid::ParseError(surf_parse_lineno, surf_parsed_filename, std::move(msg));
}
void surf_parse_assert_netpoint(const std::string& hostname, const std::string& pre, const std::string& post)
break;
}
}
- surf_parse_error(msg);
+ surf_parse_error(std::move(msg));
}
double surf_parse_get_double(const std::string& s)
void STag_surfxml_platform() {
XBT_ATTRIB_UNUSED double version = surf_parse_get_double(A_surfxml_platform_version);
- xbt_assert((version >= 1.0), "******* BIG FAT WARNING *********\n "
+ surf_parse_assert((version >= 1.0), "******* BIG FAT WARNING *********\n "
"You're using an ancient XML file.\n"
"Since SimGrid 3.1, units are Bytes, Flops, and seconds "
"instead of MBytes, MFlops and seconds.\n"
"Last, do not forget to also update your values for "
"the calls to MSG_task_create (if any).");
- xbt_assert((version >= 3.0), "******* BIG FAT WARNING *********\n "
+ surf_parse_assert((version >= 3.0), "******* BIG FAT WARNING *********\n "
"You're using an old XML file.\n"
"Use simgrid_update_xml to update your file automatically. "
"This program is installed automatically with SimGrid, or "
"available in the tools/ directory of the source archive.");
- xbt_assert((version >= 4.0),
- "******* FILE %s IS TOO OLD (v:%.1f) *********\n "
+ surf_parse_assert((version >= 4.0),
+ std::string("******* THIS FILE IS TOO OLD (v:")+std::to_string(version)+") *********\n "
"Changes introduced in SimGrid 3.13:\n"
" - 'power' attribute of hosts (and others) got renamed to 'speed'.\n"
" - In <trace_connect>, attribute kind=\"POWER\" is now kind=\"SPEED\".\n"
"\n\n"
"Use simgrid_update_xml to update your file automatically. "
"This program is installed automatically with SimGrid, or "
- "available in the tools/ directory of the source archive.",
- surf_parsed_filename.c_str(), version);
+ "available in the tools/ directory of the source archive.");
if (version < 4.1) {
XBT_INFO("You're using a v%.1f XML file (%s) while the current standard is v4.1 "
"That's fine, the new version is backward compatible. \n\n"
"available in the tools/ directory of the source archive.",
version, surf_parsed_filename.c_str());
}
- xbt_assert(version <= 4.1,
- "******* FILE %s COMES FROM THE FUTURE (v:%.1f) *********\n "
+ surf_parse_assert(version <= 4.1,
+ std::string("******* THIS FILE COMES FROM THE FUTURE (v:")+std::to_string(version)+") *********\n "
"The most recent formalism that this version of SimGrid understands is v4.1.\n"
- "Please update your code, or use another, more adapted, file.",
- surf_parsed_filename.c_str(), version);
+ "Please update your code, or use another, more adapted, file.");
}
void ETag_surfxml_platform(){
simgrid::s4u::Engine::on_platform_created();
}
/* Call the lexer to parse the currently opened file */
-int surf_parse()
+void surf_parse()
{
- return surf_parse_lex();
+ bool err = surf_parse_lex();
+ surf_parse_assert(not err, "Flex returned an error code");
}
static void handler()
{
- // Avoid doing crazy things if we get an uncaught exception inside
- // an uncaught exception
+ // Avoid doing crazy things if we get an uncaught exception inside an uncaught exception
static std::atomic_flag lock = ATOMIC_FLAG_INIT;
if (lock.test_and_set()) {
XBT_ERROR("Handling an exception raised an exception. Bailing out.");
std::rethrow_exception(e);
}
+ // Parse error are handled differently, as the call stack does not matter, only the file location
+ catch (simgrid::ParseError& e) {
+ XBT_ERROR("%s", e.what());
+ XBT_ERROR("Exiting now.");
+ std::abort();
+ }
+
// We manage C++ exception ourselves
catch (std::exception& e) {
log_exception(xbt_log_priority_critical, "Uncaught exception", e);
catch (const simgrid::ForcefulKillException&) {
XBT_ERROR("Received a ForcefulKillException at the top-level exception handler. Maybe a Java->C++ call that is not "
- "protected "
- "in a try/catch?");
+ "protected in a try/catch?");
show_backtrace(bt);
}
std::abort();
}
}
+ XBT_INFO("BAM");
}
void install_exception_handler()
$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/flatifier ../platforms/bogus_disk_attachment.xml "--log=root.fmt:[%10.6r]%e[%i:%P@%h]%e%m%n"
> [ 0.000000] [0:maestro@] Switching to the L07 model to handle parallel tasks.
> [ 0.000000] [0:maestro@] Parse error at ../platforms/bogus_disk_attachment.xml:19: Unable to attach storage cdisk: host plouf does not exist.
-> [ 0.000000] [0:maestro@] Exiting now
+> [ 0.000000] [0:maestro@] Exiting now.
> [ 0.000000] [0:maestro@] Switching to the L07 model to handle parallel tasks.
> [ 0.000000] [0:maestro@] Parse error at ../platforms/bogus_missing_src_gateway.xml:14: zoneRoute gw_src='nod-cluster_router.cluster.us' does name a node. Existing netpoints:
> 'node-1.cluster.us','node-2.cluster.us','node-3.cluster.us','node-4.cluster.us','node-cluster_router.cluster.us','noeud-1.grappe.fr','noeud-2.grappe.fr','noeud-3.grappe.fr','noeud-4.grappe.fr','noeud-grappe_router.grappe.fr'
-> [ 0.000000] [0:maestro@] Exiting now
+> [ 0.000000] [0:maestro@] Exiting now.
! expect signal SIGABRT
$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/flatifier ../platforms/bogus_missing_dst_gateway.xml "--log=root.fmt:[%10.6r]%e[%i:%P@%h]%e%m%n"
> [ 0.000000] [0:maestro@] Switching to the L07 model to handle parallel tasks.
> [ 0.000000] [0:maestro@] Parse error at ../platforms/bogus_missing_dst_gateway.xml:14: zoneRoute gw_dst='neud-grappe_router.grappe.fr' does name a node. Existing netpoints:
> 'node-1.cluster.us','node-2.cluster.us','node-3.cluster.us','node-4.cluster.us','node-cluster_router.cluster.us','noeud-1.grappe.fr','noeud-2.grappe.fr','noeud-3.grappe.fr','noeud-4.grappe.fr','noeud-grappe_router.grappe.fr'
-> [ 0.000000] [0:maestro@] Exiting now
+> [ 0.000000] [0:maestro@] Exiting now.