def run(self):
        logger.info("[port_listener] starting")
        self.queuer.start()
        last_update_time = datetime.datetime.now()
        t_tic = 0
        last_time_packet_recieved = datetime.datetime.now()
        if self.DEBUG:
            max_neuronid = 200
        while not self.done:
            try:
                t_tic, last_update_time = self.handle_timer_forces(
                    last_update_time, last_time_packet_recieved, t_tic)
                # if done every 200 ms

                if not self.DEBUG:
                    #print "trying to recive"
                    data = self.queuer.get_packet()
                    if data is None:
                        break

                    # print "received"
                    (ip_time_out_byte, pad_byte, flags_byte, tag_byte,
                     dest_port_byte, source_port_byte, dest_addr_short,
                     source_addr_short, command_short, sequence_short,
                     arg1_int, arg2_int, arg3_int) =\
                        struct.unpack_from("<BBBBBBHHHHiii", data, 0)
                    header_length = 26
                    spikedatalen = len(data) - header_length
                    t_tic = arg1_int
                    last_time_packet_recieved = datetime.datetime.now()

                    for spike in range(0, spikedatalen, 4):
                        spikeWord = struct.unpack_from("<I", data, spike +
                                                       header_length)[0]
                        x = packet_conversions.get_x_from_key(spikeWord)
                        y = packet_conversions.get_y_from_key(spikeWord)
                        p = packet_conversions.get_p_from_key(spikeWord)
                        nid = packet_conversions.get_nid_from_key(spikeWord)
                        # logger.debug("received packet from {},{},{}".format(x,y,p))
                        self.visualiser.spike_recieved({
                            'coords': [x, y, p],
                            'neuron_id': nid,
                            'tag': tag_byte,
                            'time_in_ticks': t_tic,
                            'spike_word': spikeWord
                        })
                else:  #create fake spikes
                    t_tic = self.generate_fake_spikes(packet_count, t_tic)

            except socket.timeout:
                pass
            except Exception as e:
                if not self.done:
                    traceback.print_exc()
                    logger.debug(
                        "[visualiser_listener] Error receiving data: %s" % e)
    def run(self):
        logger.info("[port_listener] starting")
        self.queuer.start()
        last_update_time = datetime.datetime.now()
        t_tic = 0
        last_time_packet_recieved = datetime.datetime.now()
        if self.DEBUG:
            max_neuronid = 200
        while not self.done:
            try:
                t_tic, last_update_time = self.handle_timer_forces(
                        last_update_time, last_time_packet_recieved, t_tic)
                # if done every 200 ms


                if not self.DEBUG:
                    #print "trying to recive"
                    data = self.queuer.get_packet()
                    if data is None:
                        break
                    
                    # print "received"
                    (ip_time_out_byte, pad_byte, flags_byte, tag_byte,
                     dest_port_byte, source_port_byte, dest_addr_short,
                     source_addr_short, command_short, sequence_short,
                     arg1_int, arg2_int, arg3_int) =\
                        struct.unpack_from("<BBBBBBHHHHiii", data, 0)
                    header_length = 26
                    spikedatalen = len(data) - header_length
                    t_tic = arg1_int
                    last_time_packet_recieved = datetime.datetime.now()

                    for spike in range(0, spikedatalen, 4):
                        spikeWord = struct.unpack_from("<I", data, spike + header_length)[0]
                        x = packet_conversions.get_x_from_key(spikeWord)
                        y = packet_conversions.get_y_from_key(spikeWord)
                        p = packet_conversions.get_p_from_key(spikeWord)
                        nid = packet_conversions.get_nid_from_key(spikeWord)
                        # logger.debug("received packet from {},{},{}".format(x,y,p))
                        self.visualiser.spike_recieved({'coords':[x,y,p],
                                                       'neuron_id':nid,
                                                       'tag': tag_byte,
                                                       'time_in_ticks': t_tic,
                                                       'spike_word': spikeWord})
                else:#create fake spikes
                    t_tic = self.generate_fake_spikes(packet_count, t_tic)

            except socket.timeout:
                pass
            except Exception as e:
                if not self.done:
                    traceback.print_exc()
                    logger.debug("[visualiser_listener] Error receiving data: %s" % e)
 def convert_normal_pop_spike_to_x_y(self, spike_word):
     '''
     takes the spike_word (key) and converts it into a neuron id, for the vertex
     it then converts the neuron id into a x and y coord and adds one to the colour
     '''
     neuron_id = packet_conversions.get_nid_from_key(spike_word)
     x = packet_conversions.get_x_from_key(spike_word)
     y = packet_conversions.get_y_from_key(spike_word)
     p = packet_conversions.get_p_from_key(spike_word)
     subvert = self.locate_subvert(x, y, p)
     real_neuron_id = subvert.lo_atom + neuron_id
     x_coord = math.floor(real_neuron_id/self.y_dim)
     y_coord = real_neuron_id - (x_coord * self.y_dim)
     return x_coord, y_coord, 1
 def convert_normal_pop_spike_to_x_y(self, spike_word):
     '''
     takes the spike_word (key) and converts it into a neuron id, for the vertex
     it then converts the neuron id into a x and y coord and adds one to the colour
     '''
     neuron_id = packet_conversions.get_nid_from_key(spike_word)
     x = packet_conversions.get_x_from_key(spike_word)
     y = packet_conversions.get_y_from_key(spike_word)
     p = packet_conversions.get_p_from_key(spike_word)
     subvert = self.locate_subvert(x, y, p)
     real_neuron_id = subvert.lo_atom + neuron_id
     x_coord = math.floor(real_neuron_id / self.y_dim)
     y_coord = real_neuron_id - (x_coord * self.y_dim)
     return x_coord, y_coord, 1
    def updateMasterPopulationTable(self, spec, blockStartAddr, rowIndex, key,
                                    MASTER_POP_TABLE):
        """
        Writes an entry in the Master Population Table for the newly
        created synaptic block.
        An entry in the table is a 16-bit value, with the following structure:
        Bits [2:0]  Row length information. This value (from 0->7)
                    indicates the maximum number of synapses in this
                    block. It is translated in the row length translation
                    table by the executing code each time the table is
                    accessed, to calculate offsets.
        Bits [15:3] Address within the synaptic matrix region of the
                    start of the block. This is 1K bytes aligned, so
                    the true value is found by shifting left by 7 bits
                    then adding the start address of the memory region.
        """
        # Which core has this projection arrived from?
        x = packet_conversions.get_x_from_key(key)
        y = packet_conversions.get_y_from_key(key)
        # the plus one in p calc is due to the router table subtracting one off
        # its routing key for p (also due to unknown reasons). As the c code
        # compenstates for it, we also need to
        p = packet_conversions.get_p_from_key(key)
        # Calculate the index into the master population table for
        # a projection from the given core:
        tableSlotAddr = \
            packet_conversions.get_mpt_sb_mem_addrs_from_coords(x, y, p)
        # What is the write address in the table for this index?

        spec.comment("\nUpdate entry in master population table for incoming"
                + " connection from {}, {}, {}:\n".format(x, y, p))

        # Process start address (align to 1K boundary then shift right by 10 and
        # left by 3 (i.e. 7) to make it the top 13-bits of the field):
        if (blockStartAddr & 0x3FF) != 0:
            raise Exception(
                "Synaptic Block start address is not aligned to a 1K boundary")
        #moves by 7 to tack on at the end the row_length information
        # which resides in the last 3 bits
        entryAddrField = blockStartAddr >> 7
        # Assembly entry:
        newEntry = entryAddrField | rowIndex

        # Write entry:
        spec.switchWriteFocus(region = MASTER_POP_TABLE)
        spec.setWritePtr(data = tableSlotAddr)
        spec.write(data = newEntry, sizeof = 'uint16')
        return
    def updateMasterPopulationTable(self, spec, blockStartAddr, rowIndex, key,
                                    MASTER_POP_TABLE):
        """
        Writes an entry in the Master Population Table for the newly
        created synaptic block.
        An entry in the table is a 16-bit value, with the following structure:
        Bits [2:0]  Row length information. This value (from 0->7)
                    indicates the maximum number of synapses in this
                    block. It is translated in the row length translation
                    table by the executing code each time the table is
                    accessed, to calculate offsets.
        Bits [15:3] Address within the synaptic matrix region of the
                    start of the block. This is 1K bytes aligned, so
                    the true value is found by shifting left by 7 bits
                    then adding the start address of the memory region.
        """
        # Which core has this projection arrived from?
        x = packet_conversions.get_x_from_key(key)
        y = packet_conversions.get_y_from_key(key)
        # the plus one in p calc is due to the router table subtracting one off
        # its routing key for p (also due to unknown reasons). As the c code
        # compenstates for it, we also need to
        p = packet_conversions.get_p_from_key(key)
        # Calculate the index into the master population table for
        # a projection from the given core:
        tableSlotAddr = \
            packet_conversions.get_mpt_sb_mem_addrs_from_coords(x, y, p)
        # What is the write address in the table for this index?

        spec.comment("\nUpdate entry in master population table for incoming" +
                     " connection from {}, {}, {}:\n".format(x, y, p))

        # Process start address (align to 1K boundary then shift right by 10 and
        # left by 3 (i.e. 7) to make it the top 13-bits of the field):
        if (blockStartAddr & 0x3FF) != 0:
            raise Exception(
                "Synaptic Block start address is not aligned to a 1K boundary")
        #moves by 7 to tack on at the end the row_length information
        # which resides in the last 3 bits
        entryAddrField = blockStartAddr >> 7
        # Assembly entry:
        newEntry = entryAddrField | rowIndex

        # Write entry:
        spec.switchWriteFocus(region=MASTER_POP_TABLE)
        spec.setWritePtr(data=tableSlotAddr)
        spec.write(data=newEntry, sizeof='uint16')
        return
    def writeSynapticMatrixAndMasterPopulationTable(self, spec, subvertex,
                                                    allSynBlockSz,weight_scale,
                                                    MASTER_POP_TABLE,
                                                    SYNAPTIC_MATRIX):
        """
        Simultaneously generates both the master population table and the
        synatic matrix.

        Master Population Table (MPT):
        Table of 1152 entries (one per numbered core on a 48-node board
        arranged in an 8 x 8 grid) giving offset pointer to synapse rows
        for that source population.

        Synaptic Matrix:
        One block for each projection in the network (sub_edge in the graph).
        Blocks are always aligned to 1K boundaries (within the region).
        Each block contains one row for each arriving axon.
        Each row contains a header of two words and then one 32-bit word for
        each synapse. The row contents depend on the connector type.
        """
        spec.comment("\nWriting Synaptic Matrix and Master Population Table:\n")

        # Zero all entries in the Master Population Table so that all unused
        # entries are assumed empty:
        spec.switchWriteFocus(region=MASTER_POP_TABLE)
        myRepeatReg = 4
        spec.moveToReg(destReg = myRepeatReg,
                       data = SynapticManager.MASTER_POPULATION_ENTRIES)
        spec.write(data=0, repeatReg = myRepeatReg, sizeof = 'uint16')

        # Track writes inside the synaptic matrix region:
        next_block_start_addr = 0
        n_synapse_type_bits = self.get_n_synapse_type_bits()

        # For each entry in subedge into the subvertex, create a
        # sub-synaptic list
        for subedge in subvertex.in_subedges:

            # Only deal with incoming projection subedges
            if not subedge.pruneable and isinstance(subedge, ProjectionSubedge):

                x = packet_conversions.get_x_from_key(subedge.key)
                y = packet_conversions.get_y_from_key(subedge.key)
                p = packet_conversions.get_p_from_key(subedge.key)
                spec.comment("\nWriting matrix for subedge from"
                        + " {}, {}, {}\n".format(x, y, p))

                sublist = subedge.get_synapse_sublist()
                rowIO = subedge.edge.get_synapse_row_io()
                #if (logger.isEnabledFor("debug")):
                #    logger.debug("Writing subedge from {} ({}-{}) to {} ({}-{})"
                #            .format(sourceSubvertex.vertex.label,
                #                    sourceSubvertex.lo_atom,
                #                    sourceSubvertex.hi_atom,
                #                    subvertex.vertex.label, subvertex.lo_atom,
                #                    subvertex.hi_atom))
                #    rows = sublist.get_rows()
                #    for i in range(len(rows)):
                #        logger.debug("{}: {}".format(i, rows[i]))

                # Get the maximum row length in words, excluding headers
                max_row_length = max([rowIO.get_n_words(row)
                        for row in sublist.get_rows()])
                # Get an entry in the row length table for this length
                row_index, row_length = \
                    self.selectMinimumRowLength(max_row_length)
                if max_row_length == 0 or row_length == 0:
                    print ""

                # Write the synaptic block for the sublist
                (block_start_addr, next_block_start_addr) = \
                    self.writeSynapseRowInfo(sublist, rowIO, spec,
                            next_block_start_addr, row_length,
                            SYNAPTIC_MATRIX, weight_scale,
                            n_synapse_type_bits)
                if ((next_block_start_addr - 1) > allSynBlockSz):
                    raise Exception(
                            "Too much synapse memory consumed (used {} of {})!"
                            .format(next_block_start_addr - 1, allSynBlockSz))
                self.updateMasterPopulationTable(spec, block_start_addr,
                                                 row_index, subedge.key,
                                                 MASTER_POP_TABLE)
    def writeSynapticMatrixAndMasterPopulationTable(self, spec, subvertex,
                                                    allSynBlockSz,
                                                    weight_scale,
                                                    MASTER_POP_TABLE,
                                                    SYNAPTIC_MATRIX):
        """
        Simultaneously generates both the master population table and the
        synatic matrix.

        Master Population Table (MPT):
        Table of 1152 entries (one per numbered core on a 48-node board
        arranged in an 8 x 8 grid) giving offset pointer to synapse rows
        for that source population.

        Synaptic Matrix:
        One block for each projection in the network (sub_edge in the graph).
        Blocks are always aligned to 1K boundaries (within the region).
        Each block contains one row for each arriving axon.
        Each row contains a header of two words and then one 32-bit word for
        each synapse. The row contents depend on the connector type.
        """
        spec.comment(
            "\nWriting Synaptic Matrix and Master Population Table:\n")

        # Zero all entries in the Master Population Table so that all unused
        # entries are assumed empty:
        spec.switchWriteFocus(region=MASTER_POP_TABLE)
        myRepeatReg = 4
        spec.moveToReg(destReg=myRepeatReg,
                       data=SynapticManager.MASTER_POPULATION_ENTRIES)
        spec.write(data=0, repeatReg=myRepeatReg, sizeof='uint16')

        # Track writes inside the synaptic matrix region:
        next_block_start_addr = 0
        n_synapse_type_bits = self.get_n_synapse_type_bits()

        # For each entry in subedge into the subvertex, create a
        # sub-synaptic list
        for subedge in subvertex.in_subedges:

            # Only deal with incoming projection subedges
            if not subedge.pruneable and isinstance(subedge,
                                                    ProjectionSubedge):

                x = packet_conversions.get_x_from_key(subedge.key)
                y = packet_conversions.get_y_from_key(subedge.key)
                p = packet_conversions.get_p_from_key(subedge.key)
                spec.comment("\nWriting matrix for subedge from" +
                             " {}, {}, {}\n".format(x, y, p))

                sublist = subedge.get_synapse_sublist()
                rowIO = subedge.edge.get_synapse_row_io()
                #if (logger.isEnabledFor("debug")):
                #    logger.debug("Writing subedge from {} ({}-{}) to {} ({}-{})"
                #            .format(sourceSubvertex.vertex.label,
                #                    sourceSubvertex.lo_atom,
                #                    sourceSubvertex.hi_atom,
                #                    subvertex.vertex.label, subvertex.lo_atom,
                #                    subvertex.hi_atom))
                #    rows = sublist.get_rows()
                #    for i in range(len(rows)):
                #        logger.debug("{}: {}".format(i, rows[i]))

                # Get the maximum row length in words, excluding headers
                max_row_length = max(
                    [rowIO.get_n_words(row) for row in sublist.get_rows()])
                # Get an entry in the row length table for this length
                row_index, row_length = \
                    self.selectMinimumRowLength(max_row_length)
                if max_row_length == 0 or row_length == 0:
                    print ""

                # Write the synaptic block for the sublist
                (block_start_addr, next_block_start_addr) = \
                    self.writeSynapseRowInfo(sublist, rowIO, spec,
                            next_block_start_addr, row_length,
                            SYNAPTIC_MATRIX, weight_scale,
                            n_synapse_type_bits)
                if ((next_block_start_addr - 1) > allSynBlockSz):
                    raise Exception(
                        "Too much synapse memory consumed (used {} of {})!".
                        format(next_block_start_addr - 1, allSynBlockSz))
                self.updateMasterPopulationTable(spec, block_start_addr,
                                                 row_index, subedge.key,
                                                 MASTER_POP_TABLE)