#include "src/smpi/include/smpi_actor.hpp"
#include "xbt/config.hpp"
+#include <algorithm>
#include <cfloat> /* DBL_MAX */
+#include <cstdint> /* intmax_t */
#include <dlfcn.h>
#include <fcntl.h>
#include <fstream>
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
* and https://lists.freebsd.org/pipermail/freebsd-current/2016-March/060284.html
*/
-#define RTLD_DEEPBIND 0
+#if !defined(RTLD_DEEPBIND) || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD
+#define WANT_RTLD_DEEPBIND 0
+#else
+#define WANT_RTLD_DEEPBIND RTLD_DEEPBIND
#endif
#if HAVE_PAPI
// No instance gets manually created; check also the smpirun.in script as
// this default name is used there as well (when the <actor> tag is generated).
static const std::string smpi_default_instance_name("smpirun");
-static simgrid::config::Flag<double> smpi_wtime_sleep(
- "smpi/wtime", "Minimum time to inject inside a call to MPI_Wtime", 0.0);
static simgrid::config::Flag<double> smpi_init_sleep(
"smpi/init", "Time to inject inside a call to MPI_Init", 0.0);
simgrid::smpi::ActorExt::init(argc, argv);
}
-int smpi_process_index(){
- return simgrid::s4u::this_actor::get_pid();
-}
-
void * smpi_process_get_user_data(){
return Actor::self()->get_impl()->get_user_data();
}
static int smpi_run_entry_point(smpi_entry_point_type entry_point, std::vector<std::string> args)
{
- int argc_saved = args.size();
- int argc=argc_saved;
- char** argv = new char*[argc + 1];
- for (int i = 0; i != argc; ++i)
- argv[i] = xbt_strdup(args[i].c_str());
- argv[argc] = nullptr;
+ // copy C strings, we need them writable
+ std::vector<char*>* args4argv = new std::vector<char*>(args.size());
+ std::transform(begin(args), end(args), begin(*args4argv), [](const std::string& s) { return xbt_strdup(s.c_str()); });
+
#if !SMPI_IFORT
- char* name = argv[0];
- char* instance = argv[1];
+ // take a copy of args4argv to keep reference of the allocated strings
+ const std::vector<char*> args2str(*args4argv);
#endif
+ int argc = args4argv->size();
+ args4argv->push_back(nullptr);
+ char** argv = args4argv->data();
+
simgrid::smpi::ActorExt::init(&argc, &argv);
#if SMPI_IFORT
for_rtl_init_ (&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;
+ for (char* s : args2str)
+ xbt_free(s);
+ delete args4argv;
#endif
if (res != 0){
int fdout = open(target.c_str(), O_CREAT | O_RDWR, S_IRWXU);
xbt_assert(fdout >= 0, "Cannot write into %s", target.c_str());
- XBT_DEBUG("Copy %ld bytes into %s", static_cast<long>(fdin_size), target.c_str());
+ XBT_DEBUG("Copy %jd bytes into %s", static_cast<intmax_t>(fdin_size), target.c_str());
#if HAVE_SENDFILE
ssize_t sent_size = sendfile(fdout, fdin, NULL, fdin_size);
- xbt_assert(sent_size == fdin_size, "Error while copying %s: only %zd bytes copied instead of %ld (errno: %d -- %s)",
- target.c_str(), sent_size, fdin_size, errno, strerror(errno));
+ xbt_assert(sent_size == fdin_size, "Error while copying %s: only %zd bytes copied instead of %jd (errno: %d -- %s)",
+ target.c_str(), sent_size, static_cast<intmax_t>(fdin_size), errno, strerror(errno));
#else
const int bufsize = 1024 * 1024 * 4;
char buf[bufsize];
smpi_copy_file(executable, target_executable, fdin_size);
// if smpi/privatize-libs is set, duplicate pointed lib and link each executable copy to a different one.
- std::string target_lib;
+ std::vector<std::string> target_libs;
for (auto const& libpath : privatize_libs_paths) {
// if we were given a full path, strip it
size_t index = libpath.find_last_of("/\\");
unsigned int pad = 7;
if (libname.length() < pad)
pad = libname.length();
- target_lib =
+ std::string target_lib =
std::string(pad - std::to_string(rank).length(), '0') + std::to_string(rank) + libname.substr(pad);
+ target_libs.push_back(target_lib);
XBT_DEBUG("copy lib %s to %s, with size %lld", libpath.c_str(), target_lib.c_str(), (long long)fdin_size2);
smpi_copy_file(libpath, target_lib, fdin_size2);
rank++;
// Load the copy and resolve the entry point:
- void* handle = dlopen(target_executable.c_str(), RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
+ void* handle = dlopen(target_executable.c_str(), RTLD_LAZY | RTLD_LOCAL | WANT_RTLD_DEEPBIND);
int saved_errno = errno;
if (simgrid::config::get_value<bool>("smpi/keep-temps") == false) {
unlink(target_executable.c_str());
- if (not target_lib.empty())
+ for (const std::string& target_lib : target_libs)
unlink(target_lib.c_str());
}
if (handle == nullptr)
if(smpi_init_sleep > 0)
simcall_process_sleep(smpi_init_sleep);
}
-
-double smpi_mpi_wtime(){
- double time;
- if (smpi_process()->initialized() != 0 && smpi_process()->finalized() == 0 && smpi_process()->sampling() == 0) {
- smpi_bench_end();
- time = SIMIX_get_clock();
- // to avoid deadlocks if used as a break condition, such as
- // while (MPI_Wtime(...) < time_limit) {
- // ....
- // }
- // because the time will not normally advance when only calls to MPI_Wtime
- // are made -> deadlock (MPI_Wtime never reaches the time limit)
- if(smpi_wtime_sleep > 0)
- simcall_process_sleep(smpi_wtime_sleep);
- smpi_bench_begin();
- } else {
- time = SIMIX_get_clock();
- }
- return time;
-}
-