From cfad5f95466d1d7e9c3250fff4c6348cdeacd2df Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Thu, 8 Feb 2024 15:56:39 +0100 Subject: [PATCH] Remove broken Linear layer --- sw/dnn/linear/data/datagen.py | 117 ---------------- sw/dnn/linear/data/params.json | 14 -- sw/dnn/linear/src/linear.h | 129 ------------------ sw/dnn/linear/src/main.c | 39 ------ target/snitch_cluster/sw/apps/Makefile | 1 - .../sw/apps/dnn/linear/Makefile | 12 -- target/snitch_cluster/sw/run.yaml | 1 - 7 files changed, 313 deletions(-) delete mode 100755 sw/dnn/linear/data/datagen.py delete mode 100644 sw/dnn/linear/data/params.json delete mode 100644 sw/dnn/linear/src/linear.h delete mode 100644 sw/dnn/linear/src/main.c delete mode 100644 target/snitch_cluster/sw/apps/dnn/linear/Makefile diff --git a/sw/dnn/linear/data/datagen.py b/sw/dnn/linear/data/datagen.py deleted file mode 100755 index b0a49d08c5..0000000000 --- a/sw/dnn/linear/data/datagen.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python3 -# 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 -# -# Tim Fischer -# Viviane Potocnik -# Luca Colagrande - -import argparse -import pathlib -import json5 -import sys -import os -import torch - -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -import data_utils # noqa: E402 -from data_utils import emit_license, \ - format_struct_definition, format_array_definition, \ - format_array_declaration, format_ifdef_wrapper # noqa: E402 - -torch.manual_seed(42) - -# AXI splits bursts crossing 4KB address boundaries. To minimize -# the occurrence of these splits the data should be aligned to 4KB -BURST_ALIGNMENT = 4096 - - -def golden_model(ifmap, weights, bias): - ifmap = ifmap.flatten(1) - return torch.matmul(ifmap, weights.T) + bias - - -def emit_header(**kwargs): - - out_channels = kwargs['channels']['out'] - in_height = kwargs['input_dim']['height'] - in_width = kwargs['input_dim']['width'] - prec = kwargs['prec'] - - torch_type = data_utils.torch_type_from_precision_t(prec) - ctype = data_utils.ctype_from_precision_t(prec) - - ifmap = torch.randn(in_height, in_width, requires_grad=False, dtype=torch_type) - weights = torch.randn(out_channels, in_width, requires_grad=False, dtype=torch_type) - bias = torch.randn(out_channels, requires_grad=False, dtype=torch_type) - ofmap = golden_model(ifmap, weights, bias) - - ch, ci = ifmap.shape - _, co = ofmap.shape - - ifmap_uid = 'ifmap' - weights_uid = 'weights' - bias_uid = 'bias' - ofmap_uid = 'ofmap' - - layer_cfg = { - 'CO': co, - 'CI': ci, - 'CH': ch, - 'CW': ci, - 'ifmap': ifmap_uid, - 'ofmap': ofmap_uid - } - - data_str = [emit_license()] - # Array forward declarations - data_str += [format_array_declaration(ctype, ifmap_uid, ifmap.shape)] - data_str += [format_array_declaration(ctype, weights_uid, weights.shape)] - data_str += [format_array_declaration(ctype, bias_uid, bias.shape)] - data_str += [format_array_declaration(ctype, ofmap_uid, ofmap.shape)] - # Layer struct - data_str += [format_struct_definition('linear_layer_t', 'layer', layer_cfg)] - # Array definitions - data_str += [format_array_definition(ctype, ifmap_uid, ifmap)] - data_str += [format_array_definition(ctype, weights_uid, weights)] - data_str += [format_array_definition(ctype, bias_uid, bias)] - # Golden results for BIST - result_def = format_array_definition(ctype, 'golden', ofmap) - data_str += [format_ifdef_wrapper('BIST', result_def)] - data_str = '\n\n'.join(data_str) - - return data_str - - -def main(): - - parser = argparse.ArgumentParser(description='Generate data for layernorm kernel') - parser.add_argument( - "-c", "--cfg", - type=pathlib.Path, - required=True, - help='Select param config file kernel' - ) - parser.add_argument( - '--section', - type=str, - help='Section to store matrices in') - parser.add_argument( - 'output', - type=pathlib.Path, - help='Path of the output header file') - args = parser.parse_args() - - # Load param config file - with args.cfg.open() as f: - param = json5.loads(f.read()) - param['section'] = args.section - - # Emit header file - with open(args.output, 'w') as f: - f.write(emit_header(**param)) - - -if __name__ == '__main__': - main() diff --git a/sw/dnn/linear/data/params.json b/sw/dnn/linear/data/params.json deleted file mode 100644 index cdb72b766c..0000000000 --- a/sw/dnn/linear/data/params.json +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2020 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 - -{ - channels: { - out: 16 - }, - input_dim: { - height: 3, - width:16 - }, - prec: "FP32" -} \ No newline at end of file diff --git a/sw/dnn/linear/src/linear.h b/sw/dnn/linear/src/linear.h deleted file mode 100644 index 82d174fcc9..0000000000 --- a/sw/dnn/linear/src/linear.h +++ /dev/null @@ -1,129 +0,0 @@ -// 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 "snrt.h" - -/** - * @struct linear_layer_struct - * @brief This structure contains all parameters necessary for Linear layers - * @var linear_layer_struct::CO - * Size of each output sample - * @var linear_layer_struct::CI - * Size of each input sample - * @var linear_layer_struct::CH - * Height of input feature map - * @var linear_layer_struct::CW - * Width of input feature map - * @var linear_layer_struct::ifmap - * Pointer to input feature map - * @var linear_layer_struct::weights - * Pointer to weights - * @var linear_layer_struct::bias - * Pointer to bias - * @var linear_layer_struct::ofmap - * Pointer to output feature map - */ -typedef struct linear_layer_struct { - uint32_t CO; - uint32_t CI; - uint32_t CH; - uint32_t CW; - - float *ifmap; - float *weights; - float *bias; - float *ofmap; - - precision_t dtype; -} linear_layer_t; - -/** - * Implementation of the linear layer - */ -static inline void linear_fp32(float *input, int32_t ldI, float *weights, - int32_t ldW, float *bias, int32_t ldB, - float *output, int32_t ldO, int in_ch, - int out_ch, int ch) { - uint32_t compute_id = snrt_cluster_compute_core_num(); - for (int c = 0; c < ch; c++) { - for (int o = 0; o < out_ch; o++) { - float sum = 0; - for (int i = 0; i < in_ch; i++) { - sum += input[c * in_ch + i] * weights[o * in_ch * ldB + i]; - } - output[c * out_ch + o * ldB] = sum + bias[o * ldB]; - printf("output[%d][%d] = %f\n", c, compute_id + o * ldB, - output[c * out_ch + o * ldB]); - } - } - - snrt_cluster_hw_barrier(); -} - -static inline void linear_layer(const linear_layer_t *l) { - uint32_t cluster_num = snrt_cluster_num(); - uint32_t cluster_id = snrt_cluster_idx(); - uint32_t compute_num = snrt_cluster_compute_core_num(); - uint32_t compute_id = snrt_cluster_compute_core_num(); - - uint32_t ifmap_size = l->CH * l->CW * sizeof(float); - uint32_t weights_size = l->CO * l->CI * sizeof(float); - uint32_t bias_size = l->CO * sizeof(float); - uint32_t ofmap_size = l->CH * l->CO * sizeof(float); - - void *ptr = (float *)snrt_l1_next(); - float *ifmap = ptr; - ptr += ifmap_size; - float *weights = ptr; - ptr += weights_size; - float *bias = ptr; - ptr += bias_size; - float *ofmap = ptr; - ptr += ofmap_size; - float *result = ptr; - ptr += ofmap_size; - - // now we DMA transfer the weights and bias into the cluster TCDM - if (snrt_is_dm_core()) { - snrt_dma_txid_t txid_bias = snrt_dma_start_1d(bias, l->bias, bias_size); - snrt_dma_txid_t txid_weights = snrt_dma_start_2d( - weights, l->weights, l->CO * sizeof(float), l->CO * sizeof(float), - l->CO * sizeof(float), l->CI * sizeof(float)); - - snrt_dma_txid_t txid_ifmap = snrt_dma_start_2d( - ifmap, l->ifmap, l->CH * sizeof(float), l->CH * sizeof(float), - l->CH * sizeof(float), l->CW * sizeof(float)); - - snrt_dma_wait_all(); - } - - snrt_cluster_hw_barrier(); - - if (snrt_is_compute_core() && - snrt_cluster_compute_core_num() < compute_num) { - // determine the row stride of each matrix - int32_t ldI = l->CH * l->CW; - int32_t ldW = compute_num * l->CO; - int32_t ldB = compute_num; - int32_t ldO = ldB; - - // determine the row offset of each matrix - int32_t offW = compute_id * l->CO; - int32_t offB = compute_id; - int32_t offO = compute_id; - - // printf("compute_id = %d, offW = %d, offB = %d, offO = %d\n", - // compute_id, offW, offB, offO); - - linear_fp32(ifmap, ldI, &weights[offW], ldW, &bias[compute_id], ldB, - ofmap, ldO, l->CI, l->CO / compute_num, l->CH); - - } else { - snrt_cluster_hw_barrier(); - } - - snrt_cluster_hw_barrier(); -} diff --git a/sw/dnn/linear/src/main.c b/sw/dnn/linear/src/main.c deleted file mode 100644 index 8a10396a1f..0000000000 --- a/sw/dnn/linear/src/main.c +++ /dev/null @@ -1,39 +0,0 @@ -// 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 - -// TODO(colluca): add IPC test and remove this flag -#define BIST - -#include "dnn.h" - -#include "data.h" - -int main() { - linear_layer(&layer); - -#ifdef BIST - // TODO: fix this, wrong values for ofmap printed - if (snrt_global_core_idx() == 0) { - // compare result with ofmap - uint32_t n_results = layer.CH * layer.CO; - uint32_t n_errors = n_results; - float tolerance = 1e-6; - for (int i = 0; i < layer.CH; i++) { - for (int j = 0; j < layer.CO; j++) { - if (golden[i * layer.CO + j] - ofmap[i * layer.CO + j] > - tolerance) { - printf( - "MISMATCH: golden[%d][%d] = %f, ofmap[%d][%d] = %f\n", - i, j, golden[i * layer.CO + j], i, j, - ofmap[i * layer.CO + j]); - } else { - n_errors--; - } - } - } - printf("[%d/%d] mismatches\n", n_errors, n_results); - return n_errors; - } -#endif -} \ No newline at end of file diff --git a/target/snitch_cluster/sw/apps/Makefile b/target/snitch_cluster/sw/apps/Makefile index b2be1f8940..3c4da406ab 100644 --- a/target/snitch_cluster/sw/apps/Makefile +++ b/target/snitch_cluster/sw/apps/Makefile @@ -15,7 +15,6 @@ SUBDIRS += dnn/fusedconv SUBDIRS += dnn/gelu SUBDIRS += dnn/gemm SUBDIRS += dnn/layernorm -SUBDIRS += dnn/linear SUBDIRS += dnn/maxpool SUBDIRS += dnn/softmax SUBDIRS += dnn/flashattention_2 diff --git a/target/snitch_cluster/sw/apps/dnn/linear/Makefile b/target/snitch_cluster/sw/apps/dnn/linear/Makefile deleted file mode 100644 index 7b43893846..0000000000 --- a/target/snitch_cluster/sw/apps/dnn/linear/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# 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 -# -# Luca Colagrande - -APP ?= linear - -include ../../../../../../sw/dnn/common.mk -include ../../common.mk - -$(DEP): $(DATA_H) \ No newline at end of file diff --git a/target/snitch_cluster/sw/run.yaml b/target/snitch_cluster/sw/run.yaml index 4f32bba17c..cb0a386f5a 100644 --- a/target/snitch_cluster/sw/run.yaml +++ b/target/snitch_cluster/sw/run.yaml @@ -74,7 +74,6 @@ runs: - elf: apps/blas/gemm/build/gemm.elf cmd: [../../../sw/blas/gemm/verify.py, "${sim_bin}", "${elf}"] - elf: apps/dnn/batchnorm/build/batchnorm.elf - - elf: apps/dnn/linear/build/linear.elf - elf: apps/dnn/maxpool/build/maxpool.elf - elf: apps/dnn/gemm/build/gemm.elf # - elf: apps/dnn/conv2d/build/conv2d.elf # Fails with wrong results