25
25
from .spif_devices import (
26
26
SPIF_FPGA_ID , SPIF_OUTPUT_FPGA_LINK , SpiNNFPGARegister )
27
27
28
+ # The maximum number of partitions that can be supported.
29
+ N_OUTGOING = 6
30
+
28
31
29
32
class SPIFOutputDevice (
30
33
ApplicationFPGAVertex , PopulationApplicationVertex ,
@@ -33,7 +36,7 @@ class SPIFOutputDevice(
33
36
Output (only) to a SPIF device.
34
37
"""
35
38
36
- __slots__ = ["__incoming_partition " , "__create_database" ]
39
+ __slots__ = ["__incoming_partitions " , "__create_database" ]
37
40
38
41
def __init__ (self , board_address = None , chip_coords = None , label = None ,
39
42
create_database = True , database_notify_host = None ,
@@ -44,7 +47,7 @@ def __init__(self, board_address=None, chip_coords=None, label=None,
44
47
SPIF_FPGA_ID , SPIF_OUTPUT_FPGA_LINK , board_address ,
45
48
chip_coords ),
46
49
label = label )
47
- self .__incoming_partition = None
50
+ self .__incoming_partitions = list ()
48
51
# Force creation of the database, to be used in the read side of things
49
52
if create_database :
50
53
set_config ("Database" , "create_database" , "True" )
@@ -58,44 +61,48 @@ def add_incoming_edge(self, edge, partition):
58
61
# Ignore non-spike partitions
59
62
if partition .identifier != SPIKE_PARTITION_ID :
60
63
return
61
- if self .__incoming_partition is not None :
64
+ if len ( self .__incoming_partitions ) >= N_OUTGOING :
62
65
raise ValueError (
63
- "Only one outgoing connection is supported per spif device"
64
- f" (existing partition: { self .__incoming_partition } " )
65
- self .__incoming_partition = partition
66
+ f"Only { N_OUTGOING } outgoing connections are supported per"
67
+ " spif device (existing partitions:"
68
+ f" { self .__incoming_partitions } " )
69
+ self .__incoming_partitions .append (partition )
66
70
if self .__create_database :
67
71
SpynnakerDataView .add_live_output_vertex (
68
- self .__incoming_partition .pre_vertex ,
69
- self .__incoming_partition .identifier )
72
+ partition .pre_vertex , partition .identifier )
70
73
71
- def _get_set_key_payload (self ):
74
+ def _get_set_key_payload (self , index ):
72
75
"""
73
76
Get the payload for the command to set the router key.
77
+
78
+ :param int index: The index of key to get
74
79
"""
75
80
r_infos = SpynnakerDataView .get_routing_infos ()
76
81
return r_infos .get_first_key_from_pre_vertex (
77
- self .__incoming_partition .pre_vertex ,
78
- self .__incoming_partition .identifier )
82
+ self .__incoming_partitions [ index ] .pre_vertex ,
83
+ self .__incoming_partitions [ index ] .identifier )
79
84
80
- def _get_set_mask_payload (self ):
85
+ def _get_set_mask_payload (self , index ):
81
86
"""
82
87
Get the payload for the command to set the router mask.
88
+
89
+ :param int index: The index of the mask to get
83
90
"""
84
91
r_infos = SpynnakerDataView .get_routing_infos ()
85
92
return r_infos .get_routing_info_from_pre_vertex (
86
- self .__incoming_partition .pre_vertex ,
87
- self .__incoming_partition .identifier ).mask
93
+ self .__incoming_partitions [ index ] .pre_vertex ,
94
+ self .__incoming_partitions [ index ] .identifier ).mask
88
95
89
96
@property
90
97
def start_resume_commands (self ):
91
98
# The commands here are delayed, as at the time of providing them,
92
99
# we don't know the key or mask of the incoming link...
93
- return [
94
- SpiNNFPGARegister . P_KEY . delayed_command (
95
- self . _get_set_key_payload ),
96
- SpiNNFPGARegister . P_MASK . delayed_command (
97
- self . _get_set_mask_payload )
98
- ]
100
+ commands = list ()
101
+ for i in range ( len ( self . __incoming_partitions )):
102
+ commands . append ( SpiNNFPGARegister . XP_KEY_BASE . delayed_command (
103
+ self . _get_set_key_payload , i ))
104
+ commands . append ( SpiNNFPGARegister . XP_MASK_BASE . delayed_command (
105
+ self . _get_set_mask_payload , i ))
99
106
100
107
@property
101
108
def pause_stop_commands (self ):
0 commit comments