Skip to content

Commit f1de7bb

Browse files
authored
Patternstim fix : allow restore phases to provide new pattern-stim (BlueBrain/CoreNeuron#121)
* Allow restore phases to provide new pattern stim via CLI * Add save-restore test with patternstim * NOTE : if restore pattern stim file has event at the checkpoint time boundary then the event could be missed. See https://bbpteam.epfl.ch/project/issues/browse/CNEUR-313 CoreNEURON Repo SHA: BlueBrain/CoreNeuron@b1ee4fa
1 parent d4bd56a commit f1de7bb

File tree

6 files changed

+38
-9
lines changed

6 files changed

+38
-9
lines changed

src/coreneuron/apps/main1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ void nrn_init_and_load_data(int argc,
265265

266266
// Invoke PatternStim
267267
if (!corenrn_param.patternstim.empty()) {
268-
nrn_mkPatternStim(corenrn_param.patternstim.c_str());
268+
nrn_mkPatternStim(corenrn_param.patternstim.c_str(), corenrn_param.tstop);
269269
}
270270

271271
/// Setting the timeout

src/coreneuron/mechanism/mech/modfile/pattern.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ void pattern_stim_setup_helper(int size, double* tv, int* gv, _threadargsproto_)
116116
info->size = size;
117117
info->tvec = tv;
118118
info->gidvec = gv;
119+
// initiate event chain (needed in case of restore)
120+
artcell_net_send ( _tqitem, -1, (Point_process*) _nt->_vdata[_ppvar[1*_STRIDE]], t + 0.0 , 1.0 ) ;
119121
}
120122
} // namespace coreneuron
121123
ENDVERBATIM

src/coreneuron/mechanism/patternstim.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extern void pattern_stim_setup_helper(int size,
5858
NrnThread* _nt,
5959
double v);
6060

61-
static size_t read_raster_file(const char* fname, double** tvec, int** gidvec);
61+
static size_t read_raster_file(const char* fname, double** tvec, int** gidvec, double tstop);
6262

6363
int nrn_extra_thread0_vdata;
6464

@@ -77,7 +77,7 @@ void nrn_set_extra_thread0_vdata() {
7777

7878
// fname is the filename of an output_spikes.h format raster file.
7979
// todo : add function for memory cleanup (to be called at the end of simulation)
80-
void nrn_mkPatternStim(const char* fname) {
80+
void nrn_mkPatternStim(const char* fname, double tstop) {
8181
int type = nrn_get_mechtype("PatternStim");
8282
if (!corenrn.get_memb_func(type).sym) {
8383
printf("nrn_set_extra_thread_vdata must be called (after mk_mech, and before nrn_setup\n");
@@ -93,7 +93,7 @@ void nrn_mkPatternStim(const char* fname) {
9393
int* gidvec;
9494

9595
// todo : handle when spike raster will be very large (int < size_t)
96-
size_t size = read_raster_file(fname, &tvec, &gidvec);
96+
size_t size = read_raster_file(fname, &tvec, &gidvec, tstop);
9797

9898
Point_process* pnt = nrn_artcell_instantiate("PatternStim");
9999
NrnThread* nt = nrn_threads + pnt->_tid;
@@ -123,7 +123,8 @@ static bool spike_comparator(const spike_type& l, const spike_type& r) {
123123
return l.first < r.first;
124124
}
125125

126-
size_t read_raster_file(const char* fname, double** tvec, int** gidvec) {
126+
127+
size_t read_raster_file(const char* fname, double** tvec, int** gidvec, double tstop) {
127128
FILE* f = fopen(fname, "r");
128129
nrn_assert(f);
129130

@@ -138,7 +139,9 @@ size_t read_raster_file(const char* fname, double** tvec, int** gidvec) {
138139
int gid;
139140

140141
while (fscanf(f, "%lf %d\n", &stime, &gid) == 2) {
141-
spikes.push_back(std::make_pair(stime, gid));
142+
if ( stime >= t && stime <= tstop) {
143+
spikes.push_back(std::make_pair(stime, gid));
144+
}
142145
}
143146

144147
fclose(f);

src/coreneuron/nrniv/nrniv_decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ extern int nrn_setup_extracon;
7070
extern void nrn_cleanup();
7171
extern void nrn_cleanup_ion_map();
7272
extern void BBS_netpar_solve(double);
73-
extern void nrn_mkPatternStim(const char* filename);
73+
extern void nrn_mkPatternStim(const char* filename, double tstop);
7474
extern int nrn_extra_thread0_vdata;
7575
extern void nrn_set_extra_thread0_vdata(void);
7676
extern Point_process* nrn_artcell_instantiate(const char* mechname);

tests/jenkins/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ pipeline {
320320
}
321321
}
322322
}
323-
stage('patstim'){
323+
stage('patstim save restore'){
324324
stages{
325325
stage('neuron'){
326326
steps{

tests/jenkins/run_corenrn.sh

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,31 @@ else
1818
fi
1919

2020
if [ "${TEST}" = "patstim" ]; then
21-
mpirun -n ${MPI_RANKS} ./${CORENRN_TYPE}/special-core --mpi -e 100 --pattern patstim.spk -d test${TEST}dat -o ${TEST}
21+
# first run full run
22+
mpirun -n ${MPI_RANKS} ./${CORENRN_TYPE}/special-core --mpi -e 100 --pattern patstim.spk -d testpatstimdat -o ${TEST}
23+
24+
# split patternstim file into two parts : total 2000 events, split at line no 1001 i.e. before events for 50 msec
25+
echo 1000 > patstim.1.spk
26+
sed -n 2,1001p patstim.spk >> patstim.1.spk
27+
echo 1000 > patstim.2.spk
28+
sed -n 1002,2001p patstim.spk >> patstim.2.spk
29+
30+
# run test with checkpoint : part 1
31+
mpirun -n ${MPI_RANKS} ./${CORENRN_TYPE}/special-core --mpi -e 49 --pattern patstim.1.spk -d testpatstimdat -o ${TEST}_part1 --checkpoint checkpoint
32+
33+
# run test with restore : part 2
34+
mpirun -n ${MPI_RANKS} ./${CORENRN_TYPE}/special-core --mpi -e 100 --pattern patstim.2.spk -d testpatstimdat -o ${TEST}_part2 --restore checkpoint
35+
36+
# run additional restore by providing full patternstim in part 2 : part 3
37+
mpirun -n ${MPI_RANKS} ./${CORENRN_TYPE}/special-core --mpi -e 100 --pattern patstim.spk -d testpatstimdat -o ${TEST}_part3 --restore checkpoint
38+
39+
# part 2 and part 3 should be same (part 3 ignore extra events in pattern stim)
40+
diff -w ${TEST}_part2/out.dat ${TEST}_part3/out.dat
41+
42+
# combine spikes from part1 and part2 should be same as full run
43+
cat ${TEST}_part1/out.dat ${TEST}_part2/out.dat > ${TEST}/out.saverestore.dat
44+
diff -w ${TEST}/out.dat ${TEST}/out.saverestore.dat
45+
2246
elif [ "${TEST}" = "ringtest" ]; then
2347
mpirun -n ${MPI_RANKS} ./${CORENRN_TYPE}/special-core --mpi -e 100 -d coredat -o ${TEST}
2448
elif [ "${TEST}" = "tqperf" ]; then

0 commit comments

Comments
 (0)