Esempio n. 1
0
    def send_events(self, label, atom_ids, send_full_keys=False):
        """ Send a number of events

        :param str label:
            The label of the vertex from which the events will originate
        :param list(int) atom_ids: array-like of atom IDs sending events
        :param bool send_full_keys:
            Determines whether to send full 32-bit keys, getting the key for
            each atom from the database, or whether to send 16-bit atom IDs
            directly
        """
        max_keys = _MAX_HALF_KEYS_PER_PACKET
        msg_type = EIEIOType.KEY_16_BIT
        if send_full_keys:
            max_keys = _MAX_FULL_KEYS_PER_PACKET
            msg_type = EIEIOType.KEY_32_BIT

        pos = 0
        x, y, p, ip_address = self.__send_address_details[label]
        while pos < len(atom_ids):
            message = EIEIODataMessage.create(msg_type)
            events_in_packet = 0
            while pos < len(atom_ids) and events_in_packet < max_keys:
                key = atom_ids[pos]
                if send_full_keys:
                    key = self._atom_id_to_key[label][key]
                message.add_key(key)
                pos += 1
                events_in_packet += 1

            self.__sender_connection.send_to(
                self.__get_sdp_data(message, x, y, p),
                (ip_address, SCP_SCAMP_PORT))
    def send_events(self, label, atom_ids, send_full_keys=False):
        """ Send a number of events

        :param label: \
            The label of the vertex from which the events will originate
        :type label: str
        :param atom_ids: array-like of atom IDs sending events
        :type atom_ids: [int]
        :param send_full_keys: Determines whether to send full 32-bit keys,\
            getting the key for each atom from the database, or whether to\
            send 16-bit atom IDs directly
        :type send_full_keys: bool
        """
        max_keys = _MAX_HALF_KEYS_PER_PACKET
        msg_type = EIEIOType.KEY_16_BIT
        if send_full_keys:
            max_keys = _MAX_FULL_KEYS_PER_PACKET
            msg_type = EIEIOType.KEY_32_BIT

        pos = 0
        while pos < len(atom_ids):
            message = EIEIODataMessage.create(msg_type)
            events_in_packet = 0
            while pos < len(atom_ids) and events_in_packet < max_keys:
                key = atom_ids[pos]
                if send_full_keys:
                    key = self._atom_id_to_key[label][key]
                message.add_key(key)
                pos += 1
                events_in_packet += 1
            ip_address, port = self._send_address_details[label]
            self._sender_connection.send_eieio_message_to(
                message, ip_address, port)
Esempio n. 3
0
    def send_events_with_payloads(self, label, atom_ids_and_payloads):
        """ Send a number of events with payloads

        :param str label:
            The label of the vertex from which the events will originate
        :param list(tuple(int,int)) atom_ids_and_payloads:
            array-like of tuples of atom IDs sending events with their payloads
        """
        msg_type = EIEIOType.KEY_PAYLOAD_32_BIT
        max_keys = _MAX_FULL_KEYS_PAYLOADS_PER_PACKET
        pos = 0
        x, y, p, ip_address = self.__send_address_details[label]
        while pos < len(atom_ids_and_payloads):
            message = EIEIODataMessage.create(msg_type)
            events = 0
            while pos < len(atom_ids_and_payloads) and events < max_keys:
                key, payload = atom_ids_and_payloads[pos]
                key = self._atom_id_to_key[label][key]
                message.add_key_and_payload(key, payload)
                pos += 1
                events += 1

            self.__sender_connection.send_to(
                self.__get_sdp_data(message, x, y, p),
                (ip_address, SCP_SCAMP_PORT))
Esempio n. 4
0
    def send_events(self, label, atom_ids, send_full_keys=False):
        """ Send a number of events

        :param label: \
            The label of the vertex from which the events will originate
        :type label: str
        :param atom_ids: array-like of atom IDs sending events
        :type atom_ids: [int]
        :param send_full_keys: Determines whether to send full 32-bit keys,\
            getting the key for each atom from the database, or whether to\
            send 16-bit atom IDs directly
        :type send_full_keys: bool
        """
        max_keys = _MAX_HALF_KEYS_PER_PACKET
        msg_type = EIEIOType.KEY_16_BIT
        if send_full_keys:
            max_keys = _MAX_FULL_KEYS_PER_PACKET
            msg_type = EIEIOType.KEY_32_BIT

        pos = 0
        while pos < len(atom_ids):
            message = EIEIODataMessage.create(msg_type)
            events_in_packet = 0
            while pos < len(atom_ids) and events_in_packet < max_keys:
                key = atom_ids[pos]
                if send_full_keys:
                    key = self._atom_id_to_key[label][key]
                message.add_key(key)
                pos += 1
                events_in_packet += 1
            ip_address, port = self._send_address_details[label]
            self._sender_connection.send_eieio_message_to(
                message, ip_address, port)
 def _assemble_message(id_to_key_map, neuron_id_rates, pos):
     scale = DataType.S1615.scale  # @UndefinedVariable
     message = EIEIODataMessage.create(EIEIOType.KEY_PAYLOAD_32_BIT)
     for _ in range(_MAX_RATES_PER_PACKET):
         neuron_id, rate = neuron_id_rates[pos]
         key = id_to_key_map[neuron_id]
         message.add_key_and_payload(key, int(round(rate * scale)))
         pos += 1
         if pos >= len(neuron_id_rates):
             break
     return message, pos
 def _assemble_message(id_to_key_map, neuron_id_rates, pos):
     scale = DataType.S1615.scale  # @UndefinedVariable
     message = EIEIODataMessage.create(EIEIOType.KEY_PAYLOAD_32_BIT)
     for _ in range(_MAX_RATES_PER_PACKET):
         neuron_id, rate = neuron_id_rates[pos]
         key = id_to_key_map[neuron_id]
         message.add_key_and_payload(
             key, int(round(Decimal(str(rate)) * scale)))
         pos += 1
         if pos >= len(neuron_id_rates):
             break
     return message, pos
Esempio n. 7
0
def read_eieio_data_message(data, offset):
    """ Reads the content of an EIEIO data message and returns an object\
        identifying the data which was contained in the packet

    :param bytes data: data received from the network as a bytestring
    :param int offset: offset at which the parsing operation should start
    :return: an object which inherits from EIEIODataMessage which contains
        parsed data received from the network
    :rtype: EIEIODataMessage
    """
    eieio_header = EIEIODataHeader.from_bytestring(data, offset)
    offset += eieio_header.size
    return EIEIODataMessage(eieio_header, data, offset)
    def _create_message_to_send(self, size, vertex, region):
        """ Creates a single message to send with the given boundaries.

        :param size: The number of bytes available for the whole packet
        :type size: int
        :param vertex: The vertex to get the keys from
        :type vertex:\
                    :py:class:`spynnaker.pyNN.models.abstract_models.buffer_models.AbstractSendsBuffersFromHost`
        :param region: The region of the vertex to get keys from
        :type region: int
        :return: A new message, or None if no keys can be added
        :rtype: None or\
                    :py:class:`spinnman.messages.eieio.data_messages.EIEIODataMessage`
        """

        # If there are no more messages to send, return None
        if not vertex.is_next_timestamp(region):
            return None

        # Create a new message
        next_timestamp = vertex.get_next_timestamp(region)
        message = EIEIODataMessage.create(EIEIOType.KEY_32_BIT,
                                          timestamp=next_timestamp)

        # If there is no room for the message, return None
        if message.size + _N_BYTES_PER_KEY > size:
            return None

        # Add keys up to the limit
        bytes_to_go = size - message.size
        while (bytes_to_go >= _N_BYTES_PER_KEY
               and vertex.is_next_key(region, next_timestamp)):

            key = vertex.get_next_key(region)
            message.add_key(key)
            bytes_to_go -= _N_BYTES_PER_KEY

        return message
from spinn_front_end_common.interface.buffer_management.storage_objects \
    import BuffersSentDeque, BufferedReceivingData, ChannelBufferState
from spinn_front_end_common.utilities.constants \
    import SDP_PORTS, BUFFERING_OPERATIONS
from .recording_utilities import TRAFFIC_IDENTIFIER, \
    get_last_sequence_number, get_region_pointer

# general imports
import threading
import logging
import traceback

logger = logging.getLogger(__name__)

# The minimum size of any message - this is the headers plus one entry
_MIN_MESSAGE_SIZE = EIEIODataMessage.min_packet_length(
    eieio_type=EIEIOType.KEY_32_BIT, is_timestamp=True)

# The number of bytes in each key to be sent
_N_BYTES_PER_KEY = EIEIOType.KEY_32_BIT.key_bytes  # @UndefinedVariable


class BufferManager(object):
    """ Manager of send buffers
    """

    __slots__ = [
        # placements object
        "_placements",

        # list of tags
        "_tags",