sPyNNaker neural_modelling 7.1.1
Loading...
Searching...
No Matches
post_events.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 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
19#ifndef _POST_EVENTS_H_
20#define _POST_EVENTS_H_
21
22// Standard includes
23#include <stdbool.h>
24#include <stdint.h>
25
26// Include debug header for log_info etc
27#include <debug.h>
28
29//---------------------------------------
30// Macros
31//---------------------------------------
33#define MAX_POST_SYNAPTIC_EVENTS 16
34
35//---------------------------------------
36// Structures
37//---------------------------------------
47
49typedef struct {
53 uint32_t prev_time;
57 const uint32_t *next_time;
59 uint32_t num_events;
63
64//---------------------------------------
65// Inline functions
66//---------------------------------------
67
68#if LOG_LEVEL >= LOG_DEBUG
71static inline void print_event_history(const post_event_history_t *events) {
72 log_debug(" ## printing entire post event history ##");
73 for (uint32_t i = 0; i <= events->count_minus_one; i++) {
74 log_debug("post event: %u, time: %u, trace: %u",
75 i, events->times[i], events->traces[i]);
76 }
77}
78#endif
79
84 uint32_t n_neurons) {
86 spin1_malloc(n_neurons * sizeof(post_event_history_t));
87 // Check allocations succeeded
88 if (post_event_history == NULL) {
89 log_error("Unable to allocate global STDP structures - Out of DTCM: Try "
90 "reducing the number of neurons per core to fix this problem ");
91 return NULL;
92 }
93
94 // Loop through neurons
95 for (uint32_t n = 0; n < n_neurons; n++) {
96 // Add initial placeholder entry to buffer
97 post_event_history[n].times[0] = 0;
100 }
101
102 return post_event_history;
103}
104
105//---------------------------------------
112 const post_event_history_t *events, uint32_t begin_time,
113 uint32_t end_time) {
114 // Start at end event - beyond end of post-event history
115 const uint32_t count = events->count_minus_one + 1;
116 const uint32_t *end_event_time = events->times + count;
117 const uint32_t *event_time = end_event_time;
118 const post_trace_t *event_trace = events->traces + count;
119
120 post_event_window_t window;
121 do {
122 // If this event is still in the future, set it as the end
123 if (*event_time > end_time) {
124 end_event_time = event_time;
125 }
126
127 // Cache pointer to this event as potential next event and go back one
128 // event.
129 // **NOTE** next_time can be invalid
130 window.next_time = event_time--;
131 window.next_trace = event_trace--;
132
133 // Keep looping while event occurred after start of window and we
134 // haven't hit beginning of array...
135 } while (*event_time > begin_time && event_time != events->times);
136
137 // Deference event to use as previous
138 window.prev_time = *event_time;
139 window.prev_trace = *event_trace;
140 window.prev_time_valid = event_time != events->times;
141
142 // Calculate number of events
143 window.num_events = (end_event_time - window.next_time);
144
145 // Return window
146 return window;
147}
148
149//---------------------------------------
154 post_event_window_t window) {
155 // Update previous time and increment next time
156 window.prev_time = *window.next_time++;
157 window.prev_trace = *window.next_trace++;
158
159 // Time will now be valid for sure!
160 window.prev_time_valid = 1;
161
162 // Decrement remaining events
163 window.num_events--;
164 return window;
165}
166
167//---------------------------------------
172static inline void post_events_add(
173 uint32_t time, post_event_history_t *events, post_trace_t trace) {
174 if (events->count_minus_one < MAX_POST_SYNAPTIC_EVENTS - 1) {
175 // If there's still space, store time at current end
176 // and increment count minus 1
177 const uint32_t new_index = ++events->count_minus_one;
178 events->times[new_index] = time;
179 events->traces[new_index] = trace;
180 } else {
181 // Otherwise Shuffle down elements
182 // **NOTE** 1st element is always an entry at time 0
183 for (uint32_t e = 2; e < MAX_POST_SYNAPTIC_EVENTS; e++) {
184 events->times[e - 1] = events->times[e];
185 events->traces[e - 1] = events->traces[e];
186 }
187
188 // Stick new time at end
189 events->times[MAX_POST_SYNAPTIC_EVENTS - 1] = time;
190 events->traces[MAX_POST_SYNAPTIC_EVENTS - 1] = trace;
191 }
192}
193
194#if LOG_LEVEL >= LOG_DEBUG
202 uint32_t begin_time, uint32_t end_time, uint32_t delay_dendritic) {
203 log_info(" ## printing post window ##");
205 post_event_history, begin_time, end_time);
206
207 while (post_window.num_events > 0) {
208 const uint32_t delayed_post_time =
209 *post_window.next_time + delay_dendritic;
210 log_info("post spike: %u, time: %u, trace: %u",
211 post_window.num_events, delayed_post_time,
212 *post_window.next_trace);
213
214 post_window = post_events_next(post_window);
215 }
216}
217#endif
218
219#endif // _POST_EVENTS_H_
uint32_t time
The current timer tick value.
Definition c_main.c:94
void log_error(const char *message,...)
void log_debug(const char *message,...)
void log_info(const char *message,...)
static uint32_t n_neurons
The number of neurons on the core.
Definition neuron.c:45
#define MAX_POST_SYNAPTIC_EVENTS
Maximum number of post-synaptic events supported.
Definition post_events.h:33
static post_event_history_t * post_events_init_buffers(uint32_t n_neurons)
Initialise an array of post-synaptic event histories.
Definition post_events.h:83
static void print_event_history(const post_event_history_t *events)
Print a post-synaptic event history.
Definition post_events.h:71
static post_event_window_t post_events_next(post_event_window_t window)
Advance a post-synaptic event window to the next event.
static void post_events_add(uint32_t time, post_event_history_t *events, post_trace_t trace)
Add a post-synaptic event to the history.
static post_event_window_t post_events_get_window_delayed(const post_event_history_t *events, uint32_t begin_time, uint32_t end_time)
Get the post-synaptic event window.
static void print_delayed_window_events(const post_event_history_t *post_event_history, uint32_t begin_time, uint32_t end_time, uint32_t delay_dendritic)
Print the post-synaptic event history.
uint32_t num_events
The number of events.
Definition post_events.h:59
uint32_t count_minus_one
Number of events stored (minus one)
Definition post_events.h:41
uint32_t times[MAX_POST_SYNAPTIC_EVENTS]
Event times.
Definition post_events.h:43
post_trace_t prev_trace
The previous post-synaptic event trace.
Definition post_events.h:51
const uint32_t * next_time
The next post-synaptic event time.
Definition post_events.h:57
uint32_t prev_time
The previous post-synaptic event time.
Definition post_events.h:53
const post_trace_t * next_trace
The next post-synaptic event trace.
Definition post_events.h:55
uint32_t prev_time_valid
Whether the previous post-synaptic event is valid (based on time)
Definition post_events.h:61
post_trace_t traces[MAX_POST_SYNAPTIC_EVENTS]
Event traces.
Definition post_events.h:45
Trace history of post-synaptic events.
Definition post_events.h:39
Post event window description.
Definition post_events.h:49
#define NULL
static post_event_history_t * post_event_history
The history data of post-events.
static post_trace_t timing_get_initial_post_trace(void)
Get an initial post-synaptic timing trace.
The type of post-spike traces.