def _process_last_ack(self, placement, region_id, end_state):
        # if the last ACK packet has not been processed on the chip,
        # process it now
        last_sent_ack = self._received_data.last_sent_packet_to_core(
            placement.x, placement.y, placement.p)
        last_sent_ack = create_eieio_command.read_eieio_command_message(
            last_sent_ack.data, 0)
        if not isinstance(last_sent_ack, HostDataRead):
            raise Exception(
                "Something somewhere went terribly wrong; looking for a "
                "HostDataRead packet, while I got {0:s}".format(last_sent_ack))

        start_ptr = end_state.start_address
        write_ptr = end_state.current_write
        end_ptr = end_state.end_address
        read_ptr = end_state.current_read

        for i in xrange(last_sent_ack.n_requests):
            in_region = region_id == last_sent_ack.region_id(i)
            if in_region and not end_state.is_state_updated:
                read_ptr += last_sent_ack.space_read(i)
                if (read_ptr == write_ptr
                        or (read_ptr == end_ptr and write_ptr == start_ptr)):
                    end_state.update_last_operation(
                        BUFFERING_OPERATIONS.BUFFER_READ.value)
                if read_ptr == end_ptr:
                    read_ptr = start_ptr
                elif read_ptr > end_ptr:
                    raise Exception(
                        "Something somewhere went terribly wrong; I was "
                        "reading beyond the region area")
        end_state.update_read_pointer(read_ptr)
        end_state.set_update_completed()
    def receive_eieio_message(self, timeout=None):
        data = self.receive(timeout)
        header = struct.unpack_from("<H", data)[0]
        if header & 0xC000 == 0x4000:
            eieio_message = read_eieio_command_message(data, 0)
        else:
            eieio_message = read_eieio_data_message(data, 0)

        return eieio_message
Ejemplo n.º 3
0
    def get_data_for_vertex(self, placement, region_to_read, state_region):
        """ Get a pointer to the data container for all the data retrieved\
            during the simulation from a specific region area of a core

        :param placement: the placement to get the data from
        :type placement: pacman.model.placements.placement.Placement
        :param region_to_read: desired data region
        :type region_to_read: int
        :param state_region: final state storage region
        :type state_region: int
        :return: pointer to a class which inherits from\
                AbstractBufferedDataStorage
        :rtype:\
                py:class:`spinn_front_end_common.interface.buffer_management.buffer_models.abstract_buffered_data_storage.AbstractBufferedDataStorage`
        """
        # flush data here
        if not self._received_data.is_data_from_region_flushed(
                placement.x, placement.y, placement.p, region_to_read):
            if not self._received_data.is_end_buffering_state_recovered(
                    placement.x, placement.y, placement.p):

                # Get the App Data for the core
                state_region_base_address = \
                    helpful_functions.locate_memory_region_for_placement(
                        placement, state_region, self._transceiver)

                # retrieve channel state memory area
                raw_number_of_channels = self._transceiver.read_memory(
                    placement.x, placement.y, state_region_base_address, 4)
                number_of_channels = struct.unpack(
                    "<I", str(raw_number_of_channels))[0]
                channel_state_data = str(
                    self._transceiver.read_memory(
                        placement.x, placement.y, state_region_base_address,
                        EndBufferingState.size_of_region(number_of_channels)))
                end_buffering_state = EndBufferingState.create_from_bytearray(
                    channel_state_data)
                self._received_data.store_end_buffering_state(
                    placement.x, placement.y, placement.p, end_buffering_state)
            else:
                end_buffering_state = self._received_data.\
                    get_end_buffering_state(
                        placement.x, placement.y, placement.p)

            end_state = end_buffering_state.get_state_for_region(
                region_to_read)
            start_ptr = end_state.start_address
            write_ptr = end_state.current_write
            end_ptr = end_state.end_address
            read_ptr = end_state.current_read

            # current read needs to be adjusted in case the last portion of the
            # memory has already been read, but the HostDataRead packet has not
            # been processed by the chip before simulation finished
            # This situation is identified by the sequence number of the last
            # packet sent to this core and the core internal state of the
            # output buffering finite state machine
            seq_no_last_ack_packet = \
                self._received_data.last_sequence_no_for_core(
                    placement.x, placement.y, placement.p)
            seq_no_internal_fsm = end_buffering_state.buffering_out_fsm_state
            if seq_no_internal_fsm == seq_no_last_ack_packet:

                # if the last ACK packet has not been processed on the chip,
                # process it now
                last_sent_ack_sdp_packet = \
                    self._received_data.last_sent_packet_to_core(
                        placement.x, placement.y, placement.p)
                last_sent_ack_packet = \
                    create_eieio_command.read_eieio_command_message(
                        last_sent_ack_sdp_packet.data, 0)
                if not isinstance(last_sent_ack_packet, HostDataRead):
                    raise Exception(
                        "Something somewhere went terribly wrong - "
                        "I was looking for a HostDataRead packet, "
                        "while I got {0:s}".format(last_sent_ack_packet))
                for i in xrange(last_sent_ack_packet.n_requests):
                    if (region_to_read == last_sent_ack_packet.region_id(i)
                            and not end_state.is_state_updated):
                        read_ptr += last_sent_ack_packet.space_read(i)
                        if (read_ptr == write_ptr or
                            (read_ptr == end_ptr and write_ptr == start_ptr)):
                            end_state.update_last_operation(
                                spinn_front_end_constants.BUFFERING_OPERATIONS.
                                BUFFER_READ.value)
                        if read_ptr == end_ptr:
                            read_ptr = start_ptr
                        elif read_ptr > end_ptr:
                            raise Exception(
                                "Something somewhere went terribly wrong - "
                                "I was reading beyond the region area some "
                                "unknown data".format(last_sent_ack_packet))
                end_state.update_read_pointer(read_ptr)
                end_state.set_update_completed()

            # now state is updated, read back values for read pointer and
            # last operation performed
            last_operation = end_state.last_buffer_operation
            read_ptr = end_state.current_read

            # now read_ptr is updated, check memory to read
            if read_ptr < write_ptr:
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, region_to_read,
                    data)

            elif read_ptr > write_ptr:
                length = end_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.store_data_in_region_buffer(
                    placement.x, placement.y, placement.p, region_to_read,
                    data)
                read_ptr = start_ptr
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, region_to_read,
                    data)

            elif (read_ptr == write_ptr
                  and last_operation == spinn_front_end_constants.
                  BUFFERING_OPERATIONS.BUFFER_WRITE.value):
                length = end_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.store_data_in_region_buffer(
                    placement.x, placement.y, placement.p, region_to_read,
                    data)
                read_ptr = start_ptr
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, region_to_read,
                    data)

            elif (read_ptr == write_ptr
                  and last_operation == spinn_front_end_constants.
                  BUFFERING_OPERATIONS.BUFFER_READ.value):
                data = bytearray()
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, region_to_read,
                    data)

        # data flush has been completed - return appropriate data
        # the two returns can be exchanged - one returns data and the other
        # returns a pointer to the structure holding the data
        return self._received_data.get_region_data_pointer(
            placement.x, placement.y, placement.p, region_to_read)
Ejemplo n.º 4
0
    def get_data_for_vertex(self, placement, recording_region_id):
        """ Get a pointer to the data container for all the data retrieved\
            during the simulation from a specific region area of a core

        :param placement: the placement to get the data from
        :type placement: pacman.model.placements.Placement
        :param recording_region_id: desired recording data region
        :type recording_region_id: int
        :return: pointer to a class which inherits from\
                AbstractBufferedDataStorage
        :rtype:\
                :py:class:`spinn_front_end_common.interface.buffer_management.buffer_models.AbstractBufferedDataStorage`
        """

        recording_data_address = \
            placement.vertex.get_recording_region_base_address(
                self._transceiver, placement)

        # Ensure the last sequence number sent has been retrieved
        if not self._received_data.is_end_buffering_sequence_number_stored(
                placement.x, placement.y, placement.p):
            self._received_data.store_end_buffering_sequence_number(
                placement.x, placement.y, placement.p,
                get_last_sequence_number(placement, self._transceiver,
                                         recording_data_address))

        # Read the data if not already received
        if not self._received_data.is_data_from_region_flushed(
                placement.x, placement.y, placement.p, recording_region_id):

            # Read the end state of the recording for this region
            if not self._received_data.is_end_buffering_state_recovered(
                    placement.x, placement.y, placement.p,
                    recording_region_id):

                end_state_address = get_region_pointer(placement,
                                                       self._transceiver,
                                                       recording_data_address,
                                                       recording_region_id)
                end_state = self._generate_end_buffering_state_from_machine(
                    placement, end_state_address)
                self._received_data.store_end_buffering_state(
                    placement.x, placement.y, placement.p, recording_region_id,
                    end_state)
            else:
                end_state = self._received_data.\
                    get_end_buffering_state(
                        placement.x, placement.y, placement.p,
                        recording_region_id)

            start_ptr = end_state.start_address
            write_ptr = end_state.current_write
            end_ptr = end_state.end_address
            read_ptr = end_state.current_read

            # current read needs to be adjusted in case the last portion of the
            # memory has already been read, but the HostDataRead packet has not
            # been processed by the chip before simulation finished
            # This situation is identified by the sequence number of the last
            # packet sent to this core and the core internal state of the
            # output buffering finite state machine
            seq_no_last_ack_packet = \
                self._received_data.last_sequence_no_for_core(
                    placement.x, placement.y, placement.p)

            # get the last sequence number
            last_sequence_number = \
                self._received_data.get_end_buffering_sequence_number(
                    placement.x, placement.y, placement.p)

            if last_sequence_number == seq_no_last_ack_packet:

                # if the last ACK packet has not been processed on the chip,
                # process it now
                last_sent_ack_sdp_packet = \
                    self._received_data.last_sent_packet_to_core(
                        placement.x, placement.y, placement.p)
                last_sent_ack_packet = \
                    create_eieio_command.read_eieio_command_message(
                        last_sent_ack_sdp_packet.data, 0)
                if not isinstance(last_sent_ack_packet, HostDataRead):
                    raise Exception(
                        "Something somewhere went terribly wrong - "
                        "I was looking for a HostDataRead packet, "
                        "while I got {0:s}".format(last_sent_ack_packet))
                for i in xrange(last_sent_ack_packet.n_requests):

                    last_ack_packet_is_of_this_region = \
                        recording_region_id == \
                        last_sent_ack_packet.region_id(i)

                    if (last_ack_packet_is_of_this_region
                            and not end_state.is_state_updated):
                        read_ptr += last_sent_ack_packet.space_read(i)
                        if (read_ptr == write_ptr or
                            (read_ptr == end_ptr and write_ptr == start_ptr)):
                            end_state.update_last_operation(
                                BUFFERING_OPERATIONS.BUFFER_READ.value)
                        if read_ptr == end_ptr:
                            read_ptr = start_ptr
                        elif read_ptr > end_ptr:
                            raise Exception(
                                "Something somewhere went terribly wrong - "
                                "I was reading beyond the region area some "
                                "unknown data".format(last_sent_ack_packet))
                end_state.update_read_pointer(read_ptr)
                end_state.set_update_completed()

            # now state is updated, read back values for read pointer and
            # last operation performed
            last_operation = end_state.last_buffer_operation
            read_ptr = end_state.current_read

            # now read_ptr is updated, check memory to read
            if read_ptr < write_ptr:
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, recording_region_id,
                    data)

            elif read_ptr > write_ptr:
                length = end_ptr - read_ptr
                if length < 0:
                    raise exceptions.ConfigurationException(
                        "The amount of data to read is negative!")
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.store_data_in_region_buffer(
                    placement.x, placement.y, placement.p, recording_region_id,
                    data)
                read_ptr = start_ptr
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, recording_region_id,
                    data)

            elif (read_ptr == write_ptr and last_operation
                  == BUFFERING_OPERATIONS.BUFFER_WRITE.value):
                length = end_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.store_data_in_region_buffer(
                    placement.x, placement.y, placement.p, recording_region_id,
                    data)
                read_ptr = start_ptr
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(placement.x, placement.y,
                                                     read_ptr, length)
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, recording_region_id,
                    data)

            elif (read_ptr == write_ptr and last_operation
                  == BUFFERING_OPERATIONS.BUFFER_READ.value):
                data = bytearray()
                self._received_data.flushing_data_from_region(
                    placement.x, placement.y, placement.p, recording_region_id,
                    data)

        # data flush has been completed - return appropriate data
        # the two returns can be exchanged - one returns data and the other
        # returns a pointer to the structure holding the data
        return self._received_data.get_region_data_pointer(
            placement.x, placement.y, placement.p, recording_region_id)