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