#include "src/internal_config.h"
#include "private.h"
#include "private.hpp"
+#include <xbt/ex.hpp>
#include "xbt/dict.h"
#include "xbt/sysdep.h"
#include "xbt/ex.h"
#include <string.h>
#include <stdio.h>
+#if HAVE_PAPI
+#include <papi.h>
+#endif
+
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#define PTR_STRLEN (2 + 2 * sizeof(void*) + 1)
-xbt_dict_t samples = NULL; /* Allocated on first use */
-xbt_dict_t calls = NULL; /* Allocated on first use */
+xbt_dict_t samples = nullptr; /* Allocated on first use */
+xbt_dict_t calls = nullptr; /* Allocated on first use */
double smpi_cpu_threshold;
double smpi_running_power;
int smpi_loaded_page = -1;
-char* smpi_start_data_exe = NULL;
+char* smpi_start_data_exe = nullptr;
int smpi_size_data_exe = 0;
-int smpi_privatize_global_variables;
+bool smpi_privatize_global_variables;
double smpi_total_benched_time = 0;
smpi_privatisation_region_t smpi_privatisation_regions;
if(fstat(fd, &st) < 0) {
xbt_die("Could not stat fd %d: %s", fd, strerror(errno));
}
- return (size_t)st.st_size;
+ return static_cast<size_t>(st.st_size);
}
#ifndef WIN32
char loc[PTR_STRLEN];
shared_metadata_t meta;
- if(size > shm_size(fd)) {
- if(ftruncate(fd, (off_t)size) < 0) {
+ if(size > shm_size(fd) && (ftruncate(fd, static_cast<off_t>(size)) < 0)) {
xbt_die("Could not truncate fd %d to %zu: %s", fd, size, strerror(errno));
- }
}
- mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(mem == MAP_FAILED) {
xbt_die("Could not map fd %d: %s", fd, strerror(errno));
}
}
}
-void smpi_switch_data_segment(int dest);
-
void smpi_bench_begin(void)
{
if (smpi_privatize_global_variables) {
if (MC_is_active() || MC_record_replay_is_active())
return;
+#if HAVE_PAPI
+ if (xbt_cfg_get_string("smpi/papi-events")[0] != '\0') {
+ int event_set = smpi_process_papi_event_set();
+ // PAPI_start sets everything to 0! See man(3) PAPI_start
+ if (PAPI_LOW_LEVEL_INITED == PAPI_is_initialized()) {
+ if (PAPI_start(event_set) != PAPI_OK) {
+ // TODO This needs some proper handling.
+ XBT_CRITICAL("Could not start PAPI counters.\n");
+ xbt_die("Error.");
+ }
+ }
+ }
+#endif
xbt_os_threadtimer_start(smpi_process_timer());
}
void smpi_bench_end(void)
{
-
if (MC_is_active() || MC_record_replay_is_active())
return;
double speedup = 1;
xbt_os_timer_t timer = smpi_process_timer();
xbt_os_threadtimer_stop(timer);
-// smpi_switch_data_segment(smpi_process_count());
+
+#if HAVE_PAPI
+ /**
+ * An MPI function has been called and now is the right time to update
+ * our PAPI counters for this process.
+ */
+ if (xbt_cfg_get_string("smpi/papi-events")[0] != '\0') {
+ papi_counter_t& counter_data = smpi_process_papi_counters();
+ int event_set = smpi_process_papi_event_set();
+ std::vector<long long> event_values = std::vector<long long>(counter_data.size());
+
+ if (PAPI_stop(event_set, &event_values[0]) != PAPI_OK) { // Error
+ XBT_CRITICAL("Could not stop PAPI counters.\n");
+ xbt_die("Error.");
+ } else {
+ for (unsigned int i = 0; i < counter_data.size(); i++) {
+ counter_data[i].second += event_values[i];
+ // XBT_DEBUG("[%i] PAPI: Counter %s: Value is now %lli (got increment by %lli\n", smpi_process_index(),
+ // counter_data[i].first.c_str(), counter_data[i].second, event_values[i]);
+ }
+ }
+ }
+#endif
+
if (smpi_process_get_sampling()) {
XBT_CRITICAL("Cannot do recursive benchmarks.");
XBT_CRITICAL("Are you trying to make a call to MPI within a SMPI_SAMPLE_ block?");
smpi_execute(xbt_os_timer_elapsed(timer)/speedup);
}
+#if HAVE_PAPI
+ if (xbt_cfg_get_string("smpi/papi-events")[0] != '\0' && TRACE_smpi_is_enabled()) {
+ char container_name[INSTR_DEFAULT_STR_SIZE];
+ smpi_container(smpi_process_index(), container_name, INSTR_DEFAULT_STR_SIZE);
+ container_t container = PJ_container_get(container_name);
+ papi_counter_t& counter_data = smpi_process_papi_counters();
+
+ for (auto& pair : counter_data) {
+ new_pajeSetVariable(surf_get_clock(), container,
+ PJ_type_get(/* countername */ pair.first.c_str(), container->type), pair.second);
+ }
+ }
+#endif
+
smpi_total_benched_time += xbt_os_timer_elapsed(timer);
}
unsigned int smpi_sleep(unsigned int secs)
{
- return private_sleep((double)secs);
+ return private_sleep(static_cast<double>(secs));
}
int smpi_usleep(useconds_t usecs)
{
- return (int)private_sleep((double)usecs / 1000000.0);
+ return static_cast<int>(private_sleep(static_cast<double>(usecs) / 1000000.0));
}
+#if _POSIX_TIMERS > 0
+int smpi_nanosleep(const struct timespec *tp, struct timespec * t)
+{
+ return static_cast<int>(private_sleep(static_cast<double>(tp->tv_sec + tp->tv_nsec / 1000000000.0)));
+}
+#endif
+
int smpi_gettimeofday(struct timeval *tv, void* tz)
{
double now;
smpi_bench_end();
now = SIMIX_get_clock();
if (tv) {
- tv->tv_sec = (time_t)now;
+ tv->tv_sec = static_cast<time_t>(now);
#ifdef WIN32
- tv->tv_usec = (useconds_t)((now - tv->tv_sec) * 1e6);
+ tv->tv_usec = static_cast<useconds_t>((now - tv->tv_sec) * 1e6);
#else
- tv->tv_usec = (suseconds_t)((now - tv->tv_sec) * 1e6);
+ tv->tv_usec = static_cast<suseconds_t>((now - tv->tv_sec) * 1e6);
#endif
}
smpi_bench_begin();
return 0;
}
+#if _POSIX_TIMERS > 0
+int smpi_clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+ //there is only one time in SMPI, so clk_id is ignored.
+ double now;
+ smpi_bench_end();
+ now = SIMIX_get_clock();
+ if (tp) {
+ tp->tv_sec = static_cast<time_t>(now);
+ tp->tv_nsec = static_cast<long int>((now - tp->tv_sec) * 1e9);
+ }
+ smpi_bench_begin();
+ return 0;
+}
+#endif
+
extern double sg_surf_precision;
unsigned long long smpi_rastro_resolution (void)
{
smpi_bench_end();
double resolution = (1/sg_surf_precision);
smpi_bench_begin();
- return (unsigned long long)resolution;
+ return static_cast<unsigned long long>(resolution);
}
unsigned long long smpi_rastro_timestamp (void)
unsigned long long sec = (unsigned long long)now;
unsigned long long pre = (now - sec) * smpi_rastro_resolution();
smpi_bench_begin();
- return (unsigned long long)sec * smpi_rastro_resolution() + pre;
+ return static_cast<unsigned long long>(sec) * smpi_rastro_resolution() + pre;
}
/* ****************************** Functions related to the SMPI_SAMPLE_ macros ************************************/
smpi_bench_end(); /* Take time from previous, unrelated computation into account */
smpi_process_set_sampling(1);
- if (!samples)
+ if (samples==nullptr)
samples = xbt_dict_new_homogeneous(free);
data = static_cast<local_data_t *>(xbt_dict_get_or_null(samples, loc));
- if (!data) {
+ if (data==nullptr) {
xbt_assert(threshold>0 || iters>0,
"You should provide either a positive amount of iterations to bench, or a positive maximal stderr (or both)");
- data = (local_data_t *) xbt_new(local_data_t, 1);
+ data = static_cast<local_data_t *>( xbt_new(local_data_t, 1));
data->count = 0;
data->sum = 0.0;
data->sum_pow2 = 0.0;
data->threshold = threshold;
data->benching = 1; // If we have no data, we need at least one
data->mean = 0;
- xbt_dict_set(samples, loc, data, NULL);
+ xbt_dict_set(samples, loc, data, nullptr);
XBT_DEBUG("XXXXX First time ever on benched nest %s.",loc);
} else {
if (data->iters != iters || data->threshold != threshold) {
// if we already have some data, check whether sample_2 should get one more bench or whether it should emulate
// the computation instead
- data->benching = !sample_enough_benchs(data);
+ data->benching = (sample_enough_benchs(data) == 0);
XBT_DEBUG("XXXX Re-entering the benched nest %s. %s",loc,
(data->benching?"more benching needed":"we have enough data, skip computes"));
}
sample = xbt_os_timer_elapsed(smpi_process_timer());
data->sum += sample;
data->sum_pow2 += sample * sample;
- n = (double)data->count;
+ n = static_cast<double>(data->count);
data->mean = data->sum / n;
data->relstderr = sqrt((data->sum_pow2 / n - data->mean * data->mean) / n) / data->mean;
- if (!sample_enough_benchs(data)) {
+ if (sample_enough_benchs(data)==0) {
data->mean = sample; // Still in benching process; We want sample_2 to simulate the exact time of this loop
// occurrence before leaving, not the mean over the history
}
snprintf(shmname, 31, "/shmalloc%p", &*data);
fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0) {
- switch(errno) {
- case EEXIST:
- xbt_die("Please cleanup /dev/shm/%s", shmname);
- default:
- xbt_die("An unhandled error occurred while opening %s. shm_open: %s", shmname, strerror(errno));
- }
+ if(errno==EEXIST)
+ xbt_die("Please cleanup /dev/shm/%s", shmname);
+ else
+ xbt_die("An unhandled error occurred while opening %s. shm_open: %s", shmname, strerror(errno));
}
data->second.fd = fd;
data->second.count = 1;
int smpi_shared_known_call(const char* func, const char* input)
{
char* loc = bprintf("%s:%s", func, input);
- xbt_ex_t ex;
int known = 0;
- if (!calls) {
- calls = xbt_dict_new_homogeneous(NULL);
+ if (calls==nullptr) {
+ calls = xbt_dict_new_homogeneous(nullptr);
}
- TRY {
+ try {
xbt_dict_get(calls, loc); /* Succeed or throw */
known = 1;
- }
- TRY_CLEANUP {
xbt_free(loc);
}
- CATCH(ex) {
+ catch (xbt_ex& ex) {
+ xbt_free(loc);
if (ex.category != not_found_error)
- RETHROW;
- xbt_ex_free(ex);
+ throw;
+ }
+ catch(...) {
+ xbt_free(loc);
+ throw;
}
return known;
}
char* loc = bprintf("%s:%s", func, input);
void* data;
- if(!calls) {
- calls = xbt_dict_new_homogeneous(NULL);
+ if(calls==nullptr) {
+ calls = xbt_dict_new_homogeneous(nullptr);
}
data = xbt_dict_get(calls, loc);
- free(loc);
+ xbt_free(loc);
return data;
}
void* smpi_shared_set_call(const char* func, const char* input, void* data) {
char* loc = bprintf("%s:%s", func, input);
- if(!calls) {
- calls = xbt_dict_new_homogeneous(NULL);
+ if(calls==0) {
+ calls = xbt_dict_new_homogeneous(nullptr);
}
- xbt_dict_set(calls, loc, data, NULL);
- free(loc);
+ xbt_dict_set(calls, loc, data, nullptr);
+ xbt_free(loc);
return data;
}
-#define TOPAGE(addr) (void *)(((unsigned long)(addr) / xbt_pagesize) * xbt_pagesize)
/** Map a given SMPI privatization segment (make a SMPI process active) */
-void smpi_switch_data_segment(int dest){
- if (smpi_loaded_page==dest)//no need to switch either
- return;
+void smpi_switch_data_segment(int dest) {
+ if (smpi_loaded_page == dest)//no need to switch, we've already loaded the one we want
+ return;
// So the job:
smpi_really_switch_data_segment(dest);
int smpi_is_privatisation_file(char* file)
{
- return strncmp("/dev/shm/my-buffer-", file, 19) == 0;
+ return strncmp("/dev/shm/my-buffer-", file, std::strlen("/dev/shm/my-buffer-")) == 0;
}
void smpi_initialize_global_memory_segments(){
#if !HAVE_PRIVATIZATION
- smpi_privatize_global_variables=0;
+ smpi_privatize_global_variables=false;
xbt_die("You are trying to use privatization on a system that does not support it. Don't.");
return;
#else
XBT_DEBUG ("bss+data segment found : size %d starting at %p", smpi_size_data_exe, smpi_start_data_exe );
if (smpi_size_data_exe == 0){//no need to switch
- smpi_privatize_global_variables=0;
+ smpi_privatize_global_variables=false;
return;
}
smpi_privatisation_regions =
- (smpi_privatisation_region_t) malloc(smpi_process_count() * sizeof(struct s_smpi_privatisation_region));
+ static_cast<smpi_privatisation_region_t>( xbt_malloc(smpi_process_count() * sizeof(struct s_smpi_privatisation_region)));
for (int i=0; i< smpi_process_count(); i++){
//create SIMIX_process_count() mappings of this size with the same data inside
- void *address = NULL;
+ void *address = nullptr;
char path[] = "/dev/shm/my-buffer-XXXXXX";
int status;
xbt_die("Impossible to set the size of the temporary file for memory mapping");
/* Ask for a free region */
- address = mmap (NULL, smpi_size_data_exe, PROT_READ | PROT_WRITE, MAP_SHARED, file_descriptor, 0);
+ address = mmap (nullptr, smpi_size_data_exe, PROT_READ | PROT_WRITE, MAP_SHARED, file_descriptor, 0);
if (address == MAP_FAILED)
xbt_die("Couldn't find a free region for memory mapping");
#endif
}
-smpi_trace_call_location_t* smpi_trace_get_call_location() {
- return smpi_process_get_call_location();
-}
-
extern "C" { /** These functions will be called from the user code **/
+ smpi_trace_call_location_t* smpi_trace_get_call_location() {
+ return smpi_process_get_call_location();
+ }
+
void smpi_trace_set_call_location(const char* file, const int line) {
smpi_trace_call_location_t* loc = smpi_process_get_call_location();