• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SpiNNakerManchester / JavaSpiNNaker / 6310285782

26 Sep 2023 08:47AM UTC coverage: 36.367% (-0.5%) from 36.866%
6310285782

Pull #658

github

dkfellows
Merge branch 'master' into java-17
Pull Request #658: Update Java version to 17 and JEE to 9

1675 of 1675 new or added lines in 266 files covered. (100.0%)

8368 of 23010 relevant lines covered (36.37%)

0.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/SpiNNaker-comms/src/main/java/uk/ac/manchester/spinnaker/transceiver/TransceiverInterface.java
1
/*
2
 * Copyright (c) 2018 The University of Manchester
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package uk.ac.manchester.spinnaker.transceiver;
17

18
import static java.lang.Thread.sleep;
19
import static java.nio.ByteBuffer.wrap;
20
import static java.util.function.Function.identity;
21
import static java.util.stream.Collectors.toList;
22
import static java.util.stream.IntStream.range;
23
import static uk.ac.manchester.spinnaker.messages.Constants.CPU_USER_0_START_ADDRESS;
24
import static uk.ac.manchester.spinnaker.messages.Constants.CPU_USER_1_START_ADDRESS;
25
import static uk.ac.manchester.spinnaker.messages.Constants.CPU_USER_2_START_ADDRESS;
26
import static uk.ac.manchester.spinnaker.messages.Constants.NO_ROUTER_DIAGNOSTIC_FILTERS;
27
import static uk.ac.manchester.spinnaker.messages.Constants.UDP_MESSAGE_MAX_SIZE;
28
import static uk.ac.manchester.spinnaker.messages.Constants.WORD_SIZE;
29
import static uk.ac.manchester.spinnaker.messages.model.AppID.DEFAULT;
30
import static uk.ac.manchester.spinnaker.messages.model.CPUState.READY;
31
import static uk.ac.manchester.spinnaker.messages.model.CPUState.RUN_TIME_EXCEPTION;
32
import static uk.ac.manchester.spinnaker.messages.model.CPUState.WATCHDOG;
33
import static uk.ac.manchester.spinnaker.messages.model.Signal.START;
34
import static uk.ac.manchester.spinnaker.messages.model.SystemVariableDefinition.sdram_heap_address;
35
import static uk.ac.manchester.spinnaker.messages.scp.SCPRequest.BOOT_CHIP;
36
import static uk.ac.manchester.spinnaker.transceiver.CommonMemoryLocations.SYS_VARS;
37
import static uk.ac.manchester.spinnaker.transceiver.FillDataType.WORD;
38
import static uk.ac.manchester.spinnaker.transceiver.Utils.getVcpuAddress;
39
import static uk.ac.manchester.spinnaker.utils.ByteBufferUtils.wordAsBuffer;
40

41
import java.io.File;
42
import java.io.IOException;
43
import java.io.InputStream;
44
import java.net.InetAddress;
45
import java.nio.ByteBuffer;
46
import java.util.Collection;
47
import java.util.EnumSet;
48
import java.util.Formatter;
49
import java.util.List;
50
import java.util.Map;
51
import java.util.Set;
52
import java.util.TreeMap;
53

54
import com.google.errorprone.annotations.CheckReturnValue;
55
import com.google.errorprone.annotations.MustBeClosed;
56

57
import jakarta.validation.Valid;
58
import jakarta.validation.constraints.NotEmpty;
59
import jakarta.validation.constraints.NotNull;
60
import jakarta.validation.constraints.Positive;
61
import jakarta.validation.constraints.PositiveOrZero;
62
import uk.ac.manchester.spinnaker.connections.ConnectionSelector;
63
import uk.ac.manchester.spinnaker.connections.SCPConnection;
64
import uk.ac.manchester.spinnaker.connections.SDPConnection;
65
import uk.ac.manchester.spinnaker.connections.model.Connection;
66
import uk.ac.manchester.spinnaker.machine.ChipLocation;
67
import uk.ac.manchester.spinnaker.machine.CoreLocation;
68
import uk.ac.manchester.spinnaker.machine.CoreSubsets;
69
import uk.ac.manchester.spinnaker.machine.Direction;
70
import uk.ac.manchester.spinnaker.machine.HasChipLocation;
71
import uk.ac.manchester.spinnaker.machine.HasCoreLocation;
72
import uk.ac.manchester.spinnaker.machine.Machine;
73
import uk.ac.manchester.spinnaker.machine.MachineDimensions;
74
import uk.ac.manchester.spinnaker.machine.MemoryLocation;
75
import uk.ac.manchester.spinnaker.machine.MulticastRoutingEntry;
76
import uk.ac.manchester.spinnaker.machine.Processor;
77
import uk.ac.manchester.spinnaker.machine.RoutingEntry;
78
import uk.ac.manchester.spinnaker.machine.ValidP;
79
import uk.ac.manchester.spinnaker.machine.tags.IPTag;
80
import uk.ac.manchester.spinnaker.machine.tags.ReverseIPTag;
81
import uk.ac.manchester.spinnaker.machine.tags.Tag;
82
import uk.ac.manchester.spinnaker.machine.tags.TagID;
83
import uk.ac.manchester.spinnaker.messages.Constants;
84
import uk.ac.manchester.spinnaker.messages.model.AppID;
85
import uk.ac.manchester.spinnaker.messages.model.CPUInfo;
86
import uk.ac.manchester.spinnaker.messages.model.CPUState;
87
import uk.ac.manchester.spinnaker.messages.model.ChipInfo;
88
import uk.ac.manchester.spinnaker.messages.model.DiagnosticFilter;
89
import uk.ac.manchester.spinnaker.messages.model.ExecutableTargets;
90
import uk.ac.manchester.spinnaker.messages.model.HeapElement;
91
import uk.ac.manchester.spinnaker.messages.model.IOBuffer;
92
import uk.ac.manchester.spinnaker.messages.model.LEDAction;
93
import uk.ac.manchester.spinnaker.messages.model.ReinjectionStatus;
94
import uk.ac.manchester.spinnaker.messages.model.RouterDiagnostics;
95
import uk.ac.manchester.spinnaker.messages.model.RouterTimeout;
96
import uk.ac.manchester.spinnaker.messages.model.Signal;
97
import uk.ac.manchester.spinnaker.messages.model.SystemVariableDefinition;
98
import uk.ac.manchester.spinnaker.messages.model.VersionInfo;
99
import uk.ac.manchester.spinnaker.messages.scp.SCPRequest;
100
import uk.ac.manchester.spinnaker.messages.sdp.SDPMessage;
101
import uk.ac.manchester.spinnaker.storage.BufferManagerStorage;
102
import uk.ac.manchester.spinnaker.storage.StorageException;
103
import uk.ac.manchester.spinnaker.utils.MappableIterable;
104
import uk.ac.manchester.spinnaker.utils.UsedInJavadocOnly;
105

106
/**
107
 * The interface supported by the {@link Transceiver}. Emulates a lot of default
108
 * handling and variant-type handling by Python.
109
 * <p>
110
 * Note that operations on a BMP are <strong>always</strong> thread-unsafe.
111
 *
112
 * @author Donal Fellows
113
 */
114
public interface TransceiverInterface extends BMPTransceiverInterface {
115
        /**
116
         * Delay between starting a program on a core and checking to see if the
117
         * core is ready for operational use. In milliseconds.
118
         */
119
        int LAUNCH_DELAY = 500;
120

121
        /**
122
         * A marker to indicate that no timeout applies.
123
         */
124
        Integer TIMEOUT_DISABLED = null;
×
125

126
        /**
127
         * How often to poll by default.
128
         */
129
        int DEFAULT_POLL_INTERVAL = 100;
130

131
        /**
132
         * The set of states that indicate a core in a failure state.
133
         */
134
        EnumSet<CPUState> DEFAULT_ERROR_STATES =
×
135
                        EnumSet.of(RUN_TIME_EXCEPTION, WATCHDOG);
×
136

137
        /**
138
         * What proportion of checks are to be expensive full checks.
139
         */
140
        int DEFAULT_CHECK_INTERVAL = 100;
141

142
        /** How many times to try booting a board. */
143
        int BOARD_BOOT_RETRIES = 5;
144

145
        /**
146
         * @return The connection selector to use for SCP messages.
147
         */
148
        @ParallelSafe
149
        ConnectionSelector<SCPConnection> getScampConnectionSelector();
150

151
        /**
152
         * Sends an SCP message, without expecting a response.
153
         *
154
         * @param message
155
         *            The message to send
156
         * @param connection
157
         *            The connection to use (omit to pick a random one)
158
         * @throws IOException
159
         *             If anything goes wrong with networking.
160
         */
161
        @ParallelSafe
162
        void sendSCPMessage(@NotNull SCPRequest<?> message,
163
                        @NotNull SCPConnection connection) throws IOException;
164

165
        /**
166
         * Sends an SDP message using one of the connections.
167
         *
168
         * @param message
169
         *            The message to send
170
         * @throws IOException
171
         *             If anything goes wrong with networking.
172
         */
173
        @ParallelSafe
174
        default void sendSDPMessage(@NotNull SDPMessage message)
175
                        throws IOException {
176
                sendSDPMessage(message, null);
×
177
        }
×
178

179
        /**
180
         * Sends an SDP message using one of the connections.
181
         *
182
         * @param message
183
         *            The message to send
184
         * @param connection
185
         *            An optional connection to use
186
         * @throws IOException
187
         *             If anything goes wrong with networking.
188
         */
189
        @ParallelSafe
190
        void sendSDPMessage(@NotNull SDPMessage message, SDPConnection connection)
191
                        throws IOException;
192

193
        /**
194
         * Get the maximum chip x-coordinate and maximum chip y-coordinate of the
195
         * chips in the machine.
196
         * <p>
197
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
198
         * multi-threaded context unless previously called from a parallel-safe
199
         * situation.
200
         *
201
         * @return The dimensions of the machine
202
         * @throws IOException
203
         *             If anything goes wrong with networking.
204
         * @throws ProcessException
205
         *             If SpiNNaker rejects a message.
206
         * @throws InterruptedException
207
         *             If the communications were interrupted.
208
         */
209
        @ParallelSafeWithCare
210
        @CheckReturnValue
211
        MachineDimensions getMachineDimensions()
212
                        throws IOException, ProcessException, InterruptedException;
213

214
        /**
215
         * Get the details of the machine made up of chips on a board and how they
216
         * are connected to each other.
217
         * <p>
218
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
219
         * multi-threaded context unless previously called from a parallel-safe
220
         * situation.
221
         *
222
         * @return A machine description
223
         * @throws IOException
224
         *             If anything goes wrong with networking.
225
         * @throws ProcessException
226
         *             If SpiNNaker rejects a message.
227
         * @throws InterruptedException
228
         *             If the communications were interrupted.
229
         */
230
        @ParallelSafeWithCare
231
        @CheckReturnValue
232
        Machine getMachineDetails()
233
                        throws IOException, ProcessException, InterruptedException;
234

235
        /**
236
         * Determines if the board can be contacted.
237
         *
238
         * @return True if the board can be contacted, False otherwise
239
         */
240
        @ParallelSafe
241
        default boolean isConnected() {
242
                return isConnected(null);
×
243
        }
244

245
        /**
246
         * Determines if the board can be contacted.
247
         *
248
         * @param connection
249
         *            The connection which is to be tested. If {@code null}, all
250
         *            connections will be tested, and the board will be considered
251
         *            to be connected if any one connection works.
252
         * @return True if the board can be contacted, False otherwise
253
         */
254
        @ParallelSafe
255
        boolean isConnected(Connection connection);
256

257
        /**
258
         * Get the version of SCAMP which is running on the board.
259
         *
260
         * @return The version identifier
261
         * @throws IOException
262
         *             If anything goes wrong with networking.
263
         * @throws ProcessException
264
         *             If SpiNNaker rejects a message.
265
         * @throws InterruptedException
266
         *             If the communications were interrupted.
267
         */
268
        @ParallelSafe
269
        @CheckReturnValue
270
        default VersionInfo getScampVersion()
271
                        throws IOException, ProcessException, InterruptedException {
272
                return getScampVersion(BOOT_CHIP, getScampConnectionSelector());
×
273
        }
274

275
        /**
276
         * Get the version of SCAMP which is running on the board.
277
         *
278
         * @param connectionSelector
279
         *            the connection to send the SCAMP version or none (if none then
280
         *            a random SCAMP connection is used).
281
         * @return The version identifier
282
         * @throws IOException
283
         *             If anything goes wrong with networking.
284
         * @throws ProcessException
285
         *             If SpiNNaker rejects a message.
286
         * @throws InterruptedException
287
         *             If the communications were interrupted.
288
         */
289
        @ParallelSafe
290
        @CheckReturnValue
291
        default VersionInfo getScampVersion(
292
                        @NotNull ConnectionSelector<SCPConnection> connectionSelector)
293
                        throws IOException, ProcessException, InterruptedException {
294
                return getScampVersion(BOOT_CHIP, connectionSelector);
×
295
        }
296

297
        /**
298
         * Get the version of SCAMP which is running on the board.
299
         *
300
         * @param chip
301
         *            the coordinates of the chip to query for SCAMP version
302
         * @return The version identifier
303
         * @throws IOException
304
         *             If anything goes wrong with networking.
305
         * @throws ProcessException
306
         *             If SpiNNaker rejects a message.
307
         * @throws InterruptedException
308
         *             If the communications were interrupted.
309
         */
310
        @ParallelSafe
311
        @CheckReturnValue
312
        default VersionInfo getScampVersion(@Valid HasChipLocation chip)
313
                        throws IOException, ProcessException, InterruptedException {
314
                return getScampVersion(chip, getScampConnectionSelector());
×
315
        }
316

317
        /**
318
         * Get the version of SCAMP which is running on the board.
319
         *
320
         * @param connectionSelector
321
         *            the connection to send the SCAMP version or none (if none then
322
         *            a random SCAMP connection is used).
323
         * @param chip
324
         *            the coordinates of the chip to query for SCAMP version
325
         * @return The version identifier
326
         * @throws IOException
327
         *             If anything goes wrong with networking.
328
         * @throws ProcessException
329
         *             If SpiNNaker rejects a message.
330
         * @throws InterruptedException
331
         *             If the communications were interrupted.
332
         */
333
        @ParallelSafe
334
        @CheckReturnValue
335
        VersionInfo getScampVersion(@Valid HasChipLocation chip,
336
                        @NotNull ConnectionSelector<SCPConnection> connectionSelector)
337
                        throws IOException, ProcessException, InterruptedException;
338

339
        /**
340
         * Attempt to boot the board. No check is performed to see if the board is
341
         * already booted.
342
         * <p>
343
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
344
         * multi-threaded context.
345
         *
346
         * @throws IOException
347
         *             If anything goes wrong with networking.
348
         * @throws InterruptedException
349
         *             If the thread is interrupted while waiting.
350
         */
351
        @ParallelUnsafe
352
        default void bootBoard() throws InterruptedException, IOException {
353
                bootBoard(null);
×
354
        }
×
355

356
        /**
357
         * Attempt to boot the board. No check is performed to see if the board is
358
         * already booted.
359
         * <p>
360
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
361
         * multi-threaded context.
362
         *
363
         * @param extraBootValues
364
         *            extra values to set during boot
365
         * @throws IOException
366
         *             If anything goes wrong with networking.
367
         * @throws InterruptedException
368
         *             If the thread is interrupted while waiting.
369
         */
370
        @ParallelUnsafe
371
        void bootBoard(Map<SystemVariableDefinition, Object> extraBootValues)
372
                        throws InterruptedException, IOException;
373

374
        /**
375
         * Ensure that the board is ready to interact with this version of the
376
         * transceiver. Boots the board if not already booted and verifies that the
377
         * version of SCAMP running is compatible with this transceiver.
378
         * <p>
379
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
380
         * multi-threaded context.
381
         *
382
         * @return The version identifier
383
         * @throws IOException
384
         *             If anything goes wrong with networking.
385
         * @throws ProcessException
386
         *             If SpiNNaker rejects a message.
387
         * @throws InterruptedException
388
         *             If the thread is interrupted while waiting.
389
         */
390
        @ParallelUnsafe
391
        @CheckReturnValue
392
        default VersionInfo ensureBoardIsReady()
393
                        throws IOException, ProcessException, InterruptedException {
394
                return ensureBoardIsReady(BOARD_BOOT_RETRIES, null);
×
395
        }
396

397
        /**
398
         * Ensure that the board is ready to interact with this version of the
399
         * transceiver. Boots the board if not already booted and verifies that the
400
         * version of SCAMP running is compatible with this transceiver.
401
         * <p>
402
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
403
         * multi-threaded context.
404
         *
405
         * @param extraBootValues
406
         *            Any additional values to set during boot
407
         * @return The version identifier
408
         * @throws IOException
409
         *             If anything goes wrong with networking.
410
         * @throws ProcessException
411
         *             If SpiNNaker rejects a message.
412
         * @throws InterruptedException
413
         *             If the thread is interrupted while waiting.
414
         */
415
        @ParallelUnsafe
416
        @CheckReturnValue
417
        default VersionInfo ensureBoardIsReady(
418
                        Map<SystemVariableDefinition, Object> extraBootValues)
419
                        throws IOException, ProcessException, InterruptedException {
420
                return ensureBoardIsReady(BOARD_BOOT_RETRIES, extraBootValues);
×
421
        }
422

423
        /**
424
         * Ensure that the board is ready to interact with this version of the
425
         * transceiver. Boots the board if not already booted and verifies that the
426
         * version of SCAMP running is compatible with this transceiver.
427
         * <p>
428
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
429
         * multi-threaded context.
430
         *
431
         * @param numRetries
432
         *            The number of times to retry booting
433
         * @return The version identifier
434
         * @throws IOException
435
         *             If anything goes wrong with networking.
436
         * @throws ProcessException
437
         *             If SpiNNaker rejects a message.
438
         * @throws InterruptedException
439
         *             If the thread is interrupted while waiting.
440
         */
441
        @ParallelUnsafe
442
        default VersionInfo ensureBoardIsReady(@PositiveOrZero int numRetries)
443
                        throws IOException, ProcessException, InterruptedException {
444
                return ensureBoardIsReady(numRetries, null);
×
445
        }
446

447
        /**
448
         * Ensure that the board is ready to interact with this version of the
449
         * transceiver. Boots the board if not already booted and verifies that the
450
         * version of SCAMP running is compatible with this transceiver.
451
         * <p>
452
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
453
         * multi-threaded context.
454
         *
455
         * @param numRetries
456
         *            The number of times to retry booting
457
         * @param extraBootValues
458
         *            Any additional values to set during boot
459
         * @return The version identifier
460
         * @throws IOException
461
         *             If anything goes wrong with networking.
462
         * @throws ProcessException
463
         *             If SpiNNaker rejects a message.
464
         * @throws InterruptedException
465
         *             If the thread is interrupted while waiting.
466
         */
467
        @ParallelUnsafe
468
        VersionInfo ensureBoardIsReady(@PositiveOrZero int numRetries,
469
                        Map<SystemVariableDefinition, Object> extraBootValues)
470
                        throws IOException, ProcessException, InterruptedException;
471

472
        /**
473
         * Get information about the processors on the board.
474
         * <p>
475
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
476
         * multi-threaded context.
477
         *
478
         * @return An iterable of the CPU information for all cores.
479
         * @throws IOException
480
         *             If anything goes wrong with networking.
481
         * @throws ProcessException
482
         *             If SpiNNaker rejects a message.
483
         * @throws InterruptedException
484
         *             If the communications were interrupted.
485
         */
486
        @ParallelUnsafe
487
        @CheckReturnValue
488
        default MappableIterable<CPUInfo> getCPUInformation()
489
                        throws IOException, ProcessException, InterruptedException {
490
                return getCPUInformation((CoreSubsets) null);
×
491
        }
492

493
        /**
494
         * Get information about a specific processor on the board.
495
         *
496
         * @param core
497
         *            The coordinates of the core to get the information about
498
         * @return The CPU information for the selected core
499
         * @throws IOException
500
         *             If anything goes wrong with networking.
501
         * @throws ProcessException
502
         *             If SpiNNaker rejects a message.
503
         * @throws InterruptedException
504
         *             If the communications were interrupted.
505
         */
506
        @ParallelSafe
507
        @CheckReturnValue
508
        default CPUInfo getCPUInformation(@Valid HasCoreLocation core)
509
                        throws IOException, ProcessException, InterruptedException {
510
                return getCPUInformation(new CoreSubsets(core)).first().orElseThrow();
×
511
        }
512

513
        /**
514
         * Get information about some processors on the board.
515
         * <p>
516
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
517
         * multi-threaded context unless the {@code coreSubsets} only contains cores
518
         * on a single board.
519
         *
520
         * @param coreSubsets
521
         *            A set of chips and cores from which to get the information. If
522
         *            {@code null}, the information from all of the cores on all of
523
         *            the chips on the board are obtained.
524
         * @return An iterable of the CPU information for the selected cores, or all
525
         *         cores if {@code coreSubsets} is {@code null}.
526
         * @throws IOException
527
         *             If anything goes wrong with networking.
528
         * @throws ProcessException
529
         *             If SpiNNaker rejects a message.
530
         * @throws InterruptedException
531
         *             If the communications were interrupted.
532
         */
533
        @ParallelSafeWithCare
534
        @CheckReturnValue
535
        MappableIterable<CPUInfo> getCPUInformation(@Valid CoreSubsets coreSubsets)
536
                        throws IOException, ProcessException, InterruptedException;
537

538
        /**
539
         * Get the full information about the chip. This is obtained by reading the
540
         * full system variable block for the chip. <em>This is an operation that
541
         * takes a bit of time; the view is not guaranteed to be internally
542
         * consistent though most values are very unlikely to change during the
543
         * read.</em>
544
         *
545
         * @param chip
546
         *            Which chip are we getting information about?
547
         * @return A full description of the chip.
548
         * @throws IOException
549
         *             If anything goes wrong with networking.
550
         * @throws ProcessException
551
         *             If SpiNNaker rejects a message.
552
         * @throws InterruptedException
553
         *             If the communications were interrupted.
554
         */
555
        @ParallelSafeWithCare
556
        @CheckReturnValue
557
        default ChipInfo getFullChipInformation(HasChipLocation chip)
558
                        throws IOException, ProcessException, InterruptedException {
559
                var buffer = readMemory(chip, SYS_VARS, UDP_MESSAGE_MAX_SIZE);
×
560
                return new ChipInfo(buffer);
×
561
        }
562

563
        /**
564
         * Get the address of user<sub>0</sub> for a given processor on the board.
565
         * <i>This does not read from the processor.</i>
566
         *
567
         * @param core
568
         *            the coordinates of the core to get the user<sub>0</sub>
569
         *            address for
570
         * @return The address for user<sub>0</sub> register for this processor
571
         */
572
        @ParallelSafe
573
        default MemoryLocation getUser0RegisterAddress(
574
                        @Valid HasCoreLocation core) {
575
                return getVcpuAddress(core).add(CPU_USER_0_START_ADDRESS);
×
576
        }
577

578
        /**
579
         * Get the address of user<sub>0</sub> for a given processor on the board.
580
         * <i>This does not read from the processor.</i>
581
         *
582
         * @param p
583
         *            the processor ID to get the user<sub>0</sub> address for
584
         * @return The address for user<sub>0</sub> register for this processor
585
         */
586
        @ParallelSafe
587
        default MemoryLocation getUser0RegisterAddress(@ValidP int p) {
588
                return getVcpuAddress(p).add(CPU_USER_0_START_ADDRESS);
×
589
        }
590

591
        /**
592
         * Get the address of user<sub>0</sub> for a given processor on the board.
593
         * <i>This does not read from the processor.</i>
594
         *
595
         * @param processor
596
         *            the processor to get the user<sub>0</sub> address for
597
         * @return The address for user<sub>0</sub> register for this processor
598
         */
599
        @ParallelSafe
600
        default MemoryLocation getUser0RegisterAddress(@Valid Processor processor) {
601
                return getVcpuAddress(processor.processorId)
×
602
                                .add(CPU_USER_0_START_ADDRESS);
×
603
        }
604

605
        /**
606
         * Get the address of user<sub>1</sub> for a given processor on the board.
607
         * <i>This does not read from the processor.</i>
608
         *
609
         * @param core
610
         *            the coordinates of the core to get the user<sub>1</sub>
611
         *            address for
612
         * @return The address for user<sub>1</sub> register for this processor
613
         */
614
        @ParallelSafe
615
        default MemoryLocation getUser1RegisterAddress(
616
                        @Valid HasCoreLocation core) {
617
                return getVcpuAddress(core).add(CPU_USER_1_START_ADDRESS);
×
618
        }
619

620
        /**
621
         * Get the address of user<sub>1</sub> for a given processor on the board.
622
         * <i>This does not read from the processor.</i>
623
         *
624
         * @param p
625
         *            the processor ID to get the user<sub>1</sub> address for
626
         * @return The address for user<sub>1</sub> register for this processor;
627
         *         this will be in System RAM and be accessible from any core of the
628
         *         chip.
629
         */
630
        @ParallelSafe
631
        default MemoryLocation getUser1RegisterAddress(@ValidP int p) {
632
                return getVcpuAddress(p).add(CPU_USER_1_START_ADDRESS);
×
633
        }
634

635
        /**
636
         * Get the address of user<sub>1</sub> for a given processor on the board.
637
         * <i>This does not read from the processor.</i>
638
         *
639
         * @param processor
640
         *            the processor to get the user<sub>1</sub> address for
641
         * @return The address for user<sub>1</sub> register for this processor;
642
         *         this will be in System RAM and be accessible from any core of the
643
         *         chip.
644
         */
645
        @ParallelSafe
646
        default MemoryLocation getUser1RegisterAddress(@Valid Processor processor) {
647
                return getVcpuAddress(processor.processorId)
×
648
                                .add(CPU_USER_1_START_ADDRESS);
×
649
        }
650

651
        /**
652
         * Get the address of user<sub>2</sub> for a given processor on the board.
653
         * <i>This does not read from the processor.</i>
654
         *
655
         * @param core
656
         *            the coordinates of the core to get the user<sub>2</sub>
657
         *            address for
658
         * @return The address for user<sub>2</sub> register for this processor;
659
         *         this will be in System RAM and be accessible from any core of the
660
         *         chip.
661
         */
662
        @ParallelSafe
663
        default MemoryLocation getUser2RegisterAddress(
664
                        @Valid HasCoreLocation core) {
665
                return getVcpuAddress(core).add(CPU_USER_2_START_ADDRESS);
×
666
        }
667

668
        /**
669
         * Get the address of user<sub>2</sub> for a given processor on the board.
670
         * <i>This does not read from the processor.</i>
671
         *
672
         * @param p
673
         *            the processor ID to get the user<sub>2</sub> address for
674
         * @return The address for user<sub>0</sub> register for this processor
675
         */
676
        @ParallelSafe
677
        default MemoryLocation getUser2RegisterAddress(@ValidP int p) {
678
                return getVcpuAddress(p).add(CPU_USER_2_START_ADDRESS);
×
679
        }
680

681
        /**
682
         * Get the address of user<sub>2</sub> for a given processor on the board.
683
         * <i>This does not read from the processor.</i>
684
         *
685
         * @param processor
686
         *            the processor to get the user<sub>2</sub> address for
687
         * @return The address for user<sub>0</sub> register for this processor
688
         */
689
        @ParallelSafe
690
        default MemoryLocation getUser2RegisterAddress(@Valid Processor processor) {
691
                return getVcpuAddress(processor.processorId)
×
692
                                .add(CPU_USER_2_START_ADDRESS);
×
693
        }
694

695
        /**
696
         * Get the contents of the IOBUF buffer for all processors.
697
         *
698
         * @return An iterable of the buffers, order undetermined.
699
         * @throws IOException
700
         *             If anything goes wrong with networking.
701
         * @throws ProcessException
702
         *             If SpiNNaker rejects a message.
703
         * @throws InterruptedException
704
         *             If the communications were interrupted.
705
         */
706
        @ParallelUnsafe
707
        @CheckReturnValue
708
        default MappableIterable<IOBuffer> getIobuf()
709
                        throws IOException, ProcessException, InterruptedException {
710
                return getIobuf((CoreSubsets) null);
×
711
        }
712

713
        /**
714
         * Get the contents of IOBUF for a given core.
715
         *
716
         * @param core
717
         *            The coordinates of the processor to get the IOBUF for
718
         * @return An IOBUF buffer
719
         * @throws IOException
720
         *             If anything goes wrong with networking.
721
         * @throws ProcessException
722
         *             If SpiNNaker rejects a message.
723
         * @throws InterruptedException
724
         *             If the communications were interrupted.
725
         */
726
        @ParallelSafe
727
        @CheckReturnValue
728
        default IOBuffer getIobuf(@Valid HasCoreLocation core)
729
                        throws IOException, ProcessException, InterruptedException {
730
                return getIobuf(new CoreSubsets(core)).first().orElseThrow();
×
731
        }
732

733
        /**
734
         * Get the contents of the IOBUF buffer for a collection of processors.
735
         *
736
         * @param coreSubsets
737
         *            A set of chips and cores from which to get the buffers.
738
         * @return An iterable of the buffers, which may not be in the order of
739
         *         {@code coreSubsets}
740
         * @throws IOException
741
         *             If anything goes wrong with networking.
742
         * @throws ProcessException
743
         *             If SpiNNaker rejects a message.
744
         * @throws InterruptedException
745
         *             If the communications were interrupted.
746
         */
747
        @ParallelSafeWithCare
748
        @CheckReturnValue
749
        MappableIterable<IOBuffer> getIobuf(@Valid CoreSubsets coreSubsets)
750
                        throws IOException, ProcessException, InterruptedException;
751

752
        /**
753
         * Clear the contents of the IOBUF buffer for all processors.
754
         *
755
         * @throws IOException
756
         *             If anything goes wrong with networking.
757
         * @throws ProcessException
758
         *             If SpiNNaker rejects a message.
759
         * @throws InterruptedException
760
         *             If the communications were interrupted.
761
         */
762
        @ParallelUnsafe
763
        default void clearIobuf()
764
                        throws IOException, ProcessException, InterruptedException {
765
                clearIobuf((CoreSubsets) null);
×
766
        }
×
767

768
        /**
769
         * Clear the contents of the IOBUF buffer for a given core.
770
         *
771
         * @param core
772
         *            The coordinates of the processor to clear the IOBUF on.
773
         * @throws IOException
774
         *             If anything goes wrong with networking.
775
         * @throws ProcessException
776
         *             If SpiNNaker rejects a message.
777
         * @throws InterruptedException
778
         *             If the communications were interrupted.
779
         */
780
        @ParallelSafe
781
        default void clearIobuf(@Valid HasCoreLocation core)
782
                        throws IOException, ProcessException, InterruptedException {
783
                clearIobuf(new CoreSubsets(core));
×
784
        }
×
785

786
        /**
787
         * Clear the contents of the IOBUF buffer for a collection of processors.
788
         *
789
         * @param coreSubsets
790
         *            A set of chips and cores on which to clear the buffers.
791
         * @throws IOException
792
         *             If anything goes wrong with networking.
793
         * @throws ProcessException
794
         *             If SpiNNaker rejects a message.
795
         * @throws InterruptedException
796
         *             If the communications were interrupted.
797
         */
798
        @ParallelSafeWithCare
799
        void clearIobuf(@Valid CoreSubsets coreSubsets)
800
                        throws IOException, ProcessException, InterruptedException;
801

802
        /**
803
         * Set the value of the watch dog timer on a specific chip.
804
         *
805
         * @param chip
806
         *            coordinates of the chip to write new watchdog parameter to
807
         * @param watchdog
808
         *            value to set the timer count to
809
         * @throws IOException
810
         *             If anything goes wrong with networking.
811
         * @throws ProcessException
812
         *             If SpiNNaker rejects a message.
813
         * @throws InterruptedException
814
         *             If the communications were interrupted.
815
         */
816
        @ParallelSafe
817
        void setWatchDogTimeoutOnChip(@Valid HasChipLocation chip, int watchdog)
818
                        throws IOException, ProcessException, InterruptedException;
819

820
        /**
821
         * Enable or disable the watch dog timer on a specific chip.
822
         *
823
         * @param chip
824
         *            coordinates of the chip to write new watchdog parameter to
825
         * @param watchdog
826
         *            whether to enable (True) or disable (False) the watchdog timer
827
         * @throws IOException
828
         *             If anything goes wrong with networking.
829
         * @throws ProcessException
830
         *             If SpiNNaker rejects a message.
831
         * @throws InterruptedException
832
         *             If the communications were interrupted.
833
         */
834
        @ParallelSafe
835
        void enableWatchDogTimerOnChip(@Valid HasChipLocation chip,
836
                        boolean watchdog)
837
                        throws IOException, ProcessException, InterruptedException;
838

839
        /**
840
         * Set the value of the watch dog timer.
841
         *
842
         * @param watchdog
843
         *            value to set the timer count to.
844
         * @throws IOException
845
         *             If anything goes wrong with networking.
846
         * @throws ProcessException
847
         *             If SpiNNaker rejects a message.
848
         * @throws InterruptedException
849
         *             If the communications were interrupted.
850
         */
851
        @ParallelUnsafe
852
        default void setWatchDogTimeout(int watchdog)
853
                        throws IOException, ProcessException, InterruptedException {
854
                for (var chip : getMachineDetails().chipCoordinates()) {
×
855
                        setWatchDogTimeoutOnChip(chip, watchdog);
×
856
                }
×
857
        }
×
858

859
        /**
860
         * Enable or disable the watch dog timer.
861
         *
862
         * @param watchdog
863
         *            whether to enable (True) or disable (False) the watch dog
864
         *            timer
865
         * @throws IOException
866
         *             If anything goes wrong with networking.
867
         * @throws ProcessException
868
         *             If SpiNNaker rejects a message.
869
         * @throws InterruptedException
870
         *             If the communications were interrupted.
871
         */
872
        @ParallelUnsafe
873
        default void enableWatchDogTimer(boolean watchdog)
874
                        throws IOException, ProcessException, InterruptedException {
875
                for (var chip : getMachineDetails().chipCoordinates()) {
×
876
                        enableWatchDogTimerOnChip(chip, watchdog);
×
877
                }
×
878
        }
×
879

880
        /**
881
         * Get a count of the number of cores which have a given state.
882
         * <p>
883
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
884
         * multi-threaded context.
885
         *
886
         * @param appID
887
         *            The ID of the application from which to get the count.
888
         * @param state
889
         *            The state count to get
890
         * @return A count of the cores with the given status
891
         * @throws IOException
892
         *             If anything goes wrong with networking.
893
         * @throws ProcessException
894
         *             If SpiNNaker rejects a message.
895
         * @throws InterruptedException
896
         *             If the communications were interrupted.
897
         */
898
        @ParallelUnsafe
899
        @CheckReturnValue
900
        int getCoreStateCount(@NotNull AppID appID, @NotNull CPUState state)
901
                        throws IOException, ProcessException, InterruptedException;
902

903
        /**
904
         * Start an executable running on a single core.
905
         *
906
         * @param core
907
         *            The coordinates of the core on which to run the executable
908
         * @param executable
909
         *            The data that is to be executed.
910
         * @param numBytes
911
         *            The number of bytes to read from the input stream.
912
         * @param appID
913
         *            The ID of the application with which to associate the
914
         *            executable
915
         * @throws IOException
916
         *             If anything goes wrong with networking or with reading from
917
         *             the input stream.
918
         * @throws ProcessException
919
         *             If SpiNNaker rejects a message.
920
         * @throws InterruptedException
921
         *             If the thread is interrupted while waiting.
922
         */
923
        @ParallelSafe
924
        default void execute(@Valid HasCoreLocation core,
925
                        @NotNull InputStream executable, @Positive int numBytes,
926
                        @NotNull AppID appID)
927
                        throws IOException, ProcessException, InterruptedException {
928
                execute(core, Set.of(core.getP()), executable, numBytes, appID);
×
929
        }
×
930

931
        /**
932
         * Start an executable running on a single chip.
933
         *
934
         * @param chip
935
         *            The coordinates of the chip on which to run the executable
936
         * @param processors
937
         *            The cores on the chip on which to run the application
938
         * @param executable
939
         *            The data that is to be executed.
940
         * @param numBytes
941
         *            The number of bytes to read from the input stream.
942
         * @param appID
943
         *            The ID of the application with which to associate the
944
         *            executable
945
         * @throws IOException
946
         *             If anything goes wrong with networking or with reading from
947
         *             the input stream.
948
         * @throws ProcessException
949
         *             If SpiNNaker rejects a message.
950
         * @throws InterruptedException
951
         *             If the thread is interrupted while waiting.
952
         */
953
        @ParallelSafe
954
        default void execute(@Valid HasChipLocation chip,
955
                        Collection<@ValidP Integer> processors,
956
                        @NotNull InputStream executable, @Positive int numBytes,
957
                        @NotNull AppID appID)
958
                        throws IOException, ProcessException, InterruptedException {
959
                execute(chip, processors, executable, numBytes, appID, false);
×
960
        }
×
961

962
        /**
963
         * Start an executable running on a single core.
964
         *
965
         * @param core
966
         *            The coordinates of the core on which to run the executable
967
         * @param executable
968
         *            The data that is to be executed.
969
         * @param numBytes
970
         *            The number of bytes to read from the input stream.
971
         * @param appID
972
         *            The ID of the application with which to associate the
973
         *            executable
974
         * @param wait
975
         *            True if the binary should enter a "wait" state on loading
976
         * @throws IOException
977
         *             If anything goes wrong with networking or with reading from
978
         *             the input stream.
979
         * @throws ProcessException
980
         *             If SpiNNaker rejects a message.
981
         * @throws InterruptedException
982
         *             If the thread is interrupted while waiting.
983
         */
984
        @ParallelSafe
985
        default void execute(@Valid HasCoreLocation core,
986
                        @NotNull InputStream executable, @Positive int numBytes,
987
                        @NotNull AppID appID, boolean wait)
988
                        throws IOException, ProcessException, InterruptedException {
989
                execute(core, Set.of(core.getP()), executable, numBytes, appID,
×
990
                                wait);
991
        }
×
992

993
        /**
994
         * Start an executable running on a single chip.
995
         *
996
         * @param chip
997
         *            The coordinates of the chip on which to run the executable
998
         * @param processors
999
         *            The cores on the chip on which to run the application
1000
         * @param executable
1001
         *            The data that is to be executed.
1002
         * @param numBytes
1003
         *            The number of bytes to read from the input stream.
1004
         * @param appID
1005
         *            The ID of the application with which to associate the
1006
         *            executable
1007
         * @param wait
1008
         *            True if the binary should enter a "wait" state on loading
1009
         * @throws IOException
1010
         *             If anything goes wrong with networking or with reading from
1011
         *             the input stream.
1012
         * @throws ProcessException
1013
         *             If SpiNNaker rejects a message.
1014
         * @throws InterruptedException
1015
         *             If the thread is interrupted while waiting.
1016
         */
1017
        @ParallelSafe
1018
        void execute(@Valid HasChipLocation chip,
1019
                        Collection<@ValidP Integer> processors,
1020
                        @NotNull InputStream executable, @Positive int numBytes,
1021
                        @NotNull AppID appID, boolean wait)
1022
                        throws IOException, ProcessException, InterruptedException;
1023

1024
        /**
1025
         * Start an executable running on a single core.
1026
         *
1027
         * @param core
1028
         *            The coordinates of the core on which to run the executable
1029
         * @param executable
1030
         *            The data that is to be executed.
1031
         * @param appID
1032
         *            The ID of the application with which to associate the
1033
         *            executable
1034
         * @throws IOException
1035
         *             If anything goes wrong with networking or with reading from
1036
         *             the file.
1037
         * @throws ProcessException
1038
         *             If SpiNNaker rejects a message.
1039
         * @throws InterruptedException
1040
         *             If the thread is interrupted while waiting.
1041
         */
1042
        @ParallelSafe
1043
        default void execute(@Valid HasCoreLocation core, @NotNull File executable,
1044
                        @NotNull AppID appID)
1045
                        throws IOException, ProcessException, InterruptedException {
1046
                execute(core, Set.of(core.getP()), executable, appID, false);
×
1047
        }
×
1048

1049
        /**
1050
         * Start an executable running on a single chip.
1051
         *
1052
         * @param chip
1053
         *            The coordinates of the chip on which to run the executable
1054
         * @param processors
1055
         *            The cores on the chip on which to run the application
1056
         * @param executable
1057
         *            The data that is to be executed.
1058
         * @param appID
1059
         *            The ID of the application with which to associate the
1060
         *            executable
1061
         * @throws IOException
1062
         *             If anything goes wrong with networking or with reading from
1063
         *             the file.
1064
         * @throws ProcessException
1065
         *             If SpiNNaker rejects a message.
1066
         * @throws InterruptedException
1067
         *             If the thread is interrupted while waiting.
1068
         */
1069
        @ParallelSafe
1070
        default void execute(@Valid HasChipLocation chip,
1071
                        Collection<@ValidP Integer> processors, @NotNull File executable,
1072
                        @NotNull AppID appID)
1073
                        throws IOException, ProcessException, InterruptedException {
1074
                execute(chip, processors, executable, appID, false);
×
1075
        }
×
1076

1077
        /**
1078
         * Start an executable running on a single core.
1079
         *
1080
         * @param core
1081
         *            The coordinates of the core on which to run the executable
1082
         * @param executable
1083
         *            The data that is to be executed.
1084
         * @param appID
1085
         *            The ID of the application with which to associate the
1086
         *            executable
1087
         * @param wait
1088
         *            True if the binary should enter a "wait" state on loading
1089
         * @throws IOException
1090
         *             If anything goes wrong with networking or with reading from
1091
         *             the file.
1092
         * @throws ProcessException
1093
         *             If SpiNNaker rejects a message.
1094
         * @throws InterruptedException
1095
         *             If the thread is interrupted while waiting.
1096
         */
1097
        @ParallelSafe
1098
        default void execute(@Valid HasCoreLocation core, @NotNull File executable,
1099
                        @NotNull AppID appID, boolean wait)
1100
                        throws IOException, ProcessException, InterruptedException {
1101
                execute(core, Set.of(core.getP()), executable, appID, wait);
×
1102
        }
×
1103

1104
        /**
1105
         * Start an executable running on a single chip.
1106
         *
1107
         * @param chip
1108
         *            The coordinates of the chip on which to run the executable
1109
         * @param processors
1110
         *            The cores on the chip on which to run the application
1111
         * @param executable
1112
         *            The data that is to be executed.
1113
         * @param appID
1114
         *            The ID of the application with which to associate the
1115
         *            executable
1116
         * @param wait
1117
         *            True if the binary should enter a "wait" state on loading
1118
         * @throws IOException
1119
         *             If anything goes wrong with networking or with reading from
1120
         *             the file.
1121
         * @throws ProcessException
1122
         *             If SpiNNaker rejects a message.
1123
         * @throws InterruptedException
1124
         *             If the thread is interrupted while waiting.
1125
         */
1126
        @ParallelSafe
1127
        void execute(@Valid HasChipLocation chip,
1128
                        Collection<@ValidP Integer> processors, @NotNull File executable,
1129
                        @NotNull AppID appID, boolean wait)
1130
                        throws IOException, ProcessException, InterruptedException;
1131

1132
        /**
1133
         * Start an executable running on a single core.
1134
         *
1135
         * @param core
1136
         *            The coordinates of the core on which to run the executable
1137
         * @param executable
1138
         *            The data that is to be executed.
1139
         * @param appID
1140
         *            The ID of the application with which to associate the
1141
         *            executable
1142
         * @throws IOException
1143
         *             If anything goes wrong with networking.
1144
         * @throws ProcessException
1145
         *             If SpiNNaker rejects a message.
1146
         * @throws InterruptedException
1147
         *             If the thread is interrupted while waiting.
1148
         */
1149
        @ParallelSafe
1150
        default void execute(@Valid HasCoreLocation core,
1151
                        @NotNull ByteBuffer executable, @NotNull AppID appID)
1152
                        throws IOException, ProcessException, InterruptedException {
1153
                execute(core, Set.of(core.getP()), executable, appID, false);
×
1154
        }
×
1155

1156
        /**
1157
         * Start an executable running on a single chip.
1158
         *
1159
         * @param chip
1160
         *            The coordinates of the chip on which to run the executable
1161
         * @param processors
1162
         *            The cores on the chip on which to run the application
1163
         * @param executable
1164
         *            The data that is to be executed.
1165
         * @param appID
1166
         *            The ID of the application with which to associate the
1167
         *            executable
1168
         * @throws IOException
1169
         *             If anything goes wrong with networking.
1170
         * @throws ProcessException
1171
         *             If SpiNNaker rejects a message.
1172
         * @throws InterruptedException
1173
         *             If the thread is interrupted while waiting.
1174
         */
1175
        @ParallelSafe
1176
        default void execute(@Valid HasChipLocation chip,
1177
                        Collection<@ValidP Integer> processors,
1178
                        @NotNull ByteBuffer executable, @NotNull AppID appID)
1179
                        throws IOException, ProcessException, InterruptedException {
1180
                execute(chip, processors, executable, appID, false);
×
1181
        }
×
1182

1183
        /**
1184
         * Start an executable running on a single core.
1185
         *
1186
         * @param core
1187
         *            The coordinates of the core on which to run the executable
1188
         * @param executable
1189
         *            The data that is to be executed.
1190
         * @param appID
1191
         *            The ID of the application with which to associate the
1192
         *            executable
1193
         * @param wait
1194
         *            True if the binary should enter a "wait" state on loading
1195
         * @throws IOException
1196
         *             If anything goes wrong with networking.
1197
         * @throws ProcessException
1198
         *             If SpiNNaker rejects a message.
1199
         * @throws InterruptedException
1200
         *             If the thread is interrupted while waiting.
1201
         */
1202
        @ParallelSafe
1203
        default void execute(@Valid HasCoreLocation core,
1204
                        @NotNull ByteBuffer executable, @NotNull AppID appID, boolean wait)
1205
                        throws IOException, ProcessException, InterruptedException {
1206
                execute(core, Set.of(core.getP()), executable, appID, wait);
×
1207
        }
×
1208

1209
        /**
1210
         * Start an executable running on a single chip.
1211
         *
1212
         * @param chip
1213
         *            The coordinates of the chip on which to run the executable
1214
         * @param processors
1215
         *            The cores on the chip on which to run the application
1216
         * @param executable
1217
         *            The data that is to be executed.
1218
         * @param appID
1219
         *            The ID of the application with which to associate the
1220
         *            executable
1221
         * @param wait
1222
         *            True if the binary should enter a "wait" state on loading
1223
         * @throws IOException
1224
         *             If anything goes wrong with networking.
1225
         * @throws ProcessException
1226
         *             If SpiNNaker rejects a message.
1227
         * @throws InterruptedException
1228
         *             If the thread is interrupted while waiting.
1229
         */
1230
        @ParallelSafe
1231
        void execute(HasChipLocation chip, Collection<Integer> processors,
1232
                        ByteBuffer executable, AppID appID, boolean wait)
1233
                        throws IOException, ProcessException, InterruptedException;
1234

1235
        /**
1236
         * Start an executable running on multiple places on the board. This will be
1237
         * optimised based on the selected cores, but it may still require a number
1238
         * of communications with the board to execute.
1239
         * <p>
1240
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1241
         * multi-threaded context.
1242
         *
1243
         * @param coreSubsets
1244
         *            Which cores on which chips to start the executable
1245
         * @param executable
1246
         *            The data that is to be executed.
1247
         * @param numBytes
1248
         *            The size of the executable data in bytes.
1249
         * @param appID
1250
         *            The ID of the application with which to associate the
1251
         *            executable
1252
         * @throws IOException
1253
         *             If anything goes wrong with networking or with reading from
1254
         *             the input stream.
1255
         * @throws ProcessException
1256
         *             If SpiNNaker rejects a message.
1257
         * @throws InterruptedException
1258
         *             If the thread is interrupted while waiting.
1259
         */
1260
        @ParallelSafeWithCare
1261
        default void executeFlood(@Valid CoreSubsets coreSubsets,
1262
                        @NotNull InputStream executable, @Positive int numBytes,
1263
                        @NotNull AppID appID)
1264
                        throws IOException, ProcessException, InterruptedException {
1265
                executeFlood(coreSubsets, executable, numBytes, appID, false);
×
1266
        }
×
1267

1268
        /**
1269
         * Start an executable running on multiple places on the board. This will be
1270
         * optimised based on the selected cores, but it may still require a number
1271
         * of communications with the board to execute.
1272
         * <p>
1273
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1274
         * multi-threaded context.
1275
         *
1276
         * @param coreSubsets
1277
         *            Which cores on which chips to start the executable
1278
         * @param executable
1279
         *            The data that is to be executed.
1280
         * @param numBytes
1281
         *            The size of the executable data in bytes.
1282
         * @param appID
1283
         *            The ID of the application with which to associate the
1284
         *            executable
1285
         * @param wait
1286
         *            True if the processors should enter a "wait" state on loading
1287
         * @throws IOException
1288
         *             If anything goes wrong with networking or with reading from
1289
         *             the input stream.
1290
         * @throws ProcessException
1291
         *             If SpiNNaker rejects a message.
1292
         * @throws InterruptedException
1293
         *             If the thread is interrupted while waiting.
1294
         */
1295
        @ParallelSafeWithCare
1296
        void executeFlood(@Valid CoreSubsets coreSubsets,
1297
                        @NotNull InputStream executable, @Positive int numBytes,
1298
                        @NotNull AppID appID, boolean wait)
1299
                        throws IOException, ProcessException, InterruptedException;
1300

1301
        /**
1302
         * Start an executable running on multiple places on the board. This will be
1303
         * optimised based on the selected cores, but it may still require a number
1304
         * of communications with the board to execute.
1305
         * <p>
1306
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1307
         * multi-threaded context.
1308
         *
1309
         * @param coreSubsets
1310
         *            Which cores on which chips to start the executable
1311
         * @param executable
1312
         *            The data that is to be executed.
1313
         * @param appID
1314
         *            The ID of the application with which to associate the
1315
         *            executable
1316
         * @throws IOException
1317
         *             If anything goes wrong with networking or with reading from
1318
         *             the file.
1319
         * @throws ProcessException
1320
         *             If SpiNNaker rejects a message.
1321
         * @throws InterruptedException
1322
         *             If the thread is interrupted while waiting.
1323
         */
1324
        @ParallelSafeWithCare
1325
        default void executeFlood(@Valid CoreSubsets coreSubsets,
1326
                        @NotNull File executable, @NotNull AppID appID)
1327
                        throws IOException, ProcessException, InterruptedException {
1328
                executeFlood(coreSubsets, executable, appID, false);
×
1329
        }
×
1330

1331
        /**
1332
         * Start an executable running on multiple places on the board. This will be
1333
         * optimised based on the selected cores, but it may still require a number
1334
         * of communications with the board to execute.
1335
         * <p>
1336
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1337
         * multi-threaded context.
1338
         *
1339
         * @param coreSubsets
1340
         *            Which cores on which chips to start the executable
1341
         * @param executable
1342
         *            The data that is to be executed.
1343
         * @param appID
1344
         *            The ID of the application with which to associate the
1345
         *            executable
1346
         * @param wait
1347
         *            True if the processors should enter a "wait" state on loading
1348
         * @throws IOException
1349
         *             If anything goes wrong with networking or with reading from
1350
         *             the file.
1351
         * @throws ProcessException
1352
         *             If SpiNNaker rejects a message.
1353
         * @throws InterruptedException
1354
         *             If the thread is interrupted while waiting.
1355
         */
1356
        @ParallelSafeWithCare
1357
        void executeFlood(@Valid CoreSubsets coreSubsets, @NotNull File executable,
1358
                        @NotNull AppID appID, boolean wait)
1359
                        throws IOException, ProcessException, InterruptedException;
1360

1361
        /**
1362
         * Start an executable running on multiple places on the board. This will be
1363
         * optimised based on the selected cores, but it may still require a number
1364
         * of communications with the board to execute.
1365
         * <p>
1366
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1367
         * multi-threaded context.
1368
         *
1369
         * @param coreSubsets
1370
         *            Which cores on which chips to start the executable
1371
         * @param executable
1372
         *            The data that is to be executed.
1373
         * @param appID
1374
         *            The ID of the application with which to associate the
1375
         *            executable
1376
         * @throws IOException
1377
         *             If anything goes wrong with networking.
1378
         * @throws ProcessException
1379
         *             If SpiNNaker rejects a message.
1380
         * @throws InterruptedException
1381
         *             If the thread is interrupted while waiting.
1382
         */
1383
        @ParallelSafeWithCare
1384
        default void executeFlood(@Valid CoreSubsets coreSubsets,
1385
                        @NotNull ByteBuffer executable, @NotNull AppID appID)
1386
                        throws IOException, ProcessException, InterruptedException {
1387
                executeFlood(coreSubsets, executable, appID, false);
×
1388
        }
×
1389

1390
        /**
1391
         * Start an executable running on multiple places on the board. This will be
1392
         * optimised based on the selected cores, but it may still require a number
1393
         * of communications with the board to execute.
1394
         * <p>
1395
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1396
         * multi-threaded context.
1397
         *
1398
         * @param coreSubsets
1399
         *            Which cores on which chips to start the executable
1400
         * @param executable
1401
         *            The data that is to be executed.
1402
         * @param appID
1403
         *            The ID of the application with which to associate the
1404
         *            executable
1405
         * @param wait
1406
         *            True if the processors should enter a "wait" state on loading
1407
         * @throws IOException
1408
         *             If anything goes wrong with networking.
1409
         * @throws ProcessException
1410
         *             If SpiNNaker rejects a message.
1411
         * @throws InterruptedException
1412
         *             If the thread is interrupted while waiting.
1413
         */
1414
        @ParallelSafeWithCare
1415
        void executeFlood(@Valid CoreSubsets coreSubsets,
1416
                        @NotNull ByteBuffer executable, @NotNull AppID appID, boolean wait)
1417
                        throws IOException, ProcessException, InterruptedException;
1418

1419
        /**
1420
         * Execute a set of binaries that make up a complete application on
1421
         * specified cores, wait for them to be ready and then start all of the
1422
         * binaries. Note this will get the binaries into {@code c_main()} but will
1423
         * not signal the barrier.
1424
         * <p>
1425
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1426
         * multi-threaded context.
1427
         *
1428
         * @param executableTargets
1429
         *            The binaries to be executed and the cores to execute them on
1430
         * @param appID
1431
         *            The application ID to give this application
1432
         * @throws IOException
1433
         *             If anything goes wrong with networking.
1434
         * @throws ProcessException
1435
         *             If SpiNNaker rejects a message.
1436
         * @throws InterruptedException
1437
         *             If the thread is interrupted while waiting.
1438
         * @throws SpinnmanException
1439
         *             If some cores enter an unexpected state.
1440
         */
1441
        @ParallelUnsafe
1442
        default void executeApplication(@Valid ExecutableTargets executableTargets,
1443
                        @NotNull AppID appID) throws IOException, ProcessException,
1444
                        InterruptedException, SpinnmanException {
1445
                // Execute each of the binaries and get them in to a "wait" state
1446
                for (var binary : executableTargets.getBinaries()) {
×
1447
                        executeFlood(executableTargets.getCoresForBinary(binary),
×
1448
                                        new File(binary), appID, true);
1449
                }
×
1450

1451
                // Sleep to allow cores to get going
1452
                sleep(LAUNCH_DELAY);
×
1453

1454
                // Check that the binaries have reached a wait state
1455
                int count = getCoreStateCount(appID, READY);
×
1456
                if (count < executableTargets.getTotalProcessors()) {
×
1457
                        var coresNotReady = getCoresNotInState(
×
1458
                                        executableTargets.getAllCoreSubsets(), READY);
×
1459
                        if (!coresNotReady.isEmpty()) {
×
1460
                                try (var f = new Formatter()) {
×
1461
                                        f.format("Only %d of %d cores reached ready state:", count,
×
1462
                                                        executableTargets.getTotalProcessors());
×
1463
                                        for (var info : coresNotReady.values()) {
×
1464
                                                f.format("\n%s", info.getStatusDescription());
×
1465
                                        }
×
1466
                                        throw new SpinnmanException(f.toString());
×
1467
                                }
1468
                        }
1469
                }
1470

1471
                // Send a signal telling the application to start
1472
                sendSignal(appID, START);
×
1473
        }
×
1474

1475
        /**
1476
         * Set the running time information for all processors.
1477
         *
1478
         * @param runTimesteps
1479
         *            How many machine timesteps will the run last. {@code null} is
1480
         *            used to indicate an infinite (unbounded until explicitly
1481
         *            stopped) run.
1482
         * @param currentTime
1483
         *            The current simulation time.
1484
         * @param syncTimesteps
1485
         *            The number of timesteps before we pause to synchronise.
1486
         * @throws IOException
1487
         *             If anything goes wrong with networking.
1488
         * @throws ProcessException
1489
         *             If SpiNNaker rejects a message.
1490
         * @throws InterruptedException
1491
         *             If the communications were interrupted.
1492
         */
1493
        @ParallelUnsafe
1494
        default void updateRuntime(@PositiveOrZero Integer runTimesteps,
1495
                        @PositiveOrZero int currentTime, @PositiveOrZero int syncTimesteps)
1496
                        throws IOException, ProcessException, InterruptedException {
1497
                updateRuntime(runTimesteps, currentTime, syncTimesteps,
×
1498
                                (CoreSubsets) null);
1499
        }
×
1500

1501
        /**
1502
         * Set the running time information for a given core.
1503
         *
1504
         * @param runTimesteps
1505
         *            How many machine timesteps will the run last. {@code null} is
1506
         *            used to indicate an infinite (unbounded until explicitly
1507
         *            stopped) run.
1508
         * @param currentTime
1509
         *            The current simulation time.
1510
         * @param syncTimesteps
1511
         *            The number of timesteps before we pause to synchronise.
1512
         * @param core
1513
         *            The coordinates of the processor to clear the IOBUF on.
1514
         * @throws IOException
1515
         *             If anything goes wrong with networking.
1516
         * @throws ProcessException
1517
         *             If SpiNNaker rejects a message.
1518
         * @throws InterruptedException
1519
         *             If the communications were interrupted.
1520
         */
1521
        @ParallelSafe
1522
        default void updateRuntime(@PositiveOrZero Integer runTimesteps,
1523
                        @PositiveOrZero int currentTime, @PositiveOrZero int syncTimesteps,
1524
                        @Valid HasCoreLocation core)
1525
                        throws IOException, ProcessException, InterruptedException {
1526
                updateRuntime(runTimesteps, currentTime, syncTimesteps,
×
1527
                                new CoreSubsets(core));
1528
        }
×
1529

1530
        /**
1531
         * Set the running time information for a collection of processors.
1532
         *
1533
         * @param runTimesteps
1534
         *            How many machine timesteps will the run last. {@code null} is
1535
         *            used to indicate an infinite (unbounded until explicitly
1536
         *            stopped) run.
1537
         * @param currentTime
1538
         *            The current simulation time.
1539
         * @param syncTimesteps
1540
         *            The number of timesteps before we pause to synchronise.
1541
         * @param coreSubsets
1542
         *            A set of chips and cores on which to set the running time.
1543
         * @throws IOException
1544
         *             If anything goes wrong with networking.
1545
         * @throws ProcessException
1546
         *             If SpiNNaker rejects a message.
1547
         * @throws InterruptedException
1548
         *             If the communications were interrupted.
1549
         */
1550
        @ParallelSafeWithCare
1551
        void updateRuntime(@PositiveOrZero Integer runTimesteps,
1552
                        @PositiveOrZero int currentTime, @PositiveOrZero int syncTimesteps,
1553
                        @Valid CoreSubsets coreSubsets)
1554
                        throws IOException, ProcessException, InterruptedException;
1555

1556
        /**
1557
         * Tell all running application cores to write their provenance data to a
1558
         * location where it can be read back, and then to go into the
1559
         * {@link CPUState#FINISHED FINISHED} state.
1560
         *
1561
         * @throws IOException
1562
         *             If anything goes wrong with networking.
1563
         * @throws ProcessException
1564
         *             If SpiNNaker rejects a message.
1565
         * @throws InterruptedException
1566
         *             If the communications were interrupted.
1567
         */
1568
        @ParallelUnsafe
1569
        default void updateProvenanceAndExit()
1570
                        throws IOException, ProcessException, InterruptedException {
1571
                updateProvenanceAndExit((CoreSubsets) null);
×
1572
        }
×
1573

1574
        /**
1575
         * Tell a running application core to write its provenance data to a
1576
         * location where it can be read back, and then to go into the
1577
         * {@link CPUState#FINISHED FINISHED} state.
1578
         *
1579
         * @param core
1580
         *            The core to tell to finish.
1581
         * @throws IOException
1582
         *             If anything goes wrong with networking.
1583
         * @throws ProcessException
1584
         *             If SpiNNaker rejects a message.
1585
         * @throws InterruptedException
1586
         *             If the communications were interrupted.
1587
         */
1588
        @ParallelSafe
1589
        default void updateProvenanceAndExit(@Valid HasCoreLocation core)
1590
                        throws IOException, ProcessException, InterruptedException {
1591
                updateProvenanceAndExit(new CoreSubsets(core));
×
1592
        }
×
1593

1594
        /**
1595
         * Tell some running application cores to write their provenance data to a
1596
         * location where it can be read back, and then to go into their
1597
         * {@link CPUState#FINISHED FINISHED} state.
1598
         *
1599
         * @param coreSubsets
1600
         *            A set of cores tell to finish.
1601
         * @throws IOException
1602
         *             If anything goes wrong with networking.
1603
         * @throws ProcessException
1604
         *             If SpiNNaker rejects a message.
1605
         * @throws InterruptedException
1606
         *             If the communications were interrupted.
1607
         */
1608
        @ParallelSafeWithCare
1609
        void updateProvenanceAndExit(@Valid CoreSubsets coreSubsets)
1610
                        throws IOException, ProcessException, InterruptedException;
1611

1612
        /**
1613
         * Write to the SDRAM on the board.
1614
         *
1615
         * @param chip
1616
         *            The coordinates of the chip where the memory is that is to be
1617
         *            written to
1618
         * @param baseAddress
1619
         *            The address in SDRAM where the region of memory is to be
1620
         *            written
1621
         * @param dataStream
1622
         *            The stream of data that is to be written.
1623
         * @param numBytes
1624
         *            The amount of data to be written in bytes.
1625
         * @throws IOException
1626
         *             If anything goes wrong with networking or reading from the
1627
         *             input stream.
1628
         * @throws ProcessException
1629
         *             If SpiNNaker rejects a message.
1630
         * @throws InterruptedException
1631
         *             If the communications were interrupted.
1632
         */
1633
        @ParallelSafe
1634
        default void writeMemory(@Valid HasChipLocation chip,
1635
                        @NotNull MemoryLocation baseAddress,
1636
                        @NotNull InputStream dataStream, @Positive int numBytes)
1637
                        throws IOException, ProcessException, InterruptedException {
1638
                writeMemory(chip.getScampCore(), baseAddress, dataStream, numBytes);
×
1639
        }
×
1640

1641
        /**
1642
         * Write to the SDRAM on the board.
1643
         *
1644
         * @param core
1645
         *            The coordinates of the core where the memory is that is to be
1646
         *            written to
1647
         * @param baseAddress
1648
         *            The address in SDRAM where the region of memory is to be
1649
         *            written
1650
         * @param dataStream
1651
         *            The stream of data that is to be written.
1652
         * @param numBytes
1653
         *            The amount of data to be written in bytes.
1654
         * @throws IOException
1655
         *             If anything goes wrong with networking or reading from the
1656
         *             input stream.
1657
         * @throws ProcessException
1658
         *             If SpiNNaker rejects a message.
1659
         * @throws InterruptedException
1660
         *             If the communications were interrupted.
1661
         */
1662
        @ParallelSafe
1663
        void writeMemory(@Valid HasCoreLocation core,
1664
                        @NotNull MemoryLocation baseAddress,
1665
                        @NotNull InputStream dataStream, @Positive int numBytes)
1666
                        throws IOException, ProcessException, InterruptedException;
1667

1668
        /**
1669
         * Write to the SDRAM on the board.
1670
         *
1671
         * @param chip
1672
         *            The coordinates of the chip where the memory is that is to be
1673
         *            written to
1674
         * @param baseAddress
1675
         *            The address in SDRAM where the region of memory is to be
1676
         *            written
1677
         * @param dataFile
1678
         *            The file holding the data that is to be written.
1679
         * @throws IOException
1680
         *             If anything goes wrong with networking or reading from the
1681
         *             file.
1682
         * @throws ProcessException
1683
         *             If SpiNNaker rejects a message.
1684
         * @throws InterruptedException
1685
         *             If the communications were interrupted.
1686
         */
1687
        @ParallelSafe
1688
        default void writeMemory(@Valid HasChipLocation chip,
1689
                        @NotNull MemoryLocation baseAddress, @NotNull File dataFile)
1690
                        throws IOException, ProcessException, InterruptedException {
1691
                writeMemory(chip.getScampCore(), baseAddress, dataFile);
×
1692
        }
×
1693

1694
        /**
1695
         * Write to the SDRAM on the board.
1696
         *
1697
         * @param core
1698
         *            The coordinates of the core where the memory is that is to be
1699
         *            written to
1700
         * @param baseAddress
1701
         *            The address in SDRAM where the region of memory is to be
1702
         *            written
1703
         * @param dataFile
1704
         *            The file holding the data that is to be written.
1705
         * @throws IOException
1706
         *             If anything goes wrong with networking or reading from the
1707
         *             file.
1708
         * @throws ProcessException
1709
         *             If SpiNNaker rejects a message.
1710
         * @throws InterruptedException
1711
         *             If the communications were interrupted.
1712
         */
1713
        @ParallelSafe
1714
        void writeMemory(@Valid HasCoreLocation core,
1715
                        @NotNull MemoryLocation baseAddress, @NotNull File dataFile)
1716
                        throws IOException, ProcessException, InterruptedException;
1717

1718
        /**
1719
         * Write to the SDRAM on the board.
1720
         *
1721
         * @param chip
1722
         *            The coordinates of the chip where the memory is that is to be
1723
         *            written to
1724
         * @param baseAddress
1725
         *            The address in SDRAM where the region of memory is to be
1726
         *            written
1727
         * @param dataWord
1728
         *            The word that is to be written (as 4 bytes).
1729
         * @throws IOException
1730
         *             If anything goes wrong with networking.
1731
         * @throws ProcessException
1732
         *             If SpiNNaker rejects a message.
1733
         * @throws InterruptedException
1734
         *             If the communications were interrupted.
1735
         */
1736
        @ParallelSafe
1737
        default void writeMemory(@Valid HasChipLocation chip,
1738
                        @NotNull MemoryLocation baseAddress, int dataWord)
1739
                        throws IOException, ProcessException, InterruptedException {
1740
                writeMemory(chip.getScampCore(), baseAddress, dataWord);
×
1741
        }
×
1742

1743
        /**
1744
         * Write to the SDRAM (or System RAM) on the board.
1745
         *
1746
         * @param core
1747
         *            The coordinates of the core where the memory is that is to be
1748
         *            written to
1749
         * @param baseAddress
1750
         *            The address in SDRAM where the region of memory is to be
1751
         *            written
1752
         * @param dataWord
1753
         *            The word that is to be written (as 4 bytes).
1754
         * @throws IOException
1755
         *             If anything goes wrong with networking.
1756
         * @throws ProcessException
1757
         *             If SpiNNaker rejects a message.
1758
         * @throws InterruptedException
1759
         *             If the communications were interrupted.
1760
         */
1761
        @ParallelSafe
1762
        default void writeMemory(@Valid HasCoreLocation core,
1763
                        @NotNull MemoryLocation baseAddress, int dataWord)
1764
                        throws IOException, ProcessException, InterruptedException {
1765
                writeMemory(core, baseAddress, wordAsBuffer(dataWord));
×
1766
        }
×
1767

1768
        /**
1769
         * Write to the SDRAM on the board.
1770
         *
1771
         * @param chip
1772
         *            The coordinates of the core where the memory is that is to be
1773
         *            written to
1774
         * @param baseAddress
1775
         *            The address in SDRAM where the region of memory is to be
1776
         *            written
1777
         * @param data
1778
         *            The data that is to be written.
1779
         * @throws IOException
1780
         *             If anything goes wrong with networking.
1781
         * @throws ProcessException
1782
         *             If SpiNNaker rejects a message.
1783
         * @throws InterruptedException
1784
         *             If the communications were interrupted.
1785
         */
1786
        @ParallelSafe
1787
        default void writeMemory(@Valid HasChipLocation chip,
1788
                        @NotNull MemoryLocation baseAddress, @NotEmpty byte[] data)
1789
                        throws IOException, ProcessException, InterruptedException {
1790
                writeMemory(chip.getScampCore(), baseAddress, wrap(data));
×
1791
        }
×
1792

1793
        /**
1794
         * Write to the SDRAM on the board.
1795
         *
1796
         * @param core
1797
         *            The coordinates of the core where the memory is that is to be
1798
         *            written to
1799
         * @param baseAddress
1800
         *            The address in SDRAM where the region of memory is to be
1801
         *            written
1802
         * @param data
1803
         *            The data that is to be written.
1804
         * @throws IOException
1805
         *             If anything goes wrong with networking.
1806
         * @throws ProcessException
1807
         *             If SpiNNaker rejects a message.
1808
         * @throws InterruptedException
1809
         *             If the communications were interrupted.
1810
         */
1811
        @ParallelSafe
1812
        default void writeMemory(@Valid HasCoreLocation core,
1813
                        @NotNull MemoryLocation baseAddress, @NotEmpty byte[] data)
1814
                        throws IOException, ProcessException, InterruptedException {
1815
                writeMemory(core, baseAddress, wrap(data));
×
1816
        }
×
1817

1818
        /**
1819
         * Write to the SDRAM on the board.
1820
         *
1821
         * @param chip
1822
         *            The coordinates of the core where the memory is that is to be
1823
         *            written to
1824
         * @param baseAddress
1825
         *            The address in SDRAM where the region of memory is to be
1826
         *            written
1827
         * @param data
1828
         *            The data that is to be written. The data should be from the
1829
         *            <i>position</i> to the <i>limit</i>.
1830
         * @throws IOException
1831
         *             If anything goes wrong with networking.
1832
         * @throws ProcessException
1833
         *             If SpiNNaker rejects a message.
1834
         * @throws InterruptedException
1835
         *             If the communications were interrupted.
1836
         */
1837
        @ParallelSafe
1838
        default void writeMemory(@Valid HasChipLocation chip,
1839
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1840
                        throws IOException, ProcessException, InterruptedException {
1841
                writeMemory(chip.getScampCore(), baseAddress, data);
×
1842
        }
×
1843

1844
        /**
1845
         * Write to the SDRAM (or System RAM) on the board.
1846
         *
1847
         * @param core
1848
         *            The coordinates of the core where the memory is that is to be
1849
         *            written to
1850
         * @param baseAddress
1851
         *            The address in SDRAM where the region of memory is to be
1852
         *            written
1853
         * @param data
1854
         *            The data that is to be written. The data should be from the
1855
         *            <i>position</i> to the <i>limit</i>.
1856
         * @throws IOException
1857
         *             If anything goes wrong with networking.
1858
         * @throws ProcessException
1859
         *             If SpiNNaker rejects a message.
1860
         * @throws InterruptedException
1861
         *             If the communications were interrupted.
1862
         */
1863
        @ParallelSafe
1864
        void writeMemory(@Valid HasCoreLocation core,
1865
                        @NotNull MemoryLocation baseAddress, @NotNull ByteBuffer data)
1866
                        throws IOException, ProcessException, InterruptedException;
1867

1868
        /**
1869
         * Write to the user<sub>0</sub> register of a core.
1870
         *
1871
         * @param core
1872
         *            The coordinates of the core whose register is to be
1873
         *            written to
1874
         * @param value
1875
         *            The word of data that is to be written.
1876
         * @throws IOException
1877
         *             If anything goes wrong with networking.
1878
         * @throws ProcessException
1879
         *             If SpiNNaker rejects a message.
1880
         * @throws InterruptedException
1881
         *             If the communications were interrupted.
1882
         */
1883
        default void writeUser0(@Valid HasCoreLocation core, int value)
1884
                        throws ProcessException, IOException, InterruptedException {
1885
                writeMemory(core.getScampCore(), getUser0RegisterAddress(core), value);
×
1886
        }
×
1887

1888
        /**
1889
         * Write to the user<sub>0</sub> register of a core.
1890
         *
1891
         * @param core
1892
         *            The coordinates of the core whose register is to be
1893
         *            written to
1894
         * @param pointer
1895
         *            The pointer/address that is to be written to the register.
1896
         * @throws IOException
1897
         *             If anything goes wrong with networking.
1898
         * @throws ProcessException
1899
         *             If SpiNNaker rejects a message.
1900
         * @throws InterruptedException
1901
         *             If the communications were interrupted.
1902
         */
1903
        default void writeUser0(@Valid HasCoreLocation core,
1904
                        @NotNull MemoryLocation pointer)
1905
                        throws ProcessException, IOException, InterruptedException {
1906
                writeMemory(core.getScampCore(), getUser0RegisterAddress(core),
×
1907
                                pointer.address());
×
1908
        }
×
1909

1910
        /**
1911
         * Write to the user<sub>1</sub> register of a core.
1912
         *
1913
         * @param core
1914
         *            The coordinates of the core whose register is to be
1915
         *            written to
1916
         * @param value
1917
         *            The word of data that is to be written.
1918
         * @throws IOException
1919
         *             If anything goes wrong with networking.
1920
         * @throws ProcessException
1921
         *             If SpiNNaker rejects a message.
1922
         * @throws InterruptedException
1923
         *             If the communications were interrupted.
1924
         */
1925
        default void writeUser1(@Valid HasCoreLocation core, int value)
1926
                        throws ProcessException, IOException, InterruptedException {
1927
                writeMemory(core.getScampCore(), getUser1RegisterAddress(core), value);
×
1928
        }
×
1929

1930
        /**
1931
         * Write to the user<sub>1</sub> register of a core.
1932
         *
1933
         * @param core
1934
         *            The coordinates of the core whose register is to be written to
1935
         * @param pointer
1936
         *            The pointer/address that is to be written to the register.
1937
         * @throws IOException
1938
         *             If anything goes wrong with networking.
1939
         * @throws ProcessException
1940
         *             If SpiNNaker rejects a message.
1941
         * @throws InterruptedException
1942
         *             If the communications were interrupted.
1943
         */
1944
        default void writeUser1(@Valid HasCoreLocation core,
1945
                        @NotNull MemoryLocation pointer)
1946
                        throws ProcessException, IOException, InterruptedException {
1947
                writeMemory(core.getScampCore(), getUser1RegisterAddress(core),
×
1948
                                pointer.address());
×
1949
        }
×
1950

1951
        /**
1952
         * Write to the user<sub>2</sub> register of a core.
1953
         *
1954
         * @param core
1955
         *            The coordinates of the core whose register is to be
1956
         *            written to
1957
         * @param value
1958
         *            The word of data that is to be written.
1959
         * @throws IOException
1960
         *             If anything goes wrong with networking.
1961
         * @throws ProcessException
1962
         *             If SpiNNaker rejects a message.
1963
         * @throws InterruptedException
1964
         *             If the communications were interrupted.
1965
         */
1966
        default void writeUser2(@Valid HasCoreLocation core, int value)
1967
                        throws ProcessException, IOException, InterruptedException {
1968
                writeMemory(core.getScampCore(), getUser2RegisterAddress(core), value);
×
1969
        }
×
1970

1971
        /**
1972
         * Write to the user<sub>2</sub> register of a core.
1973
         *
1974
         * @param core
1975
         *            The coordinates of the core whose register is to be written to
1976
         * @param pointer
1977
         *            The pointer/address that is to be written to the register.
1978
         * @throws IOException
1979
         *             If anything goes wrong with networking.
1980
         * @throws ProcessException
1981
         *             If SpiNNaker rejects a message.
1982
         * @throws InterruptedException
1983
         *             If the communications were interrupted.
1984
         */
1985
        default void writeUser2(@Valid HasCoreLocation core,
1986
                        @NotNull MemoryLocation pointer)
1987
                        throws ProcessException, IOException, InterruptedException {
1988
                writeMemory(core.getScampCore(), getUser2RegisterAddress(core),
×
1989
                                pointer.address());
×
1990
        }
×
1991

1992
        /**
1993
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
1994
         * command. If sent to a BMP, this command can be used to communicate with
1995
         * the FPGAs' debug registers; in that case, the link must be the direction
1996
         * with the same ID as the ID of the FPGA to communicate with.
1997
         * <p>
1998
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
1999
         * multi-threaded context if the link leaves the current board.
2000
         *
2001
         * @param chip
2002
         *            The coordinates of the chip whose neighbour is to be written
2003
         *            to
2004
         * @param link
2005
         *            The link direction to send the request along
2006
         * @param baseAddress
2007
         *            The address in SDRAM where the region of memory is to be
2008
         *            written
2009
         * @param dataStream
2010
         *            The stream of data that is to be written.
2011
         * @param numBytes
2012
         *            The amount of data to be written in bytes.
2013
         * @throws IOException
2014
         *             If anything goes wrong with networking or with reading from
2015
         *             the input stream.
2016
         * @throws ProcessException
2017
         *             If SpiNNaker rejects a message.
2018
         * @throws InterruptedException
2019
         *             If the communications were interrupted.
2020
         */
2021
        @ParallelSafeWithCare
2022
        default void writeNeighbourMemory(@Valid HasChipLocation chip,
2023
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2024
                        @NotNull InputStream dataStream, @Positive int numBytes)
2025
                        throws IOException, ProcessException, InterruptedException {
2026
                writeNeighbourMemory(chip.getScampCore(), link, baseAddress, dataStream,
×
2027
                                numBytes);
2028
        }
×
2029

2030
        /**
2031
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2032
         * command. If sent to a BMP, this command can be used to communicate with
2033
         * the FPGAs' debug registers; in that case, the link must be the direction
2034
         * with the same ID as the ID of the FPGA to communicate with.
2035
         * <p>
2036
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2037
         * multi-threaded context if the link leaves the current board.
2038
         *
2039
         * @param core
2040
         *            The coordinates of the core whose neighbour is to be written
2041
         *            to; the CPU to use is typically 0 (or if a BMP, the slot
2042
         *            number)
2043
         * @param link
2044
         *            The link direction to send the request along
2045
         * @param baseAddress
2046
         *            The address in SDRAM where the region of memory is to be
2047
         *            written
2048
         * @param dataStream
2049
         *            The stream of data that is to be written.
2050
         * @param numBytes
2051
         *            The amount of data to be written in bytes.
2052
         * @throws IOException
2053
         *             If anything goes wrong with networking or with reading from
2054
         *             the input stream.
2055
         * @throws ProcessException
2056
         *             If SpiNNaker rejects a message.
2057
         * @throws InterruptedException
2058
         *             If the communications were interrupted.
2059
         */
2060
        @ParallelSafeWithCare
2061
        void writeNeighbourMemory(@Valid HasCoreLocation core,
2062
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2063
                        @NotNull InputStream dataStream, @Positive int numBytes)
2064
                        throws IOException, ProcessException, InterruptedException;
2065

2066
        /**
2067
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2068
         * command. If sent to a BMP, this command can be used to communicate with
2069
         * the FPGAs' debug registers; in that case, the link must be the direction
2070
         * with the same ID as the ID of the FPGA to communicate with.
2071
         * <p>
2072
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2073
         * multi-threaded context if the link leaves the current board.
2074
         *
2075
         * @param chip
2076
         *            The coordinates of the chip whose neighbour is to be written
2077
         *            to
2078
         * @param link
2079
         *            The link direction to send the request along
2080
         * @param baseAddress
2081
         *            The address in SDRAM where the region of memory is to be
2082
         *            written
2083
         * @param dataFile
2084
         *            The file holding the data that is to be written.
2085
         * @throws IOException
2086
         *             If anything goes wrong with networking or with reading from
2087
         *             the file.
2088
         * @throws ProcessException
2089
         *             If SpiNNaker rejects a message.
2090
         * @throws InterruptedException
2091
         *             If the communications were interrupted.
2092
         */
2093
        @ParallelSafeWithCare
2094
        default void writeNeighbourMemory(@Valid HasChipLocation chip,
2095
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2096
                        @NotNull File dataFile)
2097
                        throws IOException, ProcessException, InterruptedException {
2098
                writeNeighbourMemory(chip.getScampCore(), link, baseAddress, dataFile);
×
2099
        }
×
2100

2101
        /**
2102
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2103
         * command. If sent to a BMP, this command can be used to communicate with
2104
         * the FPGAs' debug registers; in that case, the link must be the direction
2105
         * with the same ID as the ID of the FPGA to communicate with.
2106
         * <p>
2107
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2108
         * multi-threaded context if the link leaves the current board.
2109
         *
2110
         * @param core
2111
         *            The coordinates of the core whose neighbour is to be written
2112
         *            to; the CPU to use is typically 0 (or if a BMP, the slot
2113
         *            number)
2114
         * @param link
2115
         *            The link direction to send the request along
2116
         * @param baseAddress
2117
         *            The address in SDRAM where the region of memory is to be
2118
         *            written
2119
         * @param dataFile
2120
         *            The name of the file holding the data that is to be written.
2121
         * @throws IOException
2122
         *             If anything goes wrong with networking or with reading from
2123
         *             the file.
2124
         * @throws ProcessException
2125
         *             If SpiNNaker rejects a message.
2126
         * @throws InterruptedException
2127
         *             If the communications were interrupted.
2128
         */
2129
        @ParallelSafeWithCare
2130
        void writeNeighbourMemory(@Valid HasCoreLocation core,
2131
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2132
                        @NotNull File dataFile)
2133
                        throws IOException, ProcessException, InterruptedException;
2134

2135
        /**
2136
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2137
         * command. If sent to a BMP, this command can be used to communicate with
2138
         * the FPGAs' debug registers; in that case, the link must be the direction
2139
         * with the same ID as the ID of the FPGA to communicate with.
2140
         * <p>
2141
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2142
         * multi-threaded context if the link leaves the current board.
2143
         *
2144
         * @param chip
2145
         *            The coordinates of the chip whose neighbour is to be written
2146
         *            to
2147
         * @param link
2148
         *            The link direction to send the request along
2149
         * @param baseAddress
2150
         *            The address in SDRAM where the region of memory is to be
2151
         *            written
2152
         * @param dataWord
2153
         *            The word that is to be written.
2154
         * @throws IOException
2155
         *             If anything goes wrong with networking.
2156
         * @throws ProcessException
2157
         *             If SpiNNaker rejects a message.
2158
         * @throws InterruptedException
2159
         *             If the communications were interrupted.
2160
         */
2161
        @ParallelSafeWithCare
2162
        default void writeNeighbourMemory(@Valid HasChipLocation chip,
2163
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2164
                        int dataWord)
2165
                        throws IOException, ProcessException, InterruptedException {
2166
                writeNeighbourMemory(chip.getScampCore(), link, baseAddress, dataWord);
×
2167
        }
×
2168

2169
        /**
2170
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2171
         * command. If sent to a BMP, this command can be used to communicate with
2172
         * the FPGAs' debug registers; in that case, the link must be the direction
2173
         * with the same ID as the ID of the FPGA to communicate with.
2174
         * <p>
2175
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2176
         * multi-threaded context if the link leaves the current board.
2177
         *
2178
         * @param core
2179
         *            The coordinates of the core whose neighbour is to be written
2180
         *            to; the CPU to use is typically 0 (or if a BMP, the slot
2181
         *            number)
2182
         * @param link
2183
         *            The link direction to send the request along
2184
         * @param baseAddress
2185
         *            The address in SDRAM where the region of memory is to be
2186
         *            written
2187
         * @param dataWord
2188
         *            The word that is to be written.
2189
         * @throws IOException
2190
         *             If anything goes wrong with networking.
2191
         * @throws ProcessException
2192
         *             If SpiNNaker rejects a message.
2193
         * @throws InterruptedException
2194
         *             If the communications were interrupted.
2195
         */
2196
        @ParallelSafeWithCare
2197
        default void writeNeighbourMemory(@Valid HasCoreLocation core,
2198
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2199
                        int dataWord)
2200
                        throws IOException, ProcessException, InterruptedException {
2201
                writeNeighbourMemory(core, link, baseAddress, wordAsBuffer(dataWord));
×
2202
        }
×
2203

2204
        /**
2205
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2206
         * command. If sent to a BMP, this command can be used to communicate with
2207
         * the FPGAs' debug registers; in that case, the link must be the direction
2208
         * with the same ID as the ID of the FPGA to communicate with.
2209
         * <p>
2210
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2211
         * multi-threaded context if the link leaves the current board.
2212
         *
2213
         * @param chip
2214
         *            The coordinates of the chip whose neighbour is to be written
2215
         *            to
2216
         * @param link
2217
         *            The link direction to send the request along
2218
         * @param baseAddress
2219
         *            The address in SDRAM where the region of memory is to be
2220
         *            written
2221
         * @param data
2222
         *            The data that is to be written.
2223
         * @throws IOException
2224
         *             If anything goes wrong with networking.
2225
         * @throws ProcessException
2226
         *             If SpiNNaker rejects a message.
2227
         * @throws InterruptedException
2228
         *             If the communications were interrupted.
2229
         */
2230
        @ParallelSafeWithCare
2231
        default void writeNeighbourMemory(@Valid HasChipLocation chip,
2232
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2233
                        @NotEmpty byte[] data)
2234
                        throws IOException, ProcessException, InterruptedException {
2235
                writeNeighbourMemory(chip.getScampCore(), link, baseAddress, data);
×
2236
        }
×
2237

2238
        /**
2239
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2240
         * command. If sent to a BMP, this command can be used to communicate with
2241
         * the FPGAs' debug registers; in that case, the link must be the direction
2242
         * with the same ID as the ID of the FPGA to communicate with.
2243
         * <p>
2244
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2245
         * multi-threaded context if the link leaves the current board.
2246
         *
2247
         * @param core
2248
         *            The coordinates of the core whose neighbour is to be written
2249
         *            to; the CPU to use is typically 0 (or if a BMP, the slot
2250
         *            number)
2251
         * @param link
2252
         *            The link direction to send the request along
2253
         * @param baseAddress
2254
         *            The address in SDRAM where the region of memory is to be
2255
         *            written
2256
         * @param data
2257
         *            The data that is to be written.
2258
         * @throws IOException
2259
         *             If anything goes wrong with networking.
2260
         * @throws ProcessException
2261
         *             If SpiNNaker rejects a message.
2262
         * @throws InterruptedException
2263
         *             If the communications were interrupted.
2264
         */
2265
        @ParallelSafeWithCare
2266
        default void writeNeighbourMemory(@Valid HasCoreLocation core,
2267
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2268
                        @NotEmpty byte[] data)
2269
                        throws IOException, ProcessException, InterruptedException {
2270
                writeNeighbourMemory(core, link, baseAddress, wrap(data));
×
2271
        }
×
2272

2273
        /**
2274
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2275
         * command. If sent to a BMP, this command can be used to communicate with
2276
         * the FPGAs' debug registers; in that case, the link must be the direction
2277
         * with the same ID as the ID of the FPGA to communicate with.
2278
         * <p>
2279
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2280
         * multi-threaded context if the link leaves the current board.
2281
         *
2282
         * @param chip
2283
         *            The coordinates of the chip whose neighbour is to be written
2284
         *            to
2285
         * @param link
2286
         *            The link direction to send the request along
2287
         * @param baseAddress
2288
         *            The address in SDRAM where the region of memory is to be
2289
         *            written
2290
         * @param data
2291
         *            The data that is to be written. The data should be from the
2292
         *            <i>position</i> to the <i>limit</i>.
2293
         * @throws IOException
2294
         *             If anything goes wrong with networking.
2295
         * @throws ProcessException
2296
         *             If SpiNNaker rejects a message.
2297
         * @throws InterruptedException
2298
         *             If the communications were interrupted.
2299
         */
2300
        @ParallelSafeWithCare
2301
        default void writeNeighbourMemory(@Valid HasChipLocation chip,
2302
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2303
                        @NotNull ByteBuffer data)
2304
                        throws IOException, ProcessException, InterruptedException {
2305
                writeNeighbourMemory(chip.getScampCore(), link, baseAddress, data);
×
2306
        }
×
2307

2308
        /**
2309
         * Write to the memory of a neighbouring chip using a LINK_WRITE SCP
2310
         * command. If sent to a BMP, this command can be used to communicate with
2311
         * the FPGAs' debug registers; in that case, the link must be the direction
2312
         * with the same ID as the ID of the FPGA to communicate with.
2313
         * <p>
2314
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2315
         * multi-threaded context if the link leaves the current board.
2316
         *
2317
         * @param core
2318
         *            The coordinates of the core whose neighbour is to be written
2319
         *            to; the CPU to use is typically 0 (or if a BMP, the slot
2320
         *            number)
2321
         * @param link
2322
         *            The link direction to send the request along
2323
         * @param baseAddress
2324
         *            The address in SDRAM where the region of memory is to be
2325
         *            written
2326
         * @param data
2327
         *            The data that is to be written. The data should be from the
2328
         *            <i>position</i> to the <i>limit</i>.
2329
         * @throws IOException
2330
         *             If anything goes wrong with networking.
2331
         * @throws ProcessException
2332
         *             If SpiNNaker rejects a message.
2333
         * @throws InterruptedException
2334
         *             If the communications were interrupted.
2335
         */
2336
        @ParallelSafeWithCare
2337
        void writeNeighbourMemory(@Valid HasCoreLocation core,
2338
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2339
                        @NotNull ByteBuffer data)
2340
                        throws IOException, ProcessException, InterruptedException;
2341

2342
        /**
2343
         * Write to the SDRAM of all chips.
2344
         * <p>
2345
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2346
         * multi-threaded context. It has interlocking, but you should not rely on
2347
         * it.
2348
         *
2349
         * @param baseAddress
2350
         *            The address in SDRAM where the region of memory is to be
2351
         *            written
2352
         * @param dataStream
2353
         *            The stream of data that is to be written.
2354
         * @param numBytes
2355
         *            The amount of data to be written in bytes.
2356
         * @throws IOException
2357
         *             If anything goes wrong with networking or with reading from
2358
         *             the input stream.
2359
         * @throws ProcessException
2360
         *             If SpiNNaker rejects a message.
2361
         * @throws InterruptedException
2362
         *             If the communications were interrupted.
2363
         */
2364
        @ParallelUnsafe
2365
        void writeMemoryFlood(@NotNull MemoryLocation baseAddress,
2366
                        @NotNull InputStream dataStream, @Positive int numBytes)
2367
                        throws IOException, ProcessException, InterruptedException;
2368

2369
        /**
2370
         * Write to the SDRAM of all chips.
2371
         * <p>
2372
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2373
         * multi-threaded context. It has interlocking, but you should not rely on
2374
         * it.
2375
         *
2376
         * @param baseAddress
2377
         *            The address in SDRAM where the region of memory is to be
2378
         *            written
2379
         * @param dataFile
2380
         *            The name of the file holding the data that is to be written.
2381
         * @throws IOException
2382
         *             If anything goes wrong with networking or with reading from
2383
         *             the file.
2384
         * @throws ProcessException
2385
         *             If SpiNNaker rejects a message.
2386
         * @throws InterruptedException
2387
         *             If the communications were interrupted.
2388
         */
2389
        @ParallelUnsafe
2390
        void writeMemoryFlood(@NotNull MemoryLocation baseAddress,
2391
                        @NotNull File dataFile)
2392
                        throws IOException, ProcessException, InterruptedException;
2393

2394
        /**
2395
         * Write to the SDRAM of all chips.
2396
         * <p>
2397
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2398
         * multi-threaded context. It has interlocking, but you should not rely on
2399
         * it.
2400
         *
2401
         * @param baseAddress
2402
         *            The address in SDRAM where the region of memory is to be
2403
         *            written
2404
         * @param dataWord
2405
         *            The word that is to be written.
2406
         * @throws IOException
2407
         *             If anything goes wrong with networking.
2408
         * @throws ProcessException
2409
         *             If SpiNNaker rejects a message.
2410
         * @throws InterruptedException
2411
         *             If the communications were interrupted.
2412
         */
2413
        @ParallelUnsafe
2414
        default void writeMemoryFlood(@NotNull MemoryLocation baseAddress,
2415
                        int dataWord)
2416
                        throws IOException, ProcessException, InterruptedException {
2417
                writeMemoryFlood(baseAddress, wordAsBuffer(dataWord));
×
2418
        }
×
2419

2420
        /**
2421
         * Write to the SDRAM of all chips.
2422
         * <p>
2423
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2424
         * multi-threaded context. It has interlocking, but you should not rely on
2425
         * it.
2426
         *
2427
         * @param baseAddress
2428
         *            The address in SDRAM where the region of memory is to be
2429
         *            written
2430
         * @param data
2431
         *            The data that is to be written.
2432
         * @throws IOException
2433
         *             If anything goes wrong with networking.
2434
         * @throws ProcessException
2435
         *             If SpiNNaker rejects a message.
2436
         * @throws InterruptedException
2437
         *             If the communications were interrupted.
2438
         */
2439
        @ParallelUnsafe
2440
        default void writeMemoryFlood(@NotNull MemoryLocation baseAddress,
2441
                        @NotEmpty byte[] data)
2442
                        throws IOException, ProcessException, InterruptedException {
2443
                writeMemoryFlood(baseAddress, wrap(data));
×
2444
        }
×
2445

2446
        /**
2447
         * Write to the SDRAM of all chips.
2448
         * <p>
2449
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2450
         * multi-threaded context. It has interlocking, but you should not rely on
2451
         * it.
2452
         *
2453
         * @param baseAddress
2454
         *            The address in SDRAM where the region of memory is to be
2455
         *            written
2456
         * @param data
2457
         *            The data that is to be written. The data should be from the
2458
         *            <i>position</i> to the <i>limit</i>.
2459
         * @throws IOException
2460
         *             If anything goes wrong with networking.
2461
         * @throws ProcessException
2462
         *             If SpiNNaker rejects a message.
2463
         * @throws InterruptedException
2464
         *             If the communications were interrupted.
2465
         */
2466
        @ParallelUnsafe
2467
        void writeMemoryFlood(@NotNull MemoryLocation baseAddress,
2468
                        @NotNull ByteBuffer data)
2469
                        throws IOException, ProcessException, InterruptedException;
2470

2471
        /**
2472
         * Read some areas of SDRAM from the board.
2473
         *
2474
         * @param chip
2475
         *            The coordinates of the chip where the memory is to be read
2476
         *            from
2477
         * @param baseAddress
2478
         *            The address in SDRAM where the region of memory to be read
2479
         *            starts
2480
         * @param length
2481
         *            The length of the data to be read in bytes
2482
         * @return A little-endian buffer of data read, positioned at the start of
2483
         *         the data
2484
         * @throws IOException
2485
         *             If anything goes wrong with networking.
2486
         * @throws ProcessException
2487
         *             If SpiNNaker rejects a message.
2488
         * @throws InterruptedException
2489
         *             If the communications were interrupted.
2490
         */
2491
        @ParallelSafe
2492
        @CheckReturnValue
2493
        default ByteBuffer readMemory(@Valid HasChipLocation chip,
2494
                        @NotNull MemoryLocation baseAddress, @Positive int length)
2495
                        throws IOException, ProcessException, InterruptedException {
2496
                return readMemory(chip.getScampCore(), baseAddress, length);
×
2497
        }
2498

2499
        /**
2500
         * Read some areas of SDRAM (or System RAM) from the board.
2501
         *
2502
         * @param core
2503
         *            The coordinates of the core where the memory is to be read
2504
         *            from
2505
         * @param baseAddress
2506
         *            The address in SDRAM where the region of memory to be read
2507
         *            starts
2508
         * @param length
2509
         *            The length of the data to be read in bytes
2510
         * @return A little-endian buffer of data read, positioned at the start of
2511
         *         the data
2512
         * @throws IOException
2513
         *             If anything goes wrong with networking.
2514
         * @throws ProcessException
2515
         *             If SpiNNaker rejects a message.
2516
         * @throws InterruptedException
2517
         *             If the communications were interrupted.
2518
         */
2519
        @ParallelSafe
2520
        @CheckReturnValue
2521
        ByteBuffer readMemory(@Valid HasCoreLocation core,
2522
                        @NotNull MemoryLocation baseAddress, @Positive int length)
2523
                        throws IOException, ProcessException, InterruptedException;
2524

2525
        /**
2526
         * Read the contents of an allocated block on the heap from the board. The
2527
         * SDRAM heap can be read from any core of that chip; the DTCM heap can only
2528
         * be read from one particular core.
2529
         *
2530
         * @param core
2531
         *            The coordinates of the core where the memory is to be read
2532
         *            from
2533
         * @param element
2534
         *            The heap element to read the contents of
2535
         * @return A little-endian buffer of data read, positioned at the start of
2536
         *         the data, or {@code null} if the heap element is free.
2537
         * @throws IOException
2538
         *             If anything goes wrong with networking.
2539
         * @throws ProcessException
2540
         *             If SpiNNaker rejects a message.
2541
         * @throws InterruptedException
2542
         *             If the communications were interrupted.
2543
         */
2544
        @ParallelSafe
2545
        @CheckReturnValue
2546
        default ByteBuffer readMemory(@Valid HasCoreLocation core,
2547
                        @NotNull HeapElement element)
2548
                        throws IOException, ProcessException, InterruptedException {
2549
                if (element.isFree()) {
×
2550
                        return null;
×
2551
                }
2552
                return readMemory(core, element.dataAddress(), element.size());
×
2553
        }
2554

2555
        /**
2556
         * Read an area associated with a <em>recording region</em> from SDRAM from
2557
         * a core of a chip on the board.
2558
         *
2559
         * @param region
2560
         *            The recording region that is being read. Describes which core
2561
         *            produced the data, what <em>DSE index</em> the data came from,
2562
         *            and where in memory to actually read.
2563
         * @param storage
2564
         *            The database to write to.
2565
         * @throws IOException
2566
         *             If anything goes wrong with networking.
2567
         * @throws ProcessException
2568
         *             If SpiNNaker rejects a message.
2569
         * @throws StorageException
2570
         *             If anything goes wrong with access to the database.
2571
         * @throws InterruptedException
2572
         *             If the communications were interrupted.
2573
         */
2574
        @ParallelSafe
2575
        void readRegion(@Valid BufferManagerStorage.Region region,
2576
                        @NotNull BufferManagerStorage storage) throws IOException,
2577
                        ProcessException, StorageException, InterruptedException;
2578

2579
        /**
2580
         * Read the user<sub>0</sub> register of a core.
2581
         *
2582
         * @param core
2583
         *            The coordinates of the core to read the register of
2584
         * @return The contents of the register
2585
         * @throws IOException
2586
         *             If anything goes wrong with networking.
2587
         * @throws ProcessException
2588
         *             If SpiNNaker rejects a message.
2589
         * @throws InterruptedException
2590
         *             If the communications were interrupted.
2591
         */
2592
        @CheckReturnValue
2593
        default int readUser0(@Valid HasCoreLocation core)
2594
                        throws ProcessException, IOException, InterruptedException {
2595
                var user0 = getUser0RegisterAddress(core);
×
2596
                return readMemory(core.getScampCore(), user0, WORD_SIZE).getInt();
×
2597
        }
2598

2599
        /**
2600
         * Read the user<sub>1</sub> register of a core.
2601
         *
2602
         * @param core
2603
         *            The coordinates of the core to read the register of
2604
         * @return The contents of the register
2605
         * @throws IOException
2606
         *             If anything goes wrong with networking.
2607
         * @throws ProcessException
2608
         *             If SpiNNaker rejects a message.
2609
         * @throws InterruptedException
2610
         *             If the communications were interrupted.
2611
         */
2612
        @CheckReturnValue
2613
        default int readUser1(@Valid HasCoreLocation core)
2614
                        throws ProcessException, IOException, InterruptedException {
2615
                var user1 = getUser1RegisterAddress(core);
×
2616
                return readMemory(core.getScampCore(), user1, WORD_SIZE).getInt();
×
2617
        }
2618

2619
        /**
2620
         * Read the user<sub>2</sub> register of a core.
2621
         *
2622
         * @param core
2623
         *            The coordinates of the core to read the register of
2624
         * @return The contents of the register
2625
         * @throws IOException
2626
         *             If anything goes wrong with networking.
2627
         * @throws ProcessException
2628
         *             If SpiNNaker rejects a message.
2629
         * @throws InterruptedException
2630
         *             If the communications were interrupted.
2631
         */
2632
        @CheckReturnValue
2633
        default int readUser2(@Valid HasCoreLocation core)
2634
                        throws ProcessException, IOException, InterruptedException {
2635
                var user2 = getUser2RegisterAddress(core);
×
2636
                return readMemory(core.getScampCore(), user2, WORD_SIZE).getInt();
×
2637
        }
2638

2639
        /**
2640
         * Read some areas of memory on a neighbouring chip using a LINK_READ SCP
2641
         * command. If sent to a BMP, this command can be used to communicate with
2642
         * the FPGAs' debug registers; in that case, the link must be the direction
2643
         * with the same ID as the ID of the FPGA to communicate with.
2644
         * <p>
2645
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2646
         * multi-threaded context if the link leaves the current board.
2647
         *
2648
         * @param chip
2649
         *            The coordinates of the chip whose neighbour is to be read from
2650
         * @param link
2651
         *            The link direction to send the request along
2652
         * @param baseAddress
2653
         *            The address in SDRAM where the region of memory to be read
2654
         *            starts
2655
         * @param length
2656
         *            The length of the data to be read in bytes
2657
         * @return A little-endian buffer of data that has been read, positioned at
2658
         *         the start of the data
2659
         * @throws IOException
2660
         *             If anything goes wrong with networking.
2661
         * @throws ProcessException
2662
         *             If SpiNNaker rejects a message.
2663
         * @throws InterruptedException
2664
         *             If the communications were interrupted.
2665
         */
2666
        @ParallelSafeWithCare
2667
        default ByteBuffer readNeighbourMemory(@Valid HasChipLocation chip,
2668
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2669
                        @Positive int length)
2670
                        throws IOException, ProcessException, InterruptedException {
2671
                return readNeighbourMemory(chip.getScampCore(), link, baseAddress,
×
2672
                                length);
2673
        }
2674

2675
        /**
2676
         * Read some areas of memory on a neighbouring chip using a LINK_READ SCP
2677
         * command. If sent to a BMP, this command can be used to communicate with
2678
         * the FPGAs' debug registers; in that case, the link must be the direction
2679
         * with the same ID as the ID of the FPGA to communicate with.
2680
         * <p>
2681
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2682
         * multi-threaded context if the link leaves the current board.
2683
         *
2684
         * @param core
2685
         *            The coordinates of the chip whose neighbour is to be read
2686
         *            from, plus the CPU to use (typically 0, or if a BMP, the slot
2687
         *            number)
2688
         * @param link
2689
         *            The link direction to send the request along
2690
         * @param baseAddress
2691
         *            The address in SDRAM where the region of memory to be read
2692
         *            starts
2693
         * @param length
2694
         *            The length of the data to be read in bytes
2695
         * @return A little-endian buffer of data that has been read, positioned at
2696
         *         the start of the data
2697
         * @throws IOException
2698
         *             If anything goes wrong with networking.
2699
         * @throws ProcessException
2700
         *             If SpiNNaker rejects a message.
2701
         * @throws InterruptedException
2702
         *             If the communications were interrupted.
2703
         */
2704
        @ParallelSafeWithCare
2705
        ByteBuffer readNeighbourMemory(@Valid HasCoreLocation core,
2706
                        @NotNull Direction link, @NotNull MemoryLocation baseAddress,
2707
                        @Positive int length)
2708
                        throws IOException, ProcessException, InterruptedException;
2709

2710
        /**
2711
         * Sends a stop request for an application ID.
2712
         * <p>
2713
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2714
         * multi-threaded context.
2715
         *
2716
         * @param appID
2717
         *            The ID of the application to send to
2718
         * @throws IOException
2719
         *             If anything goes wrong with networking.
2720
         * @throws ProcessException
2721
         *             If SpiNNaker rejects a message.
2722
         * @throws InterruptedException
2723
         *             If the communications were interrupted.
2724
         */
2725
        @ParallelUnsafe
2726
        void stopApplication(@NotNull AppID appID)
2727
                        throws IOException, ProcessException, InterruptedException;
2728

2729
        /**
2730
         * Waits for the specified cores running the given application to be in some
2731
         * target state or states. Handles failures.
2732
         * <p>
2733
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2734
         * multi-threaded context if the cores are over more than a single board.
2735
         *
2736
         * @param coreSubsets
2737
         *            the cores to check are in a given sync state
2738
         * @param appID
2739
         *            the application ID that being used by the simulation
2740
         * @param cpuStates
2741
         *            The expected states once the applications are ready; success
2742
         *            is when each application is in one of these states
2743
         * @throws IOException
2744
         *             If anything goes wrong with networking.
2745
         * @throws InterruptedException
2746
         *             If the thread is interrupted while waiting.
2747
         * @throws SpinnmanException
2748
         *             If some cores enter an error state or SpiNNaker rejects a
2749
         *             message.
2750
         */
2751
        @ParallelSafeWithCare
2752
        default void waitForCoresToBeInState(@Valid CoreSubsets coreSubsets,
2753
                        @NotNull AppID appID, EnumSet<@NotNull CPUState> cpuStates)
2754
                        throws IOException, InterruptedException, SpinnmanException {
2755
                waitForCoresToBeInState(coreSubsets, appID, cpuStates, TIMEOUT_DISABLED,
×
2756
                                DEFAULT_POLL_INTERVAL, DEFAULT_ERROR_STATES,
2757
                                DEFAULT_CHECK_INTERVAL);
2758
        }
×
2759

2760
        /**
2761
         * Waits for the specified cores running the given application to be in some
2762
         * target state or states. Handles failures.
2763
         * <p>
2764
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2765
         * multi-threaded context if the cores are over more than a single board.
2766
         *
2767
         * @param allCoreSubsets
2768
         *            the cores to check are in a given sync state
2769
         * @param appID
2770
         *            the application ID that being used by the simulation
2771
         * @param cpuStates
2772
         *            The expected states once the applications are ready; success
2773
         *            is when each application is in one of these states
2774
         * @param timeout
2775
         *            The amount of time to wait in milliseconds for the cores to
2776
         *            reach one of the states, or {@code null} to wait for an
2777
         *            unbounded amount of time.
2778
         * @param timeBetweenPolls
2779
         *            Time between checking the state, in milliseconds
2780
         * @param errorStates
2781
         *            Set of states that the application can be in that indicate an
2782
         *            error, and so should raise an exception
2783
         * @param countsBetweenFullCheck
2784
         *            The number of times to use the count signal before instead
2785
         *            using the full CPU state check
2786
         * @throws IOException
2787
         *             If anything goes wrong with networking.
2788
         * @throws InterruptedException
2789
         *             If the thread is interrupted while waiting.
2790
         * @throws SpinnmanException
2791
         *             If some cores enter an error state or SpiNNaker rejects a
2792
         *             message.
2793
         */
2794
        @ParallelSafeWithCare
2795
        void waitForCoresToBeInState(@Valid CoreSubsets allCoreSubsets,
2796
                        @NotNull AppID appID, EnumSet<@NotNull CPUState> cpuStates,
2797
                        @PositiveOrZero Integer timeout, @Positive int timeBetweenPolls,
2798
                        EnumSet<@NotNull CPUState> errorStates,
2799
                        @Positive int countsBetweenFullCheck)
2800
                        throws IOException, InterruptedException, SpinnmanException;
2801

2802
        /**
2803
         * Get all cores that are in a given state.
2804
         * <p>
2805
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2806
         * multi-threaded context unless the {@code allCoreSubsets} only contains
2807
         * cores on a single board.
2808
         *
2809
         * @param allCoreSubsets
2810
         *            The cores to filter
2811
         * @param state
2812
         *            The states to filter on
2813
         * @return Core subsets object containing cores in the given state
2814
         * @throws IOException
2815
         *             If anything goes wrong with networking.
2816
         * @throws ProcessException
2817
         *             If SpiNNaker rejects a message.
2818
         * @throws InterruptedException
2819
         *             If the communications were interrupted.
2820
         */
2821
        @ParallelSafeWithCare
2822
        @CheckReturnValue
2823
        default CoreSubsets getCoresInState(@Valid CoreSubsets allCoreSubsets,
2824
                        @NotNull CPUState state)
2825
                        throws IOException, ProcessException, InterruptedException {
2826
                return getCoresInState(allCoreSubsets, EnumSet.of(state));
×
2827
        }
2828

2829
        /**
2830
         * Get all cores that are in a given set of states.
2831
         * <p>
2832
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2833
         * multi-threaded context unless the {@code allCoreSubsets} only contains
2834
         * cores on a single board.
2835
         *
2836
         * @param allCoreSubsets
2837
         *            The cores to filter
2838
         * @param states
2839
         *            The states to filter on
2840
         * @return Core subsets object containing cores in the given states
2841
         * @throws IOException
2842
         *             If anything goes wrong with networking.
2843
         * @throws ProcessException
2844
         *             If SpiNNaker rejects a message.
2845
         * @throws InterruptedException
2846
         *             If the communications were interrupted.
2847
         */
2848
        @ParallelSafeWithCare
2849
        @CheckReturnValue
2850
        default CoreSubsets getCoresInState(@Valid CoreSubsets allCoreSubsets,
2851
                        EnumSet<@NotNull CPUState> states)
2852
                        throws IOException, ProcessException, InterruptedException {
2853
                return new CoreSubsets(getCPUInformation(allCoreSubsets)
×
2854
                                .filter(info -> states.contains(info.getState()))
×
2855
                                .map(CPUInfo::asCoreLocation));
×
2856
        }
2857

2858
        /**
2859
         * Get all cores that are not in a given state.
2860
         * <p>
2861
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2862
         * multi-threaded context unless the {@code allCoreSubsets} only contains
2863
         * cores on a single board.
2864
         *
2865
         * @param allCoreSubsets
2866
         *            The cores to filter
2867
         * @param state
2868
         *            The state to filter on
2869
         * @return Core subsets object containing cores not in the given state
2870
         * @throws IOException
2871
         *             If anything goes wrong with networking.
2872
         * @throws ProcessException
2873
         *             If SpiNNaker rejects a message.
2874
         * @throws InterruptedException
2875
         *             If the communications were interrupted.
2876
         */
2877
        @ParallelSafeWithCare
2878
        @CheckReturnValue
2879
        default Map<CoreLocation, CPUInfo> getCoresNotInState(
2880
                        @Valid CoreSubsets allCoreSubsets, @NotNull CPUState state)
2881
                        throws IOException, ProcessException, InterruptedException {
2882
                return getCoresNotInState(allCoreSubsets, EnumSet.of(state));
×
2883
        }
2884

2885
        /**
2886
         * Get all cores that are not in a given set of states.
2887
         * <p>
2888
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2889
         * multi-threaded context unless the {@code allCoreSubsets} only contains
2890
         * cores on a single board.
2891
         *
2892
         * @param allCoreSubsets
2893
         *            The cores to filter
2894
         * @param states
2895
         *            The states to filter on
2896
         * @return Core subsets object containing cores not in the given states
2897
         * @throws IOException
2898
         *             If anything goes wrong with networking.
2899
         * @throws ProcessException
2900
         *             If SpiNNaker rejects a message.
2901
         * @throws InterruptedException
2902
         *             If the communications were interrupted.
2903
         */
2904
        @ParallelSafeWithCare
2905
        @CheckReturnValue
2906
        default Map<CoreLocation, CPUInfo> getCoresNotInState(
2907
                        @Valid CoreSubsets allCoreSubsets,
2908
                        EnumSet<@NotNull CPUState> states)
2909
                        throws IOException, ProcessException, InterruptedException {
2910
                return getCPUInformation(allCoreSubsets)
×
2911
                                .filter(info -> !states.contains(info.getState()))
×
2912
                                .toMap(TreeMap::new, CPUInfo::asCoreLocation, identity());
×
2913
        }
2914

2915
        /**
2916
         * Send a signal to an application.
2917
         * <p>
2918
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
2919
         * multi-threaded context.
2920
         *
2921
         * @param appID
2922
         *            The ID of the application to send to
2923
         * @param signal
2924
         *            The signal to send
2925
         * @throws IOException
2926
         *             If anything goes wrong with networking.
2927
         * @throws ProcessException
2928
         *             If SpiNNaker rejects a message.
2929
         * @throws InterruptedException
2930
         *             If the communications were interrupted.
2931
         */
2932
        @ParallelUnsafe
2933
        void sendSignal(@NotNull AppID appID, @NotNull Signal signal)
2934
                        throws IOException, ProcessException, InterruptedException;
2935

2936
        /**
2937
         * Set LED states.
2938
         *
2939
         * @param chip
2940
         *            The coordinates of the chip on which to set the LEDs
2941
         * @param ledStates
2942
         *            A map from LED index to state with 0 being off, 1 on and 2
2943
         *            inverted.
2944
         * @throws IOException
2945
         *             If anything goes wrong with networking.
2946
         * @throws ProcessException
2947
         *             If SpiNNaker rejects a message.
2948
         * @throws InterruptedException
2949
         *             If the communications were interrupted.
2950
         */
2951
        @ParallelSafe
2952
        default void setLEDs(@Valid HasChipLocation chip,
2953
                        Map<Integer, LEDAction> ledStates)
2954
                        throws IOException, ProcessException, InterruptedException {
2955
                setLEDs(chip.getScampCore(), ledStates);
×
2956
        }
×
2957

2958
        /**
2959
         * Set LED states.
2960
         *
2961
         * @param core
2962
         *            The coordinates of the core on which to set the LEDs
2963
         * @param ledStates
2964
         *            A map from LED index to state with 0 being off, 1 on and 2
2965
         *            inverted.
2966
         * @throws IOException
2967
         *             If anything goes wrong with networking.
2968
         * @throws ProcessException
2969
         *             If SpiNNaker rejects a message.
2970
         * @throws InterruptedException
2971
         *             If the communications were interrupted.
2972
         */
2973
        @ParallelSafe
2974
        void setLEDs(@Valid HasCoreLocation core, Map<Integer, LEDAction> ledStates)
2975
                        throws IOException, ProcessException, InterruptedException;
2976

2977
        /**
2978
         * Find a connection that matches the given board IP address.
2979
         *
2980
         * @param boardAddress
2981
         *            The IP address of the Ethernet connection on the board
2982
         * @return A connection for the given IP address, or {@code null} if no such
2983
         *         connection exists
2984
         */
2985
        @ParallelSafe
2986
        SCPConnection locateSpinnakerConnection(@NotNull InetAddress boardAddress);
2987

2988
        /**
2989
         * Set up an IP tag.
2990
         *
2991
         * @param tag
2992
         *            The tag to set up; note its board address can be {@code null},
2993
         *            in which case, the tag will be assigned to all boards.
2994
         * @throws IOException
2995
         *             If anything goes wrong with networking.
2996
         * @throws ProcessException
2997
         *             If SpiNNaker rejects a message.
2998
         * @throws InterruptedException
2999
         *             If the communications were interrupted.
3000
         */
3001
        @ParallelSafeWithCare
3002
        void setIPTag(@Valid IPTag tag)
3003
                        throws IOException, ProcessException, InterruptedException;
3004

3005
        /**
3006
         * Set up an IP tag to deliver messages to a particular connection.
3007
         *
3008
         * @param tag
3009
         *            The tag to set up.
3010
         * @param connection
3011
         *            The connection to deliver messages to, which must already be
3012
         *            set up to talk to the correct board.
3013
         * @throws IOException
3014
         *             If anything goes wrong with networking.
3015
         * @throws ProcessException
3016
         *             If SpiNNaker rejects a message.
3017
         * @throws InterruptedException
3018
         *             If the communications were interrupted.
3019
         */
3020
        @ParallelSafeWithCare
3021
        void setIPTag(@Valid IPTag tag, @NotNull SDPConnection connection)
3022
                        throws IOException, ProcessException, InterruptedException;
3023

3024
        /**
3025
         * Set up a reverse IP tag.
3026
         *
3027
         * @param tag
3028
         *            The reverse tag to set up; note its board address can be
3029
         *            {@code null}, in which case, the tag will be assigned to all
3030
         *            boards
3031
         * @throws IOException
3032
         *             If anything goes wrong with networking.
3033
         * @throws ProcessException
3034
         *             If SpiNNaker rejects a message.
3035
         * @throws InterruptedException
3036
         *             If the communications were interrupted.
3037
         */
3038
        @ParallelSafe
3039
        void setReverseIPTag(@Valid ReverseIPTag tag)
3040
                        throws IOException, ProcessException, InterruptedException;
3041

3042
        /**
3043
         * Clear the setting of an IP tag.
3044
         *
3045
         * @param tag
3046
         *            The tag
3047
         * @throws IOException
3048
         *             If anything goes wrong with networking.
3049
         * @throws ProcessException
3050
         *             If SpiNNaker rejects a message.
3051
         * @throws InterruptedException
3052
         *             If the communications were interrupted.
3053
         */
3054
        @ParallelSafe
3055
        default void clearIPTag(@Valid Tag tag)
3056
                        throws IOException, ProcessException, InterruptedException {
3057
                clearIPTag(tag.getTag(), tag.getBoardAddress());
×
3058
        }
×
3059

3060
        /**
3061
         * Clear the setting of an IP tag.
3062
         * <p>
3063
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
3064
         * multi-threaded context.
3065
         *
3066
         * @param tag
3067
         *            The tag ID
3068
         * @throws IOException
3069
         *             If anything goes wrong with networking.
3070
         * @throws ProcessException
3071
         *             If SpiNNaker rejects a message.
3072
         * @throws InterruptedException
3073
         *             If the communications were interrupted.
3074
         */
3075
        @ParallelUnsafe
3076
        default void clearIPTag(@TagID int tag)
3077
                        throws IOException, ProcessException, InterruptedException {
3078
                clearIPTag(tag, null);
×
3079
        }
×
3080

3081
        /**
3082
         * Clear the setting of an IP tag.
3083
         *
3084
         * @param tag
3085
         *            The tag ID
3086
         * @param boardAddress
3087
         *            Board address where the tag should be cleared. If
3088
         *            {@code null}, all SCPSender connections will send the message
3089
         *            to clear the tag
3090
         * @throws IOException
3091
         *             If anything goes wrong with networking.
3092
         * @throws ProcessException
3093
         *             If SpiNNaker rejects a message.
3094
         * @throws InterruptedException
3095
         *             If the communications were interrupted.
3096
         */
3097
        @ParallelSafe
3098
        void clearIPTag(@TagID int tag, InetAddress boardAddress)
3099
                        throws IOException, ProcessException, InterruptedException;
3100

3101
        /**
3102
         * Get the current set of tags that have been set on the board using all
3103
         * SCPSender connections.
3104
         * <p>
3105
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
3106
         * multi-threaded context.
3107
         *
3108
         * @return An iterable of tags
3109
         * @throws IOException
3110
         *             If anything goes wrong with networking.
3111
         * @throws ProcessException
3112
         *             If SpiNNaker rejects a message.
3113
         * @throws InterruptedException
3114
         *             If the communications were interrupted.
3115
         */
3116
        @ParallelUnsafe
3117
        @CheckReturnValue
3118
        default List<Tag> getTags()
3119
                        throws IOException, ProcessException, InterruptedException {
3120
                return getTags(null);
×
3121
        }
3122

3123
        /**
3124
         * Get the current set of tags that have been set on the board.
3125
         *
3126
         * @param connection
3127
         *            Connection from which the tags should be received.
3128
         * @return An iterable of tags
3129
         * @throws IOException
3130
         *             If anything goes wrong with networking.
3131
         * @throws ProcessException
3132
         *             If SpiNNaker rejects a message.
3133
         * @throws InterruptedException
3134
         *             If the communications were interrupted.
3135
         */
3136
        @ParallelSafe
3137
        @CheckReturnValue
3138
        List<Tag> getTags(SCPConnection connection)
3139
                        throws IOException, ProcessException, InterruptedException;
3140

3141
        /**
3142
         * Get the number of times each tag has had a message sent via it using all
3143
         * SCPSender connections.
3144
         * <p>
3145
         * <strong>WARNING!</strong> This operation is <em>unsafe</em> in a
3146
         * multi-threaded context.
3147
         *
3148
         * @return A map from the tags to their usage.
3149
         * @throws IOException
3150
         *             If anything goes wrong with networking.
3151
         * @throws ProcessException
3152
         *             If SpiNNaker rejects a message.
3153
         * @throws InterruptedException
3154
         *             If the communications were interrupted.
3155
         */
3156
        @ParallelUnsafe
3157
        @CheckReturnValue
3158
        default Map<Tag, Integer> getTagUsage()
3159
                        throws IOException, ProcessException, InterruptedException {
3160
                return getTagUsage(null);
×
3161
        }
3162

3163
        /**
3164
         * Get the number of times each tag has had a message sent via it for a
3165
         * connection.
3166
         *
3167
         * @param connection
3168
         *            Connection from which the tag usage should be retrieved.
3169
         * @return A map from the tags to their usage.
3170
         * @throws IOException
3171
         *             If anything goes wrong with networking.
3172
         * @throws ProcessException
3173
         *             If SpiNNaker rejects a message.
3174
         * @throws InterruptedException
3175
         *             If the communications were interrupted.
3176
         */
3177
        @ParallelSafe
3178
        @CheckReturnValue
3179
        Map<Tag, Integer> getTagUsage(@NotNull SCPConnection connection)
3180
                        throws IOException, ProcessException, InterruptedException;
3181

3182
        /**
3183
         * Allocates a chunk of SDRAM on a chip on the machine.
3184
         *
3185
         * @param chip
3186
         *            The coordinates of the chip onto which to allocate memory
3187
         * @param size
3188
         *            The amount of memory to allocate in bytes
3189
         * @return the base address of the allocated memory
3190
         * @throws IOException
3191
         *             If anything goes wrong with networking.
3192
         * @throws ProcessException
3193
         *             If SpiNNaker rejects a message.
3194
         * @throws InterruptedException
3195
         *             If the communications were interrupted.
3196
         */
3197
        @ParallelSafe
3198
        @CheckReturnValue
3199
        default MemoryLocation mallocSDRAM(@Valid HasChipLocation chip,
3200
                        @Positive int size)
3201
                        throws IOException, ProcessException, InterruptedException {
3202
                return mallocSDRAM(chip, size, DEFAULT, 0);
×
3203
        }
3204

3205
        /**
3206
         * Allocates a chunk of SDRAM on a chip on the machine.
3207
         *
3208
         * @param chip
3209
         *            The coordinates of the chip onto which to allocate memory
3210
         * @param size
3211
         *            The amount of memory to allocate in bytes
3212
         * @param appID
3213
         *            The ID of the application with which to associate the routes.
3214
         * @return the base address of the allocated memory
3215
         * @throws IOException
3216
         *             If anything goes wrong with networking.
3217
         * @throws ProcessException
3218
         *             If SpiNNaker rejects a message.
3219
         * @throws InterruptedException
3220
         *             If the communications were interrupted.
3221
         */
3222
        @ParallelSafe
3223
        @CheckReturnValue
3224
        default MemoryLocation mallocSDRAM(@Valid HasChipLocation chip,
3225
                        @Positive int size, @NotNull AppID appID)
3226
                        throws IOException, ProcessException, InterruptedException {
3227
                return mallocSDRAM(chip, size, appID, 0);
×
3228
        }
3229

3230
        /**
3231
         * Allocates a chunk of SDRAM on a chip on the machine.
3232
         *
3233
         * @param chip
3234
         *            The coordinates of the chip onto which to allocate memory
3235
         * @param size
3236
         *            The amount of memory to allocate in bytes
3237
         * @param appID
3238
         *            The ID of the application with which to associate the routes.
3239
         * @param tag
3240
         *            The tag for the SDRAM, a 8-bit (chip-wide) tag that can be
3241
         *            looked up by a SpiNNaker application to discover the address
3242
         *            of the allocated block.
3243
         * @return the base address of the allocated memory
3244
         * @throws IOException
3245
         *             If anything goes wrong with networking.
3246
         * @throws ProcessException
3247
         *             If SpiNNaker rejects a message.
3248
         * @throws InterruptedException
3249
         *             If the communications were interrupted.
3250
         */
3251
        @ParallelSafe
3252
        MemoryLocation mallocSDRAM(@Valid HasChipLocation chip, @Positive int size,
3253
                        @NotNull AppID appID, int tag)
3254
                        throws IOException, ProcessException, InterruptedException;
3255

3256
        /**
3257
         * Free allocated SDRAM.
3258
         *
3259
         * @param chip
3260
         *            The coordinates of the chip onto which to free memory
3261
         * @param baseAddress
3262
         *            The base address of the allocated memory
3263
         * @throws IOException
3264
         *             If anything goes wrong with networking.
3265
         * @throws ProcessException
3266
         *             If SpiNNaker rejects a message.
3267
         * @throws InterruptedException
3268
         *             If the communications were interrupted.
3269
         */
3270
        @ParallelSafe
3271
        void freeSDRAM(@Valid HasChipLocation chip,
3272
                        @NotNull MemoryLocation baseAddress)
3273
                        throws IOException, ProcessException, InterruptedException;
3274

3275
        /**
3276
         * Free all SDRAM allocated to a given application ID.
3277
         *
3278
         * @param chip
3279
         *            The coordinates of the chip onto which to free memory
3280
         * @param appID
3281
         *            The app ID of the owner of the allocated memory
3282
         * @return The number of blocks freed
3283
         * @throws IOException
3284
         *             If anything goes wrong with networking.
3285
         * @throws ProcessException
3286
         *             If SpiNNaker rejects a message.
3287
         * @throws InterruptedException
3288
         *             If the communications were interrupted.
3289
         */
3290
        @ParallelSafe
3291
        int freeSDRAM(@Valid HasChipLocation chip, @NotNull AppID appID)
3292
                        throws IOException, ProcessException, InterruptedException;
3293

3294
        /**
3295
         * Load a set of multicast routes on to a chip associated with the default
3296
         * application ID.
3297
         *
3298
         * @param chip
3299
         *            The coordinates of the chip onto which to load the routes
3300
         * @param routes
3301
         *            An iterable of multicast routes to load
3302
         * @throws IOException
3303
         *             If anything goes wrong with networking.
3304
         * @throws ProcessException
3305
         *             If SpiNNaker rejects a message.
3306
         * @throws InterruptedException
3307
         *             If the communications were interrupted.
3308
         */
3309
        @ParallelSafe
3310
        default void loadMulticastRoutes(@Valid HasChipLocation chip,
3311
                        Collection<@NotNull MulticastRoutingEntry> routes)
3312
                        throws IOException, ProcessException, InterruptedException {
3313
                loadMulticastRoutes(chip, routes, DEFAULT);
×
3314
        }
×
3315

3316
        /**
3317
         * Load a set of multicast routes on to a chip.
3318
         *
3319
         * @param chip
3320
         *            The coordinates of the chip onto which to load the routes
3321
         * @param routes
3322
         *            An iterable of multicast routes to load
3323
         * @param appID
3324
         *            The ID of the application with which to associate the routes.
3325
         * @throws IOException
3326
         *             If anything goes wrong with networking.
3327
         * @throws ProcessException
3328
         *             If SpiNNaker rejects a message.
3329
         * @throws InterruptedException
3330
         *             If the communications were interrupted.
3331
         */
3332
        @ParallelSafe
3333
        void loadMulticastRoutes(@Valid HasChipLocation chip,
3334
                        Collection<@NotNull MulticastRoutingEntry> routes,
3335
                        @NotNull AppID appID)
3336
                        throws IOException, ProcessException, InterruptedException;
3337

3338
        /**
3339
         * Loads a fixed route routing table entry onto a chip's router.
3340
         *
3341
         * @param chip
3342
         *            The coordinates of the chip onto which to load the route
3343
         * @param fixedRoute
3344
         *            the route for the fixed route entry on this chip
3345
         * @throws IOException
3346
         *             If anything goes wrong with networking.
3347
         * @throws ProcessException
3348
         *             If SpiNNaker rejects a message.
3349
         * @throws InterruptedException
3350
         *             If the communications were interrupted.
3351
         */
3352
        @ParallelSafe
3353
        default void loadFixedRoute(@Valid HasChipLocation chip,
3354
                        @Valid RoutingEntry fixedRoute)
3355
                        throws IOException, ProcessException, InterruptedException {
3356
                loadFixedRoute(chip, fixedRoute, DEFAULT);
×
3357
        }
×
3358

3359
        /**
3360
         * Loads a fixed route routing table entry onto a chip's router.
3361
         *
3362
         * @param chip
3363
         *            The coordinates of the chip onto which to load the route
3364
         * @param fixedRoute
3365
         *            the route for the fixed route entry on this chip
3366
         * @param appID
3367
         *            The ID of the application with which to associate the route.
3368
         * @throws IOException
3369
         *             If anything goes wrong with networking.
3370
         * @throws ProcessException
3371
         *             If SpiNNaker rejects a message.
3372
         * @throws InterruptedException
3373
         *             If the communications were interrupted.
3374
         */
3375
        @ParallelSafe
3376
        void loadFixedRoute(@Valid HasChipLocation chip,
3377
                        @Valid RoutingEntry fixedRoute, @NotNull AppID appID)
3378
                        throws IOException, ProcessException, InterruptedException;
3379

3380
        /**
3381
         * Reads a fixed route routing table entry from a chip's router.
3382
         *
3383
         * @param chip
3384
         *            The coordinate of the chip from which to read the route.
3385
         * @return the route as a fixed route entry
3386
         * @throws IOException
3387
         *             If anything goes wrong with networking.
3388
         * @throws ProcessException
3389
         *             If SpiNNaker rejects a message.
3390
         * @throws InterruptedException
3391
         *             If the communications were interrupted.
3392
         */
3393
        @ParallelSafe
3394
        @CheckReturnValue
3395
        default RoutingEntry readFixedRoute(@Valid HasChipLocation chip)
3396
                        throws IOException, ProcessException, InterruptedException {
3397
                return readFixedRoute(chip, DEFAULT);
×
3398
        }
3399

3400
        /**
3401
         * Reads a fixed route routing table entry from a chip's router.
3402
         *
3403
         * @param chip
3404
         *            The coordinate of the chip from which to read the route.
3405
         * @param appID
3406
         *            The ID of the application associated the route.
3407
         * @return the route as a fixed route entry
3408
         * @throws IOException
3409
         *             If anything goes wrong with networking.
3410
         * @throws ProcessException
3411
         *             If SpiNNaker rejects a message.
3412
         * @throws InterruptedException
3413
         *             If the communications were interrupted.
3414
         */
3415
        @ParallelSafe
3416
        @CheckReturnValue
3417
        RoutingEntry readFixedRoute(@Valid HasChipLocation chip,
3418
                        @NotNull AppID appID)
3419
                        throws IOException, ProcessException, InterruptedException;
3420

3421
        /**
3422
         * Get the current multicast routes set up on a chip.
3423
         *
3424
         * @param chip
3425
         *            The coordinates of the chip from which to get the routes
3426
         * @return An iterable of multicast routes
3427
         * @throws IOException
3428
         *             If anything goes wrong with networking.
3429
         * @throws ProcessException
3430
         *             If SpiNNaker rejects a message.
3431
         * @throws InterruptedException
3432
         *             If the communications were interrupted.
3433
         */
3434
        @ParallelSafe
3435
        @CheckReturnValue
3436
        default List<MulticastRoutingEntry> getMulticastRoutes(
3437
                        @Valid HasChipLocation chip)
3438
                        throws IOException, ProcessException, InterruptedException {
3439
                return getMulticastRoutes(chip, null);
×
3440
        }
3441

3442
        /**
3443
         * Get the current multicast routes set up on a chip.
3444
         *
3445
         * @param chip
3446
         *            The coordinates of the chip from which to get the routes
3447
         * @param appID
3448
         *            The ID of the application to filter the routes for.
3449
         *            {@code null} means "don't filter".
3450
         * @return An iterable of multicast routes
3451
         * @throws IOException
3452
         *             If anything goes wrong with networking.
3453
         * @throws ProcessException
3454
         *             If SpiNNaker rejects a message.
3455
         * @throws InterruptedException
3456
         *             If the communications were interrupted.
3457
         */
3458
        @ParallelSafe
3459
        @CheckReturnValue
3460
        List<MulticastRoutingEntry> getMulticastRoutes(@Valid HasChipLocation chip,
3461
                        AppID appID)
3462
                        throws IOException, ProcessException, InterruptedException;
3463

3464
        /**
3465
         * Remove all the multicast routes on a chip.
3466
         *
3467
         * @param chip
3468
         *            The coordinates of the chip on which to clear the routes
3469
         * @throws IOException
3470
         *             If anything goes wrong with networking.
3471
         * @throws ProcessException
3472
         *             If SpiNNaker rejects a message.
3473
         * @throws InterruptedException
3474
         *             If the communications were interrupted.
3475
         */
3476
        @ParallelSafe
3477
        void clearMulticastRoutes(@Valid HasChipLocation chip)
3478
                        throws IOException, ProcessException, InterruptedException;
3479

3480
        /**
3481
         * Get router diagnostic information from a chip.
3482
         *
3483
         * @param chip
3484
         *            The coordinates of the chip from which to get the information
3485
         * @return The router diagnostic information
3486
         * @throws IOException
3487
         *             If anything goes wrong with networking.
3488
         * @throws ProcessException
3489
         *             If SpiNNaker rejects a message.
3490
         * @throws InterruptedException
3491
         *             If the communications were interrupted.
3492
         */
3493
        @ParallelSafe
3494
        @CheckReturnValue
3495
        RouterDiagnostics getRouterDiagnostics(@Valid HasChipLocation chip)
3496
                        throws IOException, ProcessException, InterruptedException;
3497

3498
        /**
3499
         * Sets a router diagnostic filter in a router.
3500
         *
3501
         * @param chip
3502
         *            the address of the router in which this filter is being set
3503
         * @param position
3504
         *            the position in the list of filters where this filter is to be
3505
         *            added, between 0 and 15 (note that positions 0 to 11 are used
3506
         *            by the default filters, and setting these positions will
3507
         *            result in a warning).
3508
         * @param diagnosticFilter
3509
         *            the diagnostic filter being set in the position.
3510
         * @throws IOException
3511
         *             If anything goes wrong with networking.
3512
         * @throws ProcessException
3513
         *             If SpiNNaker rejects a message.
3514
         * @throws InterruptedException
3515
         *             If the communications were interrupted.
3516
         */
3517
        @ParallelSafe
3518
        void setRouterDiagnosticFilter(@Valid HasChipLocation chip, int position,
3519
                        @NotNull DiagnosticFilter diagnosticFilter)
3520
                        throws IOException, ProcessException, InterruptedException;
3521

3522
        /**
3523
         * Gets a router diagnostic filter from a router.
3524
         *
3525
         * @param chip
3526
         *            the address of the router from which this filter is being
3527
         *            retrieved
3528
         * @param position
3529
         *            the position in the list of filters where this filter is to be
3530
         *            read from
3531
         * @return The diagnostic filter read
3532
         * @throws IOException
3533
         *             If anything goes wrong with networking.
3534
         * @throws ProcessException
3535
         *             If SpiNNaker rejects a message.
3536
         * @throws InterruptedException
3537
         *             If the communications were interrupted.
3538
         */
3539
        @ParallelSafe
3540
        @CheckReturnValue
3541
        DiagnosticFilter getRouterDiagnosticFilter(@Valid HasChipLocation chip,
3542
                        @PositiveOrZero int position)
3543
                        throws IOException, ProcessException, InterruptedException;
3544

3545
        /**
3546
         * Clear router diagnostic information on a chip. Resets and enables all
3547
         * diagnostic counters.
3548
         *
3549
         * @param chip
3550
         *            The coordinates of the chip
3551
         * @throws IOException
3552
         *             If anything goes wrong with networking.
3553
         * @throws ProcessException
3554
         *             If SpiNNaker rejects a message.
3555
         * @throws InterruptedException
3556
         *             If the communications were interrupted.
3557
         */
3558
        @ParallelSafe
3559
        default void clearRouterDiagnosticCounters(@Valid HasChipLocation chip)
3560
                        throws IOException, ProcessException, InterruptedException {
3561
                clearRouterDiagnosticCounters(chip, false,
×
3562
                                range(0, NO_ROUTER_DIAGNOSTIC_FILTERS).boxed()
×
3563
                                                .collect(toList()));
×
3564
        }
×
3565

3566
        /**
3567
         * Clear router diagnostic information on a chip. Resets all diagnostic
3568
         * counters.
3569
         *
3570
         * @param chip
3571
         *            The coordinates of the chip
3572
         * @param enable
3573
         *            True (default) if the counters should be enabled
3574
         * @throws IOException
3575
         *             If anything goes wrong with networking.
3576
         * @throws ProcessException
3577
         *             If SpiNNaker rejects a message.
3578
         * @throws InterruptedException
3579
         *             If the communications were interrupted.
3580
         */
3581
        @ParallelSafe
3582
        default void clearRouterDiagnosticCounters(@Valid HasChipLocation chip,
3583
                        boolean enable)
3584
                        throws IOException, ProcessException, InterruptedException {
3585
                clearRouterDiagnosticCounters(chip, enable,
×
3586
                                range(0, NO_ROUTER_DIAGNOSTIC_FILTERS).boxed()
×
3587
                                                .collect(toList()));
×
3588
        }
×
3589

3590
        /**
3591
         * Clear router diagnostic information on a chip. Resets and enables all the
3592
         * numbered counters.
3593
         *
3594
         * @param chip
3595
         *            The coordinates of the chip
3596
         * @param counterIDs
3597
         *            The IDs of the counters to reset and enable; each must be
3598
         *            between 0 and 15
3599
         * @throws IOException
3600
         *             If anything goes wrong with networking.
3601
         * @throws ProcessException
3602
         *             If SpiNNaker rejects a message.
3603
         * @throws InterruptedException
3604
         *             If the communications were interrupted.
3605
         */
3606
        @ParallelSafe
3607
        default void clearRouterDiagnosticCounters(@Valid HasChipLocation chip,
3608
                        Iterable<@NotNull Integer> counterIDs)
3609
                        throws IOException, ProcessException, InterruptedException {
3610
                clearRouterDiagnosticCounters(chip, false, counterIDs);
×
3611
        }
×
3612

3613
        /**
3614
         * Clear router diagnostic information on a chip.
3615
         *
3616
         * @param chip
3617
         *            The coordinates of the chip
3618
         * @param enable
3619
         *            True (default) if the counters should be enabled
3620
         * @param counterIDs
3621
         *            The IDs of the counters to reset and enable if enable is True;
3622
         *            each must be between 0 and 15
3623
         * @throws IOException
3624
         *             If anything goes wrong with networking.
3625
         * @throws ProcessException
3626
         *             If SpiNNaker rejects a message.
3627
         * @throws InterruptedException
3628
         *             If the communications were interrupted.
3629
         */
3630
        @ParallelSafe
3631
        void clearRouterDiagnosticCounters(@Valid HasChipLocation chip,
3632
                        boolean enable, Iterable<@NotNull Integer> counterIDs)
3633
                        throws IOException, ProcessException, InterruptedException;
3634

3635
        /**
3636
         * Get the contents of the SDRAM heap on a given chip.
3637
         *
3638
         * @param chip
3639
         *            The coordinates of the chip
3640
         * @return the list of chunks in the heap
3641
         * @throws IOException
3642
         *             If anything goes wrong with networking.
3643
         * @throws ProcessException
3644
         *             If SpiNNaker rejects a message.
3645
         * @throws InterruptedException
3646
         *             If the communications were interrupted.
3647
         */
3648
        @ParallelSafe
3649
        @CheckReturnValue
3650
        default List<HeapElement> getHeap(@Valid HasChipLocation chip)
3651
                        throws IOException, ProcessException, InterruptedException {
3652
                return getHeap(chip, sdram_heap_address);
×
3653
        }
3654

3655
        /**
3656
         * Get the contents of the given heap on a given chip.
3657
         *
3658
         * @param chip
3659
         *            The coordinates of the chip
3660
         * @param heap
3661
         *            The SystemVariableDefinition which is the heap to read
3662
         * @return the list of chunks in the heap
3663
         * @throws IOException
3664
         *             If anything goes wrong with networking.
3665
         * @throws ProcessException
3666
         *             If SpiNNaker rejects a message.
3667
         * @throws InterruptedException
3668
         *             If the communications were interrupted.
3669
         */
3670
        @ParallelSafe
3671
        @CheckReturnValue
3672
        List<HeapElement> getHeap(@Valid HasChipLocation chip,
3673
                        @NotNull SystemVariableDefinition heap)
3674
                        throws IOException, ProcessException, InterruptedException;
3675

3676
        /**
3677
         * Fill some memory with repeated data.
3678
         *
3679
         * @param chip
3680
         *            The coordinates of the chip
3681
         * @param baseAddress
3682
         *            The address at which to start the fill
3683
         * @param repeatValue
3684
         *            The data to repeat
3685
         * @param size
3686
         *            The number of bytes to fill. Must be compatible with the data
3687
         *            type i.e. if the data type is WORD, the number of bytes must
3688
         *            be divisible by 4
3689
         * @throws IOException
3690
         *             If anything goes wrong with networking.
3691
         * @throws ProcessException
3692
         *             If SpiNNaker rejects a message.
3693
         * @throws InterruptedException
3694
         *             If the communications were interrupted.
3695
         */
3696
        @ParallelSafe
3697
        default void fillMemory(@Valid HasChipLocation chip,
3698
                        @NotNull MemoryLocation baseAddress, int repeatValue,
3699
                        @Positive int size)
3700
                        throws ProcessException, IOException, InterruptedException {
3701
                fillMemory(chip, baseAddress, repeatValue, size, WORD);
×
3702
        }
×
3703

3704
        /**
3705
         * Fill some memory with repeated data.
3706
         *
3707
         * @param chip
3708
         *            The coordinates of the chip
3709
         * @param baseAddress
3710
         *            The address at which to start the fill
3711
         * @param repeatValue
3712
         *            The data to repeat
3713
         * @param size
3714
         *            The number of bytes to fill. Must be compatible with the data
3715
         *            type i.e. if the data type is WORD, the number of bytes must
3716
         *            be divisible by 4
3717
         * @param dataType
3718
         *            The type of data to fill.
3719
         * @throws IOException
3720
         *             If anything goes wrong with networking.
3721
         * @throws ProcessException
3722
         *             If SpiNNaker rejects a message.
3723
         * @throws InterruptedException
3724
         *             If the communications were interrupted.
3725
         */
3726
        @ParallelSafe
3727
        void fillMemory(@Valid HasChipLocation chip,
3728
                        @NotNull MemoryLocation baseAddress, int repeatValue,
3729
                        @Positive int size, @NotNull FillDataType dataType)
3730
                        throws ProcessException, IOException, InterruptedException;
3731

3732
        /**
3733
         * Clear the packet reinjection queues in a monitor process.
3734
         *
3735
         * @param monitorCore
3736
         *            The coordinates of the monitor core.
3737
         * @throws IOException
3738
         *             If anything goes wrong with networking.
3739
         * @throws ProcessException
3740
         *             If SpiNNaker rejects a message.
3741
         * @throws InterruptedException
3742
         *             If the communications were interrupted.
3743
         */
3744
        @ParallelSafe
3745
        void clearReinjectionQueues(@Valid HasCoreLocation monitorCore)
3746
                        throws IOException, ProcessException, InterruptedException;
3747

3748
        /**
3749
         * Clear the packet reinjection queues in some monitor processes.
3750
         *
3751
         * @param monitorCores
3752
         *            The coordinates of the monitor cores.
3753
         * @throws IOException
3754
         *             If anything goes wrong with networking.
3755
         * @throws ProcessException
3756
         *             If SpiNNaker rejects a message.
3757
         * @throws InterruptedException
3758
         *             If the communications were interrupted.
3759
         */
3760
        @ParallelSafe
3761
        void clearReinjectionQueues(@Valid CoreSubsets monitorCores)
3762
                        throws IOException, ProcessException, InterruptedException;
3763

3764
        /**
3765
         * Get the packet reinjection status of a monitor process.
3766
         *
3767
         * @param monitorCore
3768
         *            The coordinates of the monitor core.
3769
         * @return The reinjection status.
3770
         * @throws IOException
3771
         *             If anything goes wrong with networking.
3772
         * @throws ProcessException
3773
         *             If SpiNNaker rejects a message.
3774
         * @throws InterruptedException
3775
         *             If the communications were interrupted.
3776
         */
3777
        @ParallelSafe
3778
        @CheckReturnValue
3779
        ReinjectionStatus getReinjectionStatus(@Valid HasCoreLocation monitorCore)
3780
                        throws IOException, ProcessException, InterruptedException;
3781

3782
        /**
3783
         * Get the packet reinjection status of some monitor processes.
3784
         *
3785
         * @param monitorCores
3786
         *            The coordinates of the monitor cores.
3787
         * @return The reinjection statuses of the cores.
3788
         * @throws IOException
3789
         *             If anything goes wrong with networking.
3790
         * @throws ProcessException
3791
         *             If SpiNNaker rejects a message.
3792
         * @throws InterruptedException
3793
         *             If the communications were interrupted.
3794
         */
3795
        @ParallelSafe
3796
        @CheckReturnValue
3797
        Map<CoreLocation, ReinjectionStatus> getReinjectionStatus(
3798
                        @Valid CoreSubsets monitorCores)
3799
                        throws IOException, ProcessException, InterruptedException;
3800

3801
        /**
3802
         * Reset the packet reinjection counters of a monitor process.
3803
         *
3804
         * @param monitorCore
3805
         *            The coordinates of the monitor core.
3806
         * @throws IOException
3807
         *             If anything goes wrong with networking.
3808
         * @throws ProcessException
3809
         *             If SpiNNaker rejects a message.
3810
         * @throws InterruptedException
3811
         *             If the communications were interrupted.
3812
         */
3813
        @ParallelSafe
3814
        void resetReinjectionCounters(@Valid HasCoreLocation monitorCore)
3815
                        throws IOException, ProcessException, InterruptedException;
3816

3817
        /**
3818
         * Reset the packet reinjection counters of some monitor processes.
3819
         *
3820
         * @param monitorCores
3821
         *            The coordinates of the monitor cores.
3822
         * @throws IOException
3823
         *             If anything goes wrong with networking.
3824
         * @throws ProcessException
3825
         *             If SpiNNaker rejects a message.
3826
         * @throws InterruptedException
3827
         *             If the communications were interrupted.
3828
         */
3829
        @ParallelSafeWithCare
3830
        void resetReinjectionCounters(@Valid CoreSubsets monitorCores)
3831
                        throws IOException, ProcessException, InterruptedException;
3832

3833
        /**
3834
         * Set whether packets (of all types) are to be reinjected.
3835
         *
3836
         * @param monitorCore
3837
         *            The coordinates of the monitor core.
3838
         * @param reinject
3839
         *            True if all packets are to be reinjected.
3840
         * @throws IOException
3841
         *             If anything goes wrong with networking.
3842
         * @throws ProcessException
3843
         *             If SpiNNaker rejects a message.
3844
         * @throws InterruptedException
3845
         *             If the communications were interrupted.
3846
         * @throws InterruptedException
3847
         *             If the communications were interrupted.
3848
         */
3849
        @ParallelSafe
3850
        default void setReinjection(@Valid HasCoreLocation monitorCore,
3851
                        boolean reinject)
3852
                        throws IOException, ProcessException, InterruptedException {
3853
                setReinjectionTypes(monitorCore, reinject, reinject, reinject,
×
3854
                                reinject);
3855
        }
×
3856

3857
        /**
3858
         * Set whether packets (of all types) are to be reinjected.
3859
         *
3860
         * @param monitorCores
3861
         *            The coordinates of some monitor cores.
3862
         * @param reinject
3863
         *            True if all packets are to be reinjected.
3864
         * @throws IOException
3865
         *             If anything goes wrong with networking.
3866
         * @throws ProcessException
3867
         *             If SpiNNaker rejects a message.
3868
         * @throws InterruptedException
3869
         *             If the communications were interrupted.
3870
         */
3871
        @ParallelSafe
3872
        default void setReinjection(@Valid CoreSubsets monitorCores,
3873
                        boolean reinject)
3874
                        throws IOException, ProcessException, InterruptedException {
3875
                setReinjectionTypes(monitorCores, reinject, reinject, reinject,
×
3876
                                reinject);
3877
        }
×
3878

3879
        /**
3880
         * Restore whether packets are to be reinjected to a previously saved state.
3881
         *
3882
         * @param monitorCore
3883
         *            The coordinates of the monitor core.
3884
         * @param status
3885
         *            The saved reinjection status to restore.
3886
         * @throws IOException
3887
         *             If anything goes wrong with networking.
3888
         * @throws ProcessException
3889
         *             If SpiNNaker rejects a message.
3890
         * @throws InterruptedException
3891
         *             If the communications were interrupted.
3892
         */
3893
        @ParallelSafe
3894
        default void setReinjection(@Valid HasCoreLocation monitorCore,
3895
                        @NotNull ReinjectionStatus status)
3896
                        throws IOException, ProcessException, InterruptedException {
3897
                setReinjectionTypes(monitorCore, status.isReinjectingMulticast(),
×
3898
                                status.isReinjectingPointToPoint(),
×
3899
                                status.isReinjectingFixedRoute(),
×
3900
                                status.isReinjectingNearestNeighbour());
×
3901
        }
×
3902

3903
        /**
3904
         * Restore whether packets are to be reinjected to a previously saved state.
3905
         *
3906
         * @param monitorCores
3907
         *            The coordinates of some monitor cores.
3908
         * @param status
3909
         *            The saved reinjection status to restore.
3910
         * @throws IOException
3911
         *             If anything goes wrong with networking.
3912
         * @throws ProcessException
3913
         *             If SpiNNaker rejects a message.
3914
         * @throws InterruptedException
3915
         *             If the communications were interrupted.
3916
         */
3917
        @ParallelSafe
3918
        default void setReinjection(@Valid CoreSubsets monitorCores,
3919
                        @NotNull ReinjectionStatus status)
3920
                        throws IOException, ProcessException, InterruptedException {
3921
                setReinjectionTypes(monitorCores, status.isReinjectingMulticast(),
×
3922
                                status.isReinjectingPointToPoint(),
×
3923
                                status.isReinjectingFixedRoute(),
×
3924
                                status.isReinjectingNearestNeighbour());
×
3925
        }
×
3926

3927
        /**
3928
         * Set what types of packets are to be reinjected.
3929
         *
3930
         * @param monitorCore
3931
         *            The coordinates of the monitor core.
3932
         * @param multicast
3933
         *            True if multicast packets are to be reinjected.
3934
         * @param pointToPoint
3935
         *            True if point-to-point packets are to be reinjected.
3936
         * @param fixedRoute
3937
         *            True if fixed-route packets are to be reinjected.
3938
         * @param nearestNeighbour
3939
         *            True if nearest-neighbour packets are to be reinjected.
3940
         * @throws IOException
3941
         *             If anything goes wrong with networking.
3942
         * @throws ProcessException
3943
         *             If SpiNNaker rejects a message.
3944
         * @throws InterruptedException
3945
         *             If the communications were interrupted.
3946
         */
3947
        @ParallelSafe
3948
        void setReinjectionTypes(@Valid HasCoreLocation monitorCore,
3949
                        boolean multicast, boolean pointToPoint, boolean fixedRoute,
3950
                        boolean nearestNeighbour)
3951
                        throws IOException, ProcessException, InterruptedException;
3952

3953
        /**
3954
         * Set what types of packets are to be reinjected.
3955
         *
3956
         * @param monitorCores
3957
         *            The coordinates of some monitor cores.
3958
         * @param multicast
3959
         *            True if multicast packets are to be reinjected.
3960
         * @param pointToPoint
3961
         *            True if point-to-point packets are to be reinjected.
3962
         * @param fixedRoute
3963
         *            True if fixed-route packets are to be reinjected.
3964
         * @param nearestNeighbour
3965
         *            True if nearest-neighbour packets are to be reinjected.
3966
         * @throws IOException
3967
         *             If anything goes wrong with networking.
3968
         * @throws ProcessException
3969
         *             If SpiNNaker rejects a message.
3970
         * @throws InterruptedException
3971
         *             If the communications were interrupted.
3972
         */
3973
        @ParallelSafeWithCare
3974
        void setReinjectionTypes(@Valid CoreSubsets monitorCores, boolean multicast,
3975
                        boolean pointToPoint, boolean fixedRoute, boolean nearestNeighbour)
3976
                        throws IOException, ProcessException, InterruptedException;
3977

3978
        /**
3979
         * Set the emergency packet reinjection timeout.
3980
         *
3981
         * @param monitorCore
3982
         *            The coordinates of the monitor core.
3983
         * @param timeoutMantissa
3984
         *            The mantissa of the timeout value, between 0 and 15.
3985
         * @param timeoutExponent
3986
         *            The exponent of the timeout value, between 0 and 15.
3987
         * @throws IOException
3988
         *             If anything goes wrong with networking.
3989
         * @throws ProcessException
3990
         *             If SpiNNaker rejects a message.
3991
         * @throws InterruptedException
3992
         *             If the communications were interrupted.
3993
         */
3994
        @ParallelSafe
3995
        void setReinjectionEmergencyTimeout(@Valid HasCoreLocation monitorCore,
3996
                        int timeoutMantissa, int timeoutExponent)
3997
                        throws IOException, ProcessException, InterruptedException;
3998

3999
        /**
4000
         * Set the emergency packet reinjection timeout.
4001
         *
4002
         * @param monitorCore
4003
         *            The coordinates of the monitor core.
4004
         * @param timeout
4005
         *            The timeout value.
4006
         * @throws IOException
4007
         *             If anything goes wrong with networking.
4008
         * @throws ProcessException
4009
         *             If SpiNNaker rejects a message.
4010
         * @throws InterruptedException
4011
         *             If the communications were interrupted.
4012
         */
4013
        @ParallelSafe
4014
        default void setReinjectionEmergencyTimeout(
4015
                        @Valid HasCoreLocation monitorCore, @NotNull RouterTimeout timeout)
4016
                        throws IOException, ProcessException, InterruptedException {
4017
                setReinjectionEmergencyTimeout(monitorCore, timeout.mantissa(),
×
4018
                                timeout.exponent());
×
4019
        }
×
4020

4021
        /**
4022
         * Set the emergency packet reinjection timeout.
4023
         *
4024
         * @param monitorCores
4025
         *            The coordinates of some monitor cores.
4026
         * @param timeoutMantissa
4027
         *            The mantissa of the timeout value, between 0 and 15.
4028
         * @param timeoutExponent
4029
         *            The exponent of the timeout value, between 0 and 15.
4030
         * @throws IOException
4031
         *             If anything goes wrong with networking.
4032
         * @throws ProcessException
4033
         *             If SpiNNaker rejects a message.
4034
         * @throws InterruptedException
4035
         *             If the communications were interrupted.
4036
         */
4037
        @ParallelSafeWithCare
4038
        void setReinjectionEmergencyTimeout(@Valid CoreSubsets monitorCores,
4039
                        int timeoutMantissa, int timeoutExponent)
4040
                        throws IOException, ProcessException, InterruptedException;
4041

4042
        /**
4043
         * Set the emergency packet reinjection timeout.
4044
         *
4045
         * @param monitorCores
4046
         *            The coordinates of some monitor cores.
4047
         * @param timeout
4048
         *            The timeout value.
4049
         * @throws IOException
4050
         *             If anything goes wrong with networking.
4051
         * @throws ProcessException
4052
         *             If SpiNNaker rejects a message.
4053
         * @throws InterruptedException
4054
         *             If the communications were interrupted.
4055
         */
4056
        @ParallelSafeWithCare
4057
        default void setReinjectionEmergencyTimeout(@Valid CoreSubsets monitorCores,
4058
                        @NotNull RouterTimeout timeout)
4059
                        throws IOException, ProcessException, InterruptedException {
4060
                setReinjectionEmergencyTimeout(monitorCores, timeout.mantissa(),
×
4061
                                timeout.exponent());
×
4062
        }
×
4063

4064
        /**
4065
         * Set the emergency packet reinjection timeout.
4066
         *
4067
         * @param monitorCores
4068
         *            The coordinates of some monitor cores.
4069
         * @param status
4070
         *            The saved core status.
4071
         * @throws IOException
4072
         *             If anything goes wrong with networking.
4073
         * @throws ProcessException
4074
         *             If SpiNNaker rejects a message.
4075
         * @throws InterruptedException
4076
         *             If the communications were interrupted.
4077
         */
4078
        @ParallelSafeWithCare
4079
        default void setReinjectionEmergencyTimeout(@Valid CoreSubsets monitorCores,
4080
                        @NotNull ReinjectionStatus status)
4081
                        throws IOException, ProcessException, InterruptedException {
4082
                setReinjectionEmergencyTimeout(monitorCores,
×
4083
                                status.emergencyTimeout());
×
4084
        }
×
4085

4086
        /**
4087
         * Set the packet reinjection timeout.
4088
         *
4089
         * @param monitorCore
4090
         *            The coordinates of the monitor core.
4091
         * @param timeoutMantissa
4092
         *            The mantissa of the timeout value, between 0 and 15.
4093
         * @param timeoutExponent
4094
         *            The exponent of the timeout value, between 0 and 15.
4095
         * @throws IOException
4096
         *             If anything goes wrong with networking.
4097
         * @throws ProcessException
4098
         *             If SpiNNaker rejects a message.
4099
         * @throws InterruptedException
4100
         *             If the communications were interrupted.
4101
         */
4102
        @ParallelSafe
4103
        void setReinjectionTimeout(@Valid HasCoreLocation monitorCore,
4104
                        int timeoutMantissa, int timeoutExponent)
4105
                        throws IOException, ProcessException, InterruptedException;
4106

4107
        /**
4108
         * Set the packet reinjection timeout.
4109
         *
4110
         * @param monitorCore
4111
         *            The coordinates of the monitor core.
4112
         * @param timeout
4113
         *            The timeout value.
4114
         * @throws IOException
4115
         *             If anything goes wrong with networking.
4116
         * @throws ProcessException
4117
         *             If SpiNNaker rejects a message.
4118
         * @throws InterruptedException
4119
         *             If the communications were interrupted.
4120
         */
4121
        @ParallelSafe
4122
        default void setReinjectionTimeout(@Valid HasCoreLocation monitorCore,
4123
                        @NotNull RouterTimeout timeout)
4124
                        throws IOException, ProcessException, InterruptedException {
4125
                setReinjectionTimeout(monitorCore, timeout.mantissa(),
×
4126
                                timeout.exponent());
×
4127
        }
×
4128

4129
        /**
4130
         * Set the packet reinjection timeout.
4131
         *
4132
         * @param monitorCores
4133
         *            The coordinates of some monitor cores.
4134
         * @param timeoutMantissa
4135
         *            The mantissa of the timeout value, between 0 and 15.
4136
         * @param timeoutExponent
4137
         *            The exponent of the timeout value, between 0 and 15.
4138
         * @throws IOException
4139
         *             If anything goes wrong with networking.
4140
         * @throws ProcessException
4141
         *             If SpiNNaker rejects a message.
4142
         * @throws InterruptedException
4143
         *             If the communications were interrupted.
4144
         */
4145
        @ParallelSafeWithCare
4146
        void setReinjectionTimeout(@Valid CoreSubsets monitorCores,
4147
                        int timeoutMantissa, int timeoutExponent)
4148
                        throws IOException, ProcessException, InterruptedException;
4149

4150
        /**
4151
         * Set the packet reinjection timeout.
4152
         *
4153
         * @param monitorCores
4154
         *            The coordinates of some monitor cores.
4155
         * @param timeout
4156
         *            The timeout value.
4157
         * @throws IOException
4158
         *             If anything goes wrong with networking.
4159
         * @throws ProcessException
4160
         *             If SpiNNaker rejects a message.
4161
         * @throws InterruptedException
4162
         *             If the communications were interrupted.
4163
         */
4164
        @ParallelSafeWithCare
4165
        default void setReinjectionTimeout(@Valid CoreSubsets monitorCores,
4166
                        @NotNull RouterTimeout timeout)
4167
                        throws IOException, ProcessException, InterruptedException {
4168
                setReinjectionTimeout(monitorCores, timeout.mantissa(),
×
4169
                                timeout.exponent());
×
4170
        }
×
4171

4172
        /**
4173
         * Set the packet reinjection timeout.
4174
         *
4175
         * @param monitorCores
4176
         *            The coordinates of some monitor cores.
4177
         * @param status
4178
         *            The saved core status.
4179
         * @throws IOException
4180
         *             If anything goes wrong with networking.
4181
         * @throws ProcessException
4182
         *             If SpiNNaker rejects a message.
4183
         * @throws InterruptedException
4184
         *             If the communications were interrupted.
4185
         */
4186
        @ParallelSafeWithCare
4187
        default void setReinjectionTimeout(@Valid CoreSubsets monitorCores,
4188
                        @NotNull ReinjectionStatus status)
4189
                        throws IOException, ProcessException, InterruptedException {
4190
                setReinjectionTimeout(monitorCores, status.timeout());
×
4191
        }
×
4192

4193
        /**
4194
         * Save the application's multicast router tables.
4195
         *
4196
         * @param monitorCores
4197
         *            The coordinates of some monitor cores; the routers on those
4198
         *            chips will have their (current) multicast router tables saved.
4199
         * @throws IOException
4200
         *             If anything goes wrong with networking.
4201
         * @throws ProcessException
4202
         *             If SpiNNaker rejects a message.
4203
         * @throws InterruptedException
4204
         *             If the communications were interrupted.
4205
         */
4206
        @ParallelSafeWithCare
4207
        void saveApplicationRouterTables(@Valid CoreSubsets monitorCores)
4208
                        throws IOException, ProcessException, InterruptedException;
4209

4210
        /**
4211
         * Load the (previously saved) application's multicast router tables. The
4212
         * router tables <em>must</em> have been previously
4213
         * {@linkplain #saveApplicationRouterTables(CoreSubsets) saved}.
4214
         *
4215
         * @param monitorCores
4216
         *            The coordinates of some monitor cores; the routers on those
4217
         *            chips will have their multicast router tables loaded.
4218
         * @throws IOException
4219
         *             If anything goes wrong with networking.
4220
         * @throws ProcessException
4221
         *             If SpiNNaker rejects a message.
4222
         * @throws InterruptedException
4223
         *             If the communications were interrupted.
4224
         */
4225
        @ParallelSafeWithCare
4226
        void loadApplicationRouterTables(@Valid CoreSubsets monitorCores)
4227
                        throws IOException, ProcessException, InterruptedException;
4228

4229
        /**
4230
         * Load the (previously configured) system multicast router tables. The
4231
         * application's router tables <em>must</em> have been previously
4232
         * {@linkplain #saveApplicationRouterTables(CoreSubsets) saved}.
4233
         *
4234
         * @param monitorCores
4235
         *            The coordinates of some monitor cores; the routers on those
4236
         *            chips will have their multicast router tables loaded.
4237
         * @throws IOException
4238
         *             If anything goes wrong with networking.
4239
         * @throws ProcessException
4240
         *             If SpiNNaker rejects a message.
4241
         * @throws InterruptedException
4242
         *             If the communications were interrupted.
4243
         */
4244
        @ParallelSafeWithCare
4245
        void loadSystemRouterTables(@Valid CoreSubsets monitorCores)
4246
                        throws IOException, ProcessException, InterruptedException;
4247

4248
        /**
4249
         * Create a connection to a particular instance of SCAMP. Note that this
4250
         * connection is a new connection; it is not a previously existing
4251
         * connection.
4252
         *
4253
         * @param chip
4254
         *            The location of the chip on the board with this remoteHost
4255
         * @param addr
4256
         *            The IP address of the SpiNNaker board to send messages to.
4257
         * @return The SCP connection to use. It is up to the caller to arrange for
4258
         *         this to be closed at the right time.
4259
         * @throws IOException
4260
         *             If anything goes wrong with socket setup.
4261
         */
4262
        @ParallelSafe
4263
        @MustBeClosed
4264
        @UsedInJavadocOnly(Constants.class)
4265
        SCPConnection createScpConnection(ChipLocation chip, InetAddress addr)
4266
                        throws IOException;
4267
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc