From 554d08ebda1a75a4ace7fac1e4459d02dfe1b100 Mon Sep 17 00:00:00 2001
From: Jorge Blanco Alonso <jorge.blancoalonso@epfl.ch>
Date: Thu, 27 Oct 2022 15:01:10 +0200
Subject: [PATCH 1/4] Event callback slightly different per report

---
 coreneuron/io/reports/nrnreport.hpp                   |  1 +
 coreneuron/io/reports/report_configuration_parser.cpp |  1 +
 coreneuron/io/reports/report_event.cpp                | 11 +++++++----
 coreneuron/io/reports/report_event.hpp                |  4 +++-
 coreneuron/io/reports/report_handler.cpp              |  3 ++-
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/coreneuron/io/reports/nrnreport.hpp b/coreneuron/io/reports/nrnreport.hpp
index 7cdc05806..6cf133424 100644
--- a/coreneuron/io/reports/nrnreport.hpp
+++ b/coreneuron/io/reports/nrnreport.hpp
@@ -102,6 +102,7 @@ struct ReportConfiguration {
     int num_gids;                         // total number of gids
     int buffer_size;                      // hint on buffer size used for this report
     std::set<int> target;                 // list of gids for this report
+    int report_index;                     // index of the report
 };
 
 void setup_report_engine(double dt_report, double mindelay);
diff --git a/coreneuron/io/reports/report_configuration_parser.cpp b/coreneuron/io/reports/report_configuration_parser.cpp
index 6c69662b7..11cd6a13e 100644
--- a/coreneuron/io/reports/report_configuration_parser.cpp
+++ b/coreneuron/io/reports/report_configuration_parser.cpp
@@ -155,6 +155,7 @@ std::vector<ReportConfiguration> create_report_configurations(const std::string&
             // extra new line: skip
             report_conf.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
         }
+        report.report_index = i;
         reports.push_back(report);
     }
     // read population information for spike report
diff --git a/coreneuron/io/reports/report_event.cpp b/coreneuron/io/reports/report_event.cpp
index 78eb6b268..07003ca10 100644
--- a/coreneuron/io/reports/report_event.cpp
+++ b/coreneuron/io/reports/report_event.cpp
@@ -24,12 +24,14 @@ ReportEvent::ReportEvent(double dt,
                          double tstart,
                          const VarsToReport& filtered_gids,
                          const char* name,
-                         double report_dt)
+                         double report_dt,
+                         int report_index)
     : dt(dt)
     , tstart(tstart)
     , report_path(name)
     , report_dt(report_dt)
-    , vars_to_report(filtered_gids) {
+    , vars_to_report(filtered_gids)
+    , report_index_(report_index) {
     nrn_assert(filtered_gids.size());
     step = tstart / dt;
     reporting_period = static_cast<int>(report_dt / dt);
@@ -74,7 +76,7 @@ void ReportEvent::summation_alu(NrnThread* nt) {
 
 /** on deliver, call ReportingLib and setup next event */
 void ReportEvent::deliver(double t, NetCvode* nc, NrnThread* nt) {
-/* reportinglib is not thread safe */
+    /* reportinglib is not thread safe */
 #pragma omp critical
     {
         summation_alu(nt);
@@ -88,7 +90,8 @@ void ReportEvent::deliver(double t, NetCvode* nc, NrnThread* nt) {
                                 gids_to_report.data(),
                                 report_path.data());
 #endif
-        send(t + dt, nc, nt);
+        // Deterministic event time per report
+        send(t + dt + 1e-6 * report_index_, nc, nt);
         step++;
     }
 }
diff --git a/coreneuron/io/reports/report_event.hpp b/coreneuron/io/reports/report_event.hpp
index 20d325614..daffa609c 100644
--- a/coreneuron/io/reports/report_event.hpp
+++ b/coreneuron/io/reports/report_event.hpp
@@ -36,7 +36,8 @@ class ReportEvent: public DiscreteEvent {
                 double tstart,
                 const VarsToReport& filtered_gids,
                 const char* name,
-                double report_dt);
+                double report_dt,
+                int report_index);
 
     /** on deliver, call ReportingLib and setup next event */
     void deliver(double t, NetCvode* nc, NrnThread* nt) override;
@@ -48,6 +49,7 @@ class ReportEvent: public DiscreteEvent {
     double step;
     std::string report_path;
     double report_dt;
+    int report_index_;
     int reporting_period;
     std::vector<int> gids_to_report;
     double tstart;
diff --git a/coreneuron/io/reports/report_handler.cpp b/coreneuron/io/reports/report_handler.cpp
index 84341e7a4..788f7d14c 100644
--- a/coreneuron/io/reports/report_handler.cpp
+++ b/coreneuron/io/reports/report_handler.cpp
@@ -67,7 +67,8 @@ void ReportHandler::create_report(double dt, double tstop, double delay) {
                                                               t,
                                                               vars_to_report,
                                                               m_report_config.output_path.data(),
-                                                              m_report_config.report_dt);
+                                                              m_report_config.report_dt,
+                                                              m_report_config.report_index);
             report_event->send(t, net_cvode_instance, &nt);
             m_report_events.push_back(std::move(report_event));
         }

From 02654d25e54e7754ab2244f43d40dbf3b1cd414a Mon Sep 17 00:00:00 2001
From: Jorge Blanco Alonso <jorge.blancoalonso@epfl.ch>
Date: Fri, 28 Oct 2022 12:10:37 +0200
Subject: [PATCH 2/4] Dont change Binary reports behavior

---
 coreneuron/io/reports/report_configuration_parser.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/coreneuron/io/reports/report_configuration_parser.cpp b/coreneuron/io/reports/report_configuration_parser.cpp
index 11cd6a13e..1f6826e31 100644
--- a/coreneuron/io/reports/report_configuration_parser.cpp
+++ b/coreneuron/io/reports/report_configuration_parser.cpp
@@ -155,7 +155,7 @@ std::vector<ReportConfiguration> create_report_configurations(const std::string&
             // extra new line: skip
             report_conf.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
         }
-        report.report_index = i;
+        report.report_index = report.format == "SONATA" ? i : 0;
         reports.push_back(report);
     }
     // read population information for spike report

From 4e29f146be0e571fd087d298cf96cef1a59f3816 Mon Sep 17 00:00:00 2001
From: Jorge Blanco Alonso <jorge.blancoalonso@epfl.ch>
Date: Fri, 28 Oct 2022 16:03:20 +0200
Subject: [PATCH 3/4] Add report time shift only in the first iteration so it
 doesnt accumulate in each event

---
 coreneuron/io/reports/report_event.cpp | 8 +++++---
 coreneuron/io/reports/report_event.hpp | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/coreneuron/io/reports/report_event.cpp b/coreneuron/io/reports/report_event.cpp
index 07003ca10..1d54a9213 100644
--- a/coreneuron/io/reports/report_event.cpp
+++ b/coreneuron/io/reports/report_event.cpp
@@ -31,7 +31,7 @@ ReportEvent::ReportEvent(double dt,
     , report_path(name)
     , report_dt(report_dt)
     , vars_to_report(filtered_gids)
-    , report_index_(report_index) {
+    , report_t_shift_(1e-6 * report_index) {
     nrn_assert(filtered_gids.size());
     step = tstart / dt;
     reporting_period = static_cast<int>(report_dt / dt);
@@ -90,9 +90,11 @@ void ReportEvent::deliver(double t, NetCvode* nc, NrnThread* nt) {
                                 gids_to_report.data(),
                                 report_path.data());
 #endif
-        // Deterministic event time per report
-        send(t + dt + 1e-6 * report_index_, nc, nt);
+        // Deterministic event time per report to avoid deadlocks
+        send(t + dt + report_t_shift_, nc, nt);
         step++;
+        // Apply shift only in the first iteration so it doesn't accumulate
+        report_t_shift_ = 0;
     }
 }
 
diff --git a/coreneuron/io/reports/report_event.hpp b/coreneuron/io/reports/report_event.hpp
index daffa609c..4fd8a0636 100644
--- a/coreneuron/io/reports/report_event.hpp
+++ b/coreneuron/io/reports/report_event.hpp
@@ -49,7 +49,7 @@ class ReportEvent: public DiscreteEvent {
     double step;
     std::string report_path;
     double report_dt;
-    int report_index_;
+    int report_t_shift_;
     int reporting_period;
     std::vector<int> gids_to_report;
     double tstart;

From d9057292a72701de85589f9caaf39fe7c6604f0b Mon Sep 17 00:00:00 2001
From: Jorge Blanco Alonso <jorge.blancoalonso@epfl.ch>
Date: Mon, 31 Oct 2022 11:27:38 +0100
Subject: [PATCH 4/4] t shift should be a double

---
 coreneuron/io/reports/report_event.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/coreneuron/io/reports/report_event.hpp b/coreneuron/io/reports/report_event.hpp
index 4fd8a0636..9a0b7b966 100644
--- a/coreneuron/io/reports/report_event.hpp
+++ b/coreneuron/io/reports/report_event.hpp
@@ -49,7 +49,7 @@ class ReportEvent: public DiscreteEvent {
     double step;
     std::string report_path;
     double report_dt;
-    int report_t_shift_;
+    double report_t_shift_;
     int reporting_period;
     std::vector<int> gids_to_report;
     double tstart;