Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[SMPI/INSTR] Header cleanup.
[simgrid.git] / src / smpi / smpi_bench.cpp
index 21f2fd0..891b663 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "src/internal_config.h"
 #include "private.h"
+#include "private.hpp"
 #include "xbt/dict.h"
 #include "xbt/sysdep.h"
 #include "xbt/ex.h"
@@ -35,8 +36,7 @@
 #define MAP_ANONYMOUS MAP_ANON
 #endif
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi,
-                                "Logging specific to SMPI (benchmarking)");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi, "Logging specific to SMPI (benchmarking)");
 
 /* Shared allocations are handled through shared memory segments.
  * Associated data and metadata are used as follows:
@@ -88,8 +88,7 @@ namespace {
 
 /** Some location in the source code
  *
- *  This information is used by SMPI_SHARED_MALLOC to allocate
- *  some shared memory for all simulated processes.
+ *  This information is used by SMPI_SHARED_MALLOC to allocate  some shared memory for all simulated processes.
  */
 class smpi_source_location {
 public:
@@ -253,6 +252,7 @@ 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());
@@ -262,9 +262,21 @@ void smpi_bench_end(void)
     xbt_backtrace_display_current();
     xbt_die("Aborting.");
   }
+
+  if (xbt_cfg_get_string("smpi/comp-adjustment-file")[0] != '\0') { // Maybe we need to artificially speed up or slow
+                                                         // down our computation based on our statistical analysis.
+
+    smpi_trace_call_location_t* loc                  = smpi_process_get_call_location();
+    std::string key                                  = loc->get_composed_key();
+    std::map<std::string, double>::const_iterator it = location2speedup.find(key);
+    if (it != location2speedup.end()) {
+      speedup = it->second;
+    }
+  }
+  
   // Simulate the benchmarked computation unless disabled via command-line argument
-  if (sg_cfg_get_boolean("smpi/simulate_computation")) {
-    smpi_execute(xbt_os_timer_elapsed(timer));
+  if (xbt_cfg_get_boolean("smpi/simulate-computation")) {
+    smpi_execute(xbt_os_timer_elapsed(timer)/speedup);
   }
 
   smpi_total_benched_time += xbt_os_timer_elapsed(timer);
@@ -300,7 +312,6 @@ int smpi_usleep(useconds_t usecs)
   return (int)private_sleep((double)usecs / 1000000.0);
 }
 
-
 int smpi_gettimeofday(struct timeval *tv, void* tz)
 {
   double now;
@@ -357,6 +368,7 @@ static char *sample_location(int global, const char *file, int line) {
     return bprintf("%s:%d:%d", file, line, smpi_process_index());
   }
 }
+
 static int sample_enough_benchs(local_data_t *data) {
   int res = data->count >= data->iters;
   if (data->threshold>0.0) {
@@ -366,8 +378,7 @@ static int sample_enough_benchs(local_data_t *data) {
       res = 0; // stderr too high yet
   }
   XBT_DEBUG("%s (count:%d iter:%d stderr:%f thres:%f mean:%fs)",
-      (res?"enough benchs":"need more data"),
-      data->count, data->iters, data->relstderr, data->threshold, data->mean);
+      (res?"enough benchs":"need more data"), data->count, data->iters, data->relstderr, data->threshold, data->mean);
   return res;
 }
 
@@ -398,14 +409,17 @@ void smpi_sample_1(int global, const char *file, int line, int iters, double thr
     XBT_DEBUG("XXXXX First time ever on benched nest %s.",loc);
   } else {
     if (data->iters != iters || data->threshold != threshold) {
-      XBT_ERROR("Asked to bench block %s with different settings %d, %f is not %d, %f. How did you manage to give two numbers at the same line??",
-          loc, data->iters, data->threshold, iters,threshold);
+      XBT_ERROR("Asked to bench block %s with different settings %d, %f is not %d, %f. "
+                "How did you manage to give two numbers at the same line??",
+                loc, data->iters, data->threshold, iters,threshold);
       THROW_IMPOSSIBLE;
     }
 
-    // if we already have some data, check whether sample_2 should get one more bench or whether it should emulate the computation instead
+    // 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);
-    XBT_DEBUG("XXXX Re-entering the benched nest %s. %s",loc, (data->benching?"more benching needed":"we have enough data, skip computes"));
+    XBT_DEBUG("XXXX Re-entering the benched nest %s. %s",loc,
+             (data->benching?"more benching needed":"we have enough data, skip computes"));
   }
   xbt_free(loc);
 }
@@ -427,10 +441,10 @@ int smpi_sample_2(int global, const char *file, int line)
         data->count, data->iters, data->relstderr, data->threshold, data->mean);
     res = 1;
   } else {
-    // Enough data, no more bench (either we got enough data from previous visits to this benched nest, or we just ran one bench and need to bail out now that our job is done).
-    // Just sleep instead
-    XBT_DEBUG("No benchmark (either no need, or just ran one): count >= iter (%d >= %d) or stderr<thres (%f<=%f). apply the %fs delay instead",
-        data->count, data->iters, data->relstderr, data->threshold, data->mean);
+    // Enough data, no more bench (either we got enough data from previous visits to this benched nest, or we just
+    //ran one bench and need to bail out now that our job is done). Just sleep instead
+    XBT_DEBUG("No benchmark (either no need, or just ran one): count >= iter (%d >= %d) or stderr<thres (%f<=%f)."
+              " apply the %fs delay instead", data->count, data->iters, data->relstderr, data->threshold, data->mean);
     smpi_execute(data->mean);
     smpi_process_set_sampling(0);
     res = 0; // prepare to capture future, unrelated computations
@@ -439,7 +453,6 @@ int smpi_sample_2(int global, const char *file, int line)
   return res;
 }
 
-
 void smpi_sample_3(int global, const char *file, int line)
 {
   char *loc = sample_location(global, file, line);
@@ -467,7 +480,8 @@ void smpi_sample_3(int global, const char *file, int line)
   data->mean = data->sum / n;
   data->relstderr = sqrt((data->sum_pow2 / n - data->mean * data->mean) / n) / data->mean;
   if (!sample_enough_benchs(data)) {
-    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
+    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
   }
   XBT_DEBUG("Average mean after %d steps is %f, relative standard error is %f (sample was %f)", data->count,
       data->mean, data->relstderr, sample);
@@ -481,7 +495,7 @@ void smpi_sample_3(int global, const char *file, int line)
 void *smpi_shared_malloc(size_t size, const char *file, int line)
 {
   void* mem;
-  if (sg_cfg_get_boolean("smpi/use_shared_malloc")){
+  if (xbt_cfg_get_boolean("smpi/use-shared-malloc")){
     int fd;
     smpi_source_location loc(file, line);
     auto res = allocs.insert(std::make_pair(loc, shared_data_t()));
@@ -489,16 +503,15 @@ void *smpi_shared_malloc(size_t size, const char *file, int line)
     if (res.second) {
       // The insertion did not take place.
       // Generate a shared memory name from the address of the shared_data:
-      char shmname[256];
-      sprintf(shmname, "/shmalloc%p", &*data);
-      fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL,
-                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+      char shmname[32]; // cannot be longer than PSHMNAMLEN = 31 on Mac OS X (shm_open raises ENAMETOOLONG otherwise)
+      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 occured while opening %s. shm_open: %s", shmname, strerror(errno));
+            xbt_die("An unhandled error occurred while opening %s. shm_open: %s", shmname, strerror(errno));
         }
       }
       data->second.fd = fd;
@@ -525,7 +538,7 @@ void smpi_shared_free(void *ptr)
 {
   char loc[PTR_STRLEN];
 
-  if (sg_cfg_get_boolean("smpi/use_shared_malloc")){
+  if (xbt_cfg_get_boolean("smpi/use-shared-malloc")){
     snprintf(loc, PTR_STRLEN, "%p", ptr);
     auto meta = allocs_metadata.find(ptr);
     if (meta == allocs_metadata.end()) {
@@ -597,16 +610,10 @@ void* smpi_shared_set_call(const char* func, const char* input, void* data) {
    return data;
 }
 
-
-
-
 #define TOPAGE(addr) (void *)(((unsigned long)(addr) / xbt_pagesize) * xbt_pagesize)
 
-
-/** Map a given SMPI privatization segment (make a SMPI process active)
- */
+/** 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;
 
@@ -614,24 +621,19 @@ void smpi_switch_data_segment(int dest){
   smpi_really_switch_data_segment(dest);
 }
 
-/** Map a given SMPI privatization segment (make a SMPI process active)
- *  even if SMPI thinks it is already active
+/** Map a given SMPI privatization segment (make a SMPI process active)  even if SMPI thinks it is already active
  *
- *  When doing a state restoration, the state of the restored variables
- *  might not be consistent with the state of the virtual memory.
- *  In this case, we to change the data segment.
+ *  When doing a state restoration, the state of the restored variables  might not be consistent with the state of the
+ *  virtual memory. In this case, we to change the data segment.
  */
 void smpi_really_switch_data_segment(int dest) {
-
   if(smpi_size_data_exe == 0)//no need to switch
     return;
 
-#ifdef HAVE_PRIVATIZATION
-  int i;
+#if HAVE_PRIVATIZATION
   if(smpi_loaded_page==-1){//initial switch, do the copy from the real page here
-    for (i=0; i< smpi_process_count(); i++){
-      memcpy(smpi_privatisation_regions[i].address,
-        TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
+    for (int i=0; i< smpi_process_count(); i++){
+      memcpy(smpi_privatisation_regions[i].address, TOPAGE(smpi_start_data_exe), smpi_size_data_exe);
     }
   }
 
@@ -653,27 +655,25 @@ int smpi_is_privatisation_file(char* file)
 
 void smpi_initialize_global_memory_segments(){
 
-#ifndef HAVE_PRIVATIZATION
+#if !HAVE_PRIVATIZATION
   smpi_privatize_global_variables=0;
   xbt_die("You are trying to use privatization on a system that does not support it. Don't.");
   return;
 #else
 
-  int i = 0;
   smpi_get_executable_global_size();
 
-  XBT_DEBUG ("bss+data segment found : size %d starting at %p",
-    smpi_size_data_exe, smpi_start_data_exe );
+  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;
     return;
   }
 
-  smpi_privatisation_regions = (smpi_privatisation_region_t) malloc(
-    smpi_process_count() * sizeof(struct s_smpi_privatisation_region));
+  smpi_privatisation_regions =
+    (smpi_privatisation_region_t) malloc(smpi_process_count() * sizeof(struct s_smpi_privatisation_region));
 
-  for (i=0; i< smpi_process_count(); i++){
+  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;
       char path[] = "/dev/shm/my-buffer-XXXXXX";
@@ -720,24 +720,49 @@ Ask the Internet about tutorials on how to increase the files limit such as: htt
       smpi_privatisation_regions[i].file_descriptor = file_descriptor;
       smpi_privatisation_regions[i].address = address;
   }
-
 #endif
-
 }
 
 void smpi_destroy_global_memory_segments(){
   if (smpi_size_data_exe == 0)//no need to switch
     return;
-#ifdef HAVE_PRIVATIZATION
+#if HAVE_PRIVATIZATION
   int i;
   for (i=0; i< smpi_process_count(); i++){
     if(munmap(smpi_privatisation_regions[i].address, smpi_size_data_exe) < 0) {
-      XBT_WARN("Unmapping of fd %d failed: %s",
-        smpi_privatisation_regions[i].file_descriptor, strerror(errno));
+      XBT_WARN("Unmapping of fd %d failed: %s", smpi_privatisation_regions[i].file_descriptor, strerror(errno));
     }
     close(smpi_privatisation_regions[i].file_descriptor);
   }
   xbt_free(smpi_privatisation_regions);
 #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 **/
+  void smpi_trace_set_call_location(const char* file, const int line) {
+    smpi_trace_call_location_t* loc = smpi_process_get_call_location();
+
+    loc->previous_filename   = loc->filename;
+    loc->previous_linenumber = loc->linenumber;
+    loc->filename            = file;
+    loc->linenumber          = line;
+  }
 
+  /**
+   * Required for Fortran bindings
+   */
+  void smpi_trace_set_call_location_(const char* file, int* line) {
+    smpi_trace_set_call_location(file, *line);
+  }
+
+  /** 
+   * Required for Fortran if -fsecond-underscore is activated
+   */
+  void smpi_trace_set_call_location__(const char* file, int* line) {
+    smpi_trace_set_call_location(file, *line);
+  }
 }