//genesis // // tools.g - collection of simulation tools function stage if(parallel) barrier if(control_node) echo {getdate}: {argv} end else echo {getdate}: {argv} end end int try=0, arg1=1, arg2=2 function getopt str opt, optnam, optval="0" int i, optpos for(i = 1; i <= {argc}; i = i + 1) opt = {argv {i}} if(opt == "-opt") optnam = {argv {i + 1}} optpos = {argv {i + 2}} i = i + 2 end end for(i = 1; i <= {argc}; i = i + 1) opt = {argv {i}} if(opt == {strcat "-" {optnam}}) if(optpos != 0) optval = {argv {i + optpos}} i = i + optpos else optval = "1" end end end return {optval} end function get_options if({getopt {argv} -opt n {try}}) nsegs = {getopt {argv} -opt n {arg1}} if(nsegs < 1) echo error: nsegs cannot be less than 1 ({nsegs} given) quit end preplength = nsegs * lunit necells = nye * nsegs nicells = nyi * nsegs nmcells = nym * nsegs end if({getopt {argv} -opt t {try}}) simtime = {getopt {argv} -opt t {arg1}} if(simtime < 0) echo error: simtime cannot be less than 0 ({simtime} given) quit end end if({getopt {argv} -opt j {try}}) inject = {getopt {argv} -opt j {arg1}} end if({getopt {argv} -opt p {try}}) cellproto = {getopt {argv} -opt p {arg1}} end if({getopt {argv} -opt lookahead {try}}) lookahead = {getopt {argv} -opt lookahead {arg1}} if(lookahead < 0) echo error: lookahead must be greater than 0 ({lookahead} given) quit end end if({getopt {argv} -opt h {try}}) float timestep = {getopt {argv} -opt h {arg1}} if(timestep < 0) echo error: timestep cannot be less than 0 ({timestep} given) quit end SIMDT = timestep end randinit = {getopt {argv} -opt randinit {try}} solver = {getopt {argv} -opt hsolve {try}} if({getopt {argv} -opt parallel {try}}) nodes = {getopt {argv} -opt parallel {arg1}} if(nodes < 2) echo error: cannot run on less than 2 nodes ({nodes} given) quit end end end function siminit setrand -sprng if(nodes > 1) paron -nodes {nodes} -parallel if(randinit) randseed {{mynode} + {randseed}} else randseed {mynode} end parallel = 1 control_node = ({mynode} == 0) worker_node = !control_node if(worker_node) create neutral /proto/map addfield /proto/map nodelist create neutral /map disable /map end else if(randinit) randseed end end end function simschedule setclock 0 {SIMDT} setclock 1 {IODT} if(parallel) if(lookahead > 0.0) setfield /post sync_before_step 0 setlookahead {lookahead} end end if(solver) if(parallel) if(worker_node) call /model/#[] SETUP end else call /model/#[] SETUP end setmethod 11 end reset end function simfinish if(parallel) barrier paroff end end function create_volume(source, dest, ncells, x, y, z, dx, dy, dz) float x, y, z, dx, dy, dz str source, dest float xc, dc int ncells str cell, name, list int nslice, remainder, node, idx, i if(ncells > 1) dc = dx / (ncells - 1) end if(parallel) if(control_node) xc = x idx = 0 nslice = ncells / (nodes - 1) remainder = ncells - nslice * (nodes - 1) for(node = 1; node <= remainder; node = node + 1) for(i = 1; i <= nslice + 1; i = i + 1) copy@{node} {source} {dest}[{idx}] position@{node} {dest}[{idx}] {xc} {rand {y} {y + dy}} \ {rand {z} {z + dz}} idx = idx + 1 xc = xc + dc end list = list @ "," @ {node} end if(nslice > 0) for(node = remainder + 1; node < nodes; node = node + 1) for(i = 1; i <= nslice; i = i + 1) copy@{node} {source} {dest}[{idx}] position@{node} {dest}[{idx}] {xc} {rand {y} {y + dy}} \ {rand {z} {z + dz}} idx = idx + 1 xc = xc + dc end list = list @ "," @ {node} end end list = {substring {list} 2} name = {getpath {dest} -tail} copy@other /proto/map /map/{name} setfield@other /map/{name} nodelist {list} end else xc = x copy {source} {dest} -repeat {ncells} foreach cell ({el {dest}[]}) position {cell} {xc} {rand {y} {y + dy}} {rand {z} {z + dz}} xc = xc + dc end end end function present(path) str path, c foreach c ({el {path}}) return 1 end return 0 end function volume_connect(source, dest, destname, x1, y1, z1, x2, y2, z2, prob) str source, dest, destname float prob if(parallel) if(worker_node) str node str destnodes = {getfield /map/{destname} nodelist} if({present {source}}) foreach node ({arglist {strsub {destnodes} "," " " -all}}) rvolumeconnect {source} {dest}@{node} -relative \ -sourcemask box -1 -1 -1 1 1 1 \ -destmask box {x1} {y1} {z1} {x2} {y2} {z2} \ -probability {prob} end end barrier else barrier end else volumeconnect {source} {dest} -relative -sourcemask box -1 -1 -1 1 1 1 \ -destmask box {x1} {y1} {z1} {x2} {y2} {z2} -probability {prob} end end function volume_delay(source, dest, velocity) str source, dest float velocity if(parallel) if(worker_node) rvolumedelay {source} {dest} -radial {velocity} -uniform 0.5 barrier rvolumedelay {source} {dest} -add -fixed 0.001 barrier else barrier barrier end else volumedelay {source} {dest} -radial {velocity} -uniform 0.5 volumedelay {source} {dest} -add -fixed 0.001 end end function volume_weight(source, dest, weight) str source, dest float weight, w0, rate int decay = {getopt {argv} -opt decay {try}} if(decay) rate = {getopt {argv} -opt decay {arg1}} w0 = {getopt {argv} -opt decay {arg2}} end if(parallel) if(worker_node) if(decay) rvolumeweight {source} {dest} -decay {rate} {w0} {weight} else rvolumeweight {source} {dest} -fixed {weight} end barrier else barrier end else if(decay) volumeweight {source} {dest} -decay {rate} {w0} {weight} else volumeweight {source} {dest} -fixed {weight} end end end function modfield(path, field) str path, field float value, factor, fac1, fac2 str c if({getopt {argv} -opt fixed {try}}) factor = {getopt {argv} -opt fixed {arg1}} foreach c ({el {path}}) if({exists {c} {field}}) value = {getfield {c} {field}} setfield {c} {field} {value * factor} end end end if({getopt {argv} -opt uniform {try}}) fac1 = {getopt {argv} -opt uniform {arg1}} fac2 = {getopt {argv} -opt uniform {arg2}} foreach c ({el {path}}) if({exists {c} {field}}) value = {getfield {c} {field}} factor = {rand {fac1} {fac2}} setfield {c} {field} {value * factor} end end end if({getopt {argv} -opt add {try}}) fac1 = {getopt {argv} -opt add {arg1}} fac2 = {getopt {argv} -opt add {arg2}} foreach c ({el {path}}) if({exists {c} {field}}) value = {getfield {c} {field}} factor = {rand {fac1} {fac2}} setfield {c} {field} {value + factor} end end end end function recspikes(source, dest, tab) str source, dest, tab, spike create spikehistory {tab} if(parallel) setfield {tab} filename {dest}-{mynode}.out \ ident_toggle 1 initialize 1 leave_open 1 flush 1 else setfield {tab} filename {dest}.out \ ident_toggle 1 initialize 1 leave_open 1 flush 1 end foreach spike ({el {source}}) addmsg {spike} {tab} SPIKESAVE end end function create_otable(tabname, length) str tabname float length create table {tabname} call {tabname} TABCREATE {length / IODT} 0 {length} setfield {tabname} step_mode 3 useclock {tabname} 1 end function create_ttable(tabname, length) str tabname float length create table {tabname} call {tabname} TABCREATE {length * FMAX} 0 {length} setfield {tabname} step_mode 4 stepsize -0.04 useclock {tabname} 1 end function write_table(tabname, file) str tabname, file tab2file {file} {tabname} table -overwrite end function recdata(src, field, out, simlength, spikes) str src, out, comp, field, spikes float simlength int i = 0 foreach comp ({el {src}}) if({spikes} == "-spikes") create_ttable {out}[{i}] {simlength} else create_otable {out}[{i}] {simlength} end addmsg {comp} {out}[{i}] INPUT {field} i = i + 1 end end function writedata(src, dest) str src, dest, tab int i = 0 if(parallel) foreach tab ({el {src}[]}) tab2file {dest}-{i}-{mynode}.out {tab} table -overwrite i = i + 1 end else foreach tab ({el {src}[]}) tab2file {dest}-{i}.out {tab} table -overwrite i = i + 1 end end end