Thanks for the updated vecevent.mod
So even if the VecStim object is not threadsafe, if a single cell model was split into pieces to run in multiple threads, could VecStim objects still be used as sources for NetCon objects targeting point processes in the multisplit cell, or not? Artificial cells aren't even associated with sections, so maybe?
Also, I have another .mod file that uses VERBATIM blocks that compiles as thread safe. What makes the difference?
Code: Select all
NEURON {
POINT_PROCESS Pr
RANGE P, P0, random, f, tau_F, d1, tau_D1, d2, tau_D2, F, D1, D2, tlast
THREADSAFE
POINTER randObjPtr
}
PARAMETER {
: the (1) is needed for the range limits to be effective
P0 = 0.5 (1) < 0, 1 > : basal release probability
: these values are from Fig.3 in Varela et al. 1997
f = 0.917 (1) < 0, 1e9 > : additive facilitation per spike
tau_F = 94 (ms) < 1e-9, 1e9 > : rate of decay back to baseline following facilitation
d1 = 0.416 (1) < 0, 1 > : multiplicative fast depression per spike
tau_D1 = 380 (ms) < 1e-9, 1e9 > : rate of decay back to baseline following fast depression
d2 = 0.975 (1) < 0, 1 > : multiplicative slow depression per spike
tau_D2 = 9200 (ms) < 1e-9, 1e9 > : rate of decay back to baseline following slow depression
}
ASSIGNED {
P : instantaneous release probability
randObjPtr : pointer to a hoc random number generator Random.uniform(0,1)
random : individual instance of random number
F : current level of facilitation
D1 : current level of fast depression
D2 : current level of slow depression
tlast (ms) : time of last spike
}
INITIAL {
P = P0
random = 1
F = 1
D1 = 1
D2 = 1
}
NET_RECEIVE(weight) {
INITIAL {
tlast = t
}
F = 1 + (F-1)*exp(-(t - tlast)/tau_F)
D1 = 1 - (1-D1)*exp(-(t - tlast)/tau_D1)
: D2 = 1 - (1-D2)*exp(-(t - tlast)/tau_D2)
: if (P0*F*D1*D2 > 1) {
if (P0*F*D1 > 1) {
P = 1
} else {
: P = P0*F*D1*D2
P = P0*F*D1
}
random = randGen()
if (random <= P) {
net_event(t)
}
tlast = t
F = F + f
D1 = D1 * d1
: D2 = D2 * d2
}
VERBATIM
double nrn_random_pick(void* r);
void* nrn_random_arg(int argpos);
ENDVERBATIM
FUNCTION randGen() {
VERBATIM
if (_p_randObjPtr) {
/*
:Supports separate independent but reproducible streams for
: each instance. However, the corresponding hoc Random
: distribution MUST be set to Random.uniform(0,1)
*/
_lrandGen = nrn_random_pick(_p_randObjPtr);
}else{
hoc_execerror("Random object ref not set correctly for randObjPtr"," only via hoc Random");
}
ENDVERBATIM
}
PROCEDURE setRandObjRef() {
VERBATIM
void** pv4 = (void**)(&_p_randObjPtr);
if (ifarg(1)) {
*pv4 = nrn_random_arg(1);
}else{
*pv4 = (void*)0;
}
ENDVERBATIM
}