Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
 def setUp(self):
     self.man = Manager()
Ejemplo n.º 4
0
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])
Ejemplo n.º 5
0
    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 [])
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
    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='neuroballad_temp_graph.gexf.gz',
                device=0,
                sample_interval=1,
                execute_in_same_thread=True):
        """
        Compiles a neuroballad circuit before execution.

        # Arguments
            duration (float): Simulation duration.
            dt (float): Time step size.
            steps (int): Number of steps to use in simulation. Optional; don't use dt if provided.
            in_list (list): List of inputs to use during compilation.
            record (tuple): Tuple of variables to record. Defaults to ('V', 'spike_state', 'I').
            extra_comps (list): List of new, custom components to include for your simulation.
            input_filename (str): The .h5 file name to use for the input.
            output_filename (str): The .h5 file name to use for recording the output.
            graph_filename (str): Name of the graph file to save the circuit to. Uses the .gexf format.
            device (int): Device to use for execution.
            sample_interval (int): Sampling interval for recording simulation output.
            execute_in_same_thread (bool): Whether to execute the circuit in the current thread.
        """
        if dt is not None:
            if steps is not None:
                warnings.warn(
                    "Both 'steps' and 'duration' arguments were specified. 'steps' argument is ignored."
                )
                steps = int(duration / dt)

            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)

        run_parameters = [duration, dt]
        with open('run_parameters.pickle', 'wb') as f:
            pickle.dump(run_parameters, f, protocol=pickle.HIGHEST_PROTOCOL)
        # 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])

        recorders = []
        for i in record:
            recorders.append((i, None))
        with open('record_parameters.pickle', 'wb') as f:
            pickle.dump(recorders, f, protocol=pickle.HIGHEST_PROTOCOL)

        if graph_filename is not None:
            nx.write_gexf(self.G, graph_filename)

        if execute_in_same_thread:
            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 [])
Ejemplo n.º 9
0
 def setUp(self):
     self.man = Manager()
Ejemplo n.º 10
0
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])