-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
snRuntime: Add
alloc_v2
functions and minor changes (#186)
* snRuntime: Add `snrt_inter_cluster_barrier()` function` * snRuntime: Add private L1 alloc pointers and heap bound checks * snRuntime: Add `snrt_compute_core_local_ptr()` function * sw: Move floating-point types to snRuntime * snRuntime: Add `snrt_l1_update_next_v2()` used to free memory * snRuntime: Add `snrt_cluster_is_last_compute_core()` function
- Loading branch information
Showing
31 changed files
with
267 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
// Copyright 2023 ETH Zurich and University of Bologna. | ||
// Copyright 2024 ETH Zurich and University of Bologna. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
static inline void snrt_exit(int exit_code); | ||
inline void snrt_exit(int exit_code); | ||
|
||
inline uint32_t snrt_cls_base_addr(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2023 ETH Zurich and University of Bologna. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
__thread snrt_allocator_t l1_allocator_v2; | ||
|
||
extern void *snrt_l1_next_v2(); | ||
|
||
extern void *snrt_l1_alloc_cluster_local(size_t size, size_t alignment); | ||
extern void *snrt_l1_alloc_compute_core_local(size_t size, size_t alignment); | ||
|
||
extern void *snrt_remote_l1_ptr(void *ptr, uint32_t src_cluster_idx, | ||
uint32_t dst_cluster_idx); | ||
|
||
extern void snrt_alloc_init_v2(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright 2023 ETH Zurich and University of Bologna. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
extern __thread snrt_allocator_t l1_allocator_v2; | ||
|
||
inline snrt_allocator_t *snrt_l1_allocator_v2() { return &l1_allocator_v2; } | ||
|
||
inline void *snrt_l1_next_v2() { return (void *)snrt_l1_allocator_v2()->next; } | ||
|
||
/** | ||
* @brief Override the L1 allocator next pointer | ||
*/ | ||
inline void snrt_l1_update_next_v2(void *next) { | ||
snrt_l1_allocator_v2()->next = (uint32_t)next; | ||
} | ||
|
||
// Check that allocation doesn't exceed allocator bounds, and raise an | ||
// exception otherwise | ||
inline void snrt_l1_alloc_check_bounds() { | ||
if (snrt_l1_allocator_v2()->next > snrt_l1_allocator_v2()->end) | ||
asm volatile("ecall \n"); | ||
} | ||
|
||
// Dynamically allocate space for a variable of size `size` in the cluster's L1 | ||
// memory. This function should be invoked by every core in a cluster. Every | ||
// core receives a pointer to the allocated variable. | ||
inline void *snrt_l1_alloc_cluster_local(size_t size, const size_t alignment) { | ||
snrt_l1_allocator_v2()->next = | ||
ALIGN_UP(snrt_l1_allocator_v2()->next, alignment); | ||
void *retval = snrt_l1_next_v2(); | ||
snrt_l1_allocator_v2()->next += size; | ||
snrt_l1_alloc_check_bounds(); | ||
return retval; | ||
} | ||
|
||
// Dynamically allocate space for N variables of size `size` in the cluster's | ||
// L1 memory, N being the number of compute cores in the cluster. This function | ||
// should be invoked by every core in a cluster. Every compute core receives a | ||
// pointer to a unique variable among the N which have been allocated. The | ||
// return value for the DM core is undefined. | ||
inline void *snrt_l1_alloc_compute_core_local(size_t size, | ||
const size_t alignment) { | ||
snrt_l1_allocator_v2()->next = | ||
ALIGN_UP(snrt_l1_allocator_v2()->next, alignment); | ||
void *retval = snrt_l1_next_v2() + size * snrt_cluster_core_idx(); | ||
snrt_l1_allocator_v2()->next += size * snrt_cluster_compute_core_num(); | ||
snrt_l1_alloc_check_bounds(); | ||
return retval; | ||
} | ||
|
||
// Takes a pointer to a variable allocated using | ||
// `snrt_l1_alloc_compute_core_local` and returns a pointer to the same | ||
// variable allocated by another core, as specified by `core_idx`. | ||
// The `size` argument should be the same used during allocation. | ||
inline void *snrt_compute_core_local_ptr(void *ptr, uint32_t core_idx, | ||
size_t size) { | ||
size_t offset = (core_idx - snrt_cluster_core_idx()) * size; | ||
return (void *)((uintptr_t)ptr + offset); | ||
} | ||
|
||
// Takes a pointer to a variable in the source cluster's L1 memory and returns | ||
// a pointer to the same offset in the destination cluster's L1 memory. | ||
inline void *snrt_remote_l1_ptr(void *ptr, uint32_t src_cluster_idx, | ||
uint32_t dst_cluster_idx) { | ||
return (void *)((uintptr_t)ptr + | ||
(dst_cluster_idx - src_cluster_idx) * SNRT_CLUSTER_OFFSET); | ||
} | ||
|
||
inline void snrt_alloc_init_v2() { | ||
// Calculate end address of the heap. The top of the TCDM address space is | ||
// reserved for the cluster-local storage (CLS) and the stack of every | ||
// core. We further provision a safety margin of 128B. The rest of the | ||
// TCDM is reserved for the heap. | ||
uint32_t heap_end_addr = snrt_cls_base_addr(); | ||
heap_end_addr -= (1 << SNRT_LOG2_STACK_SIZE) * snrt_cluster_core_num(); | ||
heap_end_addr -= 128; | ||
// Initialize L1 allocator | ||
snrt_l1_allocator_v2()->base = | ||
ALIGN_UP(snrt_l1_start_addr(), MIN_CHUNK_SIZE); | ||
snrt_l1_allocator_v2()->end = heap_end_addr; | ||
snrt_l1_allocator_v2()->next = snrt_l1_allocator_v2()->base; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2024 ETH Zurich and University of Bologna. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifdef OPENOCD_SEMIHOSTING | ||
#include "openocd.h" | ||
#endif | ||
|
||
#ifdef SNRT_CRT0_EXIT | ||
inline void snrt_exit_default(int exit_code) { | ||
exit_code = snrt_global_all_to_all_reduction(exit_code); | ||
#ifdef OPENOCD_SEMIHOSTING | ||
if (snrt_global_core_idx() == 0) __ocd_semihost_exit(exit_code); | ||
#else | ||
if (snrt_global_core_idx() == 0) | ||
*(snrt_exit_code_destination()) = (exit_code << 1) | 1; | ||
#endif | ||
} | ||
#ifndef SNRT_CRT0_ALTERNATE_EXIT | ||
inline void snrt_exit(int exit_code) { snrt_exit_default(exit_code); } | ||
#endif | ||
#endif | ||
|
||
#ifdef SNRT_INIT_CLS | ||
inline uint32_t snrt_cls_base_addr() { | ||
extern volatile uint32_t __cdata_start, __cdata_end; | ||
extern volatile uint32_t __cbss_start, __cbss_end; | ||
uint32_t cdata_size = ((uint32_t)&__cdata_end) - ((uint32_t)&__cdata_start); | ||
uint32_t cbss_size = ((uint32_t)&__cbss_end) - ((uint32_t)&__cbss_start); | ||
uint32_t l1_end_addr = SNRT_TCDM_START_ADDR + | ||
snrt_cluster_idx() * SNRT_CLUSTER_OFFSET + | ||
SNRT_TCDM_SIZE; | ||
return l1_end_addr - cdata_size - cbss_size; | ||
} | ||
#endif |
Oops, something went wrong.