Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 2d08705

Browse files
jorblancoapramodk
andauthored
Report multipopulation (#778)
* Add multipopulation support for compartment reports. * Remove old population name and population offset. Co-authored-by: Pramod Kumbhar <[email protected]>
1 parent 9b6d29c commit 2d08705

File tree

9 files changed

+70
-46
lines changed

9 files changed

+70
-46
lines changed

coreneuron/apps/main1.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,13 @@ static void trajectory_return() {
428428
}
429429
}
430430

431-
std::unique_ptr<ReportHandler> create_report_handler(ReportConfiguration& config) {
431+
std::unique_ptr<ReportHandler> create_report_handler(ReportConfiguration& config,
432+
const SpikesInfo& spikes_info) {
432433
std::unique_ptr<ReportHandler> report_handler;
433434
if (config.format == "Bin") {
434435
report_handler = std::make_unique<BinaryReportHandler>(config);
435436
} else if (config.format == "SONATA") {
436-
report_handler = std::make_unique<SonataReportHandler>(config);
437+
report_handler = std::make_unique<SonataReportHandler>(config, spikes_info);
437438
} else {
438439
if (nrnmpi_myid == 0) {
439440
printf(" WARNING : Report name '%s' has unknown format: '%s'.\n",
@@ -524,7 +525,7 @@ extern "C" int run_solve_core(int argc, char** argv) {
524525

525526
std::vector<ReportConfiguration> configs;
526527
std::vector<std::unique_ptr<ReportHandler>> report_handlers;
527-
std::vector<std::pair<std::string, int>> spikes_population_name_offset;
528+
SpikesInfo spikes_info;
528529
bool reports_needs_finalize = false;
529530

530531
if (!corenrn_param.is_quiet()) {
@@ -539,7 +540,7 @@ extern "C" int run_solve_core(int argc, char** argv) {
539540
if (!corenrn_param.reportfilepath.empty()) {
540541
configs = create_report_configurations(corenrn_param.reportfilepath,
541542
corenrn_param.outpath,
542-
spikes_population_name_offset);
543+
spikes_info);
543544
reports_needs_finalize = !configs.empty();
544545
}
545546

@@ -592,7 +593,8 @@ extern "C" int run_solve_core(int argc, char** argv) {
592593
// register all reports into reportinglib
593594
double min_report_dt = INT_MAX;
594595
for (size_t i = 0; i < configs.size(); i++) {
595-
std::unique_ptr<ReportHandler> report_handler = create_report_handler(configs[i]);
596+
std::unique_ptr<ReportHandler> report_handler = create_report_handler(configs[i],
597+
spikes_info);
596598
if (report_handler) {
597599
report_handler->create_report(dt, tstop, delay);
598600
report_handlers.push_back(std::move(report_handler));
@@ -645,7 +647,7 @@ extern "C" int run_solve_core(int argc, char** argv) {
645647
// write spike information to outpath
646648
{
647649
Instrumentor::phase p("output-spike");
648-
output_spikes(output_dir.c_str(), spikes_population_name_offset);
650+
output_spikes(output_dir.c_str(), spikes_info);
649651
}
650652

651653
// copy weights back to NEURON NetCon

coreneuron/io/output_spikes.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,9 @@ static void sort_spikes(std::vector<double>& spikevec_time, std::vector<int>& sp
154154
/** Split spikevec_time and spikevec_gid by populations
155155
* Add spike data with population name and gid offset tolibsonatareport API
156156
*/
157-
static void output_spike_populations(
158-
const std::vector<std::pair<std::string, int>>& population_name_offset) {
157+
void output_spike_populations(const SpikesInfo& spikes_info) {
159158
// Write spikes with default population name and offset
160-
if (population_name_offset.empty()) {
159+
if (spikes_info.population_info.empty()) {
161160
sonata_add_spikes_population("All",
162161
0,
163162
spikevec_time.data(),
@@ -166,15 +165,15 @@ static void output_spike_populations(
166165
spikevec_gid.size());
167166
return;
168167
}
169-
int n_populations = population_name_offset.size();
168+
int n_populations = spikes_info.population_info.size();
170169
for (int idx = 0; idx < n_populations; idx++) {
171-
auto cur_pop = population_name_offset[idx];
172-
std::string population_name = cur_pop.first;
173-
int population_offset = cur_pop.second;
170+
const auto& curr_pop = spikes_info.population_info[idx];
171+
std::string population_name = curr_pop.first;
172+
int population_offset = curr_pop.second;
174173
int gid_lower = population_offset;
175174
int gid_upper = std::numeric_limits<int>::max();
176175
if (idx != n_populations - 1) {
177-
gid_upper = population_name_offset[idx + 1].second - 1;
176+
gid_upper = spikes_info.population_info[idx + 1].second - 1;
178177
}
179178
std::vector<double> pop_spikevec_time;
180179
std::vector<int> pop_spikevec_gid;
@@ -198,10 +197,7 @@ static void output_spike_populations(
198197
* \todo : MPI related code should be factored into nrnmpi.c
199198
* Check spike record length which is set to 64 chars
200199
*/
201-
static void output_spikes_parallel(
202-
const char* outpath,
203-
const char* filename,
204-
const std::vector<std::pair<std::string, int>>& population_name_offset) {
200+
static void output_spikes_parallel(const char* outpath, const SpikesInfo& spikes_info) {
205201
std::stringstream ss;
206202
ss << outpath << "/out.dat";
207203
std::string fname = ss.str();
@@ -211,8 +207,8 @@ static void output_spikes_parallel(
211207
remove(fname.c_str());
212208
}
213209
#ifdef ENABLE_SONATA_REPORTS
214-
sonata_create_spikefile(outpath, filename);
215-
output_spike_populations(population_name_offset);
210+
sonata_create_spikefile(outpath, spikes_info.file_name.data());
211+
output_spike_populations(spikes_info);
216212
sonata_write_spike_populations();
217213
sonata_close_spikefile();
218214
#endif // ENABLE_SONATA_REPORTS
@@ -280,16 +276,15 @@ static void output_spikes_serial(const char* outpath) {
280276
fclose(f);
281277
}
282278

283-
void output_spikes(const char* outpath,
284-
const std::vector<std::pair<std::string, int>>& population_name_offset) {
279+
void output_spikes(const char* outpath, const SpikesInfo& spikes_info) {
285280
// try to transfer spikes to NEURON. If successfull, don't write out.dat
286281
if (all_spikes_return(spikevec_time, spikevec_gid)) {
287282
clear_spike_vectors();
288283
return;
289284
}
290285
#if NRNMPI
291286
if (corenrn_param.mpi_enable && nrnmpi_initialized()) {
292-
output_spikes_parallel(outpath, "out", population_name_offset);
287+
output_spikes_parallel(outpath, spikes_info);
293288
} else
294289
#endif
295290
{

coreneuron/io/output_spikes.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
#include <string>
1212
#include <vector>
1313
#include <utility>
14+
#include "coreneuron/io/reports/nrnreport.hpp"
1415
namespace coreneuron {
15-
void output_spikes(const char* outpath,
16-
const std::vector<std::pair<std::string, int>>& population_name_offset);
16+
void output_spikes(const char* outpath, const SpikesInfo& spikes_info);
1717
void mk_spikevec_buffer(int);
1818

1919
extern std::vector<double> spikevec_time;

coreneuron/io/reports/nrnreport.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ struct SummationReportMapping {
3939
std::unordered_map<std::string, SummationReport> summation_reports_;
4040
};
4141

42+
struct SpikesInfo {
43+
std::string file_name = "out";
44+
std::vector<std::pair<std::string, int>> population_info;
45+
};
46+
4247
// name of the variable in mod file that is used to indicate which synapse
4348
// is enabled or disable for reporting
4449
#define SELECTED_VAR_MOD_NAME "selected_for_report"
@@ -87,7 +92,6 @@ struct ReportConfiguration {
8792
std::string unit; // unit of the report
8893
std::string format; // format of the report (Bin, hdf5, SONATA)
8994
std::string type_str; // type of report string
90-
std::string population_name; // population name of the report
9195
TargetType target_type; // type of the target
9296
ReportType type; // type of the report
9397
SectionType section_type; // type of section report
@@ -97,15 +101,13 @@ struct ReportConfiguration {
97101
double stop; // stop time of report
98102
int num_gids; // total number of gids
99103
int buffer_size; // hint on buffer size used for this report
100-
uint64_t population_offset; // offset of the node ids in the population
101104
std::set<int> target; // list of gids for this report
102105
};
103106

104107
void setup_report_engine(double dt_report, double mindelay);
105-
std::vector<ReportConfiguration> create_report_configurations(
106-
const std::string& filename,
107-
const std::string& output_dir,
108-
std::vector<std::pair<std::string, int>>& spikes_population_name);
108+
std::vector<ReportConfiguration> create_report_configurations(const std::string& filename,
109+
const std::string& output_dir,
110+
SpikesInfo& spikes_info);
109111
void finalize_report();
110112
void nrn_flush_reports(double t);
111113
void set_report_buffer_size(int n);

coreneuron/io/reports/report_configuration_parser.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,9 @@ void register_target_type(ReportConfiguration& report, ReportType report_type) {
103103
}
104104
}
105105

106-
std::vector<ReportConfiguration> create_report_configurations(
107-
const std::string& conf_file,
108-
const std::string& output_dir,
109-
std::vector<std::pair<std::string, int>>& spikes_population_name_offset) {
106+
std::vector<ReportConfiguration> create_report_configurations(const std::string& conf_file,
107+
const std::string& output_dir,
108+
SpikesInfo& spikes_info) {
110109
std::vector<ReportConfiguration> reports;
111110
std::string report_on;
112111
int target;
@@ -120,8 +119,7 @@ std::vector<ReportConfiguration> create_report_configurations(
120119

121120
report_conf >> report.name >> report.target_name >> report.type_str >> report_on >>
122121
report.unit >> report.format >> target >> report.report_dt >> report.start >>
123-
report.stop >> report.num_gids >> report.buffer_size >> report.population_name >>
124-
report.population_offset;
122+
report.stop >> report.num_gids >> report.buffer_size;
125123

126124
report.target_type = static_cast<TargetType>(target);
127125
std::transform(report.type_str.begin(),
@@ -179,9 +177,10 @@ std::vector<ReportConfiguration> create_report_configurations(
179177
report_conf >> spikes_population_name;
180178
spikes_population_offset = 0;
181179
}
182-
spikes_population_name_offset.emplace_back(
180+
spikes_info.population_info.emplace_back(
183181
std::make_pair(spikes_population_name, spikes_population_offset));
184182
}
183+
report_conf >> spikes_info.file_name;
185184

186185
return reports;
187186
}

coreneuron/io/reports/sonata_report_handler.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ void SonataReportHandler::register_custom_report(const NrnThread& nt,
3838
register_report(nt, config, vars_to_report);
3939
}
4040

41+
std::pair<std::string, int> SonataReportHandler::get_population_info(int gid) {
42+
if (m_spikes_info.population_info.empty()) {
43+
return std::make_pair("All", 0);
44+
}
45+
std::pair<std::string, int> prev = m_spikes_info.population_info.front();
46+
for (const auto& name_offset: m_spikes_info.population_info) {
47+
std::string pop_name = name_offset.first;
48+
int pop_offset = name_offset.second;
49+
if (pop_offset > gid) {
50+
break;
51+
}
52+
prev = name_offset;
53+
}
54+
return prev;
55+
}
56+
4157
void SonataReportHandler::register_report(const NrnThread& nt,
4258
ReportConfiguration& config,
4359
const VarsToReport& vars_to_report) {
@@ -55,14 +71,14 @@ void SonataReportHandler::register_report(const NrnThread& nt,
5571
if (!vars.size())
5672
continue;
5773

58-
sonata_add_node(config.output_path.data(),
59-
config.population_name.data(),
60-
config.population_offset,
61-
gid);
74+
const auto& pop_info = get_population_info(gid);
75+
std::string population_name = pop_info.first;
76+
int population_offset = pop_info.second;
77+
sonata_add_node(config.output_path.data(), population_name.data(), population_offset, gid);
6278
sonata_set_report_max_buffer_size_hint(config.output_path.data(), config.buffer_size);
6379
for (const auto& variable: vars) {
6480
sonata_add_element(config.output_path.data(),
65-
config.population_name.data(),
81+
population_name.data(),
6682
gid,
6783
variable.id,
6884
variable.var_value);

coreneuron/io/reports/sonata_report_handler.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ namespace coreneuron {
1717

1818
class SonataReportHandler: public ReportHandler {
1919
public:
20-
SonataReportHandler(ReportConfiguration& config)
21-
: ReportHandler(config) {}
20+
SonataReportHandler(ReportConfiguration& config, const SpikesInfo& spikes_info)
21+
: ReportHandler(config)
22+
, m_spikes_info(spikes_info) {}
2223

2324
void create_report(double dt, double tstop, double delay) override;
2425
#ifdef ENABLE_SONATA_REPORTS
@@ -34,7 +35,11 @@ class SonataReportHandler: public ReportHandler {
3435
void register_report(const NrnThread& nt,
3536
ReportConfiguration& config,
3637
const VarsToReport& vars_to_report);
38+
std::pair<std::string, int> get_population_info(int gid);
3739
#endif // ENABLE_SONATA_REPORTS
40+
41+
private:
42+
SpikesInfo m_spikes_info;
3843
};
3944

4045
} // Namespace coreneuron

tests/integration/reportinglib/1.check.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if [ "$sonata_reports" = "ON" ]
2727
then
2828
if [ -f test_2.h5 ]
2929
then
30-
h5dump_diff=$(@H5DUMP_EXECUTABLE@ -d /report/All/data -y -O test_2.h5 | sed '1d;$d;s/,//g;s/ //g' | diff $test_ref -)
30+
h5dump_diff=$(@H5DUMP_EXECUTABLE@ -d /report/PopA/data -y -O test_2.h5 | sed '1d;$d;s/,//g;s/ //g' | diff $test_ref -)
3131

3232
if [ $? -ne 0 ]
3333
then
@@ -38,6 +38,11 @@ then
3838
echo "[ERROR] Expected SONATA soma file 'test_2.h5' doesn't exist. Test failed!" >&2
3939
exit $FAILED
4040
fi
41+
if [ ! -f spikes.h5 ]
42+
then
43+
echo "[ERROR] Expected SONATA spike file 'spikes.h5' doesn't exist. Test failed!" >&2
44+
exit $FAILED
45+
fi
4146
fi
4247

4348
# If we reach this point, all tests were successful
5 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)