if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(SMPI_Fortran_FLAGS "\"-fpic\" \"-ff2c\" \"-fno-second-underscore\"")
set(SMPI_Fortran_LIBS "\"-lgfortran\"")
+ set(SMPI_GFORTRAN 1)
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(SMPI_Fortran_FLAGS "\"-fPIC\" \"-nofor-main\"")
set(SMPI_Fortran_LIBS "\"-lifcore\"")
+ set(SMPI_IFORT 1)
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI|Flang") # flang
set(SMPI_Fortran_FLAGS "\"-fPIC\"")
set(SMPI_Fortran_LIBS "")
+ set(SMPI_FLANG 1)
endif()
set(SMPI_FORTRAN 1)
XBT_INFO("Goodbye now!");
}
+static void test_cancel(double computation_amount)
+{
+ XBT_INFO("Hello! Execute %g flops, should take 1 second", computation_amount);
+ simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_async(computation_amount);
+ simgrid::s4u::this_actor::sleep_for(0.5);
+ XBT_INFO("I changed my mind, cancel!");
+ activity->cancel();
+
+ XBT_INFO("Goodbye now!");
+}
+
int main(int argc, char* argv[])
{
simgrid::s4u::Engine e(&argc, argv);
e.load_platform(argv[1]);
simgrid::s4u::Actor::create("test", simgrid::s4u::Host::by_name("Fafard"), test, 7.6296e+07, 1.0);
simgrid::s4u::Actor::create("test", simgrid::s4u::Host::by_name("Fafard"), test, 7.6296e+07, 2.0);
+ simgrid::s4u::Actor::create("test_cancel", simgrid::s4u::Host::by_name("Boivin"), test_cancel, 98.095e+07);
e.run();
$ $SG_TEST_EXENV ${bindir:=.}/s4u-exec-async$EXEEXT ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
> [ 0.000000] (1:test@Fafard) Hello! Execute 7.6296e+07 flops with priority 1
> [ 0.000000] (2:test@Fafard) Hello! Execute 7.6296e+07 flops with priority 2
+> [ 0.000000] (3:test_cancel@Boivin) Hello! Execute 9.8095e+08 flops, should take 1 second
+> [ 0.500000] (3:test_cancel@Boivin) I changed my mind, cancel!
+> [ 0.500000] (3:test_cancel@Boivin) Goodbye now!
> [ 1.500000] (2:test@Fafard) Goodbye now!
> [ 2.000000] (0:maestro@) Simulation time 2
> [ 2.000000] (1:test@Fafard) Goodbye now!
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
-static int executor(std::vector<std::string> /*args*/)
+static void executor()
{
/* this_actor::execute() tells SimGrid to pause the calling actor
* until its host has computed the amount of flops passed as a parameter */
XBT_INFO("Done.");
/* This simple example does not do anything beyond that */
- return 0;
}
-static int privileged(std::vector<std::string> /*args*/)
+static void privileged()
{
/* This version of this_actor::execute() specifies that this execution
* gets a larger share of the resource.
* because the uneven sharing only last until the privileged actor ends.
* After this point, the unprivileged one gets 100% of the CPU and finishes
* quite quickly. */
- return 0;
}
int main(int argc, char* argv[])
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("executor", simgrid::s4u::Host::by_name("Tremblay"), executor, args);
- simgrid::s4u::Actor::create("privileged", simgrid::s4u::Host::by_name("Tremblay"), privileged, args);
+ simgrid::s4u::Actor::create("executor", simgrid::s4u::Host::by_name("Tremblay"), executor);
+ simgrid::s4u::Actor::create("privileged", simgrid::s4u::Host::by_name("Tremblay"), privileged);
e.run();
try {
simgrid::s4u::this_actor::execute(comp_size);
} catch (xbt_ex& e) {
- switch (e.category) {
- case host_error:
- XBT_INFO("Gloups. The cpu on which I'm running just turned off!. See you!");
- return -1;
- default:
- xbt_die("Unexpected behavior");
- }
+ if (e.category == host_error) {
+ XBT_INFO("Gloups. The cpu on which I'm running just turned off!. See you!");
+ return -1;
+ } else
+ xbt_die("Unexpected behavior");
}
}
XBT_INFO("I'm done. See you!");
* Raises: timeout exception.*/
virtual Activity* wait(double timeout) = 0;
/** Cancel that activity */
- //virtual void cancel();
+ virtual Activity* cancel() = 0;
/** Retrieve the current state of the activity */
Activity::State get_state() { return state_; }
size_t get_dst_data_size();
bool test();
- Activity* cancel();
+ Activity* cancel() override;
/** Retrieve the mailbox on which this comm acts */
MailboxPtr get_mailbox();
Activity* start() override;
Activity* wait() override;
Activity* wait(double timeout) override;
+ Activity* cancel() override;
bool test();
ExecPtr set_priority(double priority);
}
private:
- Host* host_ = nullptr;
- double flops_amount_ = 0.0;
- double priority_ = 1.0;
- double bound_ = 0.0;
- std::string name_ = "";
+ Host* host_ = nullptr;
+ double flops_amount_ = 0.0;
+ double priority_ = 1.0;
+ double bound_ = 0.0;
+ std::string name_ = "";
+ std::string tracing_category_ = "";
std::atomic_int_fast32_t refcount_{0};
}; // class
}
/******************************* Host simcalls ********************************/
#ifdef __cplusplus
-XBT_PUBLIC smx_activity_t simcall_execution_start(std::string name, double flops_amount, double priority, double bound,
- sg_host_t host);
+XBT_PUBLIC smx_activity_t simcall_execution_start(std::string name, std::string category, double flops_amount,
+ double priority, double bound, sg_host_t host);
XBT_PUBLIC smx_activity_t simcall_execution_parallel_start(std::string name, int host_nb, sg_host_t* host_list,
double* flops_amount, double* bytes_amount, double rate,
double timeout);
elf_end(elf);
close(fd);
xbt_die("Debugging information not found for %s\n"
- "Try recompiling with -g\nn",
+ "Try recompiling with -g\n",
info->file_name.c_str());
}
"libthr", /* thread library */
"libutil",
#endif
- "libasan", /* gcc sanitizers */
"libargp", /* workarounds for glibc-less systems */
- "libtsan",
- "libubsan",
- "libbz2",
+ "libasan", /* gcc sanitizers */
"libboost_chrono",
"libboost_context",
"libboost_context-mt",
"libboost_thread",
"libboost_timer",
"libboost_unit_test_framework",
+ "libbz2",
"libc",
"libc++",
"libcdt",
"libdw",
"libelf",
"libevent",
+ "libexecinfo",
+ "libflang",
+ "libflangrti",
"libgcc_s",
+ "libgfortran",
"libimf",
"libintlc",
"libirng",
"liblua5.3",
"liblzma",
"libm",
+ "libomp",
"libpapi",
"libpfm",
"libpthread",
+ "libquadmath",
"librt",
"libstdc++",
"libsvml",
+ "libtsan", /* gcc sanitizers */
+ "libubsan", /* gcc sanitizers */
"libunwind",
- "libunwind-x86_64",
- "libunwind-x86",
"libunwind-ptrace",
+ "libunwind-x86",
+ "libunwind-x86_64",
"libz"};
static bool is_simgrid_lib(const std::string& libname)
task->name ?: "", simdata->host_nb, simdata->host_list, simdata->flops_parallel_amount,
simdata->bytes_parallel_amount, -1.0, timeout));
XBT_DEBUG("Parallel execution action created: %p", simdata->compute.get());
+ if (task->category != nullptr)
+ simcall_set_category(simdata->compute, task->category);
} else {
simdata->compute = boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(
- simcall_execution_start(task->name ?: "", simdata->flops_amount, simdata->priority, simdata->bound,
- MSG_process_get_host(MSG_process_self())));
+ simcall_execution_start(task->name ?: "", task->category ?: "", simdata->flops_amount, simdata->priority,
+ simdata->bound, MSG_process_get_host(MSG_process_self())));
}
- if (task->category != nullptr)
- simcall_set_category(simdata->compute, task->category);
+
comp_state = simcall_execution_wait(simdata->compute);
simdata->setNotUsed();
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/plugins/energy.h"
-#include "simgrid/plugins/load.h"
#include "simgrid/s4u/Engine.hpp"
#include "src/include/surf/surf.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_energy, surf, "Logging specific to the SURF energy plugin");
+// Forwards declaration needed to make this function a friend (because friends have external linkage by default)
+static void on_simulation_end();
+
namespace simgrid {
namespace plugin {
};
class HostEnergy {
+ friend void ::on_simulation_end(); // For access to host_was_used_
public:
static simgrid::xbt::Extension<simgrid::s4u::Host, HostEnergy> EXTENSION_ID;
int pstate_ = 0;
const int pstate_off_ = -1;
+ /* Only used to split total energy into unused/used hosts.
+ * If you want to get this info for something else, rather use the host_load plugin
+ */
+ bool host_was_used_ = false;
public:
double watts_off_ = 0.0; /*< Consumption when the machine is turned off (shutdown) */
double total_energy_ = 0.0; /*< Total energy consumed by the host */
if (cpu_load > 1) // A machine with a load > 1 consumes as much as a fully loaded machine, not more
cpu_load = 1;
+ if (cpu_load > 0)
+ host_was_used_ = true;
/* The problem with this model is that the load is always 0 or 1, never something less.
* Another possibility could be to model the total energy as
current_power_values.push_back(current_power_values.at(1));
} else { // size == 3
current_power_values[2] = current_power_values.at(1);
- static thread_local bool displayed_warning = false;
+ static bool displayed_warning = false;
if (not displayed_warning) { // Otherwise we get in the worst case no_pstate*no_hosts warnings
XBT_WARN("Host %s is a single-core machine and part of the power profile is '%s'"
", which is in the 'Idle:OneCore:AllCores' format."
for (size_t i = 0; i < hosts.size(); i++) {
if (dynamic_cast<simgrid::s4u::VirtualMachine*>(hosts[i]) == nullptr) { // Ignore virtual machines
- bool host_was_used = (sg_host_get_computed_flops(hosts[i]) != 0);
double energy = hosts[i]->extension<HostEnergy>()->get_consumed_energy();
total_energy += energy;
- if (host_was_used)
+ if (hosts[i]->extension<HostEnergy>()->host_was_used_)
used_hosts_energy += energy;
}
}
if (HostEnergy::EXTENSION_ID.valid())
return;
- sg_host_load_plugin_init();
-
HostEnergy::EXTENSION_ID = simgrid::s4u::Host::extension_create<HostEnergy>();
simgrid::s4u::Host::on_creation.connect(&on_creation);
#include "simgrid/plugins/load.h"
#include "src/include/surf/surf.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include <simgrid/s4u.hpp>
namespace simgrid {
namespace plugin {
+static const double activity_uninitialized_remaining_cost = -1;
+
class HostLoad {
public:
static simgrid::xbt::Extension<simgrid::s4u::Host, HostLoad> EXTENSION_ID;
, current_speed_(host_->get_speed())
, current_flops_(host_->pimpl_cpu->get_constraint()->get_usage())
, theor_max_flops_(0)
- , was_prev_idle_(current_flops_ == 0)
{
}
~HostLoad() = default;
explicit HostLoad(simgrid::s4u::Host&& ptr) = delete;
double get_current_load();
- double get_average_load() { return (theor_max_flops_ == 0) ? 0 : computed_flops_ / theor_max_flops_; };
- double get_computed_flops() { return computed_flops_; }
- double get_idle_time() { return idle_time_; } /** Return idle time since last reset */
- double get_total_idle_time() { return total_idle_time_; } /** Return idle time over the whole simulation */
+ double get_average_load() { update(); return (theor_max_flops_ == 0) ? 0 : computed_flops_ / theor_max_flops_; };
+ double get_computed_flops() { update(); return computed_flops_; }
+ double get_idle_time() { update(); return idle_time_; } /** Return idle time since last reset */
+ double get_total_idle_time() { update(); return total_idle_time_; } /** Return idle time over the whole simulation */
void update();
+ void add_activity(simgrid::kernel::activity::ExecImplPtr activity);
void reset();
private:
simgrid::s4u::Host* host_ = nullptr;
+ /* Stores all currently ongoing activities (computations) on this machine */
+ std::map<simgrid::kernel::activity::ExecImplPtr, /* cost still remaining*/double> current_activities;
double last_updated_ = 0;
double last_reset_ = 0;
/**
- * current_speed each core is running at right now
+ * current_speed each core is running at; we need to store this as the speed
+ * will already have changed once we get notified
*/
double current_speed_ = 0;
/**
double idle_time_ = 0;
double total_idle_time_ = 0; /* This gets never reset */
double theor_max_flops_ = 0;
- bool was_prev_idle_ = true; /* A host is idle at the beginning */
};
simgrid::xbt::Extension<simgrid::s4u::Host, HostLoad> HostLoad::EXTENSION_ID;
+void HostLoad::add_activity(simgrid::kernel::activity::ExecImplPtr activity)
+{
+ current_activities.insert({activity, activity_uninitialized_remaining_cost});
+}
+
void HostLoad::update()
{
double now = surf_get_clock();
- /* Current flop per second computed by the cpu; current_flops = k * pstate_speed_in_flops, k @in {0, 1, ..., cores}
- * number of active cores */
- current_flops_ = host_->pimpl_cpu->get_constraint()->get_usage();
+ // This loop updates the flops that the host executed for the ongoing computations
+ auto iter = begin(current_activities);
+ while (iter != end(current_activities)) {
+ auto& activity = iter->first; // Just an alias
+ auto& remaining_cost_after_last_update = iter->second; // Just an alias
+ auto current_iter = iter;
+ ++iter;
+
+ if (activity->surf_action_->get_finish_time() != now && activity->state_ == e_smx_state_t::SIMIX_RUNNING) {
+ if (remaining_cost_after_last_update == activity_uninitialized_remaining_cost) {
+ remaining_cost_after_last_update = activity->surf_action_->get_cost();
+ }
+ double computed_flops_since_last_update = remaining_cost_after_last_update - /*remaining now*/activity->get_remaining();
+ computed_flops_ += computed_flops_since_last_update;
+ remaining_cost_after_last_update = activity->get_remaining();
+ }
+ else if (activity->state_ == e_smx_state_t::SIMIX_DONE) {
+ computed_flops_ += remaining_cost_after_last_update;
+ current_activities.erase(current_iter);
+ }
+ }
- /* flops == pstate_speed * cores_being_currently_used */
- computed_flops_ += (now - last_updated_) * current_flops_;
+ /* Current flop per second computed by the cpu; current_flops = k * pstate_speed_in_flops, k @in {0, 1, ..., cores-1}
+ * designates number of active cores; will be 0 if CPU is currently idle */
+ current_flops_ = host_->pimpl_cpu->get_constraint()->get_usage();
- if (was_prev_idle_) {
+ if (current_flops_ == 0) {
idle_time_ += (now - last_updated_);
total_idle_time_ += (now - last_updated_);
+ XBT_DEBUG("[%s]: Currently idle -> Added %f seconds to idle time (totaling %fs)", host_->get_cname(), (now - last_updated_), idle_time_);
}
theor_max_flops_ += current_speed_ * host_->get_core_count() * (now - last_updated_);
current_speed_ = host_->get_speed();
last_updated_ = now;
- was_prev_idle_ = (current_flops_ == 0);
}
/**
theor_max_flops_ = 0;
current_flops_ = host_->pimpl_cpu->get_constraint()->get_usage();
current_speed_ = host_->get_speed();
- was_prev_idle_ = (current_flops_ == 0);
}
} // namespace plugin
} // namespace simgrid
host.extension_set(new HostLoad(&host));
});
- simgrid::surf::CpuAction::on_state_change.connect(&on_action_state_change);
+ simgrid::kernel::activity::ExecImpl::on_creation.connect([](simgrid::kernel::activity::ExecImplPtr activity){
+ if (activity->host_ != nullptr) { // We only run on one host
+ simgrid::s4u::Host* host = activity->host_;
+ if (dynamic_cast<simgrid::s4u::VirtualMachine*>(activity->host_))
+ host = dynamic_cast<simgrid::s4u::VirtualMachine*>(activity->host_)->get_pm();
+
+ host->extension<HostLoad>()->add_activity(activity);
+ host->extension<HostLoad>()->update(); // If the system was idle until now, we need to update *before*
+ // this computation starts running so we can keep track of the
+ // idle time. (Communication operations don't trigger this hook!)
+ }
+ else { // This runs on multiple hosts
+ XBT_DEBUG("HostLoad plugin currently does not support executions on several hosts");
+ }
+ });
+ simgrid::kernel::activity::ExecImpl::on_completion.connect([](simgrid::kernel::activity::ExecImplPtr activity){
+ if (activity->host_ != nullptr) { // We only run on one host
+ simgrid::s4u::Host* host = activity->host_;
+ if (dynamic_cast<simgrid::s4u::VirtualMachine*>(activity->host_))
+ host = dynamic_cast<simgrid::s4u::VirtualMachine*>(activity->host_)->get_pm();
+
+ host->extension<HostLoad>()->update();
+ }
+ else { // This runs on multiple hosts
+ XBT_DEBUG("HostLoad plugin currently does not support executions on several hosts");
+ }
+ });
simgrid::s4u::Host::on_state_change.connect(&on_host_change);
simgrid::s4u::Host::on_speed_change.connect(&on_host_change);
}
Activity* Comm::cancel()
{
- simgrid::kernel::activity::CommImplPtr commPimpl =
- boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(pimpl_);
- commPimpl->cancel();
+ simgrid::simix::simcall([this] { dynamic_cast<kernel::activity::CommImpl*>(pimpl_.get())->cancel(); });
+ state_ = State::CANCELED;
return this;
}
Activity* Exec::start()
{
- pimpl_ = simcall_execution_start(name_, flops_amount_, 1. / priority_, bound_, host_);
+ pimpl_ = simcall_execution_start(name_, tracing_category_, flops_amount_, 1. / priority_, bound_, host_);
state_ = State::STARTED;
return this;
}
+Activity* Exec::cancel()
+{
+ simgrid::simix::simcall([this] { dynamic_cast<kernel::activity::ExecImpl*>(pimpl_.get())->cancel(); });
+ state_ = State::CANCELED;
+ return this;
+}
+
Activity* Exec::wait()
{
simcall_execution_wait(pimpl_);
ExecPtr Exec::set_tracing_category(std::string category)
{
- if (category.empty())
- return this;
-
- simgrid::simix::simcall([this, category] {
- boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_)->set_category(category);
- });
+ xbt_assert(state_ == State::INITED, "Cannot change the tracing category of an exec after its start");
+ tracing_category_ = category;
return this;
}
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/kernel/routing/NetPoint.hpp"
+#include "simgrid/s4u/Actor.hpp"
#include "simgrid/s4u/Engine.hpp"
-#include "src/simix/smx_host_private.hpp"
+#include "simgrid/s4u/Exec.hpp"
#include "src/surf/HostImpl.hpp"
#include <string>
}
void Host::execute(double flops, double priority)
{
- smx_activity_t s = simcall_execution_start("", flops, 1 / priority /*priority*/, 0. /*bound*/, this);
- simcall_execution_wait(s);
+ this_actor::exec_init(flops)->set_host(this)->set_priority(1 / priority)->start()->wait();
}
} // namespace s4u
return nullptr;
} else {
- return SIMIX_execution_start("suspend", 0.0, 1.0, 0.0, this->host_);
+ return SIMIX_execution_start("suspend", "", 0.0, 1.0, 0.0, this->host_);
}
}
* @param host host where the synchro will be executed
* @return A new SIMIX execution synchronization
*/
-smx_activity_t simcall_execution_start(std::string name, double flops_amount, double priority, double bound,
- simgrid::s4u::Host* host)
+smx_activity_t simcall_execution_start(std::string name, std::string category, double flops_amount, double priority,
+ double bound, simgrid::s4u::Host* host)
{
/* checking for infinite values */
xbt_assert(std::isfinite(flops_amount), "flops_amount is not finite!");
xbt_assert(std::isfinite(priority), "priority is not finite!");
- return simgrid::simix::simcall([name, flops_amount, priority, bound, host] {
- return SIMIX_execution_start(name, flops_amount, priority, bound, host);
+ return simgrid::simix::simcall([name, category, flops_amount, priority, bound, host] {
+ return SIMIX_execution_start(name, category, flops_amount, priority, bound, host);
});
}
process_list.clear();
}
-boost::intrusive_ptr<simgrid::kernel::activity::ExecImpl>
-SIMIX_execution_start(std::string name, double flops_amount, double priority, double bound, sg_host_t host)
+simgrid::kernel::activity::ExecImplPtr SIMIX_execution_start(std::string name, std::string category,
+ double flops_amount, double priority, double bound,
+ sg_host_t host)
{
/* set surf's action */
simgrid::kernel::resource::Action* surf_action = nullptr;
surf_action = host->pimpl_cpu->execution_start(flops_amount);
surf_action->set_priority(priority);
if (bound > 0)
- static_cast<simgrid::surf::CpuAction*>(surf_action)->set_bound(bound);
+ surf_action->set_bound(bound);
}
simgrid::kernel::activity::ExecImplPtr exec = simgrid::kernel::activity::ExecImplPtr(
new simgrid::kernel::activity::ExecImpl(name, surf_action, /*timeout_detector*/ nullptr, host));
+ exec->set_category(category);
XBT_DEBUG("Create execute synchro %p: %s", exec.get(), exec->name_.c_str());
simgrid::kernel::activity::ExecImpl::on_creation(exec);
return exec;
}
-boost::intrusive_ptr<simgrid::kernel::activity::ExecImpl>
-SIMIX_execution_parallel_start(std::string name, int host_nb, sg_host_t* host_list, double* flops_amount,
- double* bytes_amount, double rate, double timeout)
+simgrid::kernel::activity::ExecImplPtr SIMIX_execution_parallel_start(std::string name, int host_nb,
+ sg_host_t* host_list, double* flops_amount,
+ double* bytes_amount, double rate, double timeout)
{
/* Check that we are not mixing VMs and PMs in the parallel task */
XBT_PRIVATE void SIMIX_set_category(smx_activity_t synchro, std::string category);
-XBT_PRIVATE boost::intrusive_ptr<simgrid::kernel::activity::ExecImpl>
-SIMIX_execution_start(std::string name, double flops_amount, double priority, double bound, sg_host_t host);
-XBT_PRIVATE boost::intrusive_ptr<simgrid::kernel::activity::ExecImpl>
+XBT_PRIVATE simgrid::kernel::activity::ExecImplPtr SIMIX_execution_start(std::string name, std::string category,
+ double flops_amount, double priority,
+ double bound, sg_host_t host);
+XBT_PRIVATE simgrid::kernel::activity::ExecImplPtr
SIMIX_execution_parallel_start(std::string name, int host_nb, sg_host_t* host_list, double* flops_amount,
double* bytes_amount, double rate, double timeout);
class ActorExt {
private:
double simulated_ = 0 /* Used to time with simulated_start/elapsed */;
- int* argc_ = nullptr;
- char*** argv_ = nullptr;
simgrid::s4u::MailboxPtr mailbox_;
simgrid::s4u::MailboxPtr mailbox_small_;
xbt_mutex_t mailboxes_mutex_;
(*argv)[(*argc) - 2] = nullptr;
}
(*argc) -= 2;
- argc_ = argc;
- argv_ = argv;
// set the process attached to the mailbox
mailbox_small_->set_receiver(actor_);
XBT_DEBUG("<%ld> SMPI process has been initialized: %p", actor_->get_pid(), actor_.get());
void smpi_execute_flops(double flops) {
xbt_assert(flops >= 0, "You're trying to execute a negative amount of flops (%f)!", flops);
XBT_DEBUG("Handle real computation time: %f flops", flops);
- simgrid::s4u::ExecPtr e = simgrid::s4u::this_actor::exec_init(flops)->set_name("computation");
- e->start();
- e->set_tracing_category(TRACE_internal_smpi_get_category());
- e->wait();
+ simgrid::s4u::this_actor::exec_init(flops)
+ ->set_name("computation")
+ ->set_tracing_category(TRACE_internal_smpi_get_category())
+ ->start()
+ ->wait();
smpi_switch_data_segment(simgrid::s4u::Actor::self());
}
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp> /* trim_right / trim_left */
+#if SMPI_IFORT
+ extern "C" void for_rtl_init_ (int *, char **);
+ extern "C" void for_rtl_finish_ ();
+#elif SMPI_FLANG
+ extern "C" void __io_set_argc(int);
+ extern "C" void __io_set_argv(char **);
+#elif SMPI_GFORTRAN
+ extern "C" void _gfortran_set_args(int, char **);
+#endif
+
#ifndef RTLD_DEEPBIND
/* RTLD_DEEPBIND is a bad idea of GNU ld that obviously does not exist on other platforms
* See https://www.akkadia.org/drepper/dsohowto.pdf
static int smpi_run_entry_point(smpi_entry_point_type entry_point, std::vector<std::string> args)
{
- char noarg[] = {'\0'};
- int argc = args.size();
- std::unique_ptr<char*[]> argv(new char*[argc + 1]);
+ int argc_saved = args.size();
+ int argc=argc_saved;
+ char** argv = new char*[argc + 1];
for (int i = 0; i != argc; ++i)
- argv[i] = args[i].empty() ? noarg : &args[i].front();
+ argv[i] = xbt_strdup(args[i].c_str());
argv[argc] = nullptr;
- char ** argvptr=argv.get();
-
- simgrid::smpi::ActorExt::init(&argc, &argvptr);
+ char* name = argv[0];
+ char* instance = argv[1];
+ simgrid::smpi::ActorExt::init(&argc, &argv);
+#if SMPI_IFORT
+ for_rtl_init_ (&argc, argv);
+#elif SMPI_FLANG
+ __io_set_argc(argc);
+ __io_set_argv(argv);
+#elif SMPI_GFORTRAN
+ _gfortran_set_args(argc, argv);
+#endif
+ int res = entry_point(argc, argv);
+
+#if SMPI_IFORT
+ for_rtl_finish_ ();
+#else
+ for (int i = 0; i != argc; ++i)
+ xbt_free(argv[i]);
+ if (argc_saved > 3) {
+ xbt_free(instance);
+ xbt_free(name);
+ }
+ delete[] argv;
+#endif
- int res = entry_point(argc, argvptr);
if (res != 0){
XBT_WARN("SMPI process did not return 0. Return value : %d", res);
if (smpi_exit_status == 0)
return new CpuCas01Action(get_model(), size, is_off(), speed_.scale * speed_.peak, get_constraint(), requested_cores);
}
-CpuAction *CpuCas01::sleep(double duration)
+CpuAction* CpuCas01::sleep(double duration)
{
if (duration > 0)
duration = std::max(duration, sg_surf_precision);
set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
endforeach()
endif()
+
+ if(enable_smpi AND SMPI_FORTRAN)
+ set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90")
+ add_executable (fort_args fort_args/fort_args.f90)
+ target_link_libraries(fort_args simgrid)
+ set_target_properties(fort_args PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fort_args)
+ endif()
endif()
foreach(x coll-allgather coll-allgatherv coll-allreduce coll-alltoall coll-alltoallv coll-barrier coll-bcast
set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.c)
endforeach()
-set (teshsuite_src ${teshsuite_src} PARENT_SCOPE)
+set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/fort_args/fort_args.f90 PARENT_SCOPE)
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/coll-allreduce/coll-allreduce-large.tesh
${CMAKE_CURRENT_SOURCE_DIR}/coll-allreduce/coll-allreduce-automatic.tesh
${CMAKE_CURRENT_SOURCE_DIR}/coll-alltoall/clusters.tesh
${CMAKE_CURRENT_SOURCE_DIR}/pt2pt-pingpong/broken_hostfiles.tesh
- ${CMAKE_CURRENT_SOURCE_DIR}/pt2pt-pingpong/TI_output.tesh PARENT_SCOPE)
+ ${CMAKE_CURRENT_SOURCE_DIR}/pt2pt-pingpong/TI_output.tesh
+ ${CMAKE_CURRENT_SOURCE_DIR}/fort_args/fort_args.tesh PARENT_SCOPE)
set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/hostfile
${CMAKE_CURRENT_SOURCE_DIR}/hostfile_cluster
${CMAKE_CURRENT_SOURCE_DIR}/hostfile_coll
- ${CMAKE_CURRENT_SOURCE_DIR}/hostfile_empty PARENT_SCOPE)
+ ${CMAKE_CURRENT_SOURCE_DIR}/hostfile_empty PARENT_SCOPE)
+
if(enable_smpi)
if(NOT WIN32)
foreach(x coll-allgather coll-allgatherv coll-allreduce coll-alltoall coll-alltoallv coll-barrier coll-bcast
coll-gather coll-reduce coll-reduce-scatter coll-scatter macro-sample pt2pt-dsend pt2pt-pingpong
- type-hvector type-indexed type-struct type-vector bug-17132 timers)
+ type-hvector type-indexed type-struct type-vector bug-17132 timers)
ADD_TESH_FACTORIES(tesh-smpi-${x} "thread;ucontext;raw;boost" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/${x} ${x}.tesh)
endforeach()
+ if(SMPI_FORTRAN)
+ ADD_TESH_FACTORIES(tesh-smpi-fort_args "thread;ucontext;raw;boost" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/fort_args --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/fort_args fort_args.tesh)
+ endif()
+
foreach (ALLGATHER 2dmesh 3dmesh bruck GB loosely_lr NTSLR NTSLR_NB pair rdb rhv ring SMP_NTS smp_simple spreading_simple
ompi mpich ompi_neighborexchange mvapich2 mvapich2_smp impi)
ADD_TESH(tesh-smpi-coll-allgather-${ALLGATHER} --cfg smpi/allgather:${ALLGATHER} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/coll-allgather --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/coll-allgather coll-allgather.tesh)
--- /dev/null
+! Check that getarg does somethig sensible.
+program getarg_1
+ CHARACTER*10 ARGS, ARGS2
+ INTEGER*4 I
+ INTEGER*2 I2
+ I = 0
+ CALL GETARG(I,ARGS)
+ ! This should return the invoking command. The actual value depends
+ ! on the OS, but a blank string is wrong no matter what.
+ ! ??? What about deep embedded systems?
+ if (args.eq.'') STOP 2
+ I = 1
+ CALL GETARG(I,ARGS)
+ if (args.ne.'a') STOP 3
+ I = -1
+ CALL GETARG(I,ARGS)
+ if (args.ne.'') STOP 4
+ ! Assume we won't have been called with more that 4 args.
+ I = 4
+ CALL GETARG(I,ARGS)
+ if (args.ne.'') STOP 5
+ I = 1000
+ CALL GETARG(I,ARGS)
+ if (args.ne.'') STOP 6
+end
--- /dev/null
+p Test fortran params
+! output sort
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile -platform ${platfdir}/small_platform.xml -np 2 ${bindir:=.}/fort_args 'a' 3 -q --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning
+> [rank 0] -> Tremblay
+> [rank 1] -> Jupiter
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/simgrid)
install(TARGETS smpimain # install that binary without breaking the rpath on Mac
RUNTIME DESTINATION lib/simgrid)
+
+ if(SMPI_FORTRAN)
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
+ SET(SIMGRID_DEP "${SIMGRID_DEP} -lgfortran")
+ elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
+ SET(SIMGRID_DEP "${SIMGRID_DEP} -lifcore")
+ elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI|Flang")
+ SET(SIMGRID_DEP "${SIMGRID_DEP} -lflang")
+ if("${CMAKE_SYSTEM}" MATCHES "FreeBSD")
+ set(SIMGRID_DEP "${SIMGRID_DEP} -lexecinfo")
+ endif()
+ endif()
+ endif()
+
endif()
if(enable_smpi AND APPLE)
/* SMPI variables */
/* SMPI enabled */
#cmakedefine01 HAVE_SMPI
-/* Fortran language is available for SMPI */
+/* Fortran language is available for SMPI, and which one */
#cmakedefine01 SMPI_FORTRAN
+#cmakedefine01 SMPI_GFORTRAN
+#cmakedefine01 SMPI_FLANG
+#cmakedefine01 SMPI_IFORT
/* We have mmap and objdump to handle privatization */
#cmakedefine01 HAVE_PRIVATIZATION
/* We have PAPI to fine-grain trace execution time */