From ceeeba93ca47184b50b7acc0415765d5ade7672c Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 14:47:07 +0200 Subject: [PATCH 1/8] [treewide] refactor: Updated project structure to utilize `pyproject.toml` for managing module paths. --- iis-setup.sh | 3 + pyproject.toml | 15 ++ sw/apps/atax/scripts/datagen.py | 7 +- sw/apps/atax/scripts/verify.py | 4 +- sw/apps/correlation/scripts/datagen.py | 7 +- sw/apps/correlation/scripts/verify.py | 4 +- sw/apps/covariance/scripts/datagen.py | 7 +- sw/apps/covariance/scripts/verify.py | 4 +- sw/blas/__init__.py | 9 ++ sw/blas/axpy/scripts/datagen.py | 6 +- sw/blas/axpy/scripts/verify.py | 4 +- sw/blas/dot/scripts/datagen.py | 6 +- sw/blas/dot/scripts/verify.py | 4 +- sw/blas/gemm/__init__.py | 4 +- sw/blas/gemm/scripts/datagen.py | 100 +++++++------- sw/blas/gemm/scripts/verify.py | 6 +- sw/dnn/batchnorm/scripts/datagen.py | 10 +- sw/dnn/concat/scripts/datagen.py | 10 +- sw/dnn/concat/scripts/verify.py | 6 +- sw/dnn/conv2d/scripts/datagen.py | 10 +- sw/dnn/conv2d/scripts/verify.py | 11 +- sw/dnn/flashattention_2/__init__.py | 7 + sw/dnn/flashattention_2/scripts/datagen.py | 129 ++++++++++++------ sw/dnn/flashattention_2/scripts/verify.py | 6 +- sw/dnn/fused_concat_linear/__init__.py | 7 + sw/dnn/fused_concat_linear/scripts/datagen.py | 14 +- sw/dnn/fused_concat_linear/scripts/verify.py | 8 +- sw/dnn/fusedconv/scripts/datagen.py | 18 +-- sw/dnn/fusedconv/scripts/verify.py | 11 +- sw/dnn/gelu/scripts/datagen.py | 11 +- sw/dnn/gelu/scripts/verify.py | 6 +- sw/dnn/layernorm/__init__.py | 7 + sw/dnn/layernorm/scripts/datagen.py | 9 +- sw/dnn/layernorm/scripts/verify.py | 6 +- sw/dnn/maxpool/scripts/datagen.py | 10 +- sw/dnn/softmax/scripts/datagen.py | 10 +- sw/dnn/softmax/scripts/verify.py | 7 +- sw/dnn/transpose/scripts/datagen.py | 8 +- sw/dnn/transpose/scripts/verify.py | 6 +- util/sim/Elf.py | 2 +- util/sim/verif_utils.py | 4 +- 41 files changed, 277 insertions(+), 246 deletions(-) create mode 100644 pyproject.toml create mode 100644 sw/blas/__init__.py create mode 100644 sw/dnn/flashattention_2/__init__.py create mode 100644 sw/dnn/fused_concat_linear/__init__.py create mode 100644 sw/dnn/layernorm/__init__.py diff --git a/iis-setup.sh b/iis-setup.sh index d56886c72..72d930fd5 100755 --- a/iis-setup.sh +++ b/iis-setup.sh @@ -22,6 +22,9 @@ mkdir tmp TMPDIR=tmp pip install -r python-requirements.txt rm -rf tmp +# Install local packages in editable mode. +pip install -e . + # Bender initialization $BENDER vendor init diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..44b08ad10 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[build-system] +requires = ["setuptools>=42"] +build-backend = "setuptools.build_meta" + +[project] +name = "snitch" +authors = [ + {name = "Luca Colagrande", email = "colluca@iis.ee.ethz.ch"} +] +dynamic = ["version"] + +[tool.setuptools.package-dir] +"snitch.dnn" = "sw/dnn" +"snitch.blas" = "sw/blas" +"snitch.util" = "util" \ No newline at end of file diff --git a/sw/apps/atax/scripts/datagen.py b/sw/apps/atax/scripts/datagen.py index 4332ecc31..51317c70e 100755 --- a/sw/apps/atax/scripts/datagen.py +++ b/sw/apps/atax/scripts/datagen.py @@ -7,12 +7,9 @@ # Luca Colagrande import numpy as np -import os -import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -from data_utils import format_scalar_definition, format_array_definition, \ - format_array_declaration, format_ifdef_wrapper, DataGen # noqa: E402 +from snitch.util.sim.data_utils import format_scalar_definition, format_array_definition, \ + format_array_declaration, format_ifdef_wrapper, DataGen # AXI splits bursts crossing 4KB address boundaries. To minimize diff --git a/sw/apps/atax/scripts/verify.py b/sw/apps/atax/scripts/verify.py index cb5fe21f0..8a81033b0 100755 --- a/sw/apps/atax/scripts/verify.py +++ b/sw/apps/atax/scripts/verify.py @@ -7,11 +7,9 @@ import numpy as np import sys -from pathlib import Path from datagen import AtaxDataGen -sys.path.append(str(Path(__file__).parent / '../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 +from snitch.util.sim.verif_utils import Verifier class AtaxVerifier(Verifier): diff --git a/sw/apps/correlation/scripts/datagen.py b/sw/apps/correlation/scripts/datagen.py index a42fdfe33..b2047d5eb 100755 --- a/sw/apps/correlation/scripts/datagen.py +++ b/sw/apps/correlation/scripts/datagen.py @@ -7,12 +7,9 @@ # Luca Colagrande import numpy as np -import os -import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -from data_utils import format_scalar_definition, format_array_definition, \ - format_array_declaration, format_ifdef_wrapper, DataGen # noqa: E402 +from snitch.util.sim.data_utils import format_scalar_definition, format_array_definition, \ + format_array_declaration, format_ifdef_wrapper, DataGen # AXI splits bursts crossing 4KB address boundaries. To minimize diff --git a/sw/apps/correlation/scripts/verify.py b/sw/apps/correlation/scripts/verify.py index 67746af7f..7849f94e3 100755 --- a/sw/apps/correlation/scripts/verify.py +++ b/sw/apps/correlation/scripts/verify.py @@ -7,11 +7,9 @@ import numpy as np import sys -from pathlib import Path from datagen import CorrelationDataGen -sys.path.append(str(Path(__file__).parent / '../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 +from snitch.util.sim.verif_utils import Verifier class CorrelationVerifier(Verifier): diff --git a/sw/apps/covariance/scripts/datagen.py b/sw/apps/covariance/scripts/datagen.py index e62586a6d..44e20d55e 100755 --- a/sw/apps/covariance/scripts/datagen.py +++ b/sw/apps/covariance/scripts/datagen.py @@ -7,12 +7,9 @@ # Luca Colagrande import numpy as np -import os -import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -from data_utils import format_scalar_definition, format_array_definition, \ - format_array_declaration, format_ifdef_wrapper, DataGen # noqa: E402 +from snitch.util.sim.data_utils import format_scalar_definition, format_array_definition, \ + format_array_declaration, format_ifdef_wrapper, DataGen # AXI splits bursts crossing 4KB address boundaries. To minimize diff --git a/sw/apps/covariance/scripts/verify.py b/sw/apps/covariance/scripts/verify.py index aacbccdb1..4c5b0cdd1 100755 --- a/sw/apps/covariance/scripts/verify.py +++ b/sw/apps/covariance/scripts/verify.py @@ -7,11 +7,9 @@ import numpy as np import sys -from pathlib import Path from datagen import CovarianceDataGen -sys.path.append(str(Path(__file__).parent / '../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 +from snitch.util.sim.verif_utils import Verifier class CovarianceVerifier(Verifier): diff --git a/sw/blas/__init__.py b/sw/blas/__init__.py new file mode 100644 index 000000000..d20a3c84d --- /dev/null +++ b/sw/blas/__init__.py @@ -0,0 +1,9 @@ +# 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 +# +# Luca Colagrande + +from . import gemm + +__all__ = ['gemm'] \ No newline at end of file diff --git a/sw/blas/axpy/scripts/datagen.py b/sw/blas/axpy/scripts/datagen.py index 96b950194..117495391 100755 --- a/sw/blas/axpy/scripts/datagen.py +++ b/sw/blas/axpy/scripts/datagen.py @@ -6,12 +6,10 @@ # Author: Luca Colagrande import numpy as np -import os import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -from data_utils import format_scalar_definition, format_array_definition, \ - format_array_declaration, format_ifdef_wrapper, DataGen # noqa: E402 +from snitch.util.sim.data_utils import format_scalar_definition, format_array_definition, \ + format_array_declaration, format_ifdef_wrapper, DataGen class AxpyDataGen(DataGen): diff --git a/sw/blas/axpy/scripts/verify.py b/sw/blas/axpy/scripts/verify.py index 4568f9397..7c8d0819e 100755 --- a/sw/blas/axpy/scripts/verify.py +++ b/sw/blas/axpy/scripts/verify.py @@ -6,11 +6,9 @@ # Luca Colagrande import sys -from pathlib import Path from datagen import AxpyDataGen -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 +from snitch.util.sim.verif_utils import Verifier class AxpyVerifier(Verifier): diff --git a/sw/blas/dot/scripts/datagen.py b/sw/blas/dot/scripts/datagen.py index 01f36899e..01560c51f 100755 --- a/sw/blas/dot/scripts/datagen.py +++ b/sw/blas/dot/scripts/datagen.py @@ -4,12 +4,10 @@ # SPDX-License-Identifier: Apache-2.0 import numpy as np -import os import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -from data_utils import format_scalar_definition, format_array_definition, \ - format_scalar_declaration, format_ifdef_wrapper, DataGen # noqa: E402 +from snitch.util.sim.data_utils import format_scalar_definition, format_array_definition, \ + format_scalar_declaration, format_ifdef_wrapper, DataGen class DotDataGen(DataGen): diff --git a/sw/blas/dot/scripts/verify.py b/sw/blas/dot/scripts/verify.py index 9d61ff466..cc83af8e8 100755 --- a/sw/blas/dot/scripts/verify.py +++ b/sw/blas/dot/scripts/verify.py @@ -4,11 +4,9 @@ # SPDX-License-Identifier: Apache-2.0 import sys -from pathlib import Path from datagen import DotDataGen -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 +from snitch.util.sim.verif_utils import Verifier class DotVerifier(Verifier): diff --git a/sw/blas/gemm/__init__.py b/sw/blas/gemm/__init__.py index 19c2e2f01..aed54f147 100644 --- a/sw/blas/gemm/__init__.py +++ b/sw/blas/gemm/__init__.py @@ -4,6 +4,4 @@ # # Luca Colagrande -from .scripts import datagen - -__all__ = ['datagen'] +from .scripts.datagen import * diff --git a/sw/blas/gemm/scripts/datagen.py b/sw/blas/gemm/scripts/datagen.py index 602a596ad..e1c130ce5 100755 --- a/sw/blas/gemm/scripts/datagen.py +++ b/sw/blas/gemm/scripts/datagen.py @@ -9,15 +9,13 @@ # Luca Colagrande import numpy as np -import os import re import pyflexfloat as ff import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -import data_utils # noqa: E402 -from data_utils import DataGen, format_array_declaration, format_struct_definition, \ - format_array_definition, format_ifdef_wrapper # noqa: E402 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import DataGen, format_array_declaration, \ + format_struct_definition, format_array_definition, format_ifdef_wrapper np.random.seed(42) @@ -47,55 +45,49 @@ def infer_implementation(self, gemm_fp): prec, impl = re.search(r'gemm_fp(\d+)_(\w+)', gemm_fp).group(1, 2) return (int(prec) / 8), impl - def validate_config(self, gemm_fp, parallelize_m, - parallelize_k, m_tiles, n_tiles, k_tiles, transa, - transb, M, N, K, beta, **kwargs): - frac_m = M / m_tiles - frac_n = N / n_tiles - frac_k = K / k_tiles - - dtype, impl = self.infer_implementation(gemm_fp) - - # Calculate total TCDM occupation - # Note: doesn't account for double buffering - prec = data_utils.size_from_precision_t(dtype) - a_size = frac_m * frac_k * prec - b_size = frac_k * frac_n * prec - c_size = frac_m * frac_n * prec + def load_params(self, params): + self.M = params.get('M') + self.N = params.get('N') + self.K = params.get('K') + self.m_tiles = params.get('m_tiles') + self.n_tiles = params.get('n_tiles') + self.k_tiles = params.get('k_tiles') + self.load_a = params.get('load_a') + self.load_b = params.get('load_b') + self.load_c = params.get('load_c') + self.setup_ssr = params.get('setup_ssr') + self.parallelize_m = params.get('parallelize_m') + self.parallelize_k = params.get('parallelize_k') + self.gemm_fp = params.get('gemm_fp') + self.transa = params.get('transa') + self.transb = params.get('transb') + self.alpha = params.get('alpha', 1) + self.beta = params.get('beta') + self.section = params.get('section') + self.dtype, self.impl = self.infer_implementation(self.gemm_fp) + self.prec = data_utils.size_from_precision_t(self.dtype) + self.ff_desc = data_utils.ff_desc_from_precision_t(self.dtype) + self.ctype = data_utils.ctype_from_precision_t(self.dtype) + + def validate(self): + frac_m = self.M / self.m_tiles + frac_n = self.N / self.n_tiles + frac_k = self.K / self.k_tiles + + a_size = frac_m * frac_k * self.prec + b_size = frac_k * frac_n * self.prec + c_size = frac_m * frac_n * self.prec total_size = a_size total_size += b_size total_size += c_size data_utils.validate_tcdm_footprint(total_size) - assert (M % m_tiles) == 0, 'M is not an integer multiple of tile size' - assert (N % n_tiles) == 0, 'N is not an integer multiple of tile size' - assert (K % k_tiles) == 0, 'K is not an integer multiple of tile size' - assert not (parallelize_m and parallelize_k), 'Cannot parallelize K and M simultaneously' - assert not transa, 'SIMD kernels don\'t support transposed A matrix' - assert (dtype == 8) or (impl == 'baseline') or (impl == 'naive') \ - or transb, 'Optimized SIMD kernels only support transposed B matrix' - assert not transb or n_tiles == 1, 'Tiling in the N dimension not supported' \ - ' if B is transposed' - assert not transb or k_tiles == 1, 'Tiling in the K dimension not supported' \ - ' if B is transposed' - assert (impl == 'baseline') or (impl == 'naive') or frac_n >= 8, \ - 'N dimension of tile size must be greater or equal to the unrolling factor (8) ' \ - 'when using optimized kernels' - assert beta == 0 or beta == 1, 'Only values of 0 or 1 supported for beta' - assert not (dtype == 8 and impl == "baseline"), 'No baseline implemented' \ - ' for FP64 (switch to NAIVE)' - assert not (((dtype == 8) or (dtype == 4)) and impl == "opt_ex"), \ - 'Expanding GEMM kernels' \ - ' not supported for FP64 and FP32' - assert not (dtype == 1 and impl == "opt"), 'FP8 not supported in' \ - ' optimized implementation' \ - ' (switch to opt_ex)' - def emit_header(self, **kwargs): header = [super().emit_header()] + self.load_params(kwargs) # Validate parameters - self.validate_config(**kwargs) + self.validate() M, N, K = kwargs['M'], kwargs['N'], kwargs['K'] @@ -119,7 +111,23 @@ def emit_header(self, **kwargs): cfg = { 'prec': prec, - **kwargs, + 'setup_ssr': kwargs['setup_ssr'], + 'parallelize_m': kwargs['parallelize_m'], + 'parallelize_k': kwargs['parallelize_k'], + 'm_tiles': kwargs['m_tiles'], + 'n_tiles': kwargs['n_tiles'], + 'k_tiles': kwargs['k_tiles'], + 'load_a': kwargs['load_a'], + 'load_b': kwargs['load_b'], + 'load_c': kwargs['load_c'], + 'transa': kwargs['transa'], + 'transb': kwargs['transb'], + 'M': M, + 'N': N, + 'K': K, + 'alpha': kwargs['alpha'], + 'beta': kwargs['beta'], + 'gemm_fp': kwargs['gemm_fp'], 'a': a_uid, 'b': b_uid, 'c': c_uid, diff --git a/sw/blas/gemm/scripts/verify.py b/sw/blas/gemm/scripts/verify.py index b98e3854d..40840b327 100755 --- a/sw/blas/gemm/scripts/verify.py +++ b/sw/blas/gemm/scripts/verify.py @@ -7,12 +7,10 @@ import numpy as np import sys -from pathlib import Path from datagen import GemmDataGen -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class GemmVerifier(Verifier): diff --git a/sw/dnn/batchnorm/scripts/datagen.py b/sw/dnn/batchnorm/scripts/datagen.py index 53dce77b4..61a236ab9 100755 --- a/sw/dnn/batchnorm/scripts/datagen.py +++ b/sw/dnn/batchnorm/scripts/datagen.py @@ -10,15 +10,11 @@ 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 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import emit_license, format_struct_definition, \ + format_array_definition, format_array_declaration, format_ifdef_wrapper torch.manual_seed(42) diff --git a/sw/dnn/concat/scripts/datagen.py b/sw/dnn/concat/scripts/datagen.py index 4978a8ad7..a2b64795a 100755 --- a/sw/dnn/concat/scripts/datagen.py +++ b/sw/dnn/concat/scripts/datagen.py @@ -9,15 +9,11 @@ import numpy as np 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 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import emit_license, format_struct_definition, \ + format_array_definition, format_array_declaration, format_ifdef_wrapper torch.manual_seed(42) diff --git a/sw/dnn/concat/scripts/verify.py b/sw/dnn/concat/scripts/verify.py index b5fdc9e83..f22ec9352 100755 --- a/sw/dnn/concat/scripts/verify.py +++ b/sw/dnn/concat/scripts/verify.py @@ -7,12 +7,10 @@ import sys import torch -from pathlib import Path from datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class ConcatVerifier(Verifier): diff --git a/sw/dnn/conv2d/scripts/datagen.py b/sw/dnn/conv2d/scripts/datagen.py index 95ae015d0..0b93f1c59 100755 --- a/sw/dnn/conv2d/scripts/datagen.py +++ b/sw/dnn/conv2d/scripts/datagen.py @@ -9,15 +9,11 @@ import numpy as np import pathlib import hjson -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 # noqa: E402 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import emit_license, format_struct_definition, \ + format_array_definition, format_array_declaration torch.manual_seed(42) diff --git a/sw/dnn/conv2d/scripts/verify.py b/sw/dnn/conv2d/scripts/verify.py index 92a8b167f..28b5bfb16 100755 --- a/sw/dnn/conv2d/scripts/verify.py +++ b/sw/dnn/conv2d/scripts/verify.py @@ -11,10 +11,9 @@ import torch from data.datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -import verification # noqa: E402 -from elf import Elf # noqa: E402 -from data_utils import from_buffer, ctype_from_precision_t, check_result # noqa: E402 +from snitch.util.sim import verification +from snitch.util.sim.elf import Elf +from snitch.util.sim.data_utils import from_buffer, ctype_from_precision_t, check_result ERR_THRESHOLD = 1E-6 @@ -77,8 +76,8 @@ def main(): fail, rel_err = check_result(output_golden, output_actual, rtol=ERR_THRESHOLD) if fail: verification.dump_results_to_csv( - [output_golden, output_actual, rel_err], - Path.cwd() / 'results.csv') + [output_golden, output_actual, rel_err], + Path.cwd() / 'results.csv') print('Maximum relative error:', np.max(rel_err)) return int(fail) diff --git a/sw/dnn/flashattention_2/__init__.py b/sw/dnn/flashattention_2/__init__.py new file mode 100644 index 000000000..70d256c82 --- /dev/null +++ b/sw/dnn/flashattention_2/__init__.py @@ -0,0 +1,7 @@ +# 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 +# +# Luca Colagrande + +from .scripts.datagen import * \ No newline at end of file diff --git a/sw/dnn/flashattention_2/scripts/datagen.py b/sw/dnn/flashattention_2/scripts/datagen.py index 841fa3110..37c65d21f 100755 --- a/sw/dnn/flashattention_2/scripts/datagen.py +++ b/sw/dnn/flashattention_2/scripts/datagen.py @@ -10,25 +10,18 @@ import numpy as np import pathlib import json5 -import sys -import os import torch import pyflexfloat as ff -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../blas/")) -import data_utils # noqa: E402 -from data_utils import emit_license, \ - format_struct_definition, format_array_definition, \ - format_array_declaration # noqa: E402 -import gemm # noqa: E402 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import DataGen, format_struct_definition, \ + format_array_definition, format_array_declaration, emit_license +from snitch.blas import gemm np.random.seed(42) 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 +np.set_printoptions(formatter={'object': str}) def torch_golden_model(Q, K, V): @@ -117,13 +110,13 @@ def exact_flexfloat_golden_model(Q, K, V, B_r, B_c, desc): V_j = V[start_col:end_col,] # Compute O tile update S_ij = ff.array(np.zeros((B_r, B_c)), desc) - S_ij = gemm.datagen.GemmDataGen().exact_golden_model(1, Q_i, K_t_j, 0, S_ij) + S_ij = gemm.GemmDataGen().exact_golden_model(1, Q_i, K_t_j, 0, S_ij) m_i_prev = m_i m_i = np.maximum(m_i_prev, np.max(S_ij, 1, keepdims=True)) shifted_exp = np.exp((m_i_prev.astype(np.float32) - m_i.astype(np.float32))) P_ij = np.exp((S_ij - m_i).astype(np.float32)) PxV = ff.array(np.zeros((B_r, d)), desc) - PxV = gemm.datagen.GemmDataGen().exact_golden_model(1, P_ij, V_j, 0, PxV) + PxV = gemm.GemmDataGen().exact_golden_model(1, P_ij, V_j, 0, PxV) row_sum = np.sum(P_ij.astype(np.float32), 1, keepdims=True) if j == 0: l_i = row_sum @@ -142,22 +135,51 @@ def exact_flexfloat_golden_model(Q, K, V, B_r, B_c, desc): return np.concatenate(O_tiles, 0) +def get_gemm_implementation(self, params): + prec = params['dtype'].lower() + impl = f'gemm_{prec}_' + if params['baseline']: + impl += 'naive' + else: + impl += 'opt' + if prec == 'fp8': + impl += '_ex' + return impl + + +def load_params(self, params): + self.L = params['L'] + self.S = params['S'] + self.d = params['d'] + self.B_r = params['B_r'] + self.B_c = params['B_c'] + self.dtype = params['dtype'] + self.baseline = params['baseline'] + self.use_mask = params['use_mask'] + self.gemm_impl = self.get_gemm_implementation(params) + # self.torch_type = data_utils.torch_type_from_precision_t(self.dtype) + self.ff_desc = data_utils.ff_desc_from_precision_t(self.dtype) + self.ctype = data_utils.ctype_from_precision_t(self.dtype) + self.prec = data_utils.size_from_precision_t(self.dtype) + # Verify layer parameters are valid -def validate_config(L, S, d, B_r, B_c, dtype, baseline, gemm_impl): - assert (L % B_r) == 0, 'L is not an integer multiple of B_r' - assert (S % B_c) == 0, 'S is not an integer multiple of B_c' - assert dtype != 'FP64', 'FP64 precision is not supported yet' + + +def validate(self): + assert (self.L % self.B_r) == 0, 'L is not an integer multiple of B_r' + assert (self.S % self.B_c) == 0, 'S is not an integer multiple of B_c' + assert self.dtype != 'FP64', 'FP64 precision is not supported yet' # Calculate total TCDM occupation - prec = data_utils.size_from_precision_t(dtype) - q_fa_size = B_r * d * prec - k_fa_size = B_c * d * prec - v_fa_size = B_c * d * prec - s_fa_size = B_r * B_c * prec - p_fa_size = B_r * B_c * prec - o_fa_size = B_r * d * prec - m_i_size = B_r * prec - l_i_size = B_r * prec + q_fa_size = self.B_r * self.d * self.prec + k_fa_size = self.B_c * self.d * self.prec + v_fa_size = self.B_c * self.d * self.prec + s_fa_size = self.B_r * self.B_c * self.prec + p_fa_size = self.B_r * self.B_c * self.prec + o_fa_size = self.B_r * self.d * self.prec + m_i_size = self.B_r * self.prec + l_i_size = self.B_r * self.prec + mask_size = self.B_r * self.B_c * self.prec if self.use_mask else 0 total_size = q_fa_size total_size += k_fa_size total_size += v_fa_size * 2 # V and V^t @@ -166,26 +188,51 @@ def validate_config(L, S, d, B_r, B_c, dtype, baseline, gemm_impl): total_size += o_fa_size total_size += m_i_size * 2 # m_i and m_i_prev total_size += l_i_size + total_size += mask_size data_utils.validate_tcdm_footprint(total_size) # Q*K^t - gemm.datagen.GemmDataGen().validate_config( - gemm_fp=gemm_impl, parallelize_m=0, parallelize_k=0, m_tiles=1, n_tiles=1, - k_tiles=1, transa=0, transb=1, M=B_r, N=B_c, K=d, beta=0 - ) + gemm_gen = gemm.GemmDataGen() + gemm_params = { + 'gemm_fp': self.gemm_impl, + 'parallelize_m': 0, + 'parallelize_k': 0, + 'm_tiles': 1, + 'n_tiles': 1, + 'k_tiles': 1, + 'transa': 0, + 'transb': 1, + 'M': self.B_r, + 'N': self.B_c, + 'K': self.d, + 'beta': 0 + } + gemm_gen.load_params(gemm_params) + gemm_gen.validate() # P*V - if baseline: - gemm.datagen.GemmDataGen().validate_config( - gemm_fp=gemm_impl, parallelize_m=0, parallelize_k=0, m_tiles=1, n_tiles=1, - k_tiles=1, transa=0, transb=0, M=B_r, N=d, K=B_c, beta=1 - ) + gemm_params = { + 'gemm_fp': self.gemm_impl, + 'parallelize_m': 0, + 'parallelize_k': 0, + 'm_tiles': 1, + 'n_tiles': 1, + 'k_tiles': 1, + 'transa': 0, + 'M': self.B_r, + 'N': self.d, + 'K': self.B_c, + 'beta': 1 + } + if self.baseline: + gemm_params['transb'] = 0 + gemm_gen.load_params(gemm_params) + gemm_gen.validate() else: # P*(V^t)^t - gemm.datagen.GemmDataGen().validate_config( - gemm_fp=gemm_impl, parallelize_m=0, parallelize_k=0, m_tiles=1, n_tiles=1, - k_tiles=1, transa=0, transb=1, M=B_r, N=d, K=B_c, beta=1 - ) + gemm_params['transb'] = 1 + gemm_gen.load_params(gemm_params) + gemm_gen.validate() def get_gemm_implementation(params): @@ -209,7 +256,7 @@ def emit_header(section, params): prec = params['dtype'] gemm_impl = get_gemm_implementation(params) - validate_config(gemm_impl=gemm_impl, **params) + # TODO: Add validation (vivianep) # torch_type = data_utils.torch_type_from_precision_t(prec) ff_desc = data_utils.ff_desc_from_precision_t(prec) diff --git a/sw/dnn/flashattention_2/scripts/verify.py b/sw/dnn/flashattention_2/scripts/verify.py index 4b979286d..27e268d2a 100755 --- a/sw/dnn/flashattention_2/scripts/verify.py +++ b/sw/dnn/flashattention_2/scripts/verify.py @@ -7,13 +7,11 @@ import numpy as np import sys -from pathlib import Path from datagen import exact_flexfloat_golden_model import pyflexfloat as ff -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t, ff_desc_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t, ff_desc_from_precision_t class FlashAttention2Verifier(Verifier): diff --git a/sw/dnn/fused_concat_linear/__init__.py b/sw/dnn/fused_concat_linear/__init__.py new file mode 100644 index 000000000..70d256c82 --- /dev/null +++ b/sw/dnn/fused_concat_linear/__init__.py @@ -0,0 +1,7 @@ +# 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 +# +# Luca Colagrande + +from .scripts.datagen import * \ No newline at end of file diff --git a/sw/dnn/fused_concat_linear/scripts/datagen.py b/sw/dnn/fused_concat_linear/scripts/datagen.py index 1631eb6a4..84728b173 100755 --- a/sw/dnn/fused_concat_linear/scripts/datagen.py +++ b/sw/dnn/fused_concat_linear/scripts/datagen.py @@ -4,22 +4,20 @@ # SPDX-License-Identifier: Apache-2.0 # # Luca Colagrande +# Tim Fischer +# Viviane Potocnik import argparse import numpy as np 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 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import DataGen, format_struct_definition, \ + format_array_definition, format_array_declaration, format_ifdef_wrapper, \ + emit_license -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 diff --git a/sw/dnn/fused_concat_linear/scripts/verify.py b/sw/dnn/fused_concat_linear/scripts/verify.py index 1b9a37535..2bd0f3611 100755 --- a/sw/dnn/fused_concat_linear/scripts/verify.py +++ b/sw/dnn/fused_concat_linear/scripts/verify.py @@ -4,15 +4,15 @@ # SPDX-License-Identifier: Apache-2.0 # # Luca Colagrande +# Tim Fischer +# Viviane Potocnik import sys import torch -from pathlib import Path from datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class FusedConcatLinearVerifier(Verifier): diff --git a/sw/dnn/fusedconv/scripts/datagen.py b/sw/dnn/fusedconv/scripts/datagen.py index 3b06c5095..f3f3c718c 100755 --- a/sw/dnn/fusedconv/scripts/datagen.py +++ b/sw/dnn/fusedconv/scripts/datagen.py @@ -8,15 +8,11 @@ import argparse import pathlib import hjson -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_scalar_definition, format_array_declaration # noqa: E402 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import emit_license, format_struct_definition, \ + format_array_definition, format_scalar_definition, format_array_declaration torch.manual_seed(42) @@ -62,8 +58,8 @@ def golden_model(ifmap, weights, bn_k, bn_l, padding, stride, bn, relu, accumula for c in range(co): ofmap[h//stride['stride_y'], w//stride['stride_x'], c] = torch.dot( - ifmap_padded[h:h+fh, w:w+fw, c].flatten(), - weights[:, :, c].flatten()) + ifmap_padded[h:h+fh, w:w+fw, c].flatten(), + weights[:, :, c].flatten()) else: # Conv2d for h in range(0, ifmap_padded.shape[0] - (fh - 1), stride['stride_y']): @@ -71,8 +67,8 @@ def golden_model(ifmap, weights, bn_k, bn_l, padding, stride, bn, relu, accumula for c in range(co): ofmap[h//stride['stride_y'], w//stride['stride_x'], c] = torch.dot( - ifmap_padded[h:h+fh, w:w+fw].flatten(), - weights[c].flatten()) + ifmap_padded[h:h+fh, w:w+fw].flatten(), + weights[c].flatten()) ofmap += ofmap_before diff --git a/sw/dnn/fusedconv/scripts/verify.py b/sw/dnn/fusedconv/scripts/verify.py index ef37a4178..171ec02d1 100755 --- a/sw/dnn/fusedconv/scripts/verify.py +++ b/sw/dnn/fusedconv/scripts/verify.py @@ -11,10 +11,9 @@ import torch from data.datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -import verification # noqa: E402 -from elf import Elf # noqa: E402 -from data_utils import from_buffer, ctype_from_precision_t, check_result # noqa: E402 +from snitch.util.sim import verification +from snitch.util.sim.elf import Elf +from snitch.util.sim.data_utils import from_buffer, ctype_from_precision_t, check_result ERR_THRESHOLD = 1E-6 @@ -110,8 +109,8 @@ def main(): fail, rel_err = check_result(output_golden, output_actual, rtol=ERR_THRESHOLD) if fail: verification.dump_results_to_csv( - [output_golden, output_actual, rel_err], - Path.cwd() / 'results.csv') + [output_golden, output_actual, rel_err], + Path.cwd() / 'results.csv') print('Maximum relative error:', np.max(rel_err)) return int(fail) diff --git a/sw/dnn/gelu/scripts/datagen.py b/sw/dnn/gelu/scripts/datagen.py index a875288ca..9d2fda749 100755 --- a/sw/dnn/gelu/scripts/datagen.py +++ b/sw/dnn/gelu/scripts/datagen.py @@ -10,15 +10,12 @@ 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 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import DataGen, format_struct_definition, \ + format_array_definition, format_array_declaration, format_ifdef_wrapper, \ + emit_license torch.manual_seed(42) diff --git a/sw/dnn/gelu/scripts/verify.py b/sw/dnn/gelu/scripts/verify.py index a3a3aad99..d58bdf8af 100755 --- a/sw/dnn/gelu/scripts/verify.py +++ b/sw/dnn/gelu/scripts/verify.py @@ -7,12 +7,10 @@ import sys import torch -from pathlib import Path from datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class GeluVerifier(Verifier): diff --git a/sw/dnn/layernorm/__init__.py b/sw/dnn/layernorm/__init__.py new file mode 100644 index 000000000..70d256c82 --- /dev/null +++ b/sw/dnn/layernorm/__init__.py @@ -0,0 +1,7 @@ +# 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 +# +# Luca Colagrande + +from .scripts.datagen import * \ No newline at end of file diff --git a/sw/dnn/layernorm/scripts/datagen.py b/sw/dnn/layernorm/scripts/datagen.py index 8aa854d8d..1bb1e6996 100755 --- a/sw/dnn/layernorm/scripts/datagen.py +++ b/sw/dnn/layernorm/scripts/datagen.py @@ -11,16 +11,15 @@ import pathlib import json5 import sys -import os import torch import numpy as np import pyflexfloat as ff -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -import data_utils # noqa: E402 -from data_utils import emit_license, format_array_declaration, format_struct_definition, \ - format_array_definition, format_ifdef_wrapper # noqa: E402 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import DataGen, format_array_declaration, \ + format_struct_definition, format_array_definition, format_ifdef_wrapper, \ + emit_license torch.manual_seed(42) diff --git a/sw/dnn/layernorm/scripts/verify.py b/sw/dnn/layernorm/scripts/verify.py index 235edcf44..46d0efe60 100755 --- a/sw/dnn/layernorm/scripts/verify.py +++ b/sw/dnn/layernorm/scripts/verify.py @@ -7,12 +7,10 @@ # Viviane Potocnik import sys -from pathlib import Path from datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class LayernormVerifier(Verifier): diff --git a/sw/dnn/maxpool/scripts/datagen.py b/sw/dnn/maxpool/scripts/datagen.py index e83f733b8..4cda2fc4a 100755 --- a/sw/dnn/maxpool/scripts/datagen.py +++ b/sw/dnn/maxpool/scripts/datagen.py @@ -10,15 +10,11 @@ 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 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import emit_license, format_struct_definition, \ + format_array_definition, format_array_declaration, format_ifdef_wrapper torch.manual_seed(42) diff --git a/sw/dnn/softmax/scripts/datagen.py b/sw/dnn/softmax/scripts/datagen.py index 59c96b9f2..60d4dc62c 100755 --- a/sw/dnn/softmax/scripts/datagen.py +++ b/sw/dnn/softmax/scripts/datagen.py @@ -10,15 +10,11 @@ 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 +from snitch.util.sim import data_utils +from snitch.util.sim.data_utils import emit_license, format_struct_definition, \ + format_array_definition, format_array_declaration, format_ifdef_wrapper torch.manual_seed(42) diff --git a/sw/dnn/softmax/scripts/verify.py b/sw/dnn/softmax/scripts/verify.py index 0ad1df653..718a9e33c 100755 --- a/sw/dnn/softmax/scripts/verify.py +++ b/sw/dnn/softmax/scripts/verify.py @@ -4,15 +4,14 @@ # SPDX-License-Identifier: Apache-2.0 # # Luca Colagrande +# Viviane Potocnik import sys import torch -from pathlib import Path from datagen import golden_model -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class SoftmaxVerifier(Verifier): diff --git a/sw/dnn/transpose/scripts/datagen.py b/sw/dnn/transpose/scripts/datagen.py index 2ea51eea2..64ab02cad 100755 --- a/sw/dnn/transpose/scripts/datagen.py +++ b/sw/dnn/transpose/scripts/datagen.py @@ -8,14 +8,12 @@ # Luca Colagrande import numpy as np -import os import pyflexfloat as ff import sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../../../../util/sim/")) -from data_utils import ctype_from_precision_t, ff_desc_from_precision_t, \ - format_struct_definition, format_array_definition, \ - format_array_declaration, format_ifdef_wrapper, DataGen # noqa: E402 +from snitch.util.sim.data_utils import ctype_from_precision_t, ff_desc_from_precision_t, \ + format_struct_definition, format_array_definition, format_array_declaration, \ + format_ifdef_wrapper, DataGen np.random.seed(42) diff --git a/sw/dnn/transpose/scripts/verify.py b/sw/dnn/transpose/scripts/verify.py index 823e397a0..145a6fb7f 100755 --- a/sw/dnn/transpose/scripts/verify.py +++ b/sw/dnn/transpose/scripts/verify.py @@ -6,12 +6,10 @@ # Luca Colagrande import sys -from pathlib import Path from datagen import TransposeDataGen -sys.path.append(str(Path(__file__).parent / '../../../../util/sim/')) -from verif_utils import Verifier # noqa: E402 -from data_utils import ctype_from_precision_t # noqa: E402 +from snitch.util.sim.verif_utils import Verifier +from snitch.util.sim.data_utils import ctype_from_precision_t class TransposeVerifier(Verifier): diff --git a/util/sim/Elf.py b/util/sim/Elf.py index 0e2f530df..27c73074b 100644 --- a/util/sim/Elf.py +++ b/util/sim/Elf.py @@ -6,7 +6,7 @@ from elftools.elf.elffile import ELFFile from elftools.elf.sections import SymbolTableSection -from data_utils import from_buffer +from snitch.util.sim.data_utils import from_buffer class Elf(object): diff --git a/util/sim/verif_utils.py b/util/sim/verif_utils.py index 2a948fbfa..80b3078b5 100644 --- a/util/sim/verif_utils.py +++ b/util/sim/verif_utils.py @@ -11,9 +11,9 @@ import argparse import numpy as np import csv -from Elf import Elf +from snitch.util.sim.Elf import Elf from pathlib import Path -from data_utils import flatten, from_buffer +from snitch.util.sim.data_utils import flatten, from_buffer sys.path.append(str(Path(__file__).parent / '../../target/common/test/')) from SnitchSim import SnitchSim # noqa: E402 From 76d5d1ef8a73899a021696cd15f10e926da3a3dd Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 14:50:53 +0200 Subject: [PATCH 2/8] [pyproject] Add license header --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 44b08ad10..9e1fc9597 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +# Copyright 2023 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 + [build-system] requires = ["setuptools>=42"] build-backend = "setuptools.build_meta" From 8a010343c7677b8c626743b4fe0436c8039c5978 Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 14:52:29 +0200 Subject: [PATCH 3/8] [sw] layernorm: remove unused imports --- sw/dnn/layernorm/scripts/datagen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sw/dnn/layernorm/scripts/datagen.py b/sw/dnn/layernorm/scripts/datagen.py index 1bb1e6996..f9ba02941 100755 --- a/sw/dnn/layernorm/scripts/datagen.py +++ b/sw/dnn/layernorm/scripts/datagen.py @@ -17,7 +17,7 @@ import pyflexfloat as ff from snitch.util.sim import data_utils -from snitch.util.sim.data_utils import DataGen, format_array_declaration, \ +from snitch.util.sim.data_utils import format_array_declaration, \ format_struct_definition, format_array_definition, format_ifdef_wrapper, \ emit_license From f28f88a208ddba2c0858d98d8e7b998d92c494d6 Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 15:01:04 +0200 Subject: [PATCH 4/8] [sw] layernorm: remove unused imports --- sw/dnn/layernorm/scripts/datagen.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sw/dnn/layernorm/scripts/datagen.py b/sw/dnn/layernorm/scripts/datagen.py index f9ba02941..37f1fb3b5 100755 --- a/sw/dnn/layernorm/scripts/datagen.py +++ b/sw/dnn/layernorm/scripts/datagen.py @@ -10,7 +10,6 @@ import argparse import pathlib import json5 -import sys import torch import numpy as np From 37dd3ab84425622e846b3fac647e9af76469275d Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 15:32:04 +0200 Subject: [PATCH 5/8] [treewide] formatting: align all Python sources and fix import errors on init scripts --- sw/blas/__init__.py | 2 +- sw/blas/gemm/__init__.py | 4 +++- sw/dnn/flashattention_2/__init__.py | 8 +++++++- sw/dnn/flashattention_2/scripts/datagen.py | 17 ++--------------- sw/dnn/fused_concat_linear/__init__.py | 4 +++- sw/dnn/fused_concat_linear/scripts/datagen.py | 2 +- sw/dnn/gelu/scripts/datagen.py | 2 +- sw/dnn/layernorm/__init__.py | 5 ++++- util/trace/a2l.py | 2 +- util/trace/layout_events.py | 6 +++--- 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/sw/blas/__init__.py b/sw/blas/__init__.py index d20a3c84d..c3acdebaa 100644 --- a/sw/blas/__init__.py +++ b/sw/blas/__init__.py @@ -6,4 +6,4 @@ from . import gemm -__all__ = ['gemm'] \ No newline at end of file +__all__ = ['gemm'] diff --git a/sw/blas/gemm/__init__.py b/sw/blas/gemm/__init__.py index aed54f147..8432d35c7 100644 --- a/sw/blas/gemm/__init__.py +++ b/sw/blas/gemm/__init__.py @@ -4,4 +4,6 @@ # # Luca Colagrande -from .scripts.datagen import * +from .scripts.datagen import GemmDataGen + +__all__ = ['GemmDataGen'] diff --git a/sw/dnn/flashattention_2/__init__.py b/sw/dnn/flashattention_2/__init__.py index 70d256c82..319745fc7 100644 --- a/sw/dnn/flashattention_2/__init__.py +++ b/sw/dnn/flashattention_2/__init__.py @@ -3,5 +3,11 @@ # SPDX-License-Identifier: Apache-2.0 # # Luca Colagrande +# Viviane Potocnik -from .scripts.datagen import * \ No newline at end of file +from .scripts.datagen import exact_golden_model, exact_flexfloat_golden_model, \ + get_gemm_implementation, load_params, \ + validate, emit_header + +__all__ = ['exact_golden_model', 'exact_flexfloat_golden_model', + 'get_gemm_implementation', 'load_params', 'validate', 'emit_header'] diff --git a/sw/dnn/flashattention_2/scripts/datagen.py b/sw/dnn/flashattention_2/scripts/datagen.py index 37c65d21f..39103b855 100755 --- a/sw/dnn/flashattention_2/scripts/datagen.py +++ b/sw/dnn/flashattention_2/scripts/datagen.py @@ -14,7 +14,7 @@ import pyflexfloat as ff from snitch.util.sim import data_utils -from snitch.util.sim.data_utils import DataGen, format_struct_definition, \ +from snitch.util.sim.data_utils import format_struct_definition, \ format_array_definition, format_array_declaration, emit_license from snitch.blas import gemm @@ -135,18 +135,6 @@ def exact_flexfloat_golden_model(Q, K, V, B_r, B_c, desc): return np.concatenate(O_tiles, 0) -def get_gemm_implementation(self, params): - prec = params['dtype'].lower() - impl = f'gemm_{prec}_' - if params['baseline']: - impl += 'naive' - else: - impl += 'opt' - if prec == 'fp8': - impl += '_ex' - return impl - - def load_params(self, params): self.L = params['L'] self.S = params['S'] @@ -162,9 +150,8 @@ def load_params(self, params): self.ctype = data_utils.ctype_from_precision_t(self.dtype) self.prec = data_utils.size_from_precision_t(self.dtype) -# Verify layer parameters are valid - +# Verify layer parameters are valid def validate(self): assert (self.L % self.B_r) == 0, 'L is not an integer multiple of B_r' assert (self.S % self.B_c) == 0, 'S is not an integer multiple of B_c' diff --git a/sw/dnn/fused_concat_linear/__init__.py b/sw/dnn/fused_concat_linear/__init__.py index 70d256c82..4a88f9969 100644 --- a/sw/dnn/fused_concat_linear/__init__.py +++ b/sw/dnn/fused_concat_linear/__init__.py @@ -4,4 +4,6 @@ # # Luca Colagrande -from .scripts.datagen import * \ No newline at end of file +from .scripts.datagen import golden_model, emit_header + +__all__ = ['golden_model', 'emit_header'] diff --git a/sw/dnn/fused_concat_linear/scripts/datagen.py b/sw/dnn/fused_concat_linear/scripts/datagen.py index 84728b173..bffd80a2a 100755 --- a/sw/dnn/fused_concat_linear/scripts/datagen.py +++ b/sw/dnn/fused_concat_linear/scripts/datagen.py @@ -14,7 +14,7 @@ import torch from snitch.util.sim import data_utils -from snitch.util.sim.data_utils import DataGen, format_struct_definition, \ +from snitch.util.sim.data_utils import format_struct_definition, \ format_array_definition, format_array_declaration, format_ifdef_wrapper, \ emit_license diff --git a/sw/dnn/gelu/scripts/datagen.py b/sw/dnn/gelu/scripts/datagen.py index 9d2fda749..5a4084fb0 100755 --- a/sw/dnn/gelu/scripts/datagen.py +++ b/sw/dnn/gelu/scripts/datagen.py @@ -13,7 +13,7 @@ import torch from snitch.util.sim import data_utils -from snitch.util.sim.data_utils import DataGen, format_struct_definition, \ +from snitch.util.sim.data_utils import format_struct_definition, \ format_array_definition, format_array_declaration, format_ifdef_wrapper, \ emit_license diff --git a/sw/dnn/layernorm/__init__.py b/sw/dnn/layernorm/__init__.py index 70d256c82..65f0cf5a3 100644 --- a/sw/dnn/layernorm/__init__.py +++ b/sw/dnn/layernorm/__init__.py @@ -4,4 +4,7 @@ # # Luca Colagrande -from .scripts.datagen import * \ No newline at end of file +from .scripts.datagen import golden_model, golden_model_torch, \ + validate_config, emit_header + +__all__ = ['golden_model', 'golden_model_torch', 'validate_config', 'emit_header'] diff --git a/util/trace/a2l.py b/util/trace/a2l.py index c62633739..ad345a011 100644 --- a/util/trace/a2l.py +++ b/util/trace/a2l.py @@ -103,7 +103,7 @@ def __init__(self, elf, a2l_binary='addr2line'): @lru_cache(maxsize=1024) def addr2line(self, addr): - if type(addr) == str: + if isinstance(addr, str): addr = int(addr, 16) cmd = f'{self.a2l} -e {self.elf} -f -i {addr:x}' return Addr2LineOutput(os.popen(cmd).read()) diff --git a/util/trace/layout_events.py b/util/trace/layout_events.py index 0d0e91435..2e0df1681 100755 --- a/util/trace/layout_events.py +++ b/util/trace/layout_events.py @@ -100,7 +100,7 @@ def main(): # Symbols must be added to globals to be used in list comprehensions # see https://bugs.python.org/issue36300 tids = eval(code, {'cfg': cfg}, {'cfg': cfg}) - if type(tids) == int: + if isinstance(tids, int): tids = [tids] # Iterate hart IDs @@ -120,9 +120,9 @@ def main(): row_idx = tid col_idx = 1 + reg_idx * 2 assert row_idx < df.shape[0], f'Hart ID {row_idx} out of bounds' - assert (col_idx + 1) < df.shape[1],\ + assert (col_idx + 1) < df.shape[1], \ f'Region index {reg_idx} out of bounds for hart {tid}' - assert not isnan(df.iat[row_idx, col_idx]),\ + assert not isnan(df.iat[row_idx, col_idx]), \ (f'Region {reg_idx} looks empty for hart {tid},' f'check whether it was simulated') orow.append(int(df.iat[row_idx, col_idx])) From 47989bc81c7213ba0af5be2545d3aae05c1e527b Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 15:59:46 +0200 Subject: [PATCH 6/8] [Docker] Allow local changes in pip for pyproject --- .github/workflows/build-docker.yml | 4 ++-- .github/workflows/ci.yml | 6 +++--- util/container/Dockerfile | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 5c073ab5d..82aed938c 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -6,7 +6,7 @@ name: build-docker on: push: - branches: [main] + branches: [jssc/double-buffering] workflow_dispatch: jobs: build-docker: @@ -39,6 +39,6 @@ jobs: context: . file: util/container/Dockerfile push: true - tags: ghcr.io/pulp-platform/snitch_cluster:${{ github.ref_name }} + tags: ghcr.io/pulp-platform/snitch_cluster:double-buffering build-args: |- SNITCH_LLVM_VERSION=latest diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d73348e8..fc14f2224 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: name: Build documentation runs-on: ubuntu-22.04 container: - image: ghcr.io/pulp-platform/snitch_cluster:main + image: ghcr.io/pulp-platform/snitch_cluster:double-buffering steps: - uses: actions/checkout@v2 - name: Build docs @@ -29,7 +29,7 @@ jobs: name: Simulate SW on Snitch Cluster w/ Verilator runs-on: ubuntu-22.04 container: - image: ghcr.io/pulp-platform/snitch_cluster:main + image: ghcr.io/pulp-platform/snitch_cluster:double-buffering steps: - uses: actions/checkout@v2 with: @@ -61,7 +61,7 @@ jobs: name: Simulate SW on Snitch Cluster w/ Banshee runs-on: ubuntu-22.04 container: - image: ghcr.io/pulp-platform/snitch_cluster:main + image: ghcr.io/pulp-platform/snitch_cluster:double-buffering steps: - uses: actions/checkout@v2 with: diff --git a/util/container/Dockerfile b/util/container/Dockerfile index f6e98f713..6ecf877a3 100644 --- a/util/container/Dockerfile +++ b/util/container/Dockerfile @@ -159,6 +159,7 @@ COPY python-requirements.txt /tmp/python-requirements.txt COPY docs/requirements.txt /tmp/docs/requirements.txt COPY sw/dnn/requirements.txt /tmp/sw/dnn/requirements.txt RUN pip install -r /tmp/python-requirements.txt +RUN pip install -e . # Add Verilator to PATH ENV PATH "/tools/verilator/bin:${PATH}" From 074a2ac4bd44b14986d0aa97abbb8163c490c991 Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 16:15:52 +0200 Subject: [PATCH 7/8] [REVERT] Docker: build on PR --- .github/workflows/build-docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 82aed938c..3f8d84db7 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -7,6 +7,7 @@ name: build-docker on: push: branches: [jssc/double-buffering] + pull_request: workflow_dispatch: jobs: build-docker: From 752785d6903e548b062378eab7e60d1c68bdc70c Mon Sep 17 00:00:00 2001 From: Viviane Potocnik Date: Thu, 8 Aug 2024 17:08:46 +0200 Subject: [PATCH 8/8] [DOCKER] Copy repo to temp for pip installations --- util/container/Dockerfile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/util/container/Dockerfile b/util/container/Dockerfile index 6ecf877a3..d9b52238e 100644 --- a/util/container/Dockerfile +++ b/util/container/Dockerfile @@ -155,11 +155,9 @@ ENV VIRTUAL_ENV "/root/.venvs/snitch_cluster" RUN /opt/python/bin/python3 -m venv ${VIRTUAL_ENV} ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" # Install Python requirements -COPY python-requirements.txt /tmp/python-requirements.txt -COPY docs/requirements.txt /tmp/docs/requirements.txt -COPY sw/dnn/requirements.txt /tmp/sw/dnn/requirements.txt -RUN pip install -r /tmp/python-requirements.txt -RUN pip install -e . +COPY . /tmp/snitch_cluster +RUN pip install -r /tmp/snitch_cluster/python-requirements.txt +RUN pip install /tmp/snitch_cluster/ # Add Verilator to PATH ENV PATH "/tools/verilator/bin:${PATH}"