-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpkt_injector_vertex.py
176 lines (139 loc) · 5.86 KB
/
pkt_injector_vertex.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import struct
from enum import Enum
from data_specification.enums.data_type import DataType
from pacman.model.graphs.machine.machine_vertex import MachineVertex
from pacman.model.resources.resource_container \
import ResourceContainer, ConstantSDRAM
from pacman.model.constraints.placer_constraints import ChipAndCoreConstraint
from spinn_front_end_common.abstract_models.impl \
import MachineDataSpecableVertex
from spinn_front_end_common.utilities.constants \
import SYSTEM_BYTES_REQUIREMENT, BYTES_PER_WORD
from spinnaker_graph_front_end.utilities import SimulatorVertex
from spinnaker_graph_front_end.utilities.data_utils \
import generate_system_data_region
from spinn_utilities.overrides import overrides
class Pkt_Injector_Vertex(
SimulatorVertex,
MachineDataSpecableVertex
):
""" A packet injector for SpiNNaker network traffic tests
"""
SDRAM_REGIONS = Enum(
value="SDRAM_REGIONS",
names=[('SYSTEM', 0),
('INJECTOR', 1),
('ROUTING', 2)
]
)
def __init__(self,
iid = 0,
x_coord = None,
y_coord = None,
nkeys = 1,
throttle = 0,
use_payload = True
):
label = f"pi/{iid}"
constraints = None
if x_coord is not None:
if y_coord is not None:
label = f"pi/{x_coord}-{y_coord}/{iid}"
constraints = [ChipAndCoreConstraint(
x = int (x_coord),
y = int (y_coord)
)]
else:
print ("incompatible coordinates given")
elif y_coord is not None:
print ("incompatible coordinates given")
super(Pkt_Injector_Vertex, self).__init__(
label = label,
binary_name = "pkt_injector.aplx",
constraints = constraints
)
# number of routing keys to be used
self.NKEYS = nkeys
# injection links
if self.NKEYS == 1:
self.inj_lnk = f"inj_link{x_coord}-{y_coord}/{iid}"
else:
self.inj_lnk = []
for k in range (self.NKEYS):
self.inj_lnk.append (f"inj_link{x_coord}-{y_coord}/{iid}/{k}")
# throttle control: wait "cycles" between sending packets
self.throttle = throttle
# use packets with payloads and check for missing packets
self.use_payload = use_payload
# size of configuration structure in SDRAM
self.CONFIGURATION_BYTES = len (self.config)
# size of routing keys structure in SDRAM
self.ROUTING_BYTES = (self.NKEYS + 1) * BYTES_PER_WORD
# total SDRAM usage
self.sdram_fixed = (
SYSTEM_BYTES_REQUIREMENT +
self.CONFIGURATION_BYTES +
self.ROUTING_BYTES
)
@property
def config (self):
""" returns a packed string that corresponds to
(C struct) injector_conf in pkt_injector.c:
typedef struct injector_conf {
uint32_t throttle; // injection slow down
uint32_t active_time; // length of time for packet sending
uint32_t delayed_start; // delay the start of packet sending
uint32_t idle_end; // idle time after packet sending stops
uint32_t use_payload; // send packets with sequential payloads
} injector_conf_t;
pack: standard sizes, little-endian byte order,
explicit padding
"""
active_time = 5
delayed_start = 2
idle_end = 3
return struct.pack ("<5I",
self.throttle,
active_time,
delayed_start,
idle_end,
self.use_payload
)
@property
@overrides (MachineVertex.resources_required)
def resources_required (self):
resources = ResourceContainer (
sdram = ConstantSDRAM(self.sdram_fixed)
)
return resources
@overrides(MachineDataSpecableVertex.generate_machine_data_specification)
def generate_machine_data_specification(
self, spec, placement, machine_graph, routing_info, iptags,
reverse_iptags, machine_time_step, time_scale_factor):
# Generate the system data region for simulation.c requirements
generate_system_data_region(spec, self.SDRAM_REGIONS.SYSTEM.value,
self, machine_time_step, time_scale_factor)
# reserve and write the core configuration region
spec.reserve_memory_region (self.SDRAM_REGIONS.INJECTOR.value,
self.CONFIGURATION_BYTES)
spec.switch_write_focus (self.SDRAM_REGIONS.INJECTOR.value)
# write core configuration into spec
for c in self.config:
spec.write_value (c, data_type = DataType.UINT8)
# reserve and write the routing keys region
spec.reserve_memory_region (self.SDRAM_REGIONS.ROUTING.value,
self.ROUTING_BYTES)
spec.switch_write_focus (self.SDRAM_REGIONS.ROUTING.value)
# write number of routing keys
spec.write_value (self.NKEYS, data_type = DataType.UINT32)
# write routing keys
if self.NKEYS == 1:
spec.write_value (
routing_info.get_first_key_from_pre_vertex (
self, self.inj_lnk), data_type = DataType.UINT32
)
else:
for k in range (self.NKEYS):
spec.write_value (routing_info.get_first_key_from_pre_vertex (
self, self.inj_lnk[k]), data_type = DataType.UINT32)
spec.end_specification()