Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Key translation #1138

Merged
merged 5 commits into from
Dec 6, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions spynnaker/pyNN/spynnaker_external_device_plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def activate_live_output_for(
prefix_type=None, message_type=EIEIOType.KEY_32_BIT,
right_shift=0, payload_as_time_stamps=True, notify=True,
use_payload_prefix=True, payload_prefix=None,
payload_right_shift=0, number_of_packets_sent_per_time_step=0):
payload_right_shift=0, number_of_packets_sent_per_time_step=0,
translate_keys=False):
""" Output the spikes from a given population from SpiNNaker as they\
occur in the simulation.

Expand Down Expand Up @@ -131,6 +132,9 @@ def activate_live_output_for(
:param str label: The label of the gatherer vertex
:param list(str) partition_ids:
The names of the partitions to create edges for
:param bool translate_keys:
Whether the incoming keys from the cores should be translated
to global keys rather than core-based keys
"""
# pylint: disable=too-many-arguments, too-many-locals, protected-access
# get default params if none set
Expand All @@ -146,7 +150,7 @@ def activate_live_output_for(
right_shift, payload_as_time_stamps, use_payload_prefix,
payload_prefix, payload_right_shift,
number_of_packets_sent_per_time_step,
partition_ids=[SPIKE_PARTITION_ID])
partition_ids=[SPIKE_PARTITION_ID], translate_keys=translate_keys)

if notify:
SpynnakerExternalDevicePluginManager.add_database_socket_address(
Expand Down Expand Up @@ -195,7 +199,7 @@ def update_live_packet_gather_tracker(
right_shift=0, payload_as_time_stamps=True,
use_payload_prefix=True, payload_prefix=None,
payload_right_shift=0, number_of_packets_sent_per_time_step=0,
partition_ids=None):
partition_ids=None, translate_keys=False):
""" Add an edge from a vertex to the live packet gatherer, builds as\
needed and has all the parameters for the creation of the live\
packet gatherer if needed.
Expand All @@ -220,6 +224,7 @@ def update_live_packet_gather_tracker(
:param int payload_right_shift:
:param int number_of_packets_sent_per_time_step:
:param list(str) partition_ids:
:param bool translate_keys:
"""
# pylint: disable=too-many-arguments, too-many-locals
params = LivePacketGatherParameters(
Expand All @@ -232,7 +237,7 @@ def update_live_packet_gather_tracker(
payload_right_shift=payload_right_shift,
number_of_packets_sent_per_time_step=(
number_of_packets_sent_per_time_step),
label=lpg_label)
label=lpg_label, translate_keys=translate_keys)

# add to the tracker
get_simulator().add_live_packet_gatherer_parameters(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (c) 2021 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pyNN.spiNNaker as p

from spinnman.connections import ConnectionListener
from spinnman.messages.eieio.create_eieio_data import read_eieio_data_message
from spinnman.connections.udp_packet_connections import SCAMPConnection
from spinnman.utilities.utility_functions import reprogram_tag
from spinn_front_end_common.utilities.database import DatabaseConnection
from spinnman.messages.eieio.eieio_prefix import EIEIOPrefix
from spinnaker_testbase.base_test_case import BaseTestCase
import unittest


class UDPSCAMPConnection(SCAMPConnection):

def get_receive_method(self):
return self.receive


class TestLiveGatherTranslator(BaseTestCase):

PREFIX = 0x1234

def recv(self, data):
message = read_eieio_data_message(data, 0)
while message.is_next_element:
element = message.next_element
time = element.payload
key = element.key
self.stored_data.append((key, time))
print(f"Received key {hex(key)} at time {time}")

def start_callback(self):
reprogram_tag(self.conn, tag=1, strip=True)
self.listener.start()

def live_spike_receive_translated(self):
self.stored_data = list()
self.conn = UDPSCAMPConnection(remote_host="192.168.240.253")
print(f"Listening on port {self.conn.local_port}")
self.listener = ConnectionListener(self.conn)
self.listener.add_callback(self.recv)

db_conn = DatabaseConnection(self.start_callback, local_port=None)

p.setup(1.0)
p.set_number_of_neurons_per_core(p.SpikeSourceArray, 5)

pop = p.Population(
25, p.SpikeSourceArray([[i * 10] for i in range(25)]))
p.external_devices.activate_live_output_for(
pop, port=self.conn.local_port, translate_keys=True,
database_notify_port_num=db_conn.local_port, tag=1,
use_prefix=True, key_prefix=self.PREFIX,
prefix_type=EIEIOPrefix.UPPER_HALF_WORD)

p.run(500)

p.end()
self.listener.close()
self.conn.close()

self.assertGreater(len(self.stored_data), 0)
for key, time in self.stored_data:
self.assertEqual(key >> 16, self.PREFIX)
self.assertEqual((key & 0xFFFF) * 10, time)

def test_live_spike_receive_translated(self):
self.runsafe(self.live_spike_receive_translated)


if __name__ == '__main__':
unittest.main()