-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add linked-list kernel. Auto-flush L1D$ when finish executing.
- Loading branch information
Showing
9 changed files
with
638 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ _snrt_exit: | |
ori t0, t0, 1 | ||
la t1, tohost | ||
sw t0, 0(t1) | ||
call l1d_flush | ||
1: ret | ||
|
||
# HTIF sections | ||
|
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,77 @@ | ||
// Copyright 2025 ETH Zurich and University of Bologna. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// This file was generated automatically. | ||
|
||
#include "layer.h" | ||
|
||
int N = 64; | ||
|
||
node_t nodes[64] __attribute__((section(".data"))) = { | ||
{.payload = {.id = 23, .data = (double)71.063544}, .next = NULL}, | ||
{.payload = {.id = 25, .data = (double)73.296733}, .next = NULL}, | ||
{.payload = {.id = 7, .data = (double)-23.974755}, .next = NULL}, | ||
{.payload = {.id = 22, .data = (double)-9.31794}, .next = NULL}, | ||
{.payload = {.id = 45, .data = (double)66.822085}, .next = NULL}, | ||
{.payload = {.id = 33, .data = (double)-67.469181}, .next = NULL}, | ||
{.payload = {.id = 19, .data = (double)-28.94586}, .next = NULL}, | ||
{.payload = {.id = 59, .data = (double)34.035035}, .next = NULL}, | ||
{.payload = {.id = 46, .data = (double)40.364063}, .next = NULL}, | ||
{.payload = {.id = 9, .data = (double)36.709533}, .next = NULL}, | ||
{.payload = {.id = 40, .data = (double)-85.719498}, .next = NULL}, | ||
{.payload = {.id = 18, .data = (double)26.995658}, .next = NULL}, | ||
{.payload = {.id = 42, .data = (double)6.827975}, .next = NULL}, | ||
{.payload = {.id = 31, .data = (double)-51.037815}, .next = NULL}, | ||
{.payload = {.id = 16, .data = (double)-7.547958}, .next = NULL}, | ||
{.payload = {.id = 21, .data = (double)-46.010435}, .next = NULL}, | ||
{.payload = {.id = 36, .data = (double)85.078236}, .next = NULL}, | ||
{.payload = {.id = 41, .data = (double)37.632392}, .next = NULL}, | ||
{.payload = {.id = 29, .data = (double)-56.076965}, .next = NULL}, | ||
{.payload = {.id = 20, .data = (double)-35.143453}, .next = NULL}, | ||
{.payload = {.id = 11, .data = (double)53.662716}, .next = NULL}, | ||
{.payload = {.id = 50, .data = (double)-88.81241}, .next = NULL}, | ||
{.payload = {.id = 39, .data = (double)64.360519}, .next = NULL}, | ||
{.payload = {.id = 48, .data = (double)61.00916}, .next = NULL}, | ||
{.payload = {.id = 3, .data = (double)-19.767043}, .next = NULL}, | ||
{.payload = {.id = 30, .data = (double)-86.762279}, .next = NULL}, | ||
{.payload = {.id = 24, .data = (double)82.627225}, .next = NULL}, | ||
{.payload = {.id = 55, .data = (double)13.43601}, .next = NULL}, | ||
{.payload = {.id = 4, .data = (double)43.582854}, .next = NULL}, | ||
{.payload = {.id = 57, .data = (double)-57.474691}, .next = NULL}, | ||
{.payload = {.id = 54, .data = (double)-0.153748}, .next = NULL}, | ||
{.payload = {.id = 49, .data = (double)76.936631}, .next = NULL}, | ||
{.payload = {.id = 10, .data = (double)28.570374}, .next = NULL}, | ||
{.payload = {.id = 0, .data = (double)-71.425682}, .next = NULL}, | ||
{.payload = {.id = 60, .data = (double)-72.073936}, .next = NULL}, | ||
{.payload = {.id = 28, .data = (double)48.997796}, .next = NULL}, | ||
{.payload = {.id = 44, .data = (double)7.795458}, .next = NULL}, | ||
{.payload = {.id = 26, .data = (double)49.402762}, .next = NULL}, | ||
{.payload = {.id = 52, .data = (double)-14.313235}, .next = NULL}, | ||
{.payload = {.id = 12, .data = (double)16.706585}, .next = NULL}, | ||
{.payload = {.id = 35, .data = (double)-27.600711}, .next = NULL}, | ||
{.payload = {.id = 53, .data = (double)99.465156}, .next = NULL}, | ||
{.payload = {.id = 38, .data = (double)-72.333651}, .next = NULL}, | ||
{.payload = {.id = 32, .data = (double)-1.296833}, .next = NULL}, | ||
{.payload = {.id = 58, .data = (double)51.156432}, .next = NULL}, | ||
{.payload = {.id = 13, .data = (double)72.220582}, .next = NULL}, | ||
{.payload = {.id = 51, .data = (double)-69.431736}, .next = NULL}, | ||
{.payload = {.id = 62, .data = (double)-68.0036}, .next = NULL}, | ||
{.payload = {.id = 2, .data = (double)36.096243}, .next = NULL}, | ||
{.payload = {.id = 27, .data = (double)19.281806}, .next = NULL}, | ||
{.payload = {.id = 37, .data = (double)-23.046538}, .next = NULL}, | ||
{.payload = {.id = 5, .data = (double)19.177686}, .next = NULL}, | ||
{.payload = {.id = 34, .data = (double)-6.390022}, .next = NULL}, | ||
{.payload = {.id = 56, .data = (double)-49.717176}, .next = NULL}, | ||
{.payload = {.id = 43, .data = (double)10.645179}, .next = NULL}, | ||
{.payload = {.id = 6, .data = (double)88.486172}, .next = NULL}, | ||
{.payload = {.id = 61, .data = (double)36.056682}, .next = NULL}, | ||
{.payload = {.id = 8, .data = (double)-77.089651}, .next = NULL}, | ||
{.payload = {.id = 63, .data = (double)76.95769}, .next = NULL}, | ||
{.payload = {.id = 15, .data = (double)50.17556}, .next = NULL}, | ||
{.payload = {.id = 17, .data = (double)53.719747}, .next = NULL}, | ||
{.payload = {.id = 47, .data = (double)-31.964905}, .next = NULL}, | ||
{.payload = {.id = 1, .data = (double)-41.299974}, .next = NULL}, | ||
{.payload = {.id = 14, .data = (double)-68.368449}, .next = NULL}, | ||
}; | ||
|
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,160 @@ | ||
// Copyright 2020 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 | ||
|
||
#include <stdint.h> | ||
|
||
typedef enum { FP64 = 8, FP32 = 4, FP16 = 2, FP8 = 1 } precision_t; | ||
|
||
/** | ||
* @struct gemm_layer_struct | ||
* @brief This structure contains all parameters necessary for GEMM. | ||
* @var gemm_layer_struct::M | ||
* Dimension of matrix product MxK * KxN | ||
* @var gemm_layer_struct::M_p | ||
* M divided by number of compute cores | ||
* @var gemm_layer_struct::N | ||
* Dimension of matrix product MxK * KxN | ||
* @var gemm_layer_struct::K | ||
* Dimension of matrix product MxK * KxN | ||
* @var gemm_layer_struct::TA | ||
* Transpose matrix A | ||
* @var gemm_layer_struct::TB | ||
* Transpose matrix B | ||
* @var gemm_layer_struct::TILE_M | ||
* Tile factor across M dimension | ||
* @var gemm_layer_struct::TILE_N | ||
* Tile factor across N dimension | ||
* @var gemm_layer_struct::TILE_K | ||
* Tile factor across K dimension | ||
* @var gemm_layer_struct::A | ||
* Pointer to matrix A | ||
* @var gemm_layer_struct::B | ||
* Pointer to matrix B | ||
* @var gemm_layer_struct::C | ||
* Pointer to matrix C | ||
* @var gemm_layer_struct::ALPHA | ||
* constant factor: A * B + ALPHA * C | ||
* @var gemm_layer_struct::dtype | ||
* Precision of GEMM | ||
* @var gemm_layer_struct::expand | ||
* Use expanding DOTP instructions | ||
*/ | ||
typedef struct gemm_layer_struct { | ||
uint32_t M; | ||
uint32_t M_p; | ||
uint32_t N; | ||
uint32_t K; | ||
|
||
uint32_t TA; | ||
uint32_t TB; | ||
|
||
uint32_t TILE_M; | ||
uint32_t TILE_N; | ||
uint32_t TILE_K; | ||
|
||
double *A; | ||
double *B; | ||
double *C; | ||
|
||
uint32_t ALPHA; | ||
|
||
precision_t dtype; | ||
uint32_t expand; | ||
} gemm_layer; | ||
|
||
/** | ||
* @struct conv_layer_struct | ||
* @brief This structure contains all parameters necessary for Convolutional | ||
* layers | ||
* @var conv_layer_struct::CO | ||
* Number of output channels | ||
* @var conv_layer_struct::CI | ||
* Number of input channels | ||
* @var conv_layer_struct::IH | ||
* Height of input feature map | ||
* @var conv_layer_struct::IW | ||
* Width of input feature map | ||
* @var conv_layer_struct::OH | ||
* Height of output feature map | ||
* @var conv_layer_struct::OW | ||
* Width of output feature map | ||
* @var conv_layer_struct::FH | ||
* Height of filter | ||
* @var conv_layer_struct::FW | ||
* Width of filter | ||
* @var conv_layer_struct::pad | ||
* Padding on all sides | ||
* @var conv_layer_struct::ifmap | ||
* Pointer to input feature map | ||
* @var conv_layer_struct::weights | ||
* Pointer to weights | ||
* @var conv_layer_struct::ofmap | ||
* Pointer to output feature map | ||
* @var conv_layer_struct::TILE_CI | ||
* Tiling factor of input channel | ||
* @var conv_layer_struct::cluster2cluster | ||
* Flag for enabling cluster 2 cluster communication | ||
* @var conv_layer_struct::im2col | ||
* Flag for enabling im2col + GEMM | ||
* @var conv_layer_struct::gamma | ||
* Pointer to gamma for BatchNorm | ||
* @var conv_layer_struct::beta | ||
* Pointer to beta for BatchNorm | ||
* @var gemm_layer_struct::dtype | ||
* Precision of Convolution layer | ||
*/ | ||
typedef struct conv_layer_struct { | ||
// CONV2D | ||
uint32_t CO; | ||
uint32_t CI; | ||
uint32_t IH; | ||
uint32_t IW; | ||
uint32_t OH; | ||
uint32_t OW; | ||
uint32_t FH; | ||
uint32_t FW; | ||
uint32_t pad; | ||
|
||
double *ifmap; | ||
double *weights; | ||
double *ofmap; | ||
|
||
uint32_t TILE_CI; | ||
uint32_t cluster2cluster; | ||
uint32_t im2col; | ||
|
||
// BATCHNORM | ||
double *gamma; | ||
double *beta; | ||
|
||
precision_t dtype; | ||
} conv_layer; | ||
|
||
/** | ||
* @struct dotp_layer_struct | ||
* @brief This structure contains all parameters necessary for DOTP | ||
* layers | ||
* @var dotp_layer_struct::M | ||
* Length of the vectors | ||
* @var gemm_layer_struct::dtype | ||
* Precision of Convolution layer | ||
*/ | ||
typedef struct dotp_layer_struct { | ||
// DOTP | ||
uint32_t M; | ||
|
||
precision_t dtype; | ||
} dotp_layer; | ||
|
||
typedef struct payload_t { | ||
int id; | ||
double data; | ||
} payload_t; | ||
|
||
typedef struct node_t { | ||
payload_t payload; | ||
struct node_t *next; | ||
} node_t; |
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,125 @@ | ||
// Copyright 2025 ETH Zurich and University of Bologna. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Author: Diyou Shen <[email protected]> | ||
|
||
#include "llist.h" | ||
|
||
|
||
node_t* createNode (int id, const double data) { | ||
node_t* newnode = (node_t* ) snrt_l3alloc(sizeof(node_t)); | ||
newnode->payload.id = id; | ||
newnode->payload.data = data; | ||
newnode->next = NULL; | ||
|
||
return newnode; | ||
} | ||
|
||
|
||
int insertNode (node_t** head, node_t* newNode) { | ||
if (newNode == NULL) { | ||
// Cannot insert a NULL node. | ||
return 1; | ||
} | ||
|
||
// If the list is empty, the new node becomes the head | ||
if (*head == NULL) { | ||
*head = newNode; | ||
return 0; | ||
} | ||
|
||
// Traverse to the end of the list and append the new node | ||
node_t* current = *head; | ||
while (current->next != NULL) { | ||
current = current->next; | ||
} | ||
current->next = newNode; | ||
newNode->next = NULL; // Ensure the new node is the last node | ||
|
||
return 0; | ||
} | ||
|
||
int deleteNode (node_t** head, int id) { | ||
if (*head == NULL) { | ||
// empty linked list | ||
return 1; | ||
} | ||
|
||
node_t* tempnode = *head; | ||
node_t* prevnode = NULL; | ||
|
||
if (tempnode->payload.id == id) { | ||
*head = tempnode->next; | ||
// In theory we should free this node, but currently we don't have this function support | ||
return 0; | ||
} | ||
|
||
|
||
while (tempnode != NULL && tempnode->payload.id != id) { | ||
prevnode = tempnode; | ||
tempnode = tempnode->next; | ||
} | ||
|
||
if (tempnode == NULL) { | ||
// ID is not found in the linked-list | ||
return 2; | ||
} | ||
|
||
// Remove the node | ||
prevnode->next = tempnode->next; | ||
// In theory we should free this node, but currently we don't have this function support | ||
return 0; | ||
} | ||
|
||
void sortList(node_t** head) { | ||
if (*head == NULL || (*head)->next == NULL) { | ||
// List is empty or has only one node, no sorting needed | ||
return; | ||
} | ||
|
||
// Bubble sort logic for simplicity (can be optimized if needed) | ||
int swapped; | ||
node_t *ptr1, *lptr = NULL; | ||
|
||
do { | ||
swapped = 0; | ||
ptr1 = *head; | ||
|
||
while (ptr1->next != lptr) { | ||
if (ptr1->payload.id > ptr1->next->payload.id) { | ||
// Swap the payloads | ||
payload_t temp = ptr1->payload; | ||
ptr1->payload = ptr1->next->payload; | ||
ptr1->next->payload = temp; | ||
swapped = 1; | ||
} | ||
ptr1 = ptr1->next; | ||
} | ||
lptr = ptr1; // Move the lptr marker to the last sorted node | ||
} while (swapped); | ||
} | ||
|
||
int traverseList (node_t* head) { | ||
if (head == NULL) { | ||
// List is empty | ||
return 1; | ||
} | ||
|
||
volatile node_t* tempnode = head; | ||
while (tempnode != NULL) { | ||
tempnode = tempnode->next; | ||
} | ||
} |
Oops, something went wrong.