X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/37a44313f5760bc8cb95573360805cc42730e770..9dec3b0501e4464e246196d29dce6d03a6cbd2d7:/src/smpi/internals/smpi_global.cpp diff --git a/src/smpi/internals/smpi_global.cpp b/src/smpi/internals/smpi_global.cpp index 021bb078da..5a9137953c 100644 --- a/src/smpi/internals/smpi_global.cpp +++ b/src/smpi/internals/smpi_global.cpp @@ -13,7 +13,10 @@ #include "src/smpi/include/smpi_actor.hpp" #include "xbt/config.hpp" +#include #include /* DBL_MAX */ +#include +#include /* intmax_t */ #include #include #include @@ -28,7 +31,7 @@ # define MAC_OS_X_VERSION_10_12 101200 # endif # define HAVE_WORKING_MMAP (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) # define HAVE_WORKING_MMAP 0 #else # define HAVE_WORKING_MMAP 1 @@ -42,21 +45,24 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, "Logging specific to SMPI (ke #include #include /* trim_right / trim_left */ -#if defined(__GNUC__) - extern "C" void _gfortran_set_args(int, char **); -#elif defined(__FLANG) +#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 defined(__INTEL_COMPILER) || defined(__ICC) - extern "C" void for_rtl_init_ (int *, 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 * 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 @@ -93,8 +99,6 @@ MPI_Errhandler *MPI_ERRHANDLER_NULL = nullptr; // No instance gets manually created; check also the smpirun.in script as // this default name is used there as well (when the tag is generated). static const std::string smpi_default_instance_name("smpirun"); -static simgrid::config::Flag smpi_wtime_sleep( - "smpi/wtime", "Minimum time to inject inside a call to MPI_Wtime", 0.0); static simgrid::config::Flag smpi_init_sleep( "smpi/init", "Time to inject inside a call to MPI_Init", 0.0); @@ -128,10 +132,6 @@ void smpi_process_init(int *argc, char ***argv){ 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(); } @@ -425,23 +425,37 @@ typedef void (*smpi_fortran_entry_point_type)(); static int smpi_run_entry_point(smpi_entry_point_type entry_point, std::vector args) { - char noarg[] = {'\0'}; - int argc = args.size(); - std::unique_ptr argv(new char*[argc + 1]); - for (int i = 0; i != argc; ++i) - argv[i] = args[i].empty() ? noarg : &args[i].front(); - argv[argc] = nullptr; - char ** argvptr=argv.get(); - simgrid::smpi::ActorExt::init(&argc, &argvptr); -#if defined(__GNUC__) - _gfortran_set_args(argc, argvptr); -#elif defined(__FLANG) + // copy C strings, we need them writable + std::vector* args4argv = new std::vector(args.size()); + std::transform(begin(args), end(args), begin(*args4argv), [](const std::string& s) { return xbt_strdup(s.c_str()); }); + +#if !SMPI_IFORT + // take a copy of args4argv to keep reference of the allocated strings + const std::vector 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); +#elif SMPI_FLANG __io_set_argc(argc); - __io_set_argv(argvptr); -#elif defined(__INTEL_COMPILER) || defined(__ICC) - for_rtl_init_ (&argc, argvptr); + __io_set_argv(argv); +#elif SMPI_GFORTRAN + _gfortran_set_args(argc, argv); #endif - int res = entry_point(argc, argvptr); + int res = entry_point(argc, argv); + +#if SMPI_IFORT + for_rtl_finish_ (); +#else + for (char* s : args2str) + xbt_free(s); + delete args4argv; +#endif + if (res != 0){ XBT_WARN("SMPI process did not return 0. Return value : %d", res); if (smpi_exit_status == 0) @@ -477,31 +491,36 @@ static void smpi_copy_file(std::string src, std::string target, off_t fdin_size) 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(fdin_size), target.c_str()); + XBT_DEBUG("Copy %" PRIdMAX " bytes into %s", static_cast(fdin_size), target.c_str()); + bool slow_copy = true; #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)); -#else - const int bufsize = 1024 * 1024 * 4; - char buf[bufsize]; - while (int got = read(fdin, buf, bufsize)) { - if (got == -1) { - xbt_assert(errno == EINTR, "Cannot read from %s", src.c_str()); - } else { - char* p = buf; - int todo = got; - while (int done = write(fdout, p, todo)) { - if (done == -1) { - xbt_assert(errno == EINTR, "Cannot write into %s", target.c_str()); - } else { - p += done; - todo -= done; + if (sent_size == fdin_size) + slow_copy = false; + else if (sent_size != -1 || errno != ENOSYS) + xbt_die("Error while copying %s: only %zd bytes copied instead of %" PRIdMAX " (errno: %d -- %s)", target.c_str(), + sent_size, static_cast(fdin_size), errno, strerror(errno)); +#endif + if (slow_copy) { + const int bufsize = 1024 * 1024 * 4; + char buf[bufsize]; + while (int got = read(fdin, buf, bufsize)) { + if (got == -1) { + xbt_assert(errno == EINTR, "Cannot read from %s", src.c_str()); + } else { + char* p = buf; + int todo = got; + while (int done = write(fdout, p, todo)) { + if (done == -1) { + xbt_assert(errno == EINTR, "Cannot write into %s", target.c_str()); + } else { + p += done; + todo -= done; + } } } } } -#endif close(fdin); close(fdout); } @@ -563,7 +582,7 @@ static void smpi_init_privatization_dlopen(std::string executable) 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 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("/\\"); @@ -582,8 +601,9 @@ static void smpi_init_privatization_dlopen(std::string executable) 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); @@ -596,11 +616,11 @@ static void smpi_init_privatization_dlopen(std::string executable) 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("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) @@ -729,24 +749,3 @@ void smpi_mpi_init() { 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; -} -