From c5cb1be3e12d08525f957c791596aafcf9cdb53f Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Fri, 11 Apr 2025 11:54:33 +0200 Subject: [PATCH 1/9] Add dedicated CMakeLists.txt to target HALs and util --- CMakeLists.txt | 15 +++++++-------- ne16/hal/CMakeLists.txt | 14 ++++++++++++++ neureka/hal/CMakeLists.txt | 14 ++++++++++++++ neureka_v2/hal/CMakeLists.txt | 14 ++++++++++++++ util/CMakeLists.txt | 7 +++++++ 5 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 ne16/hal/CMakeLists.txt create mode 100644 neureka/hal/CMakeLists.txt create mode 100644 neureka_v2/hal/CMakeLists.txt create mode 100644 util/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index ccc952d..4c1a431 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,7 @@ project(pulp-nnx add_library(pulp-nnx STATIC) -target_sources(pulp-nnx PRIVATE util/pulp_nnx_util.c util/hwpe.c) -target_include_directories(pulp-nnx PUBLIC inc util) +target_include_directories(pulp-nnx PUBLIC inc) option(USE_NE16 "Use the NE16 accelerator.") option(USE_NEUREKA "Use the N-EUREKA accelerator.") @@ -20,6 +19,8 @@ endif() if (${USE_NE16}) message(STATUS "[PULP-NNX] Using the NE16 accelerator.") + add_subdirectory(ne16/hal) + target_link_libraries(pulp-nnx PUBLIC pulp-nnx-hal-ne16) target_sources(pulp-nnx PRIVATE ne16/bsp/ne16_pulp_bsp.c @@ -37,34 +38,32 @@ endif() if (${USE_NEUREKA}) message(STATUS "[PULP-NNX] Using the N-EUREKA accelerator.") + add_subdirectory(neureka/hal) + target_link_libraries(pulp-nnx PUBLIC pulp-nnx-hal-neureka) target_sources(pulp-nnx PRIVATE neureka/bsp/neureka_siracusa_bsp.c - neureka/hal/neureka.c - neureka/hal/neureka_task.c src/pulp_nnx_neureka.c ) target_include_directories(pulp-nnx PUBLIC neureka/bsp - neureka/hal neureka/gvsoc ) endif() if (${USE_NEUREKA_V2}) message(STATUS "[PULP-NNX] Using the N-EUREKA v2 accelerator.") + add_subdirectory(neureka_v2/hal) + target_link_libraries(pulp-nnx PUBLIC pulp-nnx-hal-neureka-v2) target_sources(pulp-nnx PRIVATE neureka_v2/bsp/neureka_v2_siracusa_bsp.c - neureka_v2/hal/neureka_v2.c - neureka_v2/hal/neureka_v2_task.c src/pulp_nnx_neureka_v2.c ) target_include_directories(pulp-nnx PUBLIC neureka_v2/bsp - neureka_v2/hal neureka_v2/gvsoc ) endif() diff --git a/ne16/hal/CMakeLists.txt b/ne16/hal/CMakeLists.txt new file mode 100644 index 0000000..1ec87db --- /dev/null +++ b/ne16/hal/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.18) + +project(pulp-nnx-hal-ne16 LANGUAGES C) + +add_library(pulp-nnx-hal-ne16 + STATIC + ne16.c + ne16_task.c +) + +target_include_directories(pulp-nnx-hal-ne16 PUBLIC .) + +add_subdirectory(../../util pulp-nnx-util) +target_link_libraries(pulp-nnx-hal-ne16 PUBLIC pulp-nnx-util) diff --git a/neureka/hal/CMakeLists.txt b/neureka/hal/CMakeLists.txt new file mode 100644 index 0000000..14b9f20 --- /dev/null +++ b/neureka/hal/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.18) + +project(pulp-nnx-hal-neureka LANGUAGES C) + +add_library(pulp-nnx-hal-neureka + STATIC + neureka.c + neureka_task.c +) + +target_include_directories(pulp-nnx-hal-neureka PUBLIC .) + +add_subdirectory(../../util pulp-nnx-util) +target_link_libraries(pulp-nnx-hal-neureka PUBLIC pulp-nnx-util) diff --git a/neureka_v2/hal/CMakeLists.txt b/neureka_v2/hal/CMakeLists.txt new file mode 100644 index 0000000..ae80728 --- /dev/null +++ b/neureka_v2/hal/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.18) + +project(pulp-nnx-hal-neureka-v2 LANGUAGES C) + +add_library(pulp-nnx-hal-neureka-v2 + STATIC + neureka_v2.c + neureka_v2_task.c +) + +target_include_directories(pulp-nnx-hal-neureka-v2 PUBLIC .) + +add_subdirectory(../../util pulp-nnx-util) +target_link_libraries(pulp-nnx-hal-neureka-v2 PUBLIC pulp-nnx-util) diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt new file mode 100644 index 0000000..27e8fe7 --- /dev/null +++ b/util/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(pulp-nnx-util + OBJECT + hwpe.c + pulp_nnx_util.c +) + +target_include_directories(pulp-nnx-util PUBLIC .) From 1bfc79f7e8dd6081a0e499b829de614a2e0aed33 Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Fri, 11 Apr 2025 13:50:25 +0200 Subject: [PATCH 2/9] Add test for pulp-nnx-hal --- .github/workflows/test-neureka_v2.yml | 3 +- test/.gitignore | 4 +- test/NnxBuildFlow.py | 36 ++- test/NnxTestClasses.py | 6 +- test/README.md | 7 +- test/apps/pulp-nnx-hal/CMakeLists.txt | 36 +++ test/{app => apps/pulp-nnx-hal}/README.md | 0 .../pulp-nnx-hal}/cmake/pulp-sdk-base.cmake | 0 .../cmake/pulp-sdk-siracusa.cmake | 0 .../pulp-nnx-hal}/cmake/toolchain_gnu.cmake | 0 .../pulp-nnx-hal}/inc/layer_util.h | 0 .../pulp-nnx-hal}/inc/nnx_layer.h | 0 test/{app => apps/pulp-nnx-hal}/src/main.c | 0 test/apps/pulp-nnx-hal/src/nnx_layer.c | 253 ++++++++++++++++++ test/{app => apps/pulp-nnx}/CMakeLists.txt | 2 +- test/{app => apps/pulp-nnx}/Makefile | 2 +- test/apps/pulp-nnx/README.md | 36 +++ test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake | 75 ++++++ .../pulp-nnx/cmake/pulp-sdk-siracusa.cmake | 62 +++++ test/apps/pulp-nnx/cmake/toolchain_gnu.cmake | 51 ++++ test/apps/pulp-nnx/inc/layer_util.h | 40 +++ test/apps/pulp-nnx/inc/nnx_layer.h | 26 ++ test/apps/pulp-nnx/src/main.c | 66 +++++ test/{app => apps/pulp-nnx}/src/nnx_layer.c | 0 test/conftest.py | 21 +- test/test.py | 7 +- test/testgen.py | 10 +- 27 files changed, 711 insertions(+), 32 deletions(-) create mode 100644 test/apps/pulp-nnx-hal/CMakeLists.txt rename test/{app => apps/pulp-nnx-hal}/README.md (100%) rename test/{app => apps/pulp-nnx-hal}/cmake/pulp-sdk-base.cmake (100%) rename test/{app => apps/pulp-nnx-hal}/cmake/pulp-sdk-siracusa.cmake (100%) rename test/{app => apps/pulp-nnx-hal}/cmake/toolchain_gnu.cmake (100%) rename test/{app => apps/pulp-nnx-hal}/inc/layer_util.h (100%) rename test/{app => apps/pulp-nnx-hal}/inc/nnx_layer.h (100%) rename test/{app => apps/pulp-nnx-hal}/src/main.c (100%) create mode 100644 test/apps/pulp-nnx-hal/src/nnx_layer.c rename test/{app => apps/pulp-nnx}/CMakeLists.txt (97%) rename test/{app => apps/pulp-nnx}/Makefile (98%) create mode 100644 test/apps/pulp-nnx/README.md create mode 100644 test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake create mode 100644 test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake create mode 100644 test/apps/pulp-nnx/cmake/toolchain_gnu.cmake create mode 100644 test/apps/pulp-nnx/inc/layer_util.h create mode 100644 test/apps/pulp-nnx/inc/nnx_layer.h create mode 100644 test/apps/pulp-nnx/src/main.c rename test/{app => apps/pulp-nnx}/src/nnx_layer.c (100%) diff --git a/.github/workflows/test-neureka_v2.yml b/.github/workflows/test-neureka_v2.yml index 4ee3049..604e6ec 100644 --- a/.github/workflows/test-neureka_v2.yml +++ b/.github/workflows/test-neureka_v2.yml @@ -57,4 +57,5 @@ jobs: export TOOLCHAIN_GNU_INSTALL_DIR=$GITHUB_WORKSPACE/toolchain/gnu export GVSOC=$GITHUB_WORKSPACE/gvsoc/install/bin/gvsoc cd pulp-nnx/test - pytest test.py -T tests -R -A neureka_v2 --build-flow=cmake --wmem=mram + pytest test.py --test-dir=tests --recursive --accelerator=neureka_v2 --build-flow=cmake --wmem=mram --app=pulp-nnx + pytest test.py --test-dir=tests --recursive --accelerator=neureka_v2 --build-flow=cmake --wmem=mram --app=pulp-nnx-hal diff --git a/test/.gitignore b/test/.gitignore index 50a0e48..ac1b249 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,10 +1,10 @@ BUILD build -app/build* +apps/**/build* +apps/**/gen __pycache__ .cache .pytest_cache -app/gen **/compile_commands.json **/*.log **/*.pt diff --git a/test/NnxBuildFlow.py b/test/NnxBuildFlow.py index ecd4e8d..4e21842 100644 --- a/test/NnxBuildFlow.py +++ b/test/NnxBuildFlow.py @@ -8,10 +8,23 @@ from NnxMapping import NnxName +class AppName(Enum): + pulp_nnx = "pulp-nnx" + pulp_nnx_hal = "pulp-nnx-hal" + + def __str__(self): + return self.value + + def path(self): + return f"apps/{self}" + + class NnxBuildFlow(ABC): @abstractmethod - def __init__(self, nnxName: NnxName) -> None: ... + def __init__(self, nnxName: NnxName, appName: AppName) -> None: + self.nnxName = nnxName + self.appName = appName @abstractmethod def build(self) -> None: ... @@ -31,11 +44,8 @@ def cmd_run(cmd: str, env=None) -> str: class MakeBuildFlow(NnxBuildFlow): - BUILD_CMD = "make -C app all platform=gvsoc" - RUN_CMD = "make -C app run platform=gvsoc" - - def __init__(self, nnxName: NnxName) -> None: - self.nnxName = nnxName + def __init__(self, nnxName: NnxName, appName: AppName) -> None: + super().__init__(nnxName, appName) def env(self) -> os._Environ: _env = os.environ @@ -43,11 +53,11 @@ def env(self) -> os._Environ: return _env def build(self) -> None: - Path("app/src/nnx_layer.c").touch() - _ = NnxBuildFlow.cmd_run(MakeBuildFlow.BUILD_CMD, self.env()) + Path(f"{self.appName.path()}/src/nnx_layer.c").touch() + _ = NnxBuildFlow.cmd_run(f"make -C {self.appName.path()} all platform=gvsoc", self.env()) def run(self) -> str: - return NnxBuildFlow.cmd_run(MakeBuildFlow.RUN_CMD, self.env()) + return NnxBuildFlow.cmd_run(f"make -C {self.appName.path()} run platform=gvsoc", self.env()) def __str__(self) -> str: return "make" @@ -58,16 +68,16 @@ class CmakeBuildFlow(NnxBuildFlow): TOOLCHAIN_FILE = "cmake/toolchain_gnu.cmake" GVSOC_TARGET = "siracusa" - def __init__(self, nnxName: NnxName) -> None: - self.nnxName = nnxName - self.build_dir = os.path.abspath(f"app/build_{nnxName}") + def __init__(self, nnxName: NnxName, appName: AppName) -> None: + super().__init__(nnxName, appName) + self.build_dir = os.path.abspath(f"{self.appName.path()}/build_{nnxName}") self.gvsoc_workdir = os.path.join(self.build_dir, "gvsoc_workdir") assert "GVSOC" in os.environ, "The GVSOC environment variable is not set." def prepare(self) -> None: os.makedirs(self.gvsoc_workdir, exist_ok=True) subprocess.run( - f"cmake -Sapp -B{self.build_dir} -GNinja -DCMAKE_TOOLCHAIN_FILE={CmakeBuildFlow.TOOLCHAIN_FILE} -DACCELERATOR={self.nnxName}".split(), + f"cmake -S{self.appName.path()} -B{self.build_dir} -GNinja -DCMAKE_TOOLCHAIN_FILE={CmakeBuildFlow.TOOLCHAIN_FILE} -DACCELERATOR={self.nnxName}".split(), check=True, ) diff --git a/test/NnxTestClasses.py b/test/NnxTestClasses.py index ae5856f..e7fc4eb 100644 --- a/test/NnxTestClasses.py +++ b/test/NnxTestClasses.py @@ -406,15 +406,11 @@ def source_generate( class NnxTestHeaderGenerator: - DEFAULT_HEADERS_DIR = "app/gen" - def __init__( self, nnxWeight: NnxWeight, - headers_dir: Optional[Union[str, os.PathLike]] = None, + headers_dir: Union[str, os.PathLike], ): - if headers_dir is None: - headers_dir = NnxTestHeaderGenerator.DEFAULT_HEADERS_DIR self.header_writer = HeaderWriter(headers_dir) # function that takes the weights in CoutCinK format, bitwidth, and a depthwise flag, # and returns a numpy array of dtype=np.uint8 of data in a layout correct for the accelerator diff --git a/test/README.md b/test/README.md index 5cc3e93..7f58afc 100644 --- a/test/README.md +++ b/test/README.md @@ -2,7 +2,7 @@ ## Repository structure -- app: test application +- app_*: test application - inc: test application headers - src: test application sources - gen_inc: generated test headers for data and test information @@ -36,6 +36,7 @@ $ pytest test.py --help For more information you can run the script with the `-h` flag. -## Application +## Applications -For information on the testing application and how to build it, take a look in its [README.md](app/README.md). +There are 2 applications provided, one testing the more abstract pulp_nnx interface and another one just the hardware abstraction layer, called `app_pulp_nnx` and `app_pulp_nnx_hal`. +For information on the testing applications and how to build them, take a look in their dedicated readmes: [app_pulp_nnx/README.md](app_pulp_nnx/README.md) and [app_pulp_nnx_hal/README.md](app_pulp_nnx_hal/README.md). diff --git a/test/apps/pulp-nnx-hal/CMakeLists.txt b/test/apps/pulp-nnx-hal/CMakeLists.txt new file mode 100644 index 0000000..9661332 --- /dev/null +++ b/test/apps/pulp-nnx-hal/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.18) + +# This is to omit the cross-compilation test +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + +project(test-pulp-nnx + LANGUAGES C ASM) + +add_executable(test-pulp-nnx) + +file(GLOB gen_srcs CONFIGURE_DEPENDS gen/src/*.c) +set(app_srcs src/main.c src/nnx_layer.c) + +target_sources(test-pulp-nnx PRIVATE ${app_srcs} ${gen_srcs}) +target_include_directories(test-pulp-nnx PRIVATE inc gen/inc) + +set(NUM_CORES 8 CACHE STRING "Set the number of cores used. Default 8") +set(ACCELERATOR neureka CACHE STRING "Choose an accelerator to compile the library for. Default ne16") +set_property(CACHE ACCELERATOR PROPERTY STRINGS neureka neureka_v2) + +add_compile_options(-DNUM_CORES=${NUM_CORES}) + +include(cmake/pulp-sdk-siracusa.cmake) +target_link_libraries(test-pulp-nnx PRIVATE pulp-sdk) + +if(${ACCELERATOR} STREQUAL neureka) + add_subdirectory(../../../neureka/hal pulp-nnx-hal) + target_link_libraries(test-pulp-nnx PRIVATE pulp-nnx-hal-neureka) + target_compile_definitions(test-pulp-nnx PRIVATE NNX_ACCELERATOR="neureka" NNX_NEUREKA) +elseif(${ACCELERATOR} STREQUAL neureka_v2) + add_subdirectory(../../../neureka_v2/hal pulp-nnx-hal) + target_link_libraries(test-pulp-nnx PRIVATE pulp-nnx-hal-neureka-v2) + target_compile_definitions(test-pulp-nnx PRIVATE NNX_ACCELERATOR="neureka_v2" NNX_NEUREKA_V2) +else() + message(FATAL_ERROR "Unrecognized accelerator detected: \"${ACCELERATOR}\"") +endif() diff --git a/test/app/README.md b/test/apps/pulp-nnx-hal/README.md similarity index 100% rename from test/app/README.md rename to test/apps/pulp-nnx-hal/README.md diff --git a/test/app/cmake/pulp-sdk-base.cmake b/test/apps/pulp-nnx-hal/cmake/pulp-sdk-base.cmake similarity index 100% rename from test/app/cmake/pulp-sdk-base.cmake rename to test/apps/pulp-nnx-hal/cmake/pulp-sdk-base.cmake diff --git a/test/app/cmake/pulp-sdk-siracusa.cmake b/test/apps/pulp-nnx-hal/cmake/pulp-sdk-siracusa.cmake similarity index 100% rename from test/app/cmake/pulp-sdk-siracusa.cmake rename to test/apps/pulp-nnx-hal/cmake/pulp-sdk-siracusa.cmake diff --git a/test/app/cmake/toolchain_gnu.cmake b/test/apps/pulp-nnx-hal/cmake/toolchain_gnu.cmake similarity index 100% rename from test/app/cmake/toolchain_gnu.cmake rename to test/apps/pulp-nnx-hal/cmake/toolchain_gnu.cmake diff --git a/test/app/inc/layer_util.h b/test/apps/pulp-nnx-hal/inc/layer_util.h similarity index 100% rename from test/app/inc/layer_util.h rename to test/apps/pulp-nnx-hal/inc/layer_util.h diff --git a/test/app/inc/nnx_layer.h b/test/apps/pulp-nnx-hal/inc/nnx_layer.h similarity index 100% rename from test/app/inc/nnx_layer.h rename to test/apps/pulp-nnx-hal/inc/nnx_layer.h diff --git a/test/app/src/main.c b/test/apps/pulp-nnx-hal/src/main.c similarity index 100% rename from test/app/src/main.c rename to test/apps/pulp-nnx-hal/src/main.c diff --git a/test/apps/pulp-nnx-hal/src/nnx_layer.c b/test/apps/pulp-nnx-hal/src/nnx_layer.c new file mode 100644 index 0000000..79780e9 --- /dev/null +++ b/test/apps/pulp-nnx-hal/src/nnx_layer.c @@ -0,0 +1,253 @@ +/* + * Luka Macan + * + * Copyright 2023 ETH Zurich and University of Bologna + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nnx_layer.h" +#include + +#ifdef NNX_NE16 + +#include "ne16.h" +#include "ne16_task.h" + +typedef ne16_norm_mode_e nnx_norm_mode_e; +typedef ne16_quant_t nnx_quant_t; +typedef ne16_quant_function_e nnx_quant_function_e; +typedef ne16_norm_t nnx_norm_t; +typedef ne16_task_t nnx_task_t; +typedef ne16_task_flag_e nnx_task_flag_e; +typedef ne16_task_data_t nnx_task_data_t; + +// Minimal copy from ne16/bsp/ne16_pulp_bsp.c +#define NE16_PULP_BASE_ADDR (0x00201000) +static const ne16_dev_t nnx_dev = { + .hwpe_dev = (struct hwpe_dev_t){ + .base_addr = (volatile uint32_t *)NE16_PULP_BASE_ADDR}}; + +#define nnxTaskFlagTrue ne16TaskFlagTrue +#define nnxTaskFlagFalse ne16TaskFlagFalse + +#define nnx_task_init ne16_task_init +#define nnx_task_set_op_to_conv ne16_task_set_op_to_conv +#define nnx_task_set_bits ne16_task_set_bits +#define nnx_task_set_norm_quant ne16_task_set_norm_quant +#define nnx_task_set_weight_offset ne16_task_set_weight_offset +#define nnx_task_set_dims ne16_task_set_dims +#define nnx_task_set_dims_stride2x2 ne16_task_set_dims_stride2x2 +#define nnx_task_set_addr_conv ne16_task_set_addr_conv +#define nnx_task_set_addr_norm_quant ne16_task_set_addr_norm_quant + +#define nnx_task_queue_empty ne16_task_queue_empty + +#elif defined NNX_NEUREKA + +#include "neureka.h" +#include "neureka_task.h" + +typedef neureka_norm_mode_e nnx_norm_mode_e; +typedef neureka_quant_t nnx_quant_t; +typedef neureka_quant_function_e nnx_quant_function_e; +typedef neureka_norm_t nnx_norm_t; +typedef neureka_task_t nnx_task_t; +typedef neureka_task_flag_e nnx_task_flag_e; +typedef neureka_task_data_t nnx_task_data_t; + +// Minimal copy from neureka/bsp/neureka_siracusa_bsp.c +#define NEUREKA_SIRACUSA_BASE_ADDR (0x00201000) +static const neureka_dev_t nnx_dev = { + .hwpe_dev = (struct hwpe_dev_t){ + .base_addr = (volatile uint32_t *)NEUREKA_SIRACUSA_BASE_ADDR}}; + +#define nnxTaskFlagTrue neurekaTaskFlagTrue +#define nnxTaskFlagFalse neurekaTaskFlagFalse + +#define nnx_task_init neureka_task_init +#define nnx_task_set_op_to_conv neureka_task_set_op_to_conv +#define nnx_task_set_bits neureka_task_set_bits +#define nnx_task_set_norm_quant neureka_task_set_norm_quant +#define nnx_task_set_weight_offset neureka_task_set_weight_offset +#define nnx_task_set_dims neureka_task_set_dims +#define nnx_task_set_addr_conv neureka_task_set_addr_conv +#define nnx_task_set_addr_norm_quant neureka_task_set_addr_norm_quant + +#define nnx_task_queue_empty neureka_task_queue_empty + +#elif defined NNX_NEUREKA_V2 + +#include "neureka_v2.h" +#include "neureka_v2_task.h" + +typedef neureka_v2_norm_mode_e nnx_norm_mode_e; +typedef neureka_v2_quant_t nnx_quant_t; +typedef neureka_v2_quant_function_e nnx_quant_function_e; +typedef neureka_v2_norm_t nnx_norm_t; +typedef neureka_v2_task_t nnx_task_t; +typedef neureka_v2_task_flag_e nnx_task_flag_e; +typedef neureka_v2_task_data_t nnx_task_data_t; + +// Minimal copy from neureka_v2/bsp/neureka_v2_siracusa_bsp.c +#define NEUREKA_V2_SIRACUSA_BASE_ADDR (0x00201000) +static const neureka_v2_dev_t nnx_dev = { + .hwpe_dev = (struct hwpe_dev_t){ + .base_addr = (volatile uint32_t *)NEUREKA_V2_SIRACUSA_BASE_ADDR}}; + +#define nnxTaskFlagTrue neurekaV2TaskFlagTrue +#define nnxTaskFlagFalse neurekaV2TaskFlagFalse + +#define nnx_task_init neureka_v2_task_init +#define nnx_task_set_op_to_conv neureka_v2_task_set_op_to_conv +#define nnx_task_set_bits neureka_v2_task_set_bits +#define nnx_task_set_norm_quant neureka_v2_task_set_norm_quant +#define nnx_task_set_weight_offset neureka_v2_task_set_weight_offset +#define nnx_task_set_dims neureka_v2_task_set_dims +#define nnx_task_set_addr_conv neureka_v2_task_set_addr_conv +#define nnx_task_set_addr_norm_quant neureka_v2_task_set_addr_norm_quant + +#define nnx_task_queue_empty neureka_v2_task_queue_empty + +#endif // NNX_NE16 || NNX_NEUREKA || NNX_NEUREKA_V2 + +// Generated headers +#include "input.h" +#include "output.h" +#include "weight.h" + +#include "layer_conf.h" + +// The HAS_NORM_QUANT and HAS_BIAS are defined in layer_conf.h +#if HAS_NORM_QUANT != 0 +#include "scale.h" +#if HAS_BIAS != 0 +#include "bias.h" +#endif +#endif + +static void task_prepare(nnx_task_t *task) { + nnx_task_init(task); +#if defined NNX_NEUREKA || defined NNX_NEUREKA_V2 + nnx_task_set_op_to_conv(task, WEIGHT_HEIGHT, GROUPS > 1); +#else + nnx_task_set_op_to_conv(task, WEIGHT_HEIGHT, GROUPS > 1, STRIDE_HEIGHT); +#endif + nnx_task_set_bits(task, INPUT_BITS, OUTPUT_BITS, WEIGHT_BITS); + +#if defined NNX_NE16 || defined NNX_NEUREKA + nnx_task_set_weight_offset(task, weightOffsetModeLayerWise, WEIGHT_OFFSET); +#elif defined NNX_NEUREKA_V2 + nnx_task_set_weight_offset(task, WEIGHT_OFFSET); +#endif + +#ifdef NNX_NEUREKA +#if INPUT_SIGNED == 1 + neureka_task_set_input_signed(task); +#else + neureka_task_set_input_unsigned(task); +#endif +#if defined WMEM_SRAM || defined WMEM_MRAM + neureka_task_set_weight_source(task, neurekaWeightSourceWmem); +#else + neureka_task_set_weight_source(task, neurekaWeightSourceTcdm); +#endif +#endif + +#ifdef NNX_NEUREKA_V2 +#if INPUT_SIGNED == 1 + neureka_v2_task_set_activation_signed(task); +#else + neureka_v2_task_set_activation_unsigned(task); +#endif +#if OUTPUT_SIGNED == 1 + neureka_v2_task_set_outfeat_signed(task); +#else + neureka_v2_task_set_outfeat_unsigned(task); +#endif +#if defined WMEM_SRAM || defined WMEM_MRAM + neureka_v2_task_set_weight_source(task, neurekaV2WeightSourceWmem); +#else + neureka_v2_task_set_weight_source(task, neurekaV2WeightSourceTcdm); +#endif +#endif + + const uint32_t w_in_stride = INPUT_CHANNEL * INPUT_BITS / 8; + const uint32_t h_in_stride = INPUT_WIDTH * w_in_stride; + const uint32_t w_out_stride = OUTPUT_CHANNEL * OUTPUT_BITS / 8; + const uint32_t h_out_stride = OUTPUT_WIDTH * w_out_stride; + +#if STRIDE_HEIGHT == 2 && STRIDE_WIDTH == 2 + nnx_task_set_dims_stride2x2( + task, INPUT_HEIGHT, INPUT_WIDTH, INPUT_CHANNEL, h_in_stride, w_in_stride, + OUTPUT_HEIGHT, OUTPUT_WIDTH, OUTPUT_CHANNEL, h_out_stride, w_out_stride, + WEIGHT_HEIGHT, WEIGHT_WIDTH, PADDING_TOP, PADDING_BOTTOM, PADDING_LEFT, + PADDING_RIGHT); +#else + nnx_task_set_dims(task, INPUT_WIDTH, INPUT_CHANNEL, h_in_stride, w_in_stride, + OUTPUT_HEIGHT, OUTPUT_WIDTH, OUTPUT_CHANNEL, h_out_stride, + w_out_stride, PADDING_TOP, PADDING_BOTTOM, PADDING_LEFT, + PADDING_RIGHT); +#endif + + nnx_task_set_addr_conv(task, (uint32_t)input, INPUT_WIDTH, w_in_stride, + PADDING_TOP, PADDING_LEFT, (uint32_t)output, + (uint32_t)weight); + +#if HAS_NORM_QUANT == 1 +#if SCALE_BITS == 8 + const nnx_norm_mode_e normMode = normMode8Bit; +#elif SCALE_BITS == 32 + const nnx_norm_mode_e normMode = normMode32Bit; +#endif + + const nnx_task_flag_e flag_bias = + HAS_BIAS ? nnxTaskFlagTrue : nnxTaskFlagFalse; +#if HAS_BIAS == 1 + const uint32_t bias_addr = (uint32_t)bias; +#else + const uint32_t bias_addr = (uint32_t)NULL; +#endif + + nnx_quant_function_e quant_function = + HAS_RELU ? quantFunctionRelu : quantFunctionIdentity; + + nnx_task_set_norm_quant(task, + (nnx_quant_t){.shift_amount = OUTSHIFT, + .function = quant_function, + .flag_rounding = nnxTaskFlagFalse}, + (nnx_norm_t){.mode = normMode, + .flag_bias = flag_bias, + .flag_shift = nnxTaskFlagFalse}); + + nnx_task_set_addr_norm_quant(task, (uint32_t)scale, (uint32_t)NULL, + bias_addr); +#endif // HAS_NORM_QUANT +} + +static void task_execute(nnx_task_t *task) { + hwpe_task_queue_acquire_task(&nnx_dev.hwpe_dev, &task->id); + hwpe_task_queue_write_task(&nnx_dev.hwpe_dev, (uint32_t *)&task->data, + (int)(sizeof(nnx_task_data_t) / 4)); + hwpe_task_queue_release_and_run(&nnx_dev.hwpe_dev); + while (!nnx_task_queue_empty(&nnx_dev)) + ; +} + +void execute_nnx_layer(void *args) { + nnx_task_t task; + task_prepare(&task); + task_execute(&task); +} diff --git a/test/app/CMakeLists.txt b/test/apps/pulp-nnx/CMakeLists.txt similarity index 97% rename from test/app/CMakeLists.txt rename to test/apps/pulp-nnx/CMakeLists.txt index 1c44488..53d6776 100644 --- a/test/app/CMakeLists.txt +++ b/test/apps/pulp-nnx/CMakeLists.txt @@ -33,7 +33,7 @@ else() message(FATAL_ERROR "Unrecognized accelerator detected: \"${ACCELERATOR}\"") endif() -add_subdirectory(../.. pulp-nnx) +add_subdirectory(../../.. pulp-nnx) target_link_libraries(pulp-nnx PUBLIC pulp-sdk) target_include_directories(pulp-nnx SYSTEM PUBLIC ${PULP_SDK_INCLUDES}) target_link_libraries(test-pulp-nnx PRIVATE pulp-nnx) diff --git a/test/app/Makefile b/test/apps/pulp-nnx/Makefile similarity index 98% rename from test/app/Makefile rename to test/apps/pulp-nnx/Makefile index ca65892..b150d30 100644 --- a/test/app/Makefile +++ b/test/apps/pulp-nnx/Makefile @@ -21,7 +21,7 @@ ACCELERATOR ?= ne16 APP := main -LIBDIR := $(abspath ../..) +LIBDIR := $(abspath ../../..) ACC_DIR := $(LIBDIR)/$(ACCELERATOR) diff --git a/test/apps/pulp-nnx/README.md b/test/apps/pulp-nnx/README.md new file mode 100644 index 0000000..aa9a03a --- /dev/null +++ b/test/apps/pulp-nnx/README.md @@ -0,0 +1,36 @@ +# Test application + +## Build + +There are two build flows given for the test app, the Make one and the CMake one. +Both flows use a flag `ACCELERATOR` to decide which accelerator to build the application for. +Choices are _neureka_ and _neureka_v2_. + +### Make + +For the Make flow you need to specify the `ACCELERATOR` flag either as an environment variable +``` +export ACCELERATOR= +``` +or you can add it to the make command +``` +ACCELERATOR= make clean all run +``` + +### CMake + +For the cmake build you have to specify the `ACCELERATOR` flag with `-DACCLERATOR= and the toolchain file with the `-DCMAKE_TOOLCHAIN_FILE` flag: +``` +cmake -S . -B build -G Ninja -DACCELERATOR= -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_.cmake +``` + +After that you can build the application by running: +``` +cmake --build build +``` + +No need to regenerate the project (1st cmake command) after altering the sources, just rerun the build. + +## TODO + +- environment variables that need to be set diff --git a/test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake b/test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake new file mode 100644 index 0000000..850373b --- /dev/null +++ b/test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake @@ -0,0 +1,75 @@ +if (NOT DEFINED ENV{PULP_SDK_HOME}) + message(FATAL_ERROR "Environment variable PULP_SDK_HOME not defined.") +endif() + +set(PULP_SDK_HOME $ENV{PULP_SDK_HOME}) + +set(PULP_SDK_BASE_C_SOURCE + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/ram/ram.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/ram/alloc_extern.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/ram/hyperram/hyperram.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/read_fs/read_fs.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/host_fs/semihost.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/host_fs/host_fs.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/fs.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/flash/hyperflash/hyperflash.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/flash/flash.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/partition/partition.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/partition/flash_partition.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/crc/md5.c + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/bsp/siracusa.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/init.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/kernel.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/device.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/task.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/alloc.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/alloc_pool.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/irq.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/soc_event.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/log.c + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/time.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/hyperbus/hyperbus-v3.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/uart/uart-v1.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/udma/udma-v3.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/cluster/cluster.c + ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/io.c + ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/fprintf.c + ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/prf.c + ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/sprintf.c + ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/semihost.c +) + +set(PULP_SDK_BASE_ASM_SOURCE + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/crt0.S + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/irq_asm.S + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/task_asm.S + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/time_asm.S + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/soc_event_v2_itc.S + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/cluster/pe-eu-v3.S +) + +set(PULP_SDK_BASE_INCLUDE + ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/include + ${PULP_SDK_HOME}/rtos/pulpos/common/include + ${PULP_SDK_HOME}/rtos/pulpos/common/kernel + ${PULP_SDK_HOME}/rtos/pulpos/pulp_archi/include + ${PULP_SDK_HOME}/rtos/pulpos/pulp_hal/include + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_api/include + ${PULP_SDK_HOME}/rtos/pulpos/pulp/include + ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/include +) + +set(PULP_SDK_BASE_COMPILE_FLAGS + -D__riscv__ + -D__CONFIG_UDMA__ + -D__PULPOS2__ + -D__PLATFORM__=ARCHI_PLATFORM_GVSOC + -DARCHI_CLUSTER_NB_PE=8 + -DPOS_CONFIG_IO_UART=0 + -DPOS_CONFIG_IO_UART_BAUDRATE=115200 + -DPOS_CONFIG_IO_UART_ITF=0 + -D__TRACE_LEVEL__=3 + -DPI_LOG_LOCAL_LEVEL=2 +) + +set_source_files_properties(${PULP_SDK_BASE_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) diff --git a/test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake b/test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake new file mode 100644 index 0000000..1c117d7 --- /dev/null +++ b/test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake @@ -0,0 +1,62 @@ +include(cmake/pulp-sdk-base.cmake) + +set(PULP_SDK_HOME $ENV{PULP_SDK_HOME}) + +set(SIRACUSA_COMPILE_FLAGS + -include ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa/config.h + -DCONFIG_SIRACUSA + -DCONFIG_BOARD_VERSION_SIRACUSA + -DCONFIG_PROFILE_SIRACUSA + -DSKIP_PLL_INIT + -DUSE_HYPERFLASH + -DUSE_HYPERRAM + -DPULP_CHIP_STR=siracusa +) + +set(SIRACUSA_INCLUDES + ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/include + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/include +) + +set(PULP_SDK_SIRACUSA_C_SOURCE + ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/pll.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/soc.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cdn_print.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/command_list.c + #${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c_obj_if.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cps_impl.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/src/siracusa_padctrl.c +) + +set_source_files_properties(${PULP_SDK_SIRACUSA_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) + +add_library(pulp-sdk OBJECT ${PULP_SDK_BASE_C_SOURCE} ${PULP_SDK_BASE_ASM_SOURCE} ${PULP_SDK_SIRACUSA_C_SOURCE} ${PULP_SDK_SIRACUSA_ASM_SOURCE}) + +set(PULP_SDK_COMPILE_FLAGS ${SIRACUSA_COMPILE_FLAGS} ${PULP_SDK_BASE_COMPILE_FLAGS}) +set(PULP_SDK_INCLUDES ${SIRACUSA_INCLUDES} ${PULP_SDK_BASE_INCLUDE}) + +target_include_directories(pulp-sdk SYSTEM PUBLIC ${PULP_SDK_INCLUDES}) +target_compile_options(pulp-sdk PUBLIC ${PULP_SDK_COMPILE_FLAGS}) +target_compile_options(pulp-sdk PRIVATE + -Wno-sign-conversion + -Wno-unused-function + -Wno-unused-parameter + -Wno-conversion + -Wno-sign-conversion + -Wno-unused-variable + -Wno-sign-compare + -Wno-return-type + -fno-inline-functions +) + +target_compile_options(pulp-sdk INTERFACE + -Wno-unused-function +) + +target_link_options(pulp-sdk PUBLIC + -Wl,--gc-sections + -L${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel + -Tchips/siracusa/link.ld +) diff --git a/test/apps/pulp-nnx/cmake/toolchain_gnu.cmake b/test/apps/pulp-nnx/cmake/toolchain_gnu.cmake new file mode 100644 index 0000000..85fd3d0 --- /dev/null +++ b/test/apps/pulp-nnx/cmake/toolchain_gnu.cmake @@ -0,0 +1,51 @@ +if (NOT DEFINED ENV{TOOLCHAIN_GNU_INSTALL_DIR}) + message(FATAL_ERROR "Environment variable TOOLCHAIN_GNU_INSTALL_DIR not defined.") +endif() + +set(TOOLCHAIN_PREFIX $ENV{TOOLCHAIN_GNU_INSTALL_DIR}/bin/riscv32-unknown-elf) + +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy) +set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-objdump) +set(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar) +set(SIZE ${TOOLCHAIN_PREFIX}-size) + +set(ISA rv32imc_zfinx_xpulpv3) +set(PE 8) +set(FC 1) + +set(CMAKE_EXECUTABLE_SUFFIX ".elf") + +add_compile_options( + -march=${ISA} + -ffunction-sections + -fdata-sections + -fomit-frame-pointer + -fno-jump-tables + -fno-tree-loop-distribute-patterns + -O3 + -DNUM_CORES=${NUM_CORES} + -MMD + -MP +) + +add_link_options( + -MMD + -MP + -march=${ISA} + -nostartfiles + -nostdlib + -Wl,--print-memory-usage +) + +link_libraries( + -lm + -lgcc +) + +add_compile_definitions(__LINK_LD) +add_compile_definitions(__TOOLCHAIN_GCC__) diff --git a/test/apps/pulp-nnx/inc/layer_util.h b/test/apps/pulp-nnx/inc/layer_util.h new file mode 100644 index 0000000..e44ede9 --- /dev/null +++ b/test/apps/pulp-nnx/inc/layer_util.h @@ -0,0 +1,40 @@ +/* + * Luka Macan + * + * Copyright 2023 ETH Zurich and University of Bologna + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __LAYER_UTIL_H__ +#define __LAYER_UTIL_H__ + +#include "layer_conf.h" +#include + +static void layer_info() { + printf("Layer info:\n" + " - input: (%dx%dx%d)\n" + " - output: (%dx%dx%d)\n" + " - weight: (%dx%dx%dx%d)\n" + " - stride: (%dx%d)\n" + " - padding: (%dx%dx%dx%d)\n", + INPUT_HEIGHT, INPUT_WIDTH, INPUT_CHANNEL, OUTPUT_HEIGHT, OUTPUT_WIDTH, + OUTPUT_CHANNEL, WEIGHT_CHANNEL_OUT, WEIGHT_HEIGHT, WEIGHT_WIDTH, + WEIGHT_CHANNEL_IN, STRIDE_HEIGHT, STRIDE_WIDTH, PADDING_TOP, + PADDING_BOTTOM, PADDING_LEFT, PADDING_RIGHT); +} + +#endif // __LAYER_UTIL_H__ diff --git a/test/apps/pulp-nnx/inc/nnx_layer.h b/test/apps/pulp-nnx/inc/nnx_layer.h new file mode 100644 index 0000000..cbaf4b9 --- /dev/null +++ b/test/apps/pulp-nnx/inc/nnx_layer.h @@ -0,0 +1,26 @@ +/* + * Luka Macan + * + * Copyright 2023 ETH Zurich and University of Bologna + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __NNX_LAYER_H__ +#define __NNX_LAYER_H__ + +void execute_nnx_layer(void *unused_args); + +#endif // __NNX_LAYER_H__ diff --git a/test/apps/pulp-nnx/src/main.c b/test/apps/pulp-nnx/src/main.c new file mode 100644 index 0000000..d488a3b --- /dev/null +++ b/test/apps/pulp-nnx/src/main.c @@ -0,0 +1,66 @@ +/* + * Luka Macan + * + * Copyright 2023 ETH Zurich and University of Bologna + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "layer_util.h" +#include "nnx_layer.h" +#include "output.h" +#ifdef NNX_NEUREKA_V2 +#include "string.h" +#include "weight.h" +#include "weight_l2.h" +#endif + +int main() { + struct pi_device cl_dev; + struct pi_cluster_conf cl_conf; + struct pi_cluster_task cl_task; + + printf("\nTest " TEST_NAME " starting\n"); + + printf("\nAccelerator: " NNX_ACCELERATOR "\n"); + + printf("\n"); + layer_info(); + +#ifdef NNX_NEUREKA_V2 + // We have to initialize the mram/sram weight memory from l2 + memcpy((void *)weight, (void *)weight_l2, WEIGHT_SIZE); +#endif + + pi_cluster_conf_init(&cl_conf); + pi_open_from_conf(&cl_dev, &cl_conf); + if (pi_cluster_open(&cl_dev)) { + printf("ERROR: Failed to open cluster.\n"); + pmsis_exit(-1); + } + pi_cluster_send_task_to_cl( + &cl_dev, pi_cluster_task(&cl_task, execute_nnx_layer, NULL)); + + printf("\n"); + check_output(); + + pi_cluster_close(&cl_dev); + + printf("\nTest " TEST_NAME " finished\n"); + + return 0; +} diff --git a/test/app/src/nnx_layer.c b/test/apps/pulp-nnx/src/nnx_layer.c similarity index 100% rename from test/app/src/nnx_layer.c rename to test/apps/pulp-nnx/src/nnx_layer.c diff --git a/test/conftest.py b/test/conftest.py index dfbb909..8e320e9 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -22,7 +22,7 @@ import pydantic import pytest -from NnxBuildFlow import CmakeBuildFlow, NnxBuildFlowName +from NnxBuildFlow import AppName, CmakeBuildFlow, NnxBuildFlowName from NnxMapping import NnxMapping, NnxName from NnxTestClasses import NnxTest, NnxTestGenerator, NnxWmem from TestClasses import implies @@ -76,6 +76,13 @@ def pytest_addoption(parser): default=NnxWmem.tcdm, help="Choose the weight memory destination. Default: tcdm", ) + parser.addoption( + "--app", + type=AppName, + choices=list(AppName), + default=AppName.pulp_nnx, + help="Choose an app to test. Default: pulp-nnx", + ) @pytest.fixture @@ -86,14 +93,19 @@ def nnxName(request) -> NnxName: @pytest.fixture def buildFlowName(request) -> NnxBuildFlowName: nnxName = request.config.getoption("--accelerator") + appName = request.config.getoption("app") buildFlowName = request.config.getoption("buildFlowName") assert implies( buildFlowName == NnxBuildFlowName.cmake, nnxName == NnxName.neureka_v2 ), "The cmake build flow has been tested only with the neureka_v2 accelerator" + assert implies( + buildFlowName == NnxBuildFlowName.make, appName == AppName.pulp_nnx + ), "The make build flow is only tested by the app_pulp_nnx" + if buildFlowName == NnxBuildFlowName.cmake: - CmakeBuildFlow(nnxName).prepare() + CmakeBuildFlow(nnxName, appName).prepare() return buildFlowName @@ -109,6 +121,11 @@ def wmem(request) -> NnxWmem: return _wmem +@pytest.fixture +def appName(request) -> AppName: + return request.config.getoption("--app") + + def _find_test_dirs(path: Union[str, os.PathLike]): return [dirpath for dirpath, _, _ in os.walk(path) if NnxTest.is_test_dir(dirpath)] diff --git a/test/test.py b/test/test.py index 86aa1ed..7f29068 100644 --- a/test/test.py +++ b/test/test.py @@ -18,7 +18,7 @@ import re -from NnxBuildFlow import NnxBuildFlowClsMapping, NnxBuildFlowName +from NnxBuildFlow import AppName, NnxBuildFlowClsMapping, NnxBuildFlowName from NnxMapping import NnxMapping, NnxName from NnxTestClasses import NnxTest, NnxTestHeaderGenerator, NnxWmem @@ -38,15 +38,16 @@ def test( buildFlowName: NnxBuildFlowName, wmem: NnxWmem, nnxTestName: str, + appName: AppName, ): testConfCls, weightCls = NnxMapping[nnxName] # conftest.py makes sure the test is valid and generated nnxTest = NnxTest.load(testConfCls, nnxTestName) - NnxTestHeaderGenerator(weightCls(wmem)).generate(nnxTestName, nnxTest) + NnxTestHeaderGenerator(weightCls(wmem), f"{appName.path()}/gen").generate(nnxTestName, nnxTest) - buildFlow = NnxBuildFlowClsMapping[buildFlowName](nnxName) + buildFlow = NnxBuildFlowClsMapping[buildFlowName](nnxName, appName) buildFlow.build() stdout = buildFlow.run() diff --git a/test/testgen.py b/test/testgen.py index 37c1ba9..ce495a1 100644 --- a/test/testgen.py +++ b/test/testgen.py @@ -24,6 +24,7 @@ import toml +from NnxBuildFlow import AppName from NnxMapping import NnxMapping, NnxName from NnxTestClasses import ( NnxTest, @@ -46,7 +47,7 @@ def headers_gen( assert test is not None if not test.is_valid(): test = NnxTestGenerator.from_conf(test.conf) - NnxTestHeaderGenerator(nnxWeight).generate(args.test_dir, test) + NnxTestHeaderGenerator(nnxWeight, args.app).generate(args.test_dir, test) def print_tensors(test: NnxTest): @@ -165,6 +166,13 @@ def add_common_arguments(parser: argparse.ArgumentParser): default=NnxWmem.tcdm, help="Choose the weight memory destination. Default: tcdm", ) + parser.add_argument( + "--app", + type=AppName, + choices=list(AppName), + default=AppName.pulp_nnx, + help="Choose an app to test. Default: pulp-nnx", + ) parser = argparse.ArgumentParser( From 45b01295f413f529a109b762c5a5cd4b401640cc Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Fri, 11 Apr 2025 13:51:05 +0200 Subject: [PATCH 3/9] Expand pytest shorthand flags --- .github/workflows/test-neureka.yml | 4 ++-- .gitlab-ci.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-neureka.yml b/.github/workflows/test-neureka.yml index c458122..a1ea66d 100644 --- a/.github/workflows/test-neureka.yml +++ b/.github/workflows/test-neureka.yml @@ -49,5 +49,5 @@ jobs: export PULP_RISCV_GCC_TOOLCHAIN=$GITHUB_WORKSPACE/toolchain/gnu source pulp-sdk/configs/siracusa.sh cd pulp-nnx/test - pytest test.py -T tests -R -A neureka --build-flow=make --wmem=tcdm - pytest test.py -T tests -R -A neureka --build-flow=make --wmem=sram + pytest test.py --test-dir tests --recursive --accelerator neureka --build-flow=make --wmem=tcdm + pytest test.py --test-dir tests --recursive --accelerator neureka --build-flow=make --wmem=sram diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 38d3372..b932c98 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,4 +26,4 @@ run_ne16_test: artifacts: untracked: true script: - - cd test && pytest test.py --test-dir tests --recursive -A ne16 + - cd test && pytest test.py --test-dir tests --recursive --accelerator ne16 From 98fc164779923a7ce2cd893698c805c5ccc701f6 Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Fri, 11 Apr 2025 14:05:55 +0200 Subject: [PATCH 4/9] Add toolchain option to pytest --- test/NnxBuildFlow.py | 25 ++++++--- .../pulp-nnx-hal/cmake/toolchain_llvm.cmake | 55 +++++++++++++++++++ test/apps/pulp-nnx/cmake/toolchain_llvm.cmake | 55 +++++++++++++++++++ test/conftest.py | 21 ++++++- test/test.py | 5 +- 5 files changed, 149 insertions(+), 12 deletions(-) create mode 100644 test/apps/pulp-nnx-hal/cmake/toolchain_llvm.cmake create mode 100644 test/apps/pulp-nnx/cmake/toolchain_llvm.cmake diff --git a/test/NnxBuildFlow.py b/test/NnxBuildFlow.py index 4e21842..a78305d 100644 --- a/test/NnxBuildFlow.py +++ b/test/NnxBuildFlow.py @@ -19,12 +19,21 @@ def path(self): return f"apps/{self}" +class Toolchain(Enum): + gnu = "gnu" + llvm = "llvm" + + def __str__(self): + return self.value + + class NnxBuildFlow(ABC): @abstractmethod - def __init__(self, nnxName: NnxName, appName: AppName) -> None: + def __init__(self, nnxName: NnxName, appName: AppName, toolchain: Toolchain) -> None: self.nnxName = nnxName self.appName = appName + self.toolchain = toolchain @abstractmethod def build(self) -> None: ... @@ -44,8 +53,8 @@ def cmd_run(cmd: str, env=None) -> str: class MakeBuildFlow(NnxBuildFlow): - def __init__(self, nnxName: NnxName, appName: AppName) -> None: - super().__init__(nnxName, appName) + def __init__(self, nnxName: NnxName, appName: AppName, toolchain: Toolchain) -> None: + super().__init__(nnxName, appName, toolchain) def env(self) -> os._Environ: _env = os.environ @@ -65,19 +74,19 @@ def __str__(self) -> str: class CmakeBuildFlow(NnxBuildFlow): BINARY_NAME = "test-pulp-nnx" - TOOLCHAIN_FILE = "cmake/toolchain_gnu.cmake" GVSOC_TARGET = "siracusa" - def __init__(self, nnxName: NnxName, appName: AppName) -> None: - super().__init__(nnxName, appName) - self.build_dir = os.path.abspath(f"{self.appName.path()}/build_{nnxName}") + def __init__(self, nnxName: NnxName, appName: AppName, toolchain: Toolchain) -> None: + super().__init__(nnxName, appName, toolchain) + self.build_dir = os.path.abspath(f"{self.appName.path()}/build_{nnxName}_{toolchain}") self.gvsoc_workdir = os.path.join(self.build_dir, "gvsoc_workdir") assert "GVSOC" in os.environ, "The GVSOC environment variable is not set." + self.toolchain_file = f"cmake/toolchain_{self.toolchain}.cmake" def prepare(self) -> None: os.makedirs(self.gvsoc_workdir, exist_ok=True) subprocess.run( - f"cmake -S{self.appName.path()} -B{self.build_dir} -GNinja -DCMAKE_TOOLCHAIN_FILE={CmakeBuildFlow.TOOLCHAIN_FILE} -DACCELERATOR={self.nnxName}".split(), + f"cmake -S{self.appName.path()} -B{self.build_dir} -GNinja -DCMAKE_TOOLCHAIN_FILE={self.toolchain_file} -DACCELERATOR={self.nnxName}".split(), check=True, ) diff --git a/test/apps/pulp-nnx-hal/cmake/toolchain_llvm.cmake b/test/apps/pulp-nnx-hal/cmake/toolchain_llvm.cmake new file mode 100644 index 0000000..c818e70 --- /dev/null +++ b/test/apps/pulp-nnx-hal/cmake/toolchain_llvm.cmake @@ -0,0 +1,55 @@ +if (NOT DEFINED ENV{TOOLCHAIN_LLVM_INSTALL_DIR}) + message(FATAL_ERROR "Environment variable TOOLCHAIN_LLVM_INSTALL_DIR not defined.") +endif() + +set(TOOLCHAIN_BIN $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/bin) +set(PICOLIBC $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/picolibc/riscv) +set(COMPILER_RT $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/lib/clang/15.0.0/lib/baremetal/rv32imc/) + +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN}/clang) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/clang++) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN}/clang) +set(CMAKE_OBJCOPY ${TOOLCHAIN_BIN}/llvm-objcopy) +set(CMAKE_OBJDUMP ${TOOLCHAIN_BIN}/llvm-objdump) + +set(ISA rv32imc_zfinx_xpulpv2) + +set(CMAKE_EXECUTABLE_SUFFIX ".elf") + +add_compile_options( + -target riscv32-unknown-elf + -march=${ISA} + -ffunction-sections + -fdata-sections + -fomit-frame-pointer + -mno-relax + -O3 + -DNUM_CORES=${NUM_CORES} + -MMD + -MP + --sysroot=${PICOLIBC} + -fno-builtin-memcpy + -fno-builtin-memset +) + +add_link_options( + -target riscv32-unknown-elf + -MMD + -MP + -nostartfiles + -march=${ISA} + --sysroot=${PICOLIBC} + -L${COMPILER_RT} + -z norelro + -fno-builtin-memcpy + -fno-builtin-memset +) + +link_libraries( + -lm +) + +add_compile_definitions(__LINK_LD) +add_compile_definitions(__TOOLCHAIN_LLVM__) diff --git a/test/apps/pulp-nnx/cmake/toolchain_llvm.cmake b/test/apps/pulp-nnx/cmake/toolchain_llvm.cmake new file mode 100644 index 0000000..c818e70 --- /dev/null +++ b/test/apps/pulp-nnx/cmake/toolchain_llvm.cmake @@ -0,0 +1,55 @@ +if (NOT DEFINED ENV{TOOLCHAIN_LLVM_INSTALL_DIR}) + message(FATAL_ERROR "Environment variable TOOLCHAIN_LLVM_INSTALL_DIR not defined.") +endif() + +set(TOOLCHAIN_BIN $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/bin) +set(PICOLIBC $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/picolibc/riscv) +set(COMPILER_RT $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/lib/clang/15.0.0/lib/baremetal/rv32imc/) + +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN}/clang) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/clang++) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN}/clang) +set(CMAKE_OBJCOPY ${TOOLCHAIN_BIN}/llvm-objcopy) +set(CMAKE_OBJDUMP ${TOOLCHAIN_BIN}/llvm-objdump) + +set(ISA rv32imc_zfinx_xpulpv2) + +set(CMAKE_EXECUTABLE_SUFFIX ".elf") + +add_compile_options( + -target riscv32-unknown-elf + -march=${ISA} + -ffunction-sections + -fdata-sections + -fomit-frame-pointer + -mno-relax + -O3 + -DNUM_CORES=${NUM_CORES} + -MMD + -MP + --sysroot=${PICOLIBC} + -fno-builtin-memcpy + -fno-builtin-memset +) + +add_link_options( + -target riscv32-unknown-elf + -MMD + -MP + -nostartfiles + -march=${ISA} + --sysroot=${PICOLIBC} + -L${COMPILER_RT} + -z norelro + -fno-builtin-memcpy + -fno-builtin-memset +) + +link_libraries( + -lm +) + +add_compile_definitions(__LINK_LD) +add_compile_definitions(__TOOLCHAIN_LLVM__) diff --git a/test/conftest.py b/test/conftest.py index 8e320e9..f24f8ff 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -22,7 +22,7 @@ import pydantic import pytest -from NnxBuildFlow import AppName, CmakeBuildFlow, NnxBuildFlowName +from NnxBuildFlow import AppName, CmakeBuildFlow, NnxBuildFlowName, Toolchain from NnxMapping import NnxMapping, NnxName from NnxTestClasses import NnxTest, NnxTestGenerator, NnxWmem from TestClasses import implies @@ -83,6 +83,13 @@ def pytest_addoption(parser): default=AppName.pulp_nnx, help="Choose an app to test. Default: pulp-nnx", ) + parser.addoption( + "--toolchain", + type=Toolchain, + choices=list(Toolchain), + default=Toolchain.gnu, + help="Choose an app to test. Default: gnu", + ) @pytest.fixture @@ -95,6 +102,7 @@ def buildFlowName(request) -> NnxBuildFlowName: nnxName = request.config.getoption("--accelerator") appName = request.config.getoption("app") buildFlowName = request.config.getoption("buildFlowName") + toolchain = request.config.getoption("--toolchain") assert implies( buildFlowName == NnxBuildFlowName.cmake, nnxName == NnxName.neureka_v2 @@ -104,8 +112,12 @@ def buildFlowName(request) -> NnxBuildFlowName: buildFlowName == NnxBuildFlowName.make, appName == AppName.pulp_nnx ), "The make build flow is only tested by the app_pulp_nnx" + assert implies( + buildFlowName == NnxBuildFlowName.make, toolchain == Toolchain.gnu + ), "The make build flow has only been tested with the gnu toolchain" + if buildFlowName == NnxBuildFlowName.cmake: - CmakeBuildFlow(nnxName, appName).prepare() + CmakeBuildFlow(nnxName, appName, toolchain).prepare() return buildFlowName @@ -126,6 +138,11 @@ def appName(request) -> AppName: return request.config.getoption("--app") +@pytest.fixture +def toolchain(request) -> Toolchain: + return request.config.getoption("--toolchain") + + def _find_test_dirs(path: Union[str, os.PathLike]): return [dirpath for dirpath, _, _ in os.walk(path) if NnxTest.is_test_dir(dirpath)] diff --git a/test/test.py b/test/test.py index 7f29068..93bd502 100644 --- a/test/test.py +++ b/test/test.py @@ -18,7 +18,7 @@ import re -from NnxBuildFlow import AppName, NnxBuildFlowClsMapping, NnxBuildFlowName +from NnxBuildFlow import AppName, NnxBuildFlowClsMapping, NnxBuildFlowName, Toolchain from NnxMapping import NnxMapping, NnxName from NnxTestClasses import NnxTest, NnxTestHeaderGenerator, NnxWmem @@ -39,6 +39,7 @@ def test( wmem: NnxWmem, nnxTestName: str, appName: AppName, + toolchain: Toolchain, ): testConfCls, weightCls = NnxMapping[nnxName] @@ -47,7 +48,7 @@ def test( NnxTestHeaderGenerator(weightCls(wmem), f"{appName.path()}/gen").generate(nnxTestName, nnxTest) - buildFlow = NnxBuildFlowClsMapping[buildFlowName](nnxName, appName) + buildFlow = NnxBuildFlowClsMapping[buildFlowName](nnxName, appName, toolchain) buildFlow.build() stdout = buildFlow.run() From 2075dddd740f588515e26ea7d2e80a459834bdb4 Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Fri, 11 Apr 2025 14:06:44 +0200 Subject: [PATCH 5/9] Formatting --- test/NnxBuildFlow.py | 24 ++++++++++++++++++------ test/test.py | 4 +++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/test/NnxBuildFlow.py b/test/NnxBuildFlow.py index a78305d..4827114 100644 --- a/test/NnxBuildFlow.py +++ b/test/NnxBuildFlow.py @@ -30,7 +30,9 @@ def __str__(self): class NnxBuildFlow(ABC): @abstractmethod - def __init__(self, nnxName: NnxName, appName: AppName, toolchain: Toolchain) -> None: + def __init__( + self, nnxName: NnxName, appName: AppName, toolchain: Toolchain + ) -> None: self.nnxName = nnxName self.appName = appName self.toolchain = toolchain @@ -53,7 +55,9 @@ def cmd_run(cmd: str, env=None) -> str: class MakeBuildFlow(NnxBuildFlow): - def __init__(self, nnxName: NnxName, appName: AppName, toolchain: Toolchain) -> None: + def __init__( + self, nnxName: NnxName, appName: AppName, toolchain: Toolchain + ) -> None: super().__init__(nnxName, appName, toolchain) def env(self) -> os._Environ: @@ -63,10 +67,14 @@ def env(self) -> os._Environ: def build(self) -> None: Path(f"{self.appName.path()}/src/nnx_layer.c").touch() - _ = NnxBuildFlow.cmd_run(f"make -C {self.appName.path()} all platform=gvsoc", self.env()) + _ = NnxBuildFlow.cmd_run( + f"make -C {self.appName.path()} all platform=gvsoc", self.env() + ) def run(self) -> str: - return NnxBuildFlow.cmd_run(f"make -C {self.appName.path()} run platform=gvsoc", self.env()) + return NnxBuildFlow.cmd_run( + f"make -C {self.appName.path()} run platform=gvsoc", self.env() + ) def __str__(self) -> str: return "make" @@ -76,9 +84,13 @@ class CmakeBuildFlow(NnxBuildFlow): BINARY_NAME = "test-pulp-nnx" GVSOC_TARGET = "siracusa" - def __init__(self, nnxName: NnxName, appName: AppName, toolchain: Toolchain) -> None: + def __init__( + self, nnxName: NnxName, appName: AppName, toolchain: Toolchain + ) -> None: super().__init__(nnxName, appName, toolchain) - self.build_dir = os.path.abspath(f"{self.appName.path()}/build_{nnxName}_{toolchain}") + self.build_dir = os.path.abspath( + f"{self.appName.path()}/build_{nnxName}_{toolchain}" + ) self.gvsoc_workdir = os.path.join(self.build_dir, "gvsoc_workdir") assert "GVSOC" in os.environ, "The GVSOC environment variable is not set." self.toolchain_file = f"cmake/toolchain_{self.toolchain}.cmake" diff --git a/test/test.py b/test/test.py index 93bd502..401c993 100644 --- a/test/test.py +++ b/test/test.py @@ -46,7 +46,9 @@ def test( # conftest.py makes sure the test is valid and generated nnxTest = NnxTest.load(testConfCls, nnxTestName) - NnxTestHeaderGenerator(weightCls(wmem), f"{appName.path()}/gen").generate(nnxTestName, nnxTest) + NnxTestHeaderGenerator(weightCls(wmem), f"{appName.path()}/gen").generate( + nnxTestName, nnxTest + ) buildFlow = NnxBuildFlowClsMapping[buildFlowName](nnxName, appName, toolchain) buildFlow.build() From 1c38dabc4ced5ba4e8935662d8aca0b20ee829f1 Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Fri, 11 Apr 2025 15:03:42 +0200 Subject: [PATCH 6/9] Create a single readme for apps and add the env var section --- test/apps/{pulp-nnx-hal => }/README.md | 19 ++++++++++---- test/apps/pulp-nnx/README.md | 36 -------------------------- 2 files changed, 14 insertions(+), 41 deletions(-) rename test/apps/{pulp-nnx-hal => }/README.md (62%) delete mode 100644 test/apps/pulp-nnx/README.md diff --git a/test/apps/pulp-nnx-hal/README.md b/test/apps/README.md similarity index 62% rename from test/apps/pulp-nnx-hal/README.md rename to test/apps/README.md index aa9a03a..ff12af7 100644 --- a/test/apps/pulp-nnx-hal/README.md +++ b/test/apps/README.md @@ -1,4 +1,10 @@ -# Test application +# Test applications + +There are 2 testing applications: +1. pulp-nnx - tests the whole library +2. pulp-nnx-hal - tests just the hardware abstraction layer parts + +Both apps are very similar except for the fact that the Make build flow is not implemented for the pulp-nnx-hal app. ## Build @@ -6,6 +12,13 @@ There are two build flows given for the test app, the Make one and the CMake one Both flows use a flag `ACCELERATOR` to decide which accelerator to build the application for. Choices are _neureka_ and _neureka_v2_. +### Environment variables + +Both build fows expect some environment variables to be set and will fail if they are not set: +- `GVSOC` - path to the `gvsoc` executable (not the directory) +- `TOOLCHAIN_LLVM_INSTALL_DIR` - path to the llvm install directory +- `PULP_SDK_HOME` - path to the pulp-sdk directory + ### Make For the Make flow you need to specify the `ACCELERATOR` flag either as an environment variable @@ -30,7 +43,3 @@ cmake --build build ``` No need to regenerate the project (1st cmake command) after altering the sources, just rerun the build. - -## TODO - -- environment variables that need to be set diff --git a/test/apps/pulp-nnx/README.md b/test/apps/pulp-nnx/README.md deleted file mode 100644 index aa9a03a..0000000 --- a/test/apps/pulp-nnx/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Test application - -## Build - -There are two build flows given for the test app, the Make one and the CMake one. -Both flows use a flag `ACCELERATOR` to decide which accelerator to build the application for. -Choices are _neureka_ and _neureka_v2_. - -### Make - -For the Make flow you need to specify the `ACCELERATOR` flag either as an environment variable -``` -export ACCELERATOR= -``` -or you can add it to the make command -``` -ACCELERATOR= make clean all run -``` - -### CMake - -For the cmake build you have to specify the `ACCELERATOR` flag with `-DACCLERATOR= and the toolchain file with the `-DCMAKE_TOOLCHAIN_FILE` flag: -``` -cmake -S . -B build -G Ninja -DACCELERATOR= -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_.cmake -``` - -After that you can build the application by running: -``` -cmake --build build -``` - -No need to regenerate the project (1st cmake command) after altering the sources, just rerun the build. - -## TODO - -- environment variables that need to be set From 14a0aff6212b661f6528c42d39416126533b0c35 Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Sun, 13 Apr 2025 21:52:15 +0200 Subject: [PATCH 7/9] Move common cmake files out of apps --- test/NnxBuildFlow.py | 2 +- test/apps/pulp-nnx-hal/CMakeLists.txt | 2 +- .../cmake/pulp-sdk-siracusa.cmake | 62 --------------- test/apps/pulp-nnx/CMakeLists.txt | 2 +- test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake | 75 ------------------- .../pulp-nnx/cmake/pulp-sdk-siracusa.cmake | 62 --------------- test/apps/pulp-nnx/cmake/toolchain_gnu.cmake | 51 ------------- test/apps/pulp-nnx/cmake/toolchain_llvm.cmake | 55 -------------- .../pulp-sdk-siracusa.cmake} | 59 +++++++++++++++ .../cmake/toolchain_gnu.cmake | 0 .../cmake/toolchain_llvm.cmake | 0 11 files changed, 62 insertions(+), 308 deletions(-) delete mode 100644 test/apps/pulp-nnx-hal/cmake/pulp-sdk-siracusa.cmake delete mode 100644 test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake delete mode 100644 test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake delete mode 100644 test/apps/pulp-nnx/cmake/toolchain_gnu.cmake delete mode 100644 test/apps/pulp-nnx/cmake/toolchain_llvm.cmake rename test/{apps/pulp-nnx-hal/cmake/pulp-sdk-base.cmake => cmake/pulp-sdk-siracusa.cmake} (61%) rename test/{apps/pulp-nnx-hal => }/cmake/toolchain_gnu.cmake (100%) rename test/{apps/pulp-nnx-hal => }/cmake/toolchain_llvm.cmake (100%) diff --git a/test/NnxBuildFlow.py b/test/NnxBuildFlow.py index 4827114..7271591 100644 --- a/test/NnxBuildFlow.py +++ b/test/NnxBuildFlow.py @@ -93,7 +93,7 @@ def __init__( ) self.gvsoc_workdir = os.path.join(self.build_dir, "gvsoc_workdir") assert "GVSOC" in os.environ, "The GVSOC environment variable is not set." - self.toolchain_file = f"cmake/toolchain_{self.toolchain}.cmake" + self.toolchain_file = f"../../cmake/toolchain_{self.toolchain}.cmake" def prepare(self) -> None: os.makedirs(self.gvsoc_workdir, exist_ok=True) diff --git a/test/apps/pulp-nnx-hal/CMakeLists.txt b/test/apps/pulp-nnx-hal/CMakeLists.txt index 9661332..a4326d6 100644 --- a/test/apps/pulp-nnx-hal/CMakeLists.txt +++ b/test/apps/pulp-nnx-hal/CMakeLists.txt @@ -20,7 +20,7 @@ set_property(CACHE ACCELERATOR PROPERTY STRINGS neureka neureka_v2) add_compile_options(-DNUM_CORES=${NUM_CORES}) -include(cmake/pulp-sdk-siracusa.cmake) +include(../../cmake/pulp-sdk-siracusa.cmake) target_link_libraries(test-pulp-nnx PRIVATE pulp-sdk) if(${ACCELERATOR} STREQUAL neureka) diff --git a/test/apps/pulp-nnx-hal/cmake/pulp-sdk-siracusa.cmake b/test/apps/pulp-nnx-hal/cmake/pulp-sdk-siracusa.cmake deleted file mode 100644 index 1c117d7..0000000 --- a/test/apps/pulp-nnx-hal/cmake/pulp-sdk-siracusa.cmake +++ /dev/null @@ -1,62 +0,0 @@ -include(cmake/pulp-sdk-base.cmake) - -set(PULP_SDK_HOME $ENV{PULP_SDK_HOME}) - -set(SIRACUSA_COMPILE_FLAGS - -include ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa/config.h - -DCONFIG_SIRACUSA - -DCONFIG_BOARD_VERSION_SIRACUSA - -DCONFIG_PROFILE_SIRACUSA - -DSKIP_PLL_INIT - -DUSE_HYPERFLASH - -DUSE_HYPERRAM - -DPULP_CHIP_STR=siracusa -) - -set(SIRACUSA_INCLUDES - ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/include - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/include -) - -set(PULP_SDK_SIRACUSA_C_SOURCE - ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/pll.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/soc.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cdn_print.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/command_list.c - #${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c_obj_if.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cps_impl.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/src/siracusa_padctrl.c -) - -set_source_files_properties(${PULP_SDK_SIRACUSA_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) - -add_library(pulp-sdk OBJECT ${PULP_SDK_BASE_C_SOURCE} ${PULP_SDK_BASE_ASM_SOURCE} ${PULP_SDK_SIRACUSA_C_SOURCE} ${PULP_SDK_SIRACUSA_ASM_SOURCE}) - -set(PULP_SDK_COMPILE_FLAGS ${SIRACUSA_COMPILE_FLAGS} ${PULP_SDK_BASE_COMPILE_FLAGS}) -set(PULP_SDK_INCLUDES ${SIRACUSA_INCLUDES} ${PULP_SDK_BASE_INCLUDE}) - -target_include_directories(pulp-sdk SYSTEM PUBLIC ${PULP_SDK_INCLUDES}) -target_compile_options(pulp-sdk PUBLIC ${PULP_SDK_COMPILE_FLAGS}) -target_compile_options(pulp-sdk PRIVATE - -Wno-sign-conversion - -Wno-unused-function - -Wno-unused-parameter - -Wno-conversion - -Wno-sign-conversion - -Wno-unused-variable - -Wno-sign-compare - -Wno-return-type - -fno-inline-functions -) - -target_compile_options(pulp-sdk INTERFACE - -Wno-unused-function -) - -target_link_options(pulp-sdk PUBLIC - -Wl,--gc-sections - -L${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel - -Tchips/siracusa/link.ld -) diff --git a/test/apps/pulp-nnx/CMakeLists.txt b/test/apps/pulp-nnx/CMakeLists.txt index 53d6776..f9b3728 100644 --- a/test/apps/pulp-nnx/CMakeLists.txt +++ b/test/apps/pulp-nnx/CMakeLists.txt @@ -20,7 +20,7 @@ set_property(CACHE ACCELERATOR PROPERTY STRINGS neureka neureka_v2) add_compile_options(-DNUM_CORES=${NUM_CORES}) -include(cmake/pulp-sdk-siracusa.cmake) +include(../../cmake/pulp-sdk-siracusa.cmake) target_link_libraries(test-pulp-nnx PRIVATE pulp-sdk) if(${ACCELERATOR} STREQUAL neureka) diff --git a/test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake b/test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake deleted file mode 100644 index 850373b..0000000 --- a/test/apps/pulp-nnx/cmake/pulp-sdk-base.cmake +++ /dev/null @@ -1,75 +0,0 @@ -if (NOT DEFINED ENV{PULP_SDK_HOME}) - message(FATAL_ERROR "Environment variable PULP_SDK_HOME not defined.") -endif() - -set(PULP_SDK_HOME $ENV{PULP_SDK_HOME}) - -set(PULP_SDK_BASE_C_SOURCE - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/ram/ram.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/ram/alloc_extern.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/ram/hyperram/hyperram.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/read_fs/read_fs.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/host_fs/semihost.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/host_fs/host_fs.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/fs/fs.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/flash/hyperflash/hyperflash.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/flash/flash.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/partition/partition.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/partition/flash_partition.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/crc/md5.c - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/bsp/siracusa.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/init.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/kernel.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/device.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/task.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/alloc.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/alloc_pool.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/irq.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/soc_event.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/log.c - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/time.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/hyperbus/hyperbus-v3.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/uart/uart-v1.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/udma/udma-v3.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/cluster/cluster.c - ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/io.c - ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/fprintf.c - ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/prf.c - ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/sprintf.c - ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/semihost.c -) - -set(PULP_SDK_BASE_ASM_SOURCE - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/crt0.S - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/irq_asm.S - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/task_asm.S - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/time_asm.S - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel/soc_event_v2_itc.S - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/cluster/pe-eu-v3.S -) - -set(PULP_SDK_BASE_INCLUDE - ${PULP_SDK_HOME}/rtos/pulpos/common/lib/libc/minimal/include - ${PULP_SDK_HOME}/rtos/pulpos/common/include - ${PULP_SDK_HOME}/rtos/pulpos/common/kernel - ${PULP_SDK_HOME}/rtos/pulpos/pulp_archi/include - ${PULP_SDK_HOME}/rtos/pulpos/pulp_hal/include - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_api/include - ${PULP_SDK_HOME}/rtos/pulpos/pulp/include - ${PULP_SDK_HOME}/rtos/pmsis/pmsis_bsp/include -) - -set(PULP_SDK_BASE_COMPILE_FLAGS - -D__riscv__ - -D__CONFIG_UDMA__ - -D__PULPOS2__ - -D__PLATFORM__=ARCHI_PLATFORM_GVSOC - -DARCHI_CLUSTER_NB_PE=8 - -DPOS_CONFIG_IO_UART=0 - -DPOS_CONFIG_IO_UART_BAUDRATE=115200 - -DPOS_CONFIG_IO_UART_ITF=0 - -D__TRACE_LEVEL__=3 - -DPI_LOG_LOCAL_LEVEL=2 -) - -set_source_files_properties(${PULP_SDK_BASE_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) diff --git a/test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake b/test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake deleted file mode 100644 index 1c117d7..0000000 --- a/test/apps/pulp-nnx/cmake/pulp-sdk-siracusa.cmake +++ /dev/null @@ -1,62 +0,0 @@ -include(cmake/pulp-sdk-base.cmake) - -set(PULP_SDK_HOME $ENV{PULP_SDK_HOME}) - -set(SIRACUSA_COMPILE_FLAGS - -include ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa/config.h - -DCONFIG_SIRACUSA - -DCONFIG_BOARD_VERSION_SIRACUSA - -DCONFIG_PROFILE_SIRACUSA - -DSKIP_PLL_INIT - -DUSE_HYPERFLASH - -DUSE_HYPERRAM - -DPULP_CHIP_STR=siracusa -) - -set(SIRACUSA_INCLUDES - ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/include - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/include -) - -set(PULP_SDK_SIRACUSA_C_SOURCE - ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/pll.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/soc.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cdn_print.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/command_list.c - #${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c_obj_if.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cps_impl.c - ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/src/siracusa_padctrl.c -) - -set_source_files_properties(${PULP_SDK_SIRACUSA_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) - -add_library(pulp-sdk OBJECT ${PULP_SDK_BASE_C_SOURCE} ${PULP_SDK_BASE_ASM_SOURCE} ${PULP_SDK_SIRACUSA_C_SOURCE} ${PULP_SDK_SIRACUSA_ASM_SOURCE}) - -set(PULP_SDK_COMPILE_FLAGS ${SIRACUSA_COMPILE_FLAGS} ${PULP_SDK_BASE_COMPILE_FLAGS}) -set(PULP_SDK_INCLUDES ${SIRACUSA_INCLUDES} ${PULP_SDK_BASE_INCLUDE}) - -target_include_directories(pulp-sdk SYSTEM PUBLIC ${PULP_SDK_INCLUDES}) -target_compile_options(pulp-sdk PUBLIC ${PULP_SDK_COMPILE_FLAGS}) -target_compile_options(pulp-sdk PRIVATE - -Wno-sign-conversion - -Wno-unused-function - -Wno-unused-parameter - -Wno-conversion - -Wno-sign-conversion - -Wno-unused-variable - -Wno-sign-compare - -Wno-return-type - -fno-inline-functions -) - -target_compile_options(pulp-sdk INTERFACE - -Wno-unused-function -) - -target_link_options(pulp-sdk PUBLIC - -Wl,--gc-sections - -L${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel - -Tchips/siracusa/link.ld -) diff --git a/test/apps/pulp-nnx/cmake/toolchain_gnu.cmake b/test/apps/pulp-nnx/cmake/toolchain_gnu.cmake deleted file mode 100644 index 85fd3d0..0000000 --- a/test/apps/pulp-nnx/cmake/toolchain_gnu.cmake +++ /dev/null @@ -1,51 +0,0 @@ -if (NOT DEFINED ENV{TOOLCHAIN_GNU_INSTALL_DIR}) - message(FATAL_ERROR "Environment variable TOOLCHAIN_GNU_INSTALL_DIR not defined.") -endif() - -set(TOOLCHAIN_PREFIX $ENV{TOOLCHAIN_GNU_INSTALL_DIR}/bin/riscv32-unknown-elf) - -set(CMAKE_SYSTEM_NAME Generic) - -set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) -set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) -set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}-objcopy) -set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}-objdump) -set(CMAKE_AR ${TOOLCHAIN_PREFIX}-ar) -set(SIZE ${TOOLCHAIN_PREFIX}-size) - -set(ISA rv32imc_zfinx_xpulpv3) -set(PE 8) -set(FC 1) - -set(CMAKE_EXECUTABLE_SUFFIX ".elf") - -add_compile_options( - -march=${ISA} - -ffunction-sections - -fdata-sections - -fomit-frame-pointer - -fno-jump-tables - -fno-tree-loop-distribute-patterns - -O3 - -DNUM_CORES=${NUM_CORES} - -MMD - -MP -) - -add_link_options( - -MMD - -MP - -march=${ISA} - -nostartfiles - -nostdlib - -Wl,--print-memory-usage -) - -link_libraries( - -lm - -lgcc -) - -add_compile_definitions(__LINK_LD) -add_compile_definitions(__TOOLCHAIN_GCC__) diff --git a/test/apps/pulp-nnx/cmake/toolchain_llvm.cmake b/test/apps/pulp-nnx/cmake/toolchain_llvm.cmake deleted file mode 100644 index c818e70..0000000 --- a/test/apps/pulp-nnx/cmake/toolchain_llvm.cmake +++ /dev/null @@ -1,55 +0,0 @@ -if (NOT DEFINED ENV{TOOLCHAIN_LLVM_INSTALL_DIR}) - message(FATAL_ERROR "Environment variable TOOLCHAIN_LLVM_INSTALL_DIR not defined.") -endif() - -set(TOOLCHAIN_BIN $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/bin) -set(PICOLIBC $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/picolibc/riscv) -set(COMPILER_RT $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/lib/clang/15.0.0/lib/baremetal/rv32imc/) - -set(CMAKE_SYSTEM_NAME Generic) - -set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN}/clang) -set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN}/clang++) -set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN}/clang) -set(CMAKE_OBJCOPY ${TOOLCHAIN_BIN}/llvm-objcopy) -set(CMAKE_OBJDUMP ${TOOLCHAIN_BIN}/llvm-objdump) - -set(ISA rv32imc_zfinx_xpulpv2) - -set(CMAKE_EXECUTABLE_SUFFIX ".elf") - -add_compile_options( - -target riscv32-unknown-elf - -march=${ISA} - -ffunction-sections - -fdata-sections - -fomit-frame-pointer - -mno-relax - -O3 - -DNUM_CORES=${NUM_CORES} - -MMD - -MP - --sysroot=${PICOLIBC} - -fno-builtin-memcpy - -fno-builtin-memset -) - -add_link_options( - -target riscv32-unknown-elf - -MMD - -MP - -nostartfiles - -march=${ISA} - --sysroot=${PICOLIBC} - -L${COMPILER_RT} - -z norelro - -fno-builtin-memcpy - -fno-builtin-memset -) - -link_libraries( - -lm -) - -add_compile_definitions(__LINK_LD) -add_compile_definitions(__TOOLCHAIN_LLVM__) diff --git a/test/apps/pulp-nnx-hal/cmake/pulp-sdk-base.cmake b/test/cmake/pulp-sdk-siracusa.cmake similarity index 61% rename from test/apps/pulp-nnx-hal/cmake/pulp-sdk-base.cmake rename to test/cmake/pulp-sdk-siracusa.cmake index 850373b..e0c063f 100644 --- a/test/apps/pulp-nnx-hal/cmake/pulp-sdk-base.cmake +++ b/test/cmake/pulp-sdk-siracusa.cmake @@ -73,3 +73,62 @@ set(PULP_SDK_BASE_COMPILE_FLAGS ) set_source_files_properties(${PULP_SDK_BASE_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) + +set(SIRACUSA_COMPILE_FLAGS + -include ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa/config.h + -DCONFIG_SIRACUSA + -DCONFIG_BOARD_VERSION_SIRACUSA + -DCONFIG_PROFILE_SIRACUSA + -DSKIP_PLL_INIT + -DUSE_HYPERFLASH + -DUSE_HYPERRAM + -DPULP_CHIP_STR=siracusa +) + +set(SIRACUSA_INCLUDES + ${PULP_SDK_HOME}/rtos/pulpos/pulp/include/pos/chips/siracusa + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/include + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/include +) + +set(PULP_SDK_SIRACUSA_C_SOURCE + ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/pll.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel/chips/siracusa/soc.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cdn_print.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/command_list.c + #${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/i3c_obj_if.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/i3c/src/cps_impl.c + ${PULP_SDK_HOME}/rtos/pulpos/pulp/drivers/siracusa_padmux/src/siracusa_padctrl.c +) + +set_source_files_properties(${PULP_SDK_SIRACUSA_ASM_SOURCE} PROPERTIES COMPILE_FLAGS -DLANGUAGE_ASSEMBLY) + +add_library(pulp-sdk OBJECT ${PULP_SDK_BASE_C_SOURCE} ${PULP_SDK_BASE_ASM_SOURCE} ${PULP_SDK_SIRACUSA_C_SOURCE} ${PULP_SDK_SIRACUSA_ASM_SOURCE}) + +set(PULP_SDK_COMPILE_FLAGS ${SIRACUSA_COMPILE_FLAGS} ${PULP_SDK_BASE_COMPILE_FLAGS}) +set(PULP_SDK_INCLUDES ${SIRACUSA_INCLUDES} ${PULP_SDK_BASE_INCLUDE}) + +target_include_directories(pulp-sdk SYSTEM PUBLIC ${PULP_SDK_INCLUDES}) +target_compile_options(pulp-sdk PUBLIC ${PULP_SDK_COMPILE_FLAGS}) +target_compile_options(pulp-sdk PRIVATE + -Wno-sign-conversion + -Wno-unused-function + -Wno-unused-parameter + -Wno-conversion + -Wno-sign-conversion + -Wno-unused-variable + -Wno-sign-compare + -Wno-return-type + -fno-inline-functions +) + +target_compile_options(pulp-sdk INTERFACE + -Wno-unused-function +) + +target_link_options(pulp-sdk PUBLIC + -Wl,--gc-sections + -L${PULP_SDK_HOME}/rtos/pulpos/pulp/kernel + -Tchips/siracusa/link.ld +) diff --git a/test/apps/pulp-nnx-hal/cmake/toolchain_gnu.cmake b/test/cmake/toolchain_gnu.cmake similarity index 100% rename from test/apps/pulp-nnx-hal/cmake/toolchain_gnu.cmake rename to test/cmake/toolchain_gnu.cmake diff --git a/test/apps/pulp-nnx-hal/cmake/toolchain_llvm.cmake b/test/cmake/toolchain_llvm.cmake similarity index 100% rename from test/apps/pulp-nnx-hal/cmake/toolchain_llvm.cmake rename to test/cmake/toolchain_llvm.cmake From 650eb730a80990d06ce834916011f2ed9ad4b446 Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Sun, 13 Apr 2025 22:00:54 +0200 Subject: [PATCH 8/9] Remove idiosyncracies from the llvm cmake toolchain file --- test/cmake/toolchain_llvm.cmake | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/cmake/toolchain_llvm.cmake b/test/cmake/toolchain_llvm.cmake index c818e70..d979ee3 100644 --- a/test/cmake/toolchain_llvm.cmake +++ b/test/cmake/toolchain_llvm.cmake @@ -2,9 +2,17 @@ if (NOT DEFINED ENV{TOOLCHAIN_LLVM_INSTALL_DIR}) message(FATAL_ERROR "Environment variable TOOLCHAIN_LLVM_INSTALL_DIR not defined.") endif() +if (NOT DEFINED ENV{TOOLCHAIN_LLVM_LIBC_DIR}) + message(FATAL_ERROR "Environemnt variable TOOLCHAIN_LLVM_LIBC_DIR not defined.") +endif() + +if (NOT DEFINED ENV{TOOLCHAIN_LLVM_COMPILER_RT_DIR}) + message(FATAL_ERROR "Environemnt variable TOOLCHAIN_LLVM_COMPILER_RT_DIR not defined.") +endif() + set(TOOLCHAIN_BIN $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/bin) -set(PICOLIBC $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/picolibc/riscv) -set(COMPILER_RT $ENV{TOOLCHAIN_LLVM_INSTALL_DIR}/lib/clang/15.0.0/lib/baremetal/rv32imc/) +set(LIBC $ENV{TOOLCHAIN_LLVM_LIBC_DIR}) +set(COMPILER_RT $ENV{TOOLCHAIN_LLVM_COMPILER_RT_DIR}) set(CMAKE_SYSTEM_NAME Generic) @@ -29,7 +37,7 @@ add_compile_options( -DNUM_CORES=${NUM_CORES} -MMD -MP - --sysroot=${PICOLIBC} + --sysroot=${LIBC} -fno-builtin-memcpy -fno-builtin-memset ) @@ -40,7 +48,7 @@ add_link_options( -MP -nostartfiles -march=${ISA} - --sysroot=${PICOLIBC} + --sysroot=${LIBC} -L${COMPILER_RT} -z norelro -fno-builtin-memcpy From 06e66bf874b00b233a8d68e2a73d785a509e7b8f Mon Sep 17 00:00:00 2001 From: Luka Macan Date: Sun, 13 Apr 2025 22:40:09 +0200 Subject: [PATCH 9/9] Wrap base address defines with ifndef to allow overriding --- test/apps/pulp-nnx-hal/src/nnx_layer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/apps/pulp-nnx-hal/src/nnx_layer.c b/test/apps/pulp-nnx-hal/src/nnx_layer.c index 79780e9..f39dc79 100644 --- a/test/apps/pulp-nnx-hal/src/nnx_layer.c +++ b/test/apps/pulp-nnx-hal/src/nnx_layer.c @@ -35,7 +35,9 @@ typedef ne16_task_flag_e nnx_task_flag_e; typedef ne16_task_data_t nnx_task_data_t; // Minimal copy from ne16/bsp/ne16_pulp_bsp.c +#ifndef NE16_PULP_BASE_ADDR #define NE16_PULP_BASE_ADDR (0x00201000) +#endif static const ne16_dev_t nnx_dev = { .hwpe_dev = (struct hwpe_dev_t){ .base_addr = (volatile uint32_t *)NE16_PULP_BASE_ADDR}}; @@ -69,7 +71,9 @@ typedef neureka_task_flag_e nnx_task_flag_e; typedef neureka_task_data_t nnx_task_data_t; // Minimal copy from neureka/bsp/neureka_siracusa_bsp.c +#ifndef NEUREKA_SIRACUSA_BASE_ADDR #define NEUREKA_SIRACUSA_BASE_ADDR (0x00201000) +#endif static const neureka_dev_t nnx_dev = { .hwpe_dev = (struct hwpe_dev_t){ .base_addr = (volatile uint32_t *)NEUREKA_SIRACUSA_BASE_ADDR}}; @@ -102,7 +106,9 @@ typedef neureka_v2_task_flag_e nnx_task_flag_e; typedef neureka_v2_task_data_t nnx_task_data_t; // Minimal copy from neureka_v2/bsp/neureka_v2_siracusa_bsp.c +#ifndef NEUREKA_V2_SIRACUSA_BASE_ADDR #define NEUREKA_V2_SIRACUSA_BASE_ADDR (0x00201000) +#endif static const neureka_v2_dev_t nnx_dev = { .hwpe_dev = (struct hwpe_dev_t){ .base_addr = (volatile uint32_t *)NEUREKA_V2_SIRACUSA_BASE_ADDR}};