Defining a POINTER to be a list
Defining a POINTER to be a list
I have the following NEURON block in a MOD file:
NEURON {
POINT_PROCESS NMDASynPost
POINTER s[2047]
RANGE e, i, mg_conc, g, b, g_syn[2047]
NONSPECIFIC_CURRENT i
}
When I run modlunit on the file, I get the following error:
model 1.1.1.1 1994/10/12 17:22:51
Checking units of nmdasynpost.mod
syntax error:
syntax is: USEION ion READ list WRITE list:
Illegal block at line 6 in file nmdasynpost.mod
POINTER s[2047]
In this model, a value for s is received from each of 2,047 afferent neurons. Hence, I'd like s to be a list of length 2,047. (What would be even better would be to have s be a list of variable size, in case I decide to change the size of my network later.) What have I done wrong, and how do I fix it?
EDIT: Now that I think about it, I'm not sure how s would ever work as a list (array is what I mean). How would I set the pointer to 2,047 different variables? I'm using NEURON's Python implementation, and there seems to be no way to make h.setpointer accept a many-variable pointer.
(For a related case, see http://www.neuron.yale.edu/phpbb/viewto ... f=16&t=310.)
Many thanks,
Dan
NEURON {
POINT_PROCESS NMDASynPost
POINTER s[2047]
RANGE e, i, mg_conc, g, b, g_syn[2047]
NONSPECIFIC_CURRENT i
}
When I run modlunit on the file, I get the following error:
model 1.1.1.1 1994/10/12 17:22:51
Checking units of nmdasynpost.mod
syntax error:
syntax is: USEION ion READ list WRITE list:
Illegal block at line 6 in file nmdasynpost.mod
POINTER s[2047]
In this model, a value for s is received from each of 2,047 afferent neurons. Hence, I'd like s to be a list of length 2,047. (What would be even better would be to have s be a list of variable size, in case I decide to change the size of my network later.) What have I done wrong, and how do I fix it?
EDIT: Now that I think about it, I'm not sure how s would ever work as a list (array is what I mean). How would I set the pointer to 2,047 different variables? I'm using NEURON's Python implementation, and there seems to be no way to make h.setpointer accept a many-variable pointer.
(For a related case, see http://www.neuron.yale.edu/phpbb/viewto ... f=16&t=310.)
Many thanks,
Dan
Re: Defining a POINTER to be a list
The concept of array of pointers is not implemented in nmodl. So one needs to implement the necessary functionality in the mod file using VERBATIM blocks. This would be particularly easy if
the hoc PtrVector exposed its public double** pd_ wiht a c accessor function like happens with the hoc Vector class. I should do that. In lieu of that, you have to do it all in VERBATIM blocks.
The relevant mod file fragments are
and here is a test
the hoc PtrVector exposed its public double** pd_ wiht a c accessor function like happens with the hoc Vector class. I should do that. In lieu of that, you have to do it all in VERBATIM blocks.
The relevant mod file fragments are
Code: Select all
$ cat pvec.mod
NEURON {
POINT_PROCESS Foo
POINTER pvec
}
ASSIGNED { pvec }
PROCEDURE declare_pvec(n) {
VERBATIM
{
double*** pd = (double***)(&(_p_pvec));
*pd = (double**)hoc_Ecalloc((size_t)_ln, sizeof(double*));
}
ENDVERBATIM
}
PROCEDURE set_pvec(i) {
VERBATIM
{
double** pd = (double**)_p_pvec;
pd[(int)_li] = hoc_pgetarg(2);
}
ENDVERBATIM
}
FUNCTION getval(i) {
VERBATIM
{
double** pd = (double**)_p_pvec;
_lgetval = *pd[(int)_li];
}
ENDVERBATIM
}
Code: Select all
$ cat pvec.hoc
x = 1
y = 2
create soma
objref foo
foo = new Foo(.5)
{
foo.declare_pvec(2)
foo.set_pvec(0, &x)
foo.set_pvec(1, &y)
}
foo.getval(0)
x=5
foo.getval(0)
Re: Defining a POINTER to be a list
Many thanks! It appears that range variables cannot be arrays as well.
-
- Site Admin
- Posts: 6302
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: Defining a POINTER to be a list
You're thinking about how to implement an array of parameters. Why not use an array of POINTERs for that too? Store the parameter values in a Vector, and link each parameter POINTER to the corresponding Vector element.dabliss wrote:It appears that range variables cannot be arrays as well.
Re: Defining a POINTER to be a list
Yep, that worked for me.
I guess I can't run this model in parallel?
Code: Select all
Notice: Use of POINTER is not thread safe.
Notice: VERBATIM blocks are not thread safe
-
- Site Admin
- Posts: 6302
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: Defining a POINTER to be a list
True. POINTERs require confining code to a single address space.dabliss wrote:I guess I can't run this model in parallel?
Re: Defining a POINTER to be a list
Strictly speaking, POINTER is threadsafe if it points to an address which is part of the same thread. In practice, modulo multisplit, this means it has to point to some variable that is part of
the same cell. So POINTER can be threadsafe if it points to a another mechanism variable that exists in the same compartment or section. However this cannot be automatically determined
by the nmodl translator, so it is up the the author/user to judge whether the usage of the mod file is, in fact, threadsafe and, if so, it is correct to so declare at the beginning of the NEURON block
using the keyword
THREADSAFE
the same cell. So POINTER can be threadsafe if it points to a another mechanism variable that exists in the same compartment or section. However this cannot be automatically determined
by the nmodl translator, so it is up the the author/user to judge whether the usage of the mod file is, in fact, threadsafe and, if so, it is correct to so declare at the beginning of the NEURON block
using the keyword
THREADSAFE
Re: Defining a POINTER to be a list
Mod file ASSIGNED and STATE variables can be declared as arrays. However the size is determined at compile time and is not dynamically adjustable.
Re: Defining a POINTER to be a list
Ah, many thanks for the explanation.
Follow-up question: Is it true that, using the code you supplied above (pvec), I don't need to include in my model a call to setpointer?
Follow-up question: Is it true that, using the code you supplied above (pvec), I don't need to include in my model a call to setpointer?
Re: Defining a POINTER to be a list
Correct. The replacement call in the test is
foo.set_pvec(...)
Note that my mod file contains no checking. Things that can go wrong are: indices < 0 or >= n, Memory that is pointed to is freed, Not all pointers are set.
Segmentatiion violations might occur if the pointers do not point to valid memory. and worse will occur if invalid pointers try to change what they point to.
foo.set_pvec(...)
Note that my mod file contains no checking. Things that can go wrong are: indices < 0 or >= n, Memory that is pointed to is freed, Not all pointers are set.
Segmentatiion violations might occur if the pointers do not point to valid memory. and worse will occur if invalid pointers try to change what they point to.
-
- Site Admin
- Posts: 6302
- Joined: Wed May 18, 2005 4:50 pm
- Location: Yale University School of Medicine
- Contact:
Re: Defining a POINTER to be a list
But PARAMETER variables cannot?hines wrote:Mod file ASSIGNED and STATE variables can be declared as arrays.
Re: Defining a POINTER to be a list
My mistake, PARAMETER variables can also be fixed length array RANGE variables as well
Re: Defining a POINTER to be a list
How would I make a call to set_pvec in Python?
The last line of the above chunk of code raises the following error:
This is because set_pvec is expecting the address of x (&x), which I'm not sure can be passed in Python.
Code: Select all
from neuron import h
x = 1
foo = h.Foo(0.5)
foo.declare_pvec(2)
foo.set_pvec(0, x)
Code: Select all
bad stack access: expecting (double *); really (double)
NEURON: interpreter stack type error
near line 0
create soma
^
Foo[0].set_pvec(0, 1)
oc_restore_code tobj_count=1 should be 0
Re: Defining a POINTER to be a list
Yes. It is not allowed to take the address of the python x reference.
If you can arrange to use range variable (or hoc variables) in place of x, then you can call
foo.set_vec(0, h._ref_x) #where x is the range variable name. In particular
might prove helpful.
If you can arrange to use range variable (or hoc variables) in place of x, then you can call
foo.set_vec(0, h._ref_x) #where x is the range variable name. In particular
Code: Select all
v = h.Vector(20)
for i in range(len(v)):
foo.set_vec(i, v._ref_x[i])
Re: Defining a POINTER to be a list
Hello,
I am facing the same issue, but time is now 2020. Dear experts, is there an easy way to
accomplish to declare an array of POINTERs in a Point Process?
I am facing the same issue, but time is now 2020. Dear experts, is there an easy way to
accomplish to declare an array of POINTERs in a Point Process?