def launch_nk(params,debug=False,device=0,log=False): """ Launch Neurokernel """ if log: screen = True logger = setup_logger(file_name=params['name'] +'.log', screen=screen) man = Manager() man.add(LPU, params['name'], params['dt'], params['n_dict'], params['s_dict'], input_file=params['input_file'], output_file=params['output_file'], device=device, debug=debug, components=params['components']) man.spawn() man.start(int(params['steps'])) man.wait()
def run_lif(payload): """ Run an example lif model through the nk_server json interface """ print payload payload = json.loads(payload) params = payload['params'] sim_input = payload['input'] data_dir = 'data/'+params['sim_uid'] + '/' + params['sim_exp'] +'/' try: os.stat('data/'+params['sim_uid']+'/') except: os.mkdir('data/'+params['sim_uid']+'/') try: os.stat(data_dir) except: os.mkdir(data_dir) dt = params['sim_dt'] Nt = params['sim_steps'] dur = Nt/dt G = nx.DiGraph() # or nx.MultiDiGraph() G.add_nodes_from([0]) G.node[0] = { 'model': 'LeakyIAF_rest', 'name': 'neuron_0', 'extern': True, # indicates whether the neuron can receive an external input signal 'public': True, # indicates whether the neuron can emit output to other LPUs 'spiking': True, # indicates whether the neuron outputs spikes or a membrane voltage 'selector': '/a[0]', # every public neuron must have a selector 'V': params['par_V'], # initial membrane voltage 'Vr': params['par_Vr'], # reset voltage ## The same as the implicit resting potential 'Vt': params['par_Vt'], # spike threshold 'R': params['par_R'], # membrane resistance 'C': params['par_C'], # membrane capacitance 'Er': params['par_rest'] # membrane capacitance } nx.write_gexf(G, data_dir +'lif_graph.gexf.gz') N_neurons = G.number_of_nodes() if sim_input == 'Default': t = np.arange(0, params['sim_dt']*params['sim_steps'], params['sim_dt']) I = np.zeros((params['sim_steps'], N_neurons), dtype=np.double) I[t>0.2] = 1e-9 I[t>0.4] = 2e-9 I[t>0.8] = 2.5e-9 with h5py.File(data_dir + 'lif_input.h5', 'w') as f: f.create_dataset('array', (Nt, N_neurons), dtype=np.double, data=I) else: print 'loading non-default inputs (WIP)' with h5py.File(data_dir + 'lif_input.h5', 'w') as f: f.create_dataset('array', (Nt, N_neurons), dtype=np.double, data=sim_input) parser = argparse.ArgumentParser() parser.add_argument('--debug', default=False, dest='debug', action='store_true', help='Write connectivity structures and inter-LPU routed data in debug folder') parser.add_argument('-l', '--log', default='none', type=str, help='Log output to screen [file, screen, both, or none; default:none]') parser.add_argument('-s', '--steps', default=params['sim_steps'], type=int, help='Number of steps [default: %s]' % params['sim_steps']) args = parser.parse_args() file_name = None screen = False if args.log.lower() in ['file', 'both']: file_name = 'lif.log' if args.log.lower() in ['screen', 'both']: screen = True logger = setup_logger(file_name=file_name, screen=screen) man = Manager() (n_dict, s_dict) = LPU.lpu_parser(data_dir+'lif_graph.gexf.gz') if params['sim_output'] != 'spike': args.debug = True man.add(LPU, 'lif', dt, n_dict, s_dict, input_file=data_dir +'lif_input.h5', output_file=data_dir +'lif_output.h5', device=0, debug=True) man.spawn() man.start(steps=params['sim_steps']) man.wait() if params['sim_output'] == 'spike': with h5py.File(data_dir +'lif_output_spike.h5') as f: data = np.array(f['array']).T.tolist() else: ######## BUG: Needs to output debug to data folder with h5py.File('./lif_V.h5') as f: data = np.array(f['array']).T.tolist() return data
class test_core_gpu(TestCase): def setUp(self): self.man = Manager() def test_transmit_spikes_one_to_one(self): m1_sel_in_gpot = Selector('') m1_sel_out_gpot = Selector('') m1_sel_in_spike = Selector('') m1_sel_out_spike = Selector('/m1/out/spike[0:4]') m1_sel, m1_sel_in, m1_sel_out, m1_sel_gpot, m1_sel_spike = \ make_sels(m1_sel_in_gpot, m1_sel_out_gpot, m1_sel_in_spike, m1_sel_out_spike) N1_gpot = SelectorMethods.count_ports(m1_sel_gpot) N1_spike = SelectorMethods.count_ports(m1_sel_spike) m2_sel_in_gpot = Selector('') m2_sel_out_gpot = Selector('') m2_sel_in_spike = Selector('/m2/in/spike[0:4]') m2_sel_out_spike = Selector('') m2_sel, m2_sel_in, m2_sel_out, m2_sel_gpot, m2_sel_spike = \ make_sels(m2_sel_in_gpot, m2_sel_out_gpot, m2_sel_in_spike, m2_sel_out_spike) N2_gpot = SelectorMethods.count_ports(m2_sel_gpot) N2_spike = SelectorMethods.count_ports(m2_sel_spike) m1_id = 'm1' self.man.add(MyModule1, m1_id, m1_sel, m1_sel_in, m1_sel_out, m1_sel_gpot, m1_sel_spike, np.zeros(N1_gpot, dtype=np.double), np.zeros(N1_spike, dtype=int), device=0, debug=debug, out_spike_data=[0, 0, 1, 1]) f, out_file_name = tempfile.mkstemp() os.close(f) m2_id = 'm2' self.man.add(MyModule2, m2_id, m2_sel, m2_sel_in, m2_sel_out, m2_sel_gpot, m2_sel_spike, np.zeros(N2_gpot, dtype=np.double), np.zeros(N2_spike, dtype=int), device=1, debug=debug, out_file_name=out_file_name) pat12 = Pattern(m1_sel, m2_sel) pat12.interface[m1_sel_out_gpot] = [0, 'in', 'gpot'] pat12.interface[m1_sel_in_gpot] = [0, 'out', 'gpot'] pat12.interface[m1_sel_out_spike] = [0, 'in', 'spike'] pat12.interface[m1_sel_in_spike] = [0, 'out', 'spike'] pat12.interface[m2_sel_in_gpot] = [1, 'out', 'gpot'] pat12.interface[m2_sel_out_gpot] = [1, 'in', 'gpot'] pat12.interface[m2_sel_in_spike] = [1, 'out', 'spike'] pat12.interface[m2_sel_out_spike] = [1, 'in', 'spike'] pat12['/m1/out/spike[0]', '/m2/in/spike[0]'] = 1 pat12['/m1/out/spike[1]', '/m2/in/spike[1]'] = 1 pat12['/m1/out/spike[2]', '/m2/in/spike[2]'] = 1 pat12['/m1/out/spike[3]', '/m2/in/spike[3]'] = 1 self.man.connect(m1_id, m2_id, pat12, 0, 1) # Run emulation for 2 steps: self.man.spawn() self.man.start(2) self.man.wait() # Get output of m2: with open(out_file_name, 'r') as f: output = pickle.load(f) os.remove(out_file_name) self.assertSequenceEqual(list(output), [0, 0, 1, 1]) def test_transmit_spikes_one_to_many(self): m1_sel_in_gpot = Selector('') m1_sel_out_gpot = Selector('') m1_sel_in_spike = Selector('') m1_sel_out_spike = Selector('/m1/out/spike[0:4]') m1_sel, m1_sel_in, m1_sel_out, m1_sel_gpot, m1_sel_spike = \ make_sels(m1_sel_in_gpot, m1_sel_out_gpot, m1_sel_in_spike, m1_sel_out_spike) N1_gpot = SelectorMethods.count_ports(m1_sel_gpot) N1_spike = SelectorMethods.count_ports(m1_sel_spike) m2_sel_in_gpot = Selector('') m2_sel_out_gpot = Selector('') m2_sel_in_spike = Selector('/m2/in/spike[0:4]') m2_sel_out_spike = Selector('') m2_sel, m2_sel_in, m2_sel_out, m2_sel_gpot, m2_sel_spike = \ make_sels(m2_sel_in_gpot, m2_sel_out_gpot, m2_sel_in_spike, m2_sel_out_spike) N2_gpot = SelectorMethods.count_ports(m2_sel_gpot) N2_spike = SelectorMethods.count_ports(m2_sel_spike) m1_id = 'm1' self.man.add(MyModule1, m1_id, m1_sel, m1_sel_in, m1_sel_out, m1_sel_gpot, m1_sel_spike, np.zeros(N1_gpot, dtype=np.double), np.zeros(N1_spike, dtype=int), device=0, debug=debug, out_spike_data=[1, 0, 0, 0]) f, out_file_name = tempfile.mkstemp() os.close(f) m2_id = 'm2' self.man.add(MyModule2, m2_id, m2_sel, m2_sel_in, m2_sel_out, m2_sel_gpot, m2_sel_spike, np.zeros(N2_gpot, dtype=np.double), np.zeros(N2_spike, dtype=int), device=1, debug=debug, out_file_name=out_file_name) pat12 = Pattern(m1_sel, m2_sel) pat12.interface[m1_sel_out_gpot] = [0, 'in', 'gpot'] pat12.interface[m1_sel_in_gpot] = [0, 'out', 'gpot'] pat12.interface[m1_sel_out_spike] = [0, 'in', 'spike'] pat12.interface[m1_sel_in_spike] = [0, 'out', 'spike'] pat12.interface[m2_sel_in_gpot] = [1, 'out', 'gpot'] pat12.interface[m2_sel_out_gpot] = [1, 'in', 'gpot'] pat12.interface[m2_sel_in_spike] = [1, 'out', 'spike'] pat12.interface[m2_sel_out_spike] = [1, 'in', 'spike'] pat12['/m1/out/spike[0]', '/m2/in/spike[0]'] = 1 pat12['/m1/out/spike[0]', '/m2/in/spike[1]'] = 1 pat12['/m1/out/spike[0]', '/m2/in/spike[2]'] = 1 pat12['/m1/out/spike[0]', '/m2/in/spike[3]'] = 1 self.man.connect(m1_id, m2_id, pat12, 0, 1) # Run emulation for 2 steps: self.man.spawn() self.man.start(2) self.man.wait() # Get output of m2: with open(out_file_name, 'r') as f: output = pickle.load(f) os.remove(out_file_name) self.assertSequenceEqual(list(output), [1, 1, 1, 1])
class Circuit(object): """ Create a Neuroballad circuit. Basic Example -------- >>> from neuroballad import * #Import Neuroballad >>> C.add([0, 2, 4], HodgkinHuxley()) #Create three neurons >>> C.add([1, 3, 5], AlphaSynapse()) #Create three synapses >>> C.join([[0,1],[1,2],[2,3],[3,4],[4,5],[5,0]]) #Join nodes together >>> C_in_a = InIStep(0, 40., 0.25, 0.50) #Create current input for node 0 >>> C_in_b = InIStep(2, 40., 0.50, 0.75) #Create current input for node 2 >>> C_in_c = InIStep(4, 40., 0.75, 0.50) #Create current input for node 4 >>> C.sim(1., 1e-4, [C_in_a, C_in_b, C_in_c]) #Use the inputs and simulate """ default_tags = {'species': 'None', 'hemisphere': 'None', 'neuropil': 'None', 'circuit': 'None', 'from': 'None', 'to': 'None', 'neurotransmitter': 'None', 'experiment_id': 'None', 'rid': 'None', 'type': 'neuron'} def __init__(self, name='', dtype=np.float64, experiment_name=''): self.G = nx.MultiDiGraph() # Neurokernel graph definition self.config = SimConfig(duration=None, steps=None, dt=1e-4, t=None, device=0) self.node_ids = [] # Graph ID's self.tracked_variables = [] # Observable variables in circuit self._inputs = None # input nodes # self._outputs = None # output nodes # self.experiment_config = [] self.experiment_name = experiment_name self.dtype = dtype # self.ICs = [] self.name = name self.manager = None # LPU Manager self.logger = None # logger def set_experiment(self, experiment_name): self.experiment_name = experiment_name Gc = copy.deepcopy(self.G) mapping = {} for i in self.G.nodes(): ii = self.json_to_tags(i) ii['experiment_name'] = experiment_name mapping[i] = self.tags_to_json(ii) Gc = nx.relabel_nodes(Gc, mapping) self.G = Gc for i, val in self.G.nodes(data=True): val['name'] = i for i in range(len(self.node_ids)): self.node_ids[i][1] = experiment_name def get_new_id(self): """Generate new ID """ if self.node_ids == []: return '1' else: return str(len(self.node_ids)+1) @property def nodes(self): return self.G.nodes def copy(self): '''Return Copy of Circuit Instance''' return copy.deepcopy(self) def merge(self, C): '''Merge circuit `C` with current circuit''' self.G = nx.compose(self.G, C.G) self.node_ids += C.node_ids def find_neurons(self, **tags_tofind): tags_tofind['type'] = 'neuron' return self.filter_nodes_by_tags(tags_tofind) def find_synapses(self, **tags_tofind): tags_tofind['type'] = 'synapse' return self.filter_nodes_by_tags(tags_tofind) def find_ports(self, **tags_tofind): tags_tofind['type'] = 'port' return self.filter_nodes_by_tags(tags_tofind) def filter_nodes_by_tags(self, tags_tofind): output = [] for i, val in self.G.nodes(data=True): skip = False for j in tags_tofind.keys(): if j not in val: skip = True else: if tags_tofind[j] in val[j]: pass else: skip = True if not skip: output.append(i) return output def tags_to_json(self, tags): """ Turns the tags dictionary to a JSON string. """ return json.dumps(tags) def json_to_tags(self, tags_str): """ Turns a tags JSON string to the dictionary. """ return json.loads(tags_str) def encode_name(self, i, experiment_name=None): '''Encode node id into json format Example ------- >>> a = C.encode_name(0, experiment_name='test') >>> a '{"name": "0", "experiment_name": "test"}' ''' i = str(i) try: i = i.decode('ascii') except Exception as e: pass # TODO: use raise ValueError('ASCII decode failed for {}, error {}'.format(i, e)) if experiment_name is None: experiment_name = self.experiment_name name_dict = {'name': str(i), 'exp': experiment_name} name = self.tags_to_json(name_dict) return name def add(self, name, neuron): """ Loops through a list of ID inputs and adds corresponding components of a specific type to the circuit. Example -------- >>> C.add([1, 2, 3], HodgkinHuxley()) """ if isinstance(neuron, Input): self._inputs.append(neuron.addToExperiment) else: for i in name: if i in self.node_ids: raise ValueError( 'Don''t use the same ID for multiple neurons!') for i in name: neuron.nadd(self, i, self.experiment_name, self.default_tags) self.node_ids.append([str(i), self.experiment_name]) def add_cluster(self, number, neuron, name=None): """ Creates a number of components of a specific type and returns their ID's. Example -------- >>> id_list = C.add_cluster(256, HodgkinHuxley()) """ cluster_inds = [] for i in range(number): i_toadd = self.get_new_id() _id = '{}-{}'.format(name, i_toadd) neuron.nadd(self, _id, self.experiment_name, self.default_tags) self.node_ids.append(_id) cluster_inds.append(_id) return cluster_inds def dense_connect_variable(self, in_array_a, in_array_b, neuron, delay=0.0, variable='', tag=0, debug=False): """ Densely connects two arrays of circuit ID's, creating a layer of unique components of a specified type in between. Example -------- >>> C.dense_join_variable(cluster_a, cluster_b, AlphaSynapse()) """ for i in in_array_a: for j in in_array_b: i_toadd = self.get_new_id() if debug: print('Added neuron ID: ' + str(i_toadd)) neuron.nadd(self, i_toadd, self.experiment_name, self.default_tags) self.node_ids.append(i_toadd) self.join([[i, i_toadd], [i_toadd, j]], delay=delay, variable=variable, tag=tag) def dense_connect(self, in_array_a, in_array_b, delay=0.0): """Densely connect clusters Densely connects two arrays of circuit ID's. Example -------- >>> C.dense_connect_variable(cluster_a, cluster_b) """ for i in in_array_a: for j in in_array_b: self.join([[i, j]], delay=delay) def dense_join_variable(self, in_array_a, in_array_b, in_array_c, delay=0.0, variable=None): """Densely connect clusters variable intermediary elements Densely connects two arrays of circuit ID's, using a third array as the matrix of components that connects the two. TODO ---- 1. Currently only support scalar delay, add component-dependent delay Example -------- >>> C.dense_join_variable(cluster_a, cluster_b, cluster_c) """ if np.isscalar(delay): delay = [delay]*2 if isinstance(variable, str): variable = [variable]*2 k = 0 in_array_c = in_array_c.flatten() for i in in_array_a: for j in in_array_b: if variable is not None: self.join([i, in_array_c[k]], delay=delay[0], variable=variable[0]) self.join([in_array_c[k], j], delay=delay[1], variable=variable[1]) else: self.join([i, in_array_c[k]], delay=delay[0]) self.join([in_array_c[k], j], delay=delay[1]) k += 1 def join(self, in_array, delay=0.0, variable=None, tag=0): """ Processes an edge list and adds the edges to the circuit. Example -------- >>> C.add([0, 2, 4], HodgkinHuxley()) #Create three neurons >>> C.add([1, 3, 5], AlphaSynapse()) #Create three synapses >>> C.join([[0,1],[1,2],[2,3],[3,4],[4,5],[5,0]]) """ in_array = np.array(in_array) # print(in_array) for i in range(in_array.shape[0]): if variable is None: self.G.add_edge(self.encode_name(str(in_array[i, 0])), self.encode_name(str(in_array[i, 1])), delay=delay, tag=tag) else: self.G.add_edge(self.encode_name(str(in_array[i, 0])), self.encode_name(str(in_array[i, 1])), delay=delay, variable=variable, tag=tag) def fit(self, inputs): """ Attempts to find parameters to fit a certain curve to the output. Not implemented at this time. """ raise NotImplementedError def load_last(self, file_name='neuroballad_temp_model.gexf.gz'): """ Loads the latest executed circuit in the directory. Example -------- >>> C.load_last() """ self.G = nx.read_gexf(file_name) self.node_ids = [] for i in self.G.nodes(): self.node_ids.append(i) # FIX def save(self, file_name='neuroballad_temp_model.gexf.gz'): """ Saves the current circuit to a file. Example -------- >>> C.save(file_name = 'my_circuit.gexf.gz') """ nx.write_gexf(self.G, file_name) def compile(self, duration, dt=None, steps=None, in_list=None, record=('V', 'spike_state', 'I'), extra_comps=None, input_filename='neuroballad_temp_model_input.h5', output_filename='neuroballad_temp_model_output.h5', graph_filename='neuroballand_temp_graph.gexf.gz', device=0, sample_interval=1): if dt is not None: if steps is not None: assert dt*steps == duration, 'dt*step != duration' else: steps = int(duration/dt) t = np.linspace(0, duration, steps) else: if steps is not None: t = np.linspace(0, duration, steps) dt = t[1] - t[0] else: raise ValueError('dt and step cannot both be None') self.config = self.config._replace(duration=duration, steps=steps, dt=dt, t=t, device=device) # compile inputs if in_list is None: in_list = self._inputs uids = [] for i in in_list: uids.append(self.encode_name(str(i.node_id), experiment_name=i.experiment_name)) input_vars = [] for i in in_list: if isinstance(i.var, list): for j in i.var: input_vars.append(j) else: input_vars.append(i.var) input_vars = list(set(input_vars)) uids = np.array(list(set(uids)), dtype='S') Is = {} Inodes = {} for i in input_vars: Inodes[i] = [] for i in in_list: in_name = self.encode_name(str(i.node_id), experiment_name=i.experiment_name) if in_name in list(self.G.nodes(data=False)): pass else: raise ValueError( 'Input node {} not found in Circuit.'.format(in_name)) if isinstance(i.var, list): for j in i.var: Inodes[j].append( self.encode_name(str(i.node_id), experiment_name=i.experiment_name)) else: Inodes[i.var].append( self.encode_name(str(i.node_id), experiment_name=i.experiment_name)) for i in input_vars: Inodes[i] = np.array(list(set(Inodes[i])), dtype='S') for i in input_vars: Is[i] = np.zeros((self.config.steps, len(Inodes[i])), dtype=self.dtype) for i in in_list: if isinstance(i.var, list): for j in i.var: Is[j] = i.add(self, Inodes[j], Is[j], t, var=j) else: Is[i.var] = i.add(self, Inodes[i.var], Is[i.var], t, var=i.var) with h5py.File(input_filename, 'w') as f: for i in input_vars: # print(i + '/uids') i_nodes = Inodes[i] """ try: i_nodes = [i.decode('ascii') for i in i_nodes] except: pass i_nodes = [self.encode_name(i) for i in i_nodes] """ i_nodes = np.array(i_nodes, dtype='S') f.create_dataset(i + '/uids', data=i_nodes) f.create_dataset(i + '/data', (self.config.steps, len(Inodes[i])), dtype=self.dtype, data=Is[i]) if graph_filename is not None: nx.write_gexf(self.G, graph_filename) from neurokernel.core_gpu import Manager from neurokernel.LPU.LPU import LPU import neurokernel.mpi_relaunch from neurokernel.LPU.InputProcessors.FileInputProcessor import \ FileInputProcessor from neurokernel.LPU.OutputProcessors.FileOutputProcessor import \ FileOutputProcessor input_processor = FileInputProcessor(input_filename) (comp_dict, conns) = LPU.graph_to_dicts(self.G) output_processor = FileOutputProcessor([(i, None) for i in list(record)], output_filename, sample_interval=sample_interval) self.manager = Manager() self.manager.add(LPU, self.experiment_name, self.config.dt, comp_dict, conns, device=self.config.device, input_processors=[input_processor], output_processors=[output_processor], debug=False, extra_comps=extra_comps if extra_comps is not None else []) # self.input.status = 'pre_run' # self.output.status = 'pre_run' def sim(self, duration, dt, steps=None, in_list=None, record=('V', 'spike_state', 'I'), log=None, device=0, sample_interval=1, input_filename='neuroballad_temp_model_input.h5', output_filename='neuroballad_temp_model_output.h5', graph_filename='neuroballand_temp_graph.gexf.gz', log_filename='neuroballand_temp_log.log', extra_comps=None, preamble=[], args=[]): """ Simulates the circuit for a set amount of time, with a fixed temporal step size and a list of inputs. TODO ---- 1. use preamble and args for slurm Example -------- >>> C.sim(1., 1e-4, InIStep(0, 10., 1., 2.)) """ from neurokernel.tools.logging import setup_logger if log is not None: screen = False file_name = None if log.lower() in ['file', 'both']: file_name = log_filename if log.lower() in ['screen', 'both']: screen = True self.logger = setup_logger(file_name=file_name, screen=screen) self.compile(duration, dt, steps=steps, in_list=in_list, record=record, extra_comps=extra_comps, input_filename=input_filename, output_filename=output_filename, graph_filename=graph_filename, device=device, sample_interval=sample_interval) self.manager.spawn() self.manager.start(self.config.steps) self.manager.wait() def collect(self): data = {'in': {}, 'out': {}} uids = {'in': {}, 'out': {}} time.sleep(1.) with h5py.File('neuroballad_temp_model_input.h5', 'r') as f: for k in f.keys(): data['in'][k] = f[k]['data'] uids['in'][k] = f[k]['uids'].astype(str) with h5py.File('neuroballad_temp_model_output.h5', 'r') as f: for k in f.keys(): if k != 'metadata': data['out'][k] = f[k]['data'][()] uids['out'][k] = f[k]['uids'][()].astype(str) return uids, data def collect_results(self): """ Collects the latest results from the executor. Useful when loading a set of results after execution. Example -------- >>> C.collect_results() """ import neurokernel.LPU.utils.visualizer as vis self.Viz = vis.visualizer() self.Viz.add_LPU('neuroballad_temp_model_output.h5', gexf_file='neuroballad_temp_model.gexf.gz', LPU='lpu') def visualize_circuit(self, prog='dot', splines='line', filename='neuroballad_temp_circuit.svg'): return visualize_circuit(self, prog=prog, splines=splines, filename=filename) def visualize_video(self, name, config={}, visualization_variable='V', out_name='test.avi'): visualize_video(self, name=name, config=config, visualization_variable=visualization_variable, out_name=out_name)
def emulate(n_lpu, n_spike, n_gpot, steps): """ Benchmark inter-LPU communication throughput. Each LPU is configured to use a different local GPU. Parameters ---------- n_lpu : int Number of LPUs. Must be at least 2 and no greater than the number of local GPUs. n_spike : int Total number of input and output spiking ports any single LPU exposes to any other LPU. Each LPU will therefore have 2*n_spike*(n_lpu-1) total spiking ports. n_gpot : int Total number of input and output graded potential ports any single LPU exposes to any other LPU. Each LPU will therefore have 2*n_gpot*(n_lpu-1) total graded potential ports. steps : int Number of steps to execute. Returns ------- average_throughput, total_throughput : float Average per-step and total received data throughput in bytes/seconds. exec_time : float Execution time in seconds. """ # Time everything starting with manager initialization: start_all = time.time() # Check whether a sufficient number of GPUs are available: drv.init() if n_lpu > drv.Device.count(): raise RuntimeError('insufficient number of available GPUs.') # Set up manager: man = Manager() # Generate selectors for configuring modules and patterns: mod_sels, pat_sels = gen_sels(n_lpu, n_spike, n_gpot) # Set up modules: for i in xrange(n_lpu): lpu_i = 'lpu%s' % i sel, sel_in, sel_out, sel_gpot, sel_spike = mod_sels[lpu_i] sel = Selector.union(sel_in, sel_out, sel_gpot, sel_spike) man.add(MyModule, lpu_i, sel, sel_in, sel_out, sel_gpot, sel_spike, None, None, ['interface', 'io', 'type'], CTRL_TAG, GPOT_TAG, SPIKE_TAG, device=i, time_sync=True) # Set up connections between module pairs: for i, j in itertools.combinations(xrange(n_lpu), 2): lpu_i = 'lpu%s' % i lpu_j = 'lpu%s' % j sel_from, sel_to, sel_in_i, sel_out_i, sel_gpot_i, sel_spike_i, \ sel_in_j, sel_out_j, sel_gpot_j, sel_spike_j = pat_sels[(lpu_i, lpu_j)] pat = Pattern.from_concat(sel_from, sel_to, from_sel=sel_from, to_sel=sel_to, data=1) pat.interface[sel_in_i, 'interface', 'io'] = [0, 'in'] pat.interface[sel_out_i, 'interface', 'io'] = [0, 'out'] pat.interface[sel_gpot_i, 'interface', 'type'] = [0, 'gpot'] pat.interface[sel_spike_i, 'interface', 'type'] = [0, 'spike'] pat.interface[sel_in_j, 'interface', 'io'] = [1, 'in'] pat.interface[sel_out_j, 'interface', 'io'] = [1, 'out'] pat.interface[sel_gpot_j, 'interface', 'type'] = [1, 'gpot'] pat.interface[sel_spike_j, 'interface', 'type'] = [1, 'spike'] man.connect(lpu_i, lpu_j, pat, 0, 1, compat_check=False) man.spawn() start_main = time.time() man.start(steps) man.wait() stop_main = time.time() return man.average_step_sync_time, (time.time()-start_all), \ (stop_main-start_main), (man.stop_time-man.start_time)