Beispiel #1
0
    def ConnectToDLS(self):

        self.chip = dls.Chip()
        self.loadConfig()
        self.CreateNetwork()

        builder = dls.Dls_program_builder()  # capmem einpendeln
        builder.set_time(0)
        builder.set_chip(self.chip)
        builder.wait_for(100000)
        builder.halt()

        #Connect to DLS and keep connection open
        self.connection = dls.connect(dls.get_allocated_board_ids()[0])

        dls.soft_reset(self.connection)
        dls.set_config_reg(
            self.connection, self.fpga_conf
        )  # chip config is only with chip, this is FPGA config
        hp.setup_dac(self.connection, self.dac)  # soft reset ? resets dac?
        dls.set_spike_router(self.connection, self.router)  # set spike router

        builder.transfer(self.connection,
                         0)  # connection, 0 is program address
        builder.execute(self.connection, 0)  # triggers execution on FPGA
        builder.fetch(self.connection)
Beispiel #2
0
    def loadConfig(self):
        '''Load the configs'''

        # set config for state neuron
        for neuron_ind in range(dls.Neuron_index.num_neurons):
            for k, v in self.capmem['neuron_params'][neuron_ind].items():
                key = dict_conv.conversion_dict[k]
                hp.fill_cap_mem_cell(self.chip.cap_mem, neuron_ind, key, v)
        self.chip.cap_mem.set(dls.Cap_mem_row(0),
                              dls.Cap_mem_column(dls.Neuron_index.num_neurons),
                              self.capmem['global_params']['v_reset'])

        if dls.get_allocated_board_ids()[0] != 'B291698':

            # set config for state neurons
            for stateNeuron in range(self.nStates):
                for k, v in self.capmem['neuron_params'][stateNeuron].items():
                    key = dict_conv.conversion_dict[k]
                    if k == 'i_refr':
                        v = 1022  # minimal refractory period
                    # elif k == 'v_syn_in':
                    #     v = 1022  # maximal inhibition
                    elif k == 'v_thresh':
                        v = self.capmem['neuron_params'][stateNeuron][
                            'v_leak'] + 100
                    hp.fill_cap_mem_cell(self.chip.cap_mem, stateNeuron, key,
                                         v)
Beispiel #3
0
    def __init__(self, nStates, nActions, multipleRuns):

        self.nStates = nStates
        self.nActions = nActions

        self.recurrentSpikeAddress = 50
        self.recurrentSpikeCumulationTime = 100
        self.chip = dls.Chip()
        self.multipleRuns = multipleRuns

        self.inhibitory = None
        #Hold lists to enable overall evaluation for LTL
        self.accumulatedStates = []
        self.accumulatedActions = []
        self.accumulatedRewards = []

        boardCalibMapping = {
            'B291698': {
                'dac': 'dac_default.json',
                'cap': 'cap_mem_29.json'
            },
            '07': {
                'dac': 'dac_07_chip_20.json',
                'cap': 'calibration_20.json'
            },
            'B201319': {
                'dac': 'dac_07_chip_24.json',
                'cap': 'calibration_24.json'
            },
            'B201330': {
                'dac': 'dac_B201330_chip_22.json',
                'cap': 'calibration_22.json'
            }
        }

        f = open(boardCalibMapping[dls.get_allocated_board_ids()[0]]['cap'],
                 'r')
        self.capmem = json.load(f)
        f.close()

        f = open(boardCalibMapping[dls.get_allocated_board_ids()[0]]['dac'],
                 'r')
        self.dac = json.load(f)
        f.close()

        self.ConnectToDLS()
    def connect(self):
        board_ids = dls.get_allocated_board_ids()
        assert (len(board_ids) == 1)
        assert (len(board_ids[0]) != 0)
        self.connection = dls.connect(board_ids[0])
        dls.soft_reset(self.connection)
        dls.set_config_reg(self.connection, self.fpga_conf)
        hp.setup_dac(self.connection, self.dac_config)
        dls.set_spike_router(self.connection, self.router)

        #print('-- before transfer')
        self.pre_builder.transfer(self.connection, 0x0)
        #print('-- before execute')
        self.pre_builder.execute(self.connection, 0x0)
        #print('-- before safefetch')
        # self.pre_builder.fetch(self.connection)
        safe_fetch(self.pre_builder, self.connection)
        #print('-- after safefetch')

        self.board_id = self.board_id if self.board_id is not None else board_ids[
            0]
    builder.set_mailbox(mailbox)
    builder.set_ppu_program(program)
    builder.set_ppu_control_reg(ppu_control_reg_end)
    builder.set_ppu_control_reg(ppu_control_reg_start)
    builder.set_time(0)
    builder.wait_until(args.wait)
    status_handle = builder.get_ppu_status_reg()
    builder.set_ppu_control_reg(ppu_control_reg_end)
    mailbox_handle = builder.get_mailbox()
    builder.halt()

    # Connect
    if args.board_id is not None:
        connection = pydls.connect(args.board_id)
    else:
        board_ids = pydls.get_allocated_board_ids()
        assert (len(board_ids) == 1)
        assert (len(board_ids[0]) != 0)
        connection = pydls.connect(board_ids[0])
    pydls.soft_reset(connection)

    # Transfer execute and copy back results
    builder.transfer(connection, 0x0)
    builder.execute(connection, 0x0)
    builder.fetch(connection)

    # Disconnect
    connection.disconnect()

    # Read mailbox
    mailbox_result = mailbox_handle.get()
Beispiel #6
0
    def Run(self,
            gamma,
            lam,
            eta,
            maxIteration,
            hdf=True,
            use32BitParams=False,
            weightUpper=None,
            weightLower=None,
            rescaleFreq=None,
            verbose=True,
            exitatory=None,
            inhibitory=None):

        #Hold lists to enable overall evaluation for LTL
        self.accumulatedStates = []
        self.accumulatedActions = []
        self.accumulatedRewards = []
        self.chip = dls.Chip()
        self.inhibitory = None

        cnt = 0
        while True:

            rn = np.random.randint(2**32)

            path = "HDFs/MDP/MDP_" + dt.datetime.now().strftime(
                '%Y_%m_%d_%H-%M-%S') + str(rn) + ".hdf5"

            try:

                #Generate the MDP problem
                self.P, self.R = mdptoolbox.example.rand(
                    self.nStates, self.nActions,
                    is_sparse=False)  #, rewardRange=(-0.3, -0.8))

                #self.P = np.array([[[1., 0.], [0., 1.]],
                #                   [[1., 0.], [0., 1.]],
                #                   [[0., 1.], [0., 1.]],
                #                   [[1., 0.], [1., 0.]]])

                #self.R = np.array([[[-1., -1.], [-1., -1.]],
                #                   [[-1., -1.], [-1., -1.]],
                #                   [[-1., 1.], [-1., -1.]],
                #                   [[-1., -1.], [1., -1.]]])

                #self.P = np.array([[[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 0., 1.], [0., 0., 0., 0., 1.]],
                #                   [[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 0., 1.]],
                #                   [[0., 1., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 0., 1.]],
                #                   [[1., 0., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 1., 0.], [1., 0., 0., 0., 0.]]])

                #self.R = np.array([[[-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., 1.], [-1., -1., -1., -1., -1.]],
                #                   [[-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., 1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.]],
                #                   [[-1., 1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.]],
                #                   [[-1., -1., -1., -1., -1.], [-1., -1., 1., -1., -1.], [-1., -1., -1., -1., -1.], [-1., -1., -1., -1., -1.], [1., -1., -1., -1., -1.]]])

                #self.P = np.array([[[1., 0.], [0., 1.]],
                #                   [[1., 0.], [0., 1.]],
                #                   [[0., 1.], [0., 1.]],
                #                   [[1., 0.], [1., 0.]]])

                #self.R = np.array([[[-1., -1.], [-1., -1.]],
                #                   [[-1., -1.], [-1., -1.]],
                #                   [[-1., 1.], [-1., -1.]],
                #                   [[-1., -1.], [1., -1.]]])

                if len(sys.argv) == 2:
                    #A file is given. Perform the network with the same R and P
                    hdf5File = h5py.File(sys.argv[1], 'r')

                    self.P = np.array(hdf5File['P'][:])
                    self.R = np.array(hdf5File['R'][:])

                #Create an hdf5 file to store the results of the execution
                if hdf:
                    hdf5File = h5py.File(path, "w")

                #Sanity check
                if self.P.shape != (self.nActions, self.nStates,
                                    self.nStates) or self.R.shape != (
                                        self.nActions, self.nStates,
                                        self.nStates):
                    raise Exception('The MDP matrices are malformed')

                if hdf:
                    hdf5File.create_dataset('P', data=self.P)
                    hdf5File.create_dataset('R', data=self.R)

                self.R = (self.R + 1) / 2.0

                rndSeed = np.random.randint(2**32)

                #The floating point numbers can take values between +- 65536
                maxPValue = (2**16) - 1
                currentMax = self.P.max()
                self.P = self.P * (maxPValue / currentMax)

                f = io.BytesIO()

                #Prepare the mailbox file
                #with open("PPU/MailboxContentMDP", 'wb') as f:
                f.write(struct.pack('>I', rndSeed))
                flat_list_P = [
                    np.uint32(it) for sublist in self.P.tolist()
                    for item in sublist for it in item
                ]
                flat_list_R = [
                    np.int8(frac.to_fractional(it))
                    for sublist in self.R.tolist() for item in sublist
                    for it in item
                ]
                f.write(struct.pack('>%uI' % len(flat_list_P), *flat_list_P))
                f.write(struct.pack('>%ub' % len(flat_list_R), *flat_list_R))
                f.write(struct.pack('>I', np.uint32(maxPValue)))
                f.write(struct.pack('>I', np.uint32(2000)))

                #Differentiate whether the 32bit parameters should be used or not
                if use32BitParams:
                    f.write(
                        struct.pack(
                            '>I',
                            np.uint32(frac.to_fractional(gamma,
                                                         precision=32))))
                    f.write(
                        struct.pack(
                            '>I',
                            np.uint32(frac.to_fractional(lam, precision=32))))
                    f.write(
                        struct.pack(
                            '>I',
                            np.uint32(frac.to_fractional(eta, precision=32))))
                else:
                    f.write(
                        struct.pack('>b', np.int8(frac.to_fractional(gamma))))
                    f.write(struct.pack('>b',
                                        np.int8(frac.to_fractional(lam))))
                    f.write(struct.pack('>b',
                                        np.int8(frac.to_fractional(eta))))

                #In case the weight shift should be used write the additional parameter to the mailbox
                if weightLower != None:
                    f.write(struct.pack('>B', np.uint8(weightLower)))
                    f.write(struct.pack('>B', np.uint8(weightUpper)))
                    f.write(struct.pack('>I', np.uint32(rescaleFreq)))

                #load the config
                self.loadConfig()

                #Create the network structure
                self.CreateNetwork(exitatory=exitatory, inhibitory=inhibitory)

                if hdf:
                    #Write the important parameters into the hdf5 file
                    hdf5File.create_dataset(
                        'date',
                        data=(
                            dt.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), ))
                    hdf5File.create_dataset('gamma', data=(gamma, ))
                    hdf5File.create_dataset('lam', data=(lam, ))
                    hdf5File.create_dataset('eta', data=(eta, ))
                    hdf5File.create_dataset('trialsPerIteration',
                                            data=(2000, ))
                    hdf5File.create_dataset(
                        'boardID', data=(dls.get_allocated_board_ids()[0], ))
                    hdf5File.create_dataset(
                        'CapMemKeys',
                        data=[str(i) for i in self.capmem.keys()])
                    hdf5File.create_dataset(
                        'CapMemValues',
                        data=[str(i) for i in self.capmem.values()])
                    hdf5File.create_dataset(
                        'DACConfKeys', data=[str(i) for i in self.dac.keys()])
                    hdf5File.create_dataset(
                        'DACConfValues',
                        data=[str(i) for i in self.dac.values()])
                    hdf5File.create_dataset('nActions', data=(self.nActions, ))
                    hdf5File.create_dataset('nStates', data=(self.nStates, ))
                    hdf5File.create_dataset('platform', data=('HW', ))
                    hdf5File.create_dataset('multipleRuns',
                                            data=(self.multipleRuns, ))
                    hdf5File.create_dataset('iterationsOnChip',
                                            data=((maxIteration / 2000) + 1, ))
                    if weightLower != None:
                        hdf5File.create_dataset('weightLower',
                                                data=(weightLower, ))
                        hdf5File.create_dataset('weightUpper',
                                                data=(weightUpper, ))
                        hdf5File.create_dataset('rescaleFreq',
                                                data=(rescaleFreq, ))

                #Start the measurement
                startTime = time.time()

                self.builder, self.spikes_builder, self.mailbox_handle, self.synram_handle, self.status_handle = self.loadPPUProgram(
                    f.getvalue())

                #Handle the case when more than 2000 iterations are needed. Dont disconnect from the board,
                #just delete the mailbox and start over again with the last weights

                #with dls.connect(dls.get_allocated_board_ids()[0]) as c:
                #dls.soft_reset(c)
                #dls.set_config_reg(c, self.fpga_conf)  # chip config is only with chip, this is FPGA config
                #hp.setup_dac(c, self.dac)  # soft reset ? resets dac?
                #dls.set_spike_router(c, self.router)  # set spike router

                self.builder.transfer(self.connection,
                                      0)  # connection, 0 is program address
                self.builder.execute(self.connection,
                                     0)  # triggers execution on FPGA
                self.builder.fetch(self.connection)

                for run in range(self.multipleRuns):

                    if hdf:
                        #Create a group for each new run
                        group = hdf5File.create_group('Run_' + str(run))
                    accumulatedStatesPerRun = []
                    accumulatedActionsPerRun = []
                    accumulatedRewardsPerRun = []

                    weights = []
                    #weights = np.array([[0, 0, 0, 0, 0, 0],
                    #                    [0, 0, 0, 0, 0, 0]])
                    #Don't change the network structure and just reupload the PPU program
                    for i in range((maxIteration / 2000) + 1):

                        #load the config
                        self.chip = dls.Chip()
                        self.loadConfig()
                        self.CreateNetwork(weights,
                                           exitatory=exitatory,
                                           inhibitory=inhibitory)
                        self.builder, self.spikes_builder, self.mailbox_handle, self.synram_handle, self.status_handle = self.loadPPUProgram(
                            f.getvalue())

                        self.builder.transfer(
                            self.connection,
                            0)  # connection, 0 is program address
                        self.builder.execute(self.connection,
                                             0)  # triggers execution on FPGA
                        self.builder.fetch(self.connection)

                        self.spikes_builder.transfer(self.connection, 0)
                        self.spikes_builder.execute(self.connection, 0)
                        self.spikes_builder.fetch(self.connection)

                        #Switch the spike router off and perform the readout
                        #self.fpga_conf = dls.Config_reg()
                        #self.fpga_conf.spike_router_enable = False
                        #dls.set_config_reg(c, self.fpga_conf)

                        #Evaluate the mailbox for states, actions weights and compute the rewards
                        spike_times, spike_address, states, actions, rewards, policy, weights, Q_table = self.EvaluateNetwork(
                            2000, verbose=verbose)

                        if hdf:
                            group.create_dataset('spikeTimes' + str(i),
                                                 data=spike_times)
                            group.create_dataset('spikeAddresses' + str(i),
                                                 data=spike_address)
                            group.create_dataset('states' + str(i),
                                                 data=states)
                            group.create_dataset('actions' + str(i),
                                                 data=actions)
                            group.create_dataset('rewards' + str(i),
                                                 data=rewards)
                            group.create_dataset('policy' + str(i),
                                                 data=policy)
                            group.create_dataset('weights' + str(i),
                                                 data=weights)
                            group.create_dataset('Qtable' + str(i),
                                                 data=Q_table)

                        #Add the states, actions and rewards for multiple iterations together
                        accumulatedStatesPerRun.extend(states)
                        accumulatedActionsPerRun.extend(actions)
                        accumulatedRewardsPerRun.extend(rewards)

                    #Add the all the states, actions and rewards from a single run together
                    self.accumulatedStates.append(states)
                    self.accumulatedActions.append(actions)
                    self.accumulatedRewards.append(rewards)

                    #Switch the spike router back on
                    #self.fpga_conf = dls.Config_reg()
                    #self.fpga_conf.spike_router_enable = True
                    #self.router = dls.Spike_router_bypass(self.recurrentSpikeCumulationTime, self.recurrentSpikeAddress)
                    #dls.set_spike_router(c, self.router)

                if hdf:
                    hdf5File.create_dataset('simulationTime',
                                            data=(time.time() - startTime, ))
                    print('Closing file')
                    hdf5File.close()

                f.close()

                return

            except Exception as e:
                print 'Network problems ' + str(cnt)
                print e
                traceback.print_exc()

                if hdf:
                    os.remove(path)

                if cnt >= 20:
                    exit()

                time.sleep(5)
                cnt += 1

                #Reconnect to chip again
                self.connection.disconnect()
                self.ConnectToDLS()