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

SpiNNakerManchester / JavaSpiNNaker / 14556105732

21 Mar 2025 04:17PM UTC coverage: 38.266%. Remained the same
14556105732

push

github

web-flow
Merge pull request #1222 from SpiNNakerManchester/more_spalloc_rest_calls

More spalloc rest calls

70 of 815 new or added lines in 33 files covered. (8.59%)

1689 existing lines in 35 files now uncovered.

9193 of 24024 relevant lines covered (38.27%)

1.15 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/protocols/NoDropPacketContext.java
1
/*
2
 * Copyright (c) 2019 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.protocols;
17

18
import static org.slf4j.LoggerFactory.getLogger;
19
import static uk.ac.manchester.spinnaker.messages.model.CPUState.RUNNING;
20

21
import java.io.IOException;
22
import java.util.List;
23
import java.util.stream.Stream;
24

25
import org.slf4j.Logger;
26

27
import com.google.errorprone.annotations.MustBeClosed;
28

29
import uk.ac.manchester.spinnaker.machine.ChipLocation;
30
import uk.ac.manchester.spinnaker.machine.CoreSubsets;
31
import uk.ac.manchester.spinnaker.machine.HasCoreLocation;
32
import uk.ac.manchester.spinnaker.messages.model.ReinjectionStatus;
33
import uk.ac.manchester.spinnaker.messages.model.RouterTimeout;
34
import uk.ac.manchester.spinnaker.transceiver.ProcessException;
35
import uk.ac.manchester.spinnaker.transceiver.TransceiverInterface;
36

37
/**
38
 * A context class that can disable dropping of packets on the SpiNNaker on-chip
39
 * network. <em>Use very carefully indeed!</em> A network that can't drop
40
 * packets is a network that can deadlock. It is not believed safe to use this
41
 * class on more than one board at a time, and it is definitely not safe to do
42
 * anything else than data transfers while the context is set.
43
 *
44
 * @author Donal Fellows
45
 * @author Alan Stokes
46
 */
47
public class NoDropPacketContext implements AutoCloseable {
UNCOV
48
        private static final Logger log = getLogger(NoDropPacketContext.class);
×
49

50
        private ReinjectionStatus lastStatus;
51

52
        private final CoreSubsets monitorCores;
53

54
        private final TransceiverInterface txrx;
55

56
        private final ChipLocation firstChip;
57

58
        private final CoreSubsets gatherers;
59

60
        /**
61
         * Standard short timeout for emergency routing.
62
         */
UNCOV
63
        private static final RouterTimeout SHORT_TIMEOUT = new RouterTimeout(1, 1);
×
64

UNCOV
65
        private static final RouterTimeout LONG_TIMEOUT = new RouterTimeout(14, 14);
×
66

UNCOV
67
        private static final RouterTimeout TEMP_TIMEOUT = new RouterTimeout(15, 4);
×
68

UNCOV
69
        private static final RouterTimeout ZERO_TIMEOUT = new RouterTimeout(0, 0);
×
70

71
        /**
72
         * Create a no-drop-packets context. This can manage multiple boards at
73
         * once, but it is <em>recommended</em> that only a single board be handled
74
         * by a context.
75
         *
76
         * @param txrx
77
         *            The transceiver to use for talking to SpiNNaker.
78
         * @param monitorCores
79
         *            The extra monitor cores on the SpiNNaker system that control
80
         *            the routers. These must be on the same board as one of the
81
         *            gatherers; this is not checked.
82
         * @param gatherers
83
         *            The gatherer cores on the SpiNNaker system that supports the
84
         *            multicast router control API.
85
         * @throws IOException
86
         *             If communications fail.
87
         * @throws ProcessException
88
         *             If SCAMP or an extra monitor rejects a message.
89
         * @throws InterruptedException
90
         *             If communications are interrupted.
91
         */
92
        @MustBeClosed
93
        public NoDropPacketContext(TransceiverInterface txrx,
94
                        CoreSubsets monitorCores, CoreSubsets gatherers)
95
                        throws IOException, ProcessException, InterruptedException {
×
96
                this.txrx = txrx;
×
UNCOV
97
                this.monitorCores = monitorCores;
×
98
                // Store the last reinjection status for resetting
99
                // NOTE: This assumes the status is the same on all cores
100
                var firstCore = monitorCores.first().orElseThrow();
×
101
                firstChip = firstCore.asChipLocation();
×
102
                lastStatus = txrx.getReinjectionStatus(firstCore);
×
103
                this.gatherers = gatherers;
×
UNCOV
104
                log.info(
×
105
                                "switching board at {} ({} monitor cores) to "
106
                                                + "non-drop mode (saved status: {})",
UNCOV
107
                                firstChip, monitorCores.size(), lastStatus);
×
108
                try {
109
                        // Set to not inject dropped packets
UNCOV
110
                        txrx.setReinjection(monitorCores, false);
×
111
                        // Clear any outstanding packets from reinjection
UNCOV
112
                        txrx.clearReinjectionQueues(gatherers);
×
113
                        // Set time outs
114
                        txrx.setReinjectionEmergencyTimeout(gatherers, SHORT_TIMEOUT);
×
115
                        txrx.setReinjectionTimeout(gatherers, LONG_TIMEOUT);
×
116
                } catch (IOException | ProcessException e) {
×
UNCOV
117
                        log.error("failed to switch board at {} to non-drop mode",
×
118
                                        firstChip, e);
119
                        throw e;
×
120
                }
×
UNCOV
121
        }
×
122

123
        /**
124
         * Create a no-drop-packets context. This can manage multiple boards at
125
         * once, but it is <em>recommended</em> that only a single board be handled
126
         * by a context.
127
         *
128
         * @param txrx
129
         *            The transceiver to use for talking to SpiNNaker.
130
         * @param monitorCores
131
         *            The extra monitor cores on the SpiNNaker system that control
132
         *            the routers. These must be on the same board as one of the
133
         *            gatherers; this is not checked.
134
         * @param gatherers
135
         *            The gatherer cores on the SpiNNaker system that supports the
136
         *            multicast router control API.
137
         * @throws IOException
138
         *             If communications fail.
139
         * @throws ProcessException
140
         *             If SCAMP or an extra monitor rejects a message.
141
         * @throws InterruptedException
142
         *             If communications are interrupted.
143
         */
144
        @MustBeClosed
145
        public NoDropPacketContext(TransceiverInterface txrx,
146
                        List<? extends HasCoreLocation> monitorCores,
147
                        List<? extends HasCoreLocation> gatherers)
148
                                        throws IOException, ProcessException, InterruptedException {
NEW
149
                this(txrx, convertToCoreSubset(monitorCores),
×
NEW
150
                                convertToCoreSubset(gatherers));
×
UNCOV
151
        }
×
152

153
        /**
154
         * Create a no-drop-packets context. This can manage multiple boards at
155
         * once, but it is <em>recommended</em> that only a single board be handled
156
         * by a context.
157
         *
158
         * @param txrx
159
         *            The transceiver to use for talking to SpiNNaker.
160
         * @param monitorCores
161
         *            The extra monitor cores on the SpiNNaker system that control
162
         *            the routers. These must be on the same board as one of the
163
         *            gatherers; this is not checked.
164
         * @param gatherers
165
         *            The gatherer cores on the SpiNNaker system that supports the
166
         *            multicast router control API.
167
         * @throws IOException
168
         *             If communications fail.
169
         * @throws ProcessException
170
         *             If SCAMP or an extra monitor rejects a message.
171
         * @throws InterruptedException
172
         *             If communications are interrupted.
173
         */
174
        @MustBeClosed
175
        public NoDropPacketContext(TransceiverInterface txrx,
176
                        Stream<? extends HasCoreLocation> monitorCores,
177
                        Stream<? extends HasCoreLocation> gatherers)
178
                                        throws IOException, ProcessException, InterruptedException {
NEW
179
                this(txrx, convertToCoreSubset(monitorCores),
×
UNCOV
180
                                convertToCoreSubset(gatherers));
×
UNCOV
181
        }
×
182

183
        private static CoreSubsets convertToCoreSubset(
184
                        List<? extends HasCoreLocation> coreLocationList) {
UNCOV
185
                var cores = new CoreSubsets();
×
UNCOV
186
                for (var coreLocation : coreLocationList) {
×
UNCOV
187
                        cores.addCore(coreLocation.asCoreLocation());
×
UNCOV
188
                }
×
UNCOV
189
                return cores;
×
190
        }
191

192
        private static CoreSubsets convertToCoreSubset(
193
                        Stream<? extends HasCoreLocation> coreLocations) {
194
                var cores = new CoreSubsets();
×
UNCOV
195
                coreLocations.forEach(loc -> cores.addCore(loc.asCoreLocation()));
×
196
                return cores;
×
197
        }
198

199
        /**
200
         * Restore the SpiNNaker board (or boards, for the brave) to its normal
201
         * operating mode.
202
         *
203
         * @throws IOException
204
         *             If communications fail.
205
         * @throws ProcessException
206
         *             If SCAMP or an extra monitor rejects a message.
207
         * @throws InterruptedException
208
         *             If communications are interrupted.
209
         */
210
        @Override
211
        public void close()
212
                        throws IOException, ProcessException, InterruptedException {
UNCOV
213
                log.info("switching board at {} to standard mode", firstChip);
×
UNCOV
214
                quietlySetTemporaryTimeouts();
×
215

216
                try {
217
                        // Do the real reset
UNCOV
218
                        txrx.setReinjectionTimeout(gatherers, lastStatus);
×
219
                        txrx.setReinjectionEmergencyTimeout(gatherers, lastStatus);
×
220
                        txrx.setReinjection(monitorCores, lastStatus);
×
221
                        log.debug("switched board at {} to standard mode", firstChip);
×
222
                        return;
×
UNCOV
223
                } catch (IOException | ProcessException | InterruptedException
×
224
                                | RuntimeException e) {
225
                        log.error("error resetting router timeouts", e);
×
226
                        throw e;
×
227
                } catch (Exception e) {
×
228
                        log.error("error resetting router timeouts", e);
×
229
                }
230
                try {
UNCOV
231
                        log.error("checking to see of the cores are OK...");
×
UNCOV
232
                        var errorCores = txrx.getCoresNotInState(monitorCores, RUNNING);
×
UNCOV
233
                        if (!errorCores.isEmpty()) {
×
UNCOV
234
                                log.error("cores in an unexpected state: {}", errorCores);
×
235
                        }
UNCOV
236
                } catch (Exception e) {
×
UNCOV
237
                        log.error("couldn't get core state", e);
×
UNCOV
238
                }
×
UNCOV
239
        }
×
240

241
        /**
242
         * This sets some temporary timeouts so that we can use SDP more safely. We
243
         * hope. Failures are ignored; if they happen, failures when setting the
244
         * real values are also likely and we'll get error messages then.
245
         */
246
        private void quietlySetTemporaryTimeouts() {
247
                try {
UNCOV
248
                        txrx.setReinjectionTimeout(gatherers, TEMP_TIMEOUT);
×
UNCOV
249
                } catch (Exception e) {
×
UNCOV
250
                        log.debug("failed to reset reinjection timeout", e);
×
UNCOV
251
                }
×
252
                try {
UNCOV
253
                        txrx.setReinjectionEmergencyTimeout(gatherers, ZERO_TIMEOUT);
×
UNCOV
254
                } catch (Exception e) {
×
UNCOV
255
                        log.debug("failed to reset emergency reinjection timeout", e);
×
UNCOV
256
                }
×
UNCOV
257
        }
×
258
}
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