From 962b4cae4102ca2ed84a97f5b69b8b4ad67af4ab Mon Sep 17 00:00:00 2001
From: Alexander Peyser <a.peyser@fz-juelich.de>
Date: Wed, 18 Jan 2017 13:06:00 +0100
Subject: [PATCH] Add profile-only-zero flag for mpi profiling

---
 miniapp/io.cpp             | 11 ++++++++++-
 miniapp/io.hpp             |  3 +++
 miniapp/miniapp.cpp        |  2 +-
 src/profiling/profiler.cpp | 13 ++++++++-----
 src/profiling/profiler.hpp |  2 +-
 5 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/miniapp/io.cpp b/miniapp/io.cpp
index d2aaef48..ad07161c 100644
--- a/miniapp/io.cpp
+++ b/miniapp/io.cpp
@@ -134,7 +134,10 @@ cl_options read_options(int argc, char** argv, bool allow_write) {
         true,       // Overwrite outputfile if exists
         "./",       // output path
         "spikes",   // file name
-        "gdf"       // file extension
+        "gdf",      // file extension
+        
+        // Turn on/off profiling output for all ranks
+        false
     };
 
     cl_options options;
@@ -191,6 +194,9 @@ cl_options read_options(int argc, char** argv, bool allow_write) {
         TCLAP::SwitchArg spike_output_arg(
             "f","spike_file_output","save spikes to file", cmd, false);
 
+        TCLAP::SwitchArg profile_only_zero_arg(
+             "z", "profile-only-zero", "Only output profile information for rank 0", cmd, false);
+
         cmd.reorder_arguments();
         cmd.parse(argc, argv);
 
@@ -230,6 +236,8 @@ cl_options read_options(int argc, char** argv, bool allow_write) {
                         update_option(options.file_extension, fopts, "file_extension");
                     }
 
+                    update_option(options.profile_only_zero, fopts, "profile_only_zero");
+
                 }
                 catch (std::exception& e) {
                     throw model_description_error(
@@ -255,6 +263,7 @@ cl_options read_options(int argc, char** argv, bool allow_write) {
         update_option(options.trace_prefix, trace_prefix_arg);
         update_option(options.trace_max_gid, trace_max_gid_arg);
         update_option(options.spike_file_output, spike_output_arg);
+        update_option(options.profile_only_zero, profile_only_zero_arg);
 
         if (options.all_to_all && options.ring) {
             throw usage_error("can specify at most one of --ring and --all-to-all");
diff --git a/miniapp/io.hpp b/miniapp/io.hpp
index ac769d43..3100de17 100644
--- a/miniapp/io.hpp
+++ b/miniapp/io.hpp
@@ -35,6 +35,9 @@ struct cl_options {
     std::string output_path;
     std::string file_name;
     std::string file_extension;
+
+    // Turn on/off profiling output for all ranks
+    bool profile_only_zero;
 };
 
 class usage_error: public std::runtime_error {
diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp
index 6094631b..c5254300 100644
--- a/miniapp/miniapp.cpp
+++ b/miniapp/miniapp.cpp
@@ -141,7 +141,7 @@ int main(int argc, char** argv) {
 
         // output profile and diagnostic feedback
         auto const num_steps = options.tfinal / options.dt;
-        util::profiler_output(0.001, m.num_cells()*num_steps);
+        util::profiler_output(0.001, m.num_cells()*num_steps, options.profile_only_zero);
         std::cout << "there were " << m.num_spikes() << " spikes\n";
 
         // save traces
diff --git a/src/profiling/profiler.cpp b/src/profiling/profiler.cpp
index 896e7bcf..a6f08e96 100644
--- a/src/profiling/profiler.cpp
+++ b/src/profiling/profiler.cpp
@@ -349,7 +349,7 @@ void profilers_restart() {
     }
 }
 
-void profiler_output(double threshold, std::size_t num_local_work_items) {
+void profiler_output(double threshold, std::size_t num_local_work_items, bool profile_only_zero) {
     profilers_stop();
 
     // Find the earliest start time and latest stop time over all profilers
@@ -385,6 +385,7 @@ void profiler_output(double threshold, std::size_t num_local_work_items) {
     auto ncomms = communication::global_policy::size();
     auto comm_rank = communication::global_policy::id();
     bool print = comm_rank==0 ? true : false;
+    bool output_this_rank = (comm_rank == 0) || ! profile_only_zero;
 
     // calculate the throughput in terms of work items per second
     auto local_throughput = num_local_work_items / wall_time;
@@ -433,9 +434,11 @@ void profiler_output(double threshold, std::size_t num_local_work_items) {
     as_json["rank"] = comm_rank;
     as_json["regions"] = p.as_json();
 
-    auto fname = std::string("profile_" + std::to_string(comm_rank));
-    std::ofstream fid(fname);
-    fid << std::setw(1) << as_json;
+    if (output_this_rank) {
+        auto fname = std::string("profile_" + std::to_string(comm_rank));
+        std::ofstream fid(fname);
+        fid << std::setw(1) << as_json;
+    }
 }
 
 #else
@@ -445,7 +448,7 @@ void profiler_enter(const char*) {}
 void profiler_leave() {}
 void profiler_leave(int) {}
 void profilers_stop() {}
-void profiler_output(double threshold, std::size_t num_local_work_items) {}
+void profiler_output(double threshold, std::size_t num_local_work_items, bool profile_only_zero) {}
 void profilers_restart() {};
 #endif
 
diff --git a/src/profiling/profiler.hpp b/src/profiling/profiler.hpp
index b000de67..0747fbdc 100644
--- a/src/profiling/profiler.hpp
+++ b/src/profiling/profiler.hpp
@@ -245,7 +245,7 @@ void profilers_stop();
 void profilers_restart();
 
 /// print the collated profiler to std::cout
-void profiler_output(double threshold, std::size_t num_local_work_items);
+void profiler_output(double threshold, std::size_t num_local_work_items, bool profile_only_zero);
 
 } // namespace util
 } // namespace mc
-- 
GitLab