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)
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)