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 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..1f6826e31 100644 --- a/coreneuron/io/reports/report_configuration_parser.cpp +++ b/coreneuron/io/reports/report_configuration_parser.cpp @@ -155,6 +155,7 @@ std::vector create_report_configurations(const std::string& // extra new line: skip report_conf.ignore(std::numeric_limits::max(), '\n'); } + report.report_index = report.format == "SONATA" ? i : 0; 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..1d54a9213 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_t_shift_(1e-6 * report_index) { nrn_assert(filtered_gids.size()); step = tstart / dt; reporting_period = static_cast(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,8 +90,11 @@ 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 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 20d325614..9a0b7b966 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; + double report_t_shift_; int reporting_period; std::vector 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)); }