def send_stop_message(self): """ Send a message to indicate the end of all the messages :return: """ if not self._sent_stop_message: self._sent_stop_message = True self.add_message_to_send(EventStopRequest())
def _send_initial_messages(self, vertex, region, progress_bar): """ Send the initial set of messages :param vertex: The vertex to get the keys from :type vertex:\ :py:class:`spynnaker.pyNN.models.abstract_models.buffer_models.abstract_sends_buffers_from_host.AbstractSendsBuffersFromHost` :param region: The region to get the keys from :type region: int :return: A list of messages :rtype: list of\ :py:class:`spinnman.messages.eieio.data_messages.eieio_32bit.eieio_32bit_timed_payload_prefix_data_message.EIEIO32BitTimedPayloadPrefixDataMessage` """ # Get the vertex load details # region_base_address = self._locate_region_address(region, vertex) region_base_address = \ helpful_functions.locate_memory_region_for_placement( self._placements.get_placement_of_subvertex(vertex), region, self._transceiver) placement = self._placements.get_placement_of_subvertex(vertex) # Add packets until out of space sent_message = False bytes_to_go = vertex.get_region_buffer_size(region) if bytes_to_go % 2 != 0: raise exceptions.SpinnFrontEndException( "The buffer region of {} must be divisible by 2".format( vertex)) all_data = "" if vertex.is_empty(region): sent_message = True else: min_size_of_packet = \ EIEIO32BitTimedPayloadPrefixDataMessage.get_min_packet_length() while (vertex.is_next_timestamp(region) and bytes_to_go > min_size_of_packet): space_available = min(bytes_to_go, 280) next_message = self._create_message_to_send( space_available, vertex, region) if next_message is None: break # Write the message to the memory data = next_message.bytestring all_data += data sent_message = True # Update the positions bytes_to_go -= len(data) progress_bar.update(len(data)) if not sent_message: raise exceptions.BufferableRegionTooSmall( "The buffer size {} is too small for any data to be added for" " region {} of vertex {}".format(bytes_to_go, region, vertex)) # If there are no more messages and there is space, add a stop request if (not vertex.is_next_timestamp(region) and bytes_to_go >= EventStopRequest.get_min_packet_length()): data = EventStopRequest().bytestring # logger.debug( # "Writing stop message of {} bytes to {} on {}, {}, {}".format( # len(data), hex(region_base_address), # placement.x, placement.y, placement.p)) all_data += data bytes_to_go -= len(data) progress_bar.update(len(data)) self._sent_messages[vertex] = BuffersSentDeque( region, sent_stop_message=True) # If there is any space left, add padding if bytes_to_go > 0: padding_packet = PaddingRequest() n_packets = bytes_to_go / padding_packet.get_min_packet_length() data = padding_packet.bytestring data *= n_packets all_data += data # Do the writing all at once for efficiency self._transceiver.write_memory(placement.x, placement.y, region_base_address, all_data)
def read_eieio_command_message(data, offset): """ Reads the content of an EIEIO command message and returns an object\ identifying the command which was contained in the packet, including\ any parameter, if required by the command :param data: data received from the network :type data: bytestring :param offset: offset at which the parsing operation should start :type offset: int :return: an object which inherits from EIEIOCommandMessage which contains\ parsed data received from the network :rtype: \ :py:class:`spinnman.messages.eieio.command_messages.eieio_command_message.EIEIOCommandMessage` """ command_header = EIEIOCommandHeader.from_bytestring(data, offset) command_number = command_header.command if (command_number == constants.EIEIO_COMMAND_IDS.DATABASE_CONFIRMATION.value): return DatabaseConfirmation.from_bytestring(command_header, data, offset + 2) # Fill in buffer area with padding elif (command_number == constants.EIEIO_COMMAND_IDS.EVENT_PADDING.value): return PaddingRequest() # End of all buffers, stop execution elif (command_number == constants.EIEIO_COMMAND_IDS.EVENT_STOP.value): return EventStopRequest() # Stop complaining that there is sdram free space for buffers elif (command_number == constants.EIEIO_COMMAND_IDS.STOP_SENDING_REQUESTS.value): return StopRequests() # Start complaining that there is sdram free space for buffers elif (command_number == constants.EIEIO_COMMAND_IDS.START_SENDING_REQUESTS.value): return StartRequests() # Spinnaker requesting new buffers for spike source population elif (command_number == constants.EIEIO_COMMAND_IDS.SPINNAKER_REQUEST_BUFFERS.value): return SpinnakerRequestBuffers.from_bytestring(command_header, data, offset + 2) # Buffers being sent from host to SpiNNaker elif (command_number == constants.EIEIO_COMMAND_IDS.HOST_SEND_SEQUENCED_DATA.value): return HostSendSequencedData.from_bytestring(command_header, data, offset + 2) # Buffers available to be read from a buffered out vertex elif (command_number == constants.EIEIO_COMMAND_IDS.SPINNAKER_REQUEST_READ_DATA.value): return SpinnakerRequestReadData.from_bytestring( command_header, data, offset + 2) # Host confirming data being read form SpiNNaker memory elif (command_number == constants.EIEIO_COMMAND_IDS.HOST_DATA_READ.value): return HostDataRead.from_bytestring(command_header, data, offset + 2) return EIEIOCommandMessage(command_header, data, offset + 2)