Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

callback for returning spikes from CORENEURON #692

Merged
merged 10 commits into from
Aug 8, 2020
Merged

callback for returning spikes from CORENEURON #692

merged 10 commits into from
Aug 8, 2020

Conversation

alexsavulescu
Copy link
Member

@alexsavulescu alexsavulescu commented Aug 3, 2020

NEURON facing callback: when we record all or some output spikes (i.e pc.spike_record( -1) or pc.spike_record(gidlist)) provide a callback so that CORENEURON can returnspike vectors.

In link with : BlueBrain/CoreNeuron#354

ps->record(spikevec, gidvec, ps->output_index_);
}
}}}
all_spiketvec = spikevec;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider reference counting all_spiketvec and all_spikegidvec through their obj_ field (if obj_ is non NULL).
In Vector.record and Vector.play this is accomplished through a more complicated InterViews Observer/Observable protocol but I don't recommend using that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean if all_spiketvec. obj_ is not null then delete it first before assigning? or something else? (Alex might have better idea about this)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Michael is referring to the usage of underlying vector, when we come back from CORENEURON make sure that this vector is still used (refcount > 0).

Copy link
Member

@pramodk pramodk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few comments to understand the implementation.

ps->record(spikevec, gidvec, ps->output_index_);
}
}}}
all_spiketvec = spikevec;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean if all_spiketvec. obj_ is not null then delete it first before assigning? or something else? (Alex might have better idea about this)

Comment on lines 1296 to 1303
if(all_spiketvec != nullptr && all_spikegidvec != nullptr) {
all_spiketvec->resize(spiketvec.size());
all_spikegidvec->resize(spikegidvec.size());
assert(all_spiketvec->capacity() == all_spikegidvec->capacity());
for(int i = 0; i < all_spiketvec->capacity(); ++i ) {
all_spiketvec->elem(i) = spiketvec[i];
all_spikegidvec->elem(i) = spikegidvec[i];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, I don't know the code but my undemanding was that: we will iterate every spikegidvec and then deliver event to respective PreSyn object with the same GID. This way the implementation work if PreSyns are using underlying different vectors.

I didn't understand fully how global all_spiketvec solution works here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we need to deliver events, since we are in "record" mode?

On spike_record, either we have gid=-1 for all gids or a gidlist, which would normally target a subset of all gids?
The deal with different vectors is not as straightforward. Say we record spikes for a subset of gids. On spikes return from CORENEURON we would have all gids spike data. We can match underlying different vectors, but then we need to consider writing out.dat for the gids that were not recorded in NEURON.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did discuss the idea of being generic with respect to the ways NEURON can have different vectors for recording spikes (and not even necessarily use gids but a user defined identifier). I don't remember if spikes are recorded on the CoreNEURON side when gid < 0 (the negative number can potentially identify a PreSyn without a gid) and just discarded if out.dat is written. But I'm not averse to the direct implementation Alex provided. It just may mean that a NEURON spike raster may have or be missing spike trains depending on whether CoreNEURON did the simulation or NEURON did the simulation. But I am ok with only supporting the NEURON case pc.spike_record(-1). Might be a good idea to comment about this limited support in the implementation.

We also discussed about a callback not being needed and just use a direct call into NEURON. But I realize not that would be a problem if CoreNEURON did not have NEURON in memory (eg. file transfer mode).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so discussed things through with Pramod. Keeping pc.spike_record(-1) code as optimisation (and apparently that would the regular case), and added code to handle pc.spike_record(gidlist).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Furthermore, we also cover the case of using pc.spike_record(-1) and then pc.spike_record(gidlist) by invalidating all_*vec pointers

@alexsavulescu alexsavulescu changed the title callback for returning all spikes from CORENEURON callback for returning spikes from CORENEURON Aug 4, 2020
@pramodk
Copy link
Member

pramodk commented Aug 4, 2020

looks good to me as well !

@alexsavulescu alexsavulescu marked this pull request as ready for review August 5, 2020 14:13
@alexsavulescu alexsavulescu force-pushed the all_spikes branch 5 times, most recently from e210224 to 25353b3 Compare August 5, 2020 19:44
@pramodk
Copy link
Member

pramodk commented Aug 5, 2020

@alexsavulescu : I took liberty to push change fafce52 to this PR. Now the issue is related to setting test:

9: numprocs=2
9: Assertion failed: file /gpfs/bbp.cscs.ch/project/proj16/kumbhar/pramod_scratch/nrn/src/nrniv/netpar.cpp, line 1112
9: 1 NEURON: gid2out_->find(gid, ps)
9: 1  near line 0
9: 1  create soma
9:             ^
9:         1 ParallelContext[0].spike_record(1, ..., ...)
9: Traceback (most recent call last):
9:   File "/gpfs/bbp.cscs.ch/project/proj16/kumbhar/pramod_scratch/nrn/test/coreneuron/test_spikes.py", line 70, in <module>
9:     test_spikes()
9:   File "/gpfs/bbp.cscs.ch/project/proj16/kumbhar/pramod_scratch/nrn/test/coreneuron/test_spikes.py", line 54, in test_spikes
9:     corenrn_all_spike_gids )
9: RuntimeError: hoc error
9: MPT ERROR: MPI_COMM_WORLD rank 1 has terminated without calling MPI_Finalize()
9: 	aborting job
1/1 Test #9: coreneuron_mpi_spikes_py .........***Failed    1.76 sec

cc: @nrnhines

@alexsavulescu
Copy link
Member Author

@pramodk I followed rxd strategy and used mpi4py.
From test/rxd/conftest.py :

    # to use NEURON with MPI, mpi4py must be imported first.
    if request.config.getoption("--mpi"):
        from mpi4py import MPI  # noqa: F401 

Copy link
Member

@pramodk pramodk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bit of mystery about failure with python+internal mpi but this looks good for merge now!

@nrnhines nrnhines merged commit cbabda2 into master Aug 8, 2020
@nrnhines nrnhines deleted the all_spikes branch August 8, 2020 12:25
olupton pushed a commit that referenced this pull request Dec 7, 2022
* Fixes compilation issue when the operator() was declared as const while it changed some of values outside of its scope in the sympy solver

* Use DefUseAnalyzeVisitor to find out whether the operator() is Using or Defining any of the variables outside its scope

* Update DefUseAnalyzeVisitor to be able to process LOCAL variables as well, given precedence to GLOBAL/RANGE variables, when they have the same name

* Added related unit tests

* Fix codegen issue in CONSTRUCTOR and DESTRUCTOR blocks code when compiled for CoreNEURON

Fixes #691
FIxes #692
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants