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())
Exemple #2
0
    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)
Exemple #3
0
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)