Here is a python example for a function that takes a vector argument, reverses it and posts a result vector.
Again, a hoc stub function is used to help with the callback.
It may be a while before I get to pure python callbacks. Mostly because I expect the typical
usage is the requirement of handling vectors and (without a lot of programming effort on my part)
those have to be hoc vectors.
The output of a three core run is:
Code: Select all
$ mpiexec -n 3 nrniv -mpi -python submitlistold.py
numprocs=3
NEURON -- VERSION 7.2 (371:249faaed5faa) 2009-11-13
Duke, Yale, and the BlueBrain Project -- Copyright 1984-2008
See http://www.neuron.yale.edu/credits.html
i= 0 from host 0 [0.0, 1.0, 2.0, 3.0] [3.0, 2.0, 1.0, 0.0]
i= 3 from host 0 [300.0, 301.0, 302.0, 303.0] [303.0, 302.0, 301.0, 300.0]
i= 2 from host 2 [200.0, 201.0, 202.0, 203.0] [203.0, 202.0, 201.0, 200.0]
i= 1 from host 1 [100.0, 101.0, 102.0, 103.0] [103.0, 102.0, 101.0, 100.0]
i= 4 from host 2 [400.0, 401.0, 402.0, 403.0] [403.0, 402.0, 401.0, 400.0]
And here is the code. Some things to note are that vector contents are copied to the
bulletin board and the original is available despite the modification of the copy when
it reaches f. Also a python quit() doesn't clean up properly and one gets an error message
on exit which is avoided with h.quit()
Code: Select all
from neuron import h
from time import sleep
pc = h.ParallelContext()
def f(i, hvec):
sleep(.1)
hvec.reverse()
pc.post(i, pc.id(), hvec)
return hvec.sum()
h('''objref po
po = new PythonObject()
func f() { return po.f($1, $o2) }
''')
pc.runworker()
for i in range(5):
pc.submit('f', i, h.Vector(4).indgen().add(i*100))
x = 0
while pc.working():
i = int(pc.upkscalar()) #the first arg of f
va = pc.upkvec() #the second arg of f
x += pc.retval()
pc.take(i)
pid = int(pc.upkscalar())
v = pc.upkvec()
print 'i=', i, 'from host', pid, list(va), list(v)
pc.done()
h.quit()