SpiNNFrontEndCommon  7.4.2
Common support code for user-facing front end systems.
chip_power_monitor.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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 
26 
27 #include <spin1_api.h>
28 #include <spinn_extra.h>
29 #include <simulation.h>
30 #include <spinnaker.h>
31 #include <recording.h>
32 #include <debug.h>
33 #include <data_specification.h>
34 
37 #define NUM_RANDOM_BITS 12
38 
40 enum {
41  SYSTEM = 0,
42  CONFIG = 1,
43  RECORDING = 2
44 };
45 
47 struct sample_params {
49  uint32_t count_limit;
51  uint32_t frequency;
52 };
53 
54 struct recording {
55  uint32_t time;
56  uint32_t core_counters[NUM_CPUS];
57 };
58 
62 static const uint32_t RECORDING_CHANNEL_ID = 0;
63 
65 enum {
66  TIMER = 0,
67  SDP = 1,
68  DMA = 2
69 };
70 
72 static uint32_t simulation_ticks = 0;
74 static uint32_t infinite_run = 0;
76 static uint32_t time;
78 static uint32_t timer = 0;
79 
81 static struct recording recording;
83 static uint32_t sample_count;
85 static uint32_t sample_count_limit;
87 static uint32_t recording_flags;
89 static uint32_t sample_frequency;
90 
98 static inline uint32_t get_sample(void) {
100 }
101 
106 static inline uint32_t get_random_busy(void) {
107  return (spin1_rand() >> 4) & ((1 << NUM_RANDOM_BITS) - 1);
108 }
109 
112 static inline void record_aggregate_sample(void) {
113  recording.time = time;
116 }
117 
120 static inline void reset_core_counters(void) {
121  for (uint32_t i = 0 ; i < NUM_CPUS ; i++) {
122  recording.core_counters[i] = 0;
123  }
124  sample_count = 0;
125 }
126 
128 static inline void rescale_sim_ticks(void) {
130  log_info("resume total_sim_ticks = %d timer %d sample_frequency %d time %d",
132 }
133 
135 static void resume_callback(void) {
136  // change simulation ticks to be a number related to sampling frequency
137  if (time == UINT32_MAX) {
138  log_debug("resume_skipped as time still zero");
139  } else {
141  // Also rescale time appropriately
143  time++;
145  // Subtract 1 again now so that this starts at the "correct" value on the next tick
146  time--;
147  log_info("resume total_sim_ticks = %d timer %d sample_frequency %d time %d",
149  recording_reset();
150  log_debug("resume_callback");
151  }
152 }
153 
158 static inline void count_core_states(void) {
159  uint32_t sample = get_sample();
160 
161  for (uint32_t i = 0, j = 1 ; i < NUM_CPUS ; i++, j <<= 1) {
162  if (!(sample & j)) {
163  recording.core_counters[i]++;
164  }
165  }
166 }
167 
171 static void sample_in_slot(UNUSED uint unused0, UNUSED uint unused1) {
172  time++;
173 
174  // handle the situation when the first time update is sent
175  if (time == 0) {
177  }
178  // check if the simulation has run to completion
179  if (simulation_is_finished()) {
181 
182  if (sample_count > 0) {
184  }
185 
187 
188  // Invert the time calculation so that any time read is correct
191 
192  return;
193  }
194 
195  uint32_t count = ++sample_count;
196  uint32_t offset = get_random_busy();
197  while (offset --> 0) {
198  // Do nothing
199  }
200 
202  if (count >= sample_count_limit) {
205  }
206 }
207 
215  log_info("count limit %d", sample_count_limit);
216  log_info("sample frequency %d", sample_frequency);
217  return true;
218 }
219 
222 static bool initialize(void) {
223  data_specification_metadata_t *ds_regions =
225  if (!data_specification_read_header(ds_regions)) {
226  return false;
227  }
230  APPLICATION_NAME_HASH, &timer, &simulation_ticks,
231  &infinite_run, &time, SDP, DMA)) {
232  return false;
233  }
234  if (!read_parameters(
235  data_specification_get_region(CONFIG, ds_regions))) {
236  return false;
237  }
238 
239  void *recording_region =
241  return recording_initialize(&recording_region, &recording_flags);
242 }
243 
248 void c_main(void) {
249  if (!initialize()) {
250  log_error("failed to initialise");
251  rt_error(RTE_SWERR);
252  }
253 
255 
256  spin1_set_timer_tick(sample_frequency);
257  spin1_callback_on(TIMER_TICK, sample_in_slot, TIMER);
258  time = UINT32_MAX;
259  simulation_run();
260 }
static bool initialize(void)
Initialises the program.
@ TIMER
The timer callback is highest priority.
@ DMA
DMA processing is lowest priority.
@ SDP
Responding to communications from host is next highest.
static void sample_in_slot(uint unused0, uint unused1)
Called to actually record a sample.
static uint32_t timer
The main simulation time period.
static uint32_t sample_count
How many samples have we done so far within this aggregate step?
static uint32_t simulation_ticks
The main simulation tick.
static uint32_t get_random_busy(void)
Computes a random value used to break up chance periodicities in sampling.
static uint32_t sample_count_limit
The number of samples to aggregate per recording entry.
static bool read_parameters(struct sample_params *sample_params)
Reads the configuration of the application out of the configuration region.
static void reset_core_counters(void)
Resets the state of the core_counters and the sample_count variables to zero.
static uint32_t sample_frequency
The frequency with which we sample the execution state of all cores.
@ SYSTEM
The system data region ID.
@ CONFIG
The configuration region ID.
@ RECORDING
The recorded data region ID.
#define NUM_RANDOM_BITS
static uint32_t get_sample(void)
Read which cores on the chip are asleep right now.
static void rescale_sim_ticks(void)
Change simulation ticks to be a number related to sampling frequency.
static uint32_t recording_flags
General recording flags. (Unused by this code.)
uint32_t count_limit
The number of samples to aggregate per recording entry.
static uint32_t infinite_run
Whether we are running "forever".
void c_main(void)
The application entry point.
uint32_t frequency
The fundamental sampling frequency.
static void count_core_states(void)
Accumulate a count of how active each core on the current chip is. The counter for the core is increm...
static const uint32_t RECORDING_CHANNEL_ID
The recording channel we use.
static void record_aggregate_sample(void)
Synchronously records the current contents of the core_counters to the recording region.
static uint32_t time
Our internal notion of time.
static void resume_callback(void)
The function to call when resuming a simulation.
Describes the format of the configuration region.
Data Specification region access API.
static void * data_specification_get_region(uint32_t region, data_specification_metadata_t *ds_regions)
Gets the address of a region.
data_specification_metadata_t * data_specification_get_data_address(void)
Gets the location of the data for this core using the user0 entry of the SARK VCPU structure.
bool data_specification_read_header(data_specification_metadata_t *ds_regions)
Reads the header from the address given and checks if the parameters are of the correct values.
The central structure that the DSE writes.
SpiNNaker debug header file.
void log_error(const char *message,...)
This function logs errors. Errors usually indicate a serious fault in the program,...
void log_debug(const char *message,...)
This function logs debugging messages. This level of message is normally not printed except when the ...
void log_info(const char *message,...)
This function logs informational messages. This is the lowest level of message normally printed.
interface for recording data into "channels" on the SDRAM in a standard way, and storing buffers to b...
bool recording_initialize(void **recording_data_address, uint32_t *recording_flags)
initialises the recording of data
Definition: recording.c:161
void recording_finalise(void)
Finishes recording - should only be called if recording_flags is not 0.
Definition: recording.c:139
bool recording_record(channel_index_t channel, void *data, size_t size_bytes)
records some data into a specific recording channel.
Definition: recording.c:105
void recording_reset(void)
resets recording to the state just after initialisation
Definition: recording.c:212
Simulation Functions Header File.
void simulation_handle_pause_resume(resume_callback_t callback)
cleans up the house keeping, falls into a sync state and handles the resetting up of states as requir...
Definition: simulation.c:113
bool simulation_is_finished(void)
determine if the simulation is finished. Will also pause the simulation for resynchronisation if requ...
Definition: simulation.c:444
void simulation_ready_to_read(void)
Indicates that all data has been written and the core is going idle, so any data can now be read.
Definition: simulation.c:131
void simulation_run(void)
Starts the simulation running, returning when it is complete,.
Definition: simulation.c:108
bool simulation_initialise(address_t address, uint32_t expected_application_magic_number, uint32_t *timer_period, uint32_t *simulation_ticks_pointer, uint32_t *infinite_run_pointer, uint32_t *time_pointer, int sdp_packet_callback_priority, int dma_transfer_complete_priority)
initialises the simulation interface which involves:
Definition: simulation.c:370
Extra definitions of things on SpiNNaker chips that aren't already mentioned in spinnaker....
static volatile system_controller_t *const system_control
System controller registers.
Definition: spinn_extra.h:1801
const sc_sleep_status_t cpu_sleep
CPU sleep (awaiting interrupt) status.
Definition: spinn_extra.h:1767
uint status
ARM968 STANDBYWFI signal for each core.
Definition: spinn_extra.h:1667