1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
{load_file("nrngui.hoc")} // load the GUI and standard run libraries
objref pc
pc = new ParallelContext()
//////////////////////////////////
// Step 1: Define the cell classes
//////////////////////////////////
{load_file("cell.hoc")}
//////////////////////////////////////////////////////////////
// Steps 2 and 3 are to create the cells and connect the cells
//////////////////////////////////////////////////////////////
NCELL = 20 // total number of cells in the ring network
// identical to total number of cells on all machines
objref cells, nclist // cells will be a List that holds
// all instances of network cells that exist on this host
// nclist will hold all NetCon instances that exist on this host
// and connect network spike sources to targets on this host (nclist)
proc mkring() {
mkcells($1) // create the cells
connectcells() // connect them together
}
// creates the cells and appends them to a List called cells
// argument is the number of cells to be created
proc mkcells() {local i localobj cell, nc, nil
cells = new List()
// each host gets every nhost'th cell,
// starting from the id of the host
// and continuing until all cells have been dealt out
for (i=pc.id; i < $1; i += pc.nhost) {
cell = new B_BallStick()
cells.append(cell)
pc.set_gid2node(i, pc.id) // associate gid i with this host
nc = cell.connect2target(nil) // attach spike detector to cell
pc.cell(i, nc) // associate gid i with spike detector
}
}
// connects the cells
// appends the NetCons to a List called nclist
proc connectcells() {local i, targid localobj src, target, syn, nc
nclist = new List()
for i=0, NCELL - 1 { // iterating over source gids
targid = (i+1)%NCELL
if (!pc.gid_exists(targid)) { continue }
target = pc.gid2cell(targid)
syn = target.synlist.object(0) // the first object in synlist
// is an ExpSyn with e = 0, therefore an excitatory synapse
nc = pc.gid_connect(i, syn)
nclist.append(nc)
nc.delay = 1
nc.weight = 0.01
}
}
mkring(NCELL) // go ahead and create the net!
//////////////////////////////////////////////////
// Instrumentation, i.e. stimulation and recording
//////////////////////////////////////////////////
// stim will be an artificial spiking cell that generates a "spike" event
// that is delivered to the first cell in the net by ncstim
// in order to initiate network spiking.
// We won't bother including this "external stimulus source" or its NetCon
// in the network's lists of cells or NetCons.
objref stim, ncstim
proc mkstim() {
// exit if the first cell in the net does not exist on this host
if (!pc.gid_exists(0)) { return }
pc.gid2cell(0).soma stim = new IClamp(.5)
stim.dur=1
stim.amp=1
return
stim = new NetStim()
stim.number = 1
stim.start = 0
ncstim = new NetCon(stim, pc.gid2cell(0).synlist.object(0))
ncstim.delay = 1 //cannot be 0 with multiple threads
ncstim.weight = 0.01
}
mkstim()
objref tvec, idvec // will be Vectors that record all spike times (tvec)
// and the corresponding id numbers of the cells that spiked (idvec)
proc spikerecord() {local i localobj nc, nil
tvec = new Vector()
idvec = new Vector()
for i=0, cells.count-1 {
nc = cells.object(i).connect2target(nil)
nc.record(tvec, idvec, nc.srcgid)
// the Vector will continue to record spike times
// even after the NetCon has been destroyed
}
}
spikerecord()
/////////////////////
// Simulation control
/////////////////////
nthread = 2
{cvode.cache_efficient(1)} // required for nrncore
{pc.nthread(nthread, 0)} // lowest_level_load stores nthread groups of cells
tstop = 100
{pc.set_maxstep(10)}
stdinit()
{pc.psolve(tstop)}
////////////////////////////
// Report simulation results
////////////////////////////
proc spikeout() { local i, rank localobj outdat
pc.barrier() // wait for all hosts to get to this point
outdat = new File()
if (pc.id==0) {
outdat.wopen("out.dat")
outdat.printf("\ntime\t cell\n") // print header once
outdat.close()
}
for rank=0, pc.nhost-1 { // host 0 first, then 1, 2, etc.
if (rank==pc.id) {
outdat.aopen("out.dat")
for i=0, tvec.size-1 {
outdat.printf("%g\t %d\n", tvec.x[i], idvec.x[i])
}
outdat.close()
}
pc.barrier() // wait for all hosts to get to this point
}
}
spikeout()
{pc.nrnbbcore_write()}
{pc.runworker()}
{pc.done()}
quit()
|