Global vs. Pointers

NMODL and the Channel Builder.
Post Reply
tardebut
Posts: 21
Joined: Thu Sep 18, 2014 8:23 am

Global vs. Pointers

Post by tardebut »

Hi Ted,

I have two mechanisms, each of them in a .mod file. And I want one to read an state from the other.
In a somewhat related post viewtopic.php?f=16&t=3192 there were two different suggestions on how to achive this.
One was declaring the state a GLOBAL variable and reading it as EXTERNAL in the receiving mechanism. The other was to use pointers.

Is there some strong reason to prefer one over the other for this particular objective?

Thanks in advance,

Omar
ted
Site Admin
Posts: 6384
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Global vs. Pointers

Post by ted »

I have two mechanisms, each of them in a .mod file. And I want one to read an state from the other.
There are two ways to pass numerical values between different mechanisms. One is to exploit the ability of every mechanism to discover the values of local ionic concentrations. In the mechanism that computes the variable of interest, declare

Code: Select all

NEURON {
  . . .
  USEION x . . . WRITE xi : or xo

STATE {
  . . .
  xi (mM) : or xo
and in the mechanism that needs this value declare

Code: Select all

NEURON {
  . . .
  USEION x . . . READ xi : or xo

ASSIGNED {
  . . .
  xi (mM) : or xo
The advantage of this is that setting up communication between mechanisms requires no auxiliary hoc statements. The disadvantages are that such coupling can only occur within the same segment, and care must be taken to avoid collisions in name space if a given section contains two or more different pairs of mechanisms that need to be coupled.

The other way to communicate between different mechanisms is to use POINTERs, which avoid these limitations at the cost of requiring a setpointer statement for every pair of different mechanism instances that must be coupled. For examples see
Spiny neuron model with dopamine-induced bistability (Gruber et al 2003)
https://senselab.med.yale.edu/ModelDB/S ... odel=39949
One was declaring the state a GLOBAL variable and reading it as EXTERNAL in the receiving mechanism.
Now I see what you meant in that post of yours; I'll have to go back to that thread to see whether it is necessary to do anything to prevent others from having the same misunderstanding.

You're confusing C's use of "global" with NMODL's use of that keyword. NMODL's GLOBAL declaration is made in the NEURON block of a mechanism, and can only be applied to ASSIGNED or PARAMETER variables. It means only that the variable(s) declared GLOBAL will have the same value in every instance of that particular mechanism. NMODL has no "EXTERNAL" keyword that would allow different kinds of mechanism to refer to the same variable. For more information about declarations in the NEURON block see
http://www.neuron.yale.edu/neuron/stati ... tml#nmodl2
tardebut
Posts: 21
Joined: Thu Sep 18, 2014 8:23 am

Re: Global vs. Pointers

Post by tardebut »

Thanks Ted.

I agree with you regarding the use of GLOBAL. And in order to declare the value of an state as GLOBAL, the assigment of xout = state1 either at the end of the DERIVATIVE block or in the BEFORE BREAKPOINT block does the trick.
In this case 'state1' is the state I want to be seen by any other mechanims irrespective of its distribution. But it is 'xout' the one declared as GLOBAL.

Now, what seems to be a working solution for the communication is to declare in the NEURON block of the receiving mechanism,

EXTERNAL xout_fromwhereitwasdeclaredasglobal

The original question regarding the comparison of this approach to the use of pointers comes from a message one get when compliling these .mod.

"Notice: Assignment to the GLOBAL variable, "xout", is not thread safe"

What does it mean?

Thanks again,

Omar
ted
Site Admin
Posts: 6384
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: Global vs. Pointers

Post by ted »

tardebut wrote:in order to declare the value of an state as GLOBAL, the assigment of xout = state1 either at the end of the DERIVATIVE block or in the BEFORE BREAKPOINT block does the trick.
True, but I'm not sure that it is useful to do that. Suppose
1. foo is the name of such a mechanism, and
2. there is a model that has multiple instances of foo, and
3. each instance has a different value of state1 (STATEs are automatically RANGE variables and are likely to have values that differ across multiple instances of a mechanism)
Then
at the end of each advance, the value of foo's xout variable will be the value of state1 from the last instance of foo that was updated. And that is completely accidental--it depends on how the model was set up and how the model's equations are evaluated in the course of an advance.

Of course, if there is only one instance of foo, this problem doesn't arise.
Now, what seems to be a working solution for the communication is to declare in the NEURON block of the receiving mechanism,

EXTERNAL xout_fromwhereitwasdeclaredasglobal
Wow, I re-read the documentation of the NEURON block, and sure enough, there is an EXTERNAL keyword that can be used in the NEURON block http://www.neuron.yale.edu/neuron/stati ... l#external. I stand corrected, and I have learned something new and possibly useful. That said, I obviously haven't run into a situation in which some other strategy didn't work. Also, the requirement that the complete hoc name of the EXTERNAL variable be named in the NMODL file makes it difficult to write generalizable code. With POINTER, I can produce a mechanism that can be coupled to any other mechanism regardless of its name, because the coupling can be specified in hoc, instead of at the time that the NMODL code is compiled.
The original question regarding the comparison of this approach to the use of pointers comes from a message one get when compliling these .mod.

"Notice: Assignment to the GLOBAL variable, "xout", is not thread safe"
If a mechanism foo has some variable bar that is supposed to be GLOBAL, then every instance of foo is supposed to see the same value for bar. Under multithreaded code execution, each thread operates in its own address space, so there is no way that bar can be truly GLOBAL. At best, bar can be "GLOBAL on a per-thread basis" that is, thread j will have its own bar which has the same value for all foos in thread j, but the bar that belongs to thread k is likely to have a different value and can only be seen by the foos in thread k.
tardebut
Posts: 21
Joined: Thu Sep 18, 2014 8:23 am

Re: Global vs. Pointers

Post by tardebut »

Thanks Ted.

Omar
Post Reply