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