32#include "../common/routing_table.h"
36#define MAX_NUM_ROUTES 1023
63 .route = entry1->
route,
72static inline void _entry(
const entry_t* entry,
int index) {
79static inline int transfer_next(
int start_index,
int n_items, uint32_t cache) {
83 uint32_t next_items = n_items;
110 log_debug(
"find merge %d %d", left, index);
116 #if LOG_LEVEL >= LOG_DEBUG
127 uint32_t next_n_items = transfer_next(
remaining_index, items_to_go, 0);
128 uint32_t next_items_to_go = items_to_go - next_n_items;
130 bool dma_in_progress =
true;
131 uint32_t read_cache = 0;
132 uint32_t write_cache = 1;
133 while (items_to_go > 0) {
136 if (dma_in_progress) {
138 dma_in_progress =
false;
142 uint32_t n_items = next_n_items;
143 uint32_t cache = read_cache;
146 if (next_items_to_go > 0) {
147 next_n_items = transfer_next(next_start, next_items_to_go, write_cache);
148 next_items_to_go -= next_n_items;
149 next_start += next_n_items;
150 dma_in_progress =
true;
151 write_cache = (write_cache + 1) & 0x1;
152 read_cache = (read_cache + 1) & 0x1;
158 for (uint32_t i = 0; i < n_items; i++) {
162 if (dma_in_progress) {
170 items_to_go = next_items_to_go;
183 log_debug(
"find merge %d %d", left, index);
207 log_debug(
"merge left %d right %d", left, right);
208 while (left < right) {
211 for (
int index = left + 1; index <= right; index++) {
234 uint32_t r_tmp =
routes[i];
254 log_debug(
"index %d routes %d", index, route);
266 log_error(
"Too many different routes to compress found %d "
267 "compared to max legal of %d",
275static inline uint32_t find_route_index(uint32_t route) {
281 log_error(
"Route 0x%08x not found!", route);
302 route_offset[i] = offset;
304 route_end[i] = offset - 1;
309 uint32_t pos_index = 0;
312 while (pos < n_entries) {
317 uint32_t route_index = find_route_index(entry.
route);
320 uint32_t read_index = pos_index;
324 if (route_index == read_index) {
326 if (pos < route_offset[route_index]) {
335 uint32_t new_pos = route_offset[route_index];
336 if (new_pos >= n_entries) {
337 log_error(
"New table position %u out of range!", new_pos);
341 if (new_pos > route_end[route_index]) {
342 log_error(
"New table position %u of region %u is out of range!",
343 new_pos, route_index);
346 route_offset[route_index] += 1;
353 if (new_pos <= pos) {
357 read_index = route_index;
360 route_index = find_route_index(entry.
route);
365 if (pos == next_index_offset) {
379 volatile bool *stop_compressing) {
380 use(failed_by_malloc);
385 log_error(
"MAX_NUM_ROUTES %d != rtr_alloc_max() %d",
393 for (
int index = 0; index < table_size; index++) {
405 if (*stop_compressing) {
406 log_info(
"Stopping as asked to stop");
415 log_debug(
"do sort_table by route %u", table_size);
419 uint32_t duration = 0xFFFFFFFF - tc[
T2_COUNT];
421 log_info(
"Sorting table took %u clock cycles", duration);
422 if (*stop_compressing) {
423 log_info(
"Stopping before compression as asked to stop");
428 int max_index = table_size - 1;
431 while (left <= max_index) {
434 log_debug(
"A %u %u %u %u", left, max_index, right, left_route);
435 while ((right < table_size - 1) &&
441 log_debug(
"compress %u %u", left, right);
445 duration = 0xFFFFFFFF - tc[
T2_COUNT];
447 log_info(
"Compressing %u routes took %u", right - left + 1, duration);
450 log_error(
"Compression not possible as already found %d "
451 "entries where max allowed is %d",
456 if (*stop_compressing) {
457 log_info(
"Stopping during compression as asked to stop");
#define check(condition, message,...)
#define use(x)
This can be used to silence gcc's "-Wall -Wextra" warnings about failure to use function arguments.
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.
API for routing table minimisation.
bool standalone(void)
Whether this is a standalone compressor.
static bool find_merge(int left, int index)
Finds if two routes can be merged.
static void sort_routes(void)
Implementation of insertion sort for routes based on frequency.
static entry_t merge(const entry_t *entry1, const entry_t *entry2)
Merges a single pair of route entries.
static uint32_t routes[MAX_NUM_ROUTES]
Table of routes being produced.
static uint32_t write_index
The index of the next place in the compressed table to write a route.
static int remaining_index
The index of the first route after the ones being compressed in this step.
#define MAX_NUM_ROUTES
Absolute maximum number of routes that we may produce.
bool minimise_run(int target_length, bool *failed_by_malloc, volatile bool *stop_compressing)
Implementation of minimise()
static bool find_merge_optimised(int left, int index)
Finds if two routes can be merged.
static bool update_frequency(int index)
Computes route histogram.
static void compress_by_route(int left, int right)
Does the actual routing compression.
static void cancel_dmas(void)
Cancel any outstanding DMA transfers.
static entry_t route_cache[2][MAX_NUM_ROUTES]
Space for caching routes while going through them.
static uint32_t routes_count
Count of unique routes (as opposed to routes with just different key_masks).
static uint32_t routes_frequency[MAX_NUM_ROUTES]
Route frequency histogram.
void sort_table(void)
Implementation of insertion sort for routes based on route information.
key_mask_t key_mask
Key and mask.
uint32_t mask
Mask for the key_mask.
bool routing_table_get_entries(uint32_t start_entry, uint32_t n_entries, entry_t *output)
Gets a pointer to several entries.
static key_mask_t key_mask_merge(key_mask_t a, key_mask_t b)
Generate a new key-mask which is a combination of two other key_masks.
static void routing_table_copy_entry(int new_index, int old_index)
Copy an entry from one index to another.
uint32_t route
Routing direction.
int routing_table_get_n_entries(void)
Get the number of entries in the routing table.
static bool key_mask_intersect(key_mask_t a, key_mask_t b)
Determine if two key_masks would match any of the same keys.
entry_t * routing_table_get_entry(uint32_t entry_id_to_find)
Gets a pointer to where this entry is stored.
static void routing_table_put_entry(const entry_t *entry, int index)
Write an entry to a specific index.
uint32_t key
Key for the key_mask.
void routing_table_wait_for_last_transfer(void)
Waits for the last transfer from routing_table_get_entries to complete.
void routing_table_remove_from_size(int size_to_remove)
updates table stores accordingly.
uint32_t source
Source of packets arriving at this entry.
Holds data for a routing table entry.
void rt_error(uint code,...)