def reserve_buffer_regions(
            self, spec, state_region, buffer_regions, region_sizes):
        """ Reserves the region for recording and the region for storing the\
            end state of the buffering

        :param spec: The data specification to reserve the region in
        :param state_region: The id of the region to use as the end state\
                region
        :param buffer_regions: The regions ids to reserve for buffering
        :param region_sizes: The sizes of the regions to reserve
        """
        if len(buffer_regions) != len(region_sizes):
            raise exceptions.ConfigurationException(
                "The number of buffer regions must match the number of"
                " regions sizes")
        if self._buffering_output:
            for (buffer_region, region_size) in zip(
                    buffer_regions, region_sizes):
                if region_size > 0:
                    spec.reserve_memory_region(
                        region=buffer_region, size=region_size,
                        label="RECORDING_REGION_{}".format(buffer_region),
                        empty=True)
            spec.reserve_memory_region(
                region=state_region,
                size=EndBufferingState.size_of_region(len(buffer_regions)),
                label='BUFFERED_OUT_STATE', empty=True)
    def reserve_buffer_regions(
            self, spec, state_region, buffer_regions, region_sizes):
        """ Reserves the region for recording and the region for storing the\
            end state of the buffering

        :param spec: The data specification to reserve the region in
        :param state_region: The id of the region to use as the end state\
                region
        :param buffer_regions: The regions ids to reserve for buffering
        :param region_sizes: The sizes of the regions to reserve
        """
        if len(buffer_regions) != len(region_sizes):
            raise exceptions.ConfigurationException(
                "The number of buffer regions must match the number of"
                " regions sizes")
        for (buffer_region, region_size) in zip(
                buffer_regions, region_sizes):
            if region_size > 0:
                self._buffered_regions.append(buffer_region)
                spec.reserve_memory_region(
                    region=buffer_region, size=region_size,
                    label="RECORDING_REGION_{}".format(buffer_region),
                    empty=True)
        spec.reserve_memory_region(
            region=state_region,
            size=EndBufferingState.size_of_region(len(buffer_regions)),
            label='BUFFERED_OUT_STATE', empty=True)
        self._buffered_state_region = state_region
 def get_buffer_state_region_size(n_buffered_regions):
     """ Get the size of the buffer state region for the given number of\
         buffered regions
     """
     return EndBufferingState.size_of_region(n_buffered_regions)
Ejemplo n.º 4
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)
    def get_data_for_vertex(self, x, y, p, 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 x: x coordinate of the chip
        :type x: int
        :param y: y coordinate of the chip
        :type y: int
        :param p: processor on the specified chip
        :type p: int
        :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(
                x, y, p, region_to_read):
            if not self._received_data.is_end_buffering_state_recovered(
                    x, y, p):

                # Get the App Data for the core
                app_data_base_address = \
                    self._transceiver.get_cpu_information_from_core(
                        x, y, p).user[0]

                # Get the position of the buffer
                state_region_base_offset_address = \
                    dsg_utilities.get_region_base_address_offset(
                        app_data_base_address, state_region)
                state_region_base_address_buf = buffer(
                    self._transceiver.read_memory(
                        x, y, state_region_base_offset_address, 4))
                state_region_base_address = struct.unpack_from(
                    "<I", state_region_base_address_buf)[0]
                state_region_base_address += app_data_base_address

                # retrieve channel state memory area
                raw_number_of_channels = self._transceiver.read_memory(
                    x, 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(
                    x, 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(
                    x, y, p, end_buffering_state)
            else:
                end_buffering_state = self._received_data.\
                    get_end_buffering_state(x, y, 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(x, y, 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(x, y, 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(x, y, read_ptr, length)
                self._received_data.flushing_data_from_region(
                    x, y, p, region_to_read, data)

            elif read_ptr > write_ptr:
                length = end_ptr - read_ptr
                data = self._transceiver.read_memory(x, y, read_ptr, length)
                self._received_data.store_data_in_region_buffer(
                    x, y, p, region_to_read, data)
                read_ptr = start_ptr
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(x, y, read_ptr, length)
                self._received_data.flushing_data_from_region(
                    x, y, 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(x, y, read_ptr, length)
                self._received_data.store_data_in_region_buffer(
                    x, y, p, region_to_read, data)
                read_ptr = start_ptr
                length = write_ptr - read_ptr
                data = self._transceiver.read_memory(x, y, read_ptr, length)
                self._received_data.flushing_data_from_region(
                    x, y, 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(
                    x, y, 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(
            x, y, p, region_to_read)
 def get_buffer_state_region_size(n_buffered_regions):
     """ Get the size of the buffer state region for the given number of\
         buffered regions
     """
     return EndBufferingState.size_of_region(n_buffered_regions)