From 2acc058e366b9913cbb0f7fca4dac27dd0a770e4 Mon Sep 17 00:00:00 2001 From: fclc Date: Mon, 30 Mar 2026 13:47:24 +0000 Subject: [PATCH 01/16] Fix GP-SDK SYSEMU launcher behavior --- gp-sdk/README.md | 5 +- gp-sdk/host/sdk/src/lib/GenericLauncher.cpp | 56 ++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/gp-sdk/README.md b/gp-sdk/README.md index 985cf8400..18c9c4a1f 100644 --- a/gp-sdk/README.md +++ b/gp-sdk/README.md @@ -62,6 +62,10 @@ sdk/hello_world_launcher --kernel_path=../../device/build/tests/print.elf --devi sdk/hello_world_launcher --kernel_path=../../device/build/tests/print.elf --device_type=silicon ``` +When using `--device_type=sysemu`, the launcher will prefer the sibling `*_dbg` ELF when it exists. Those +debug-linked images are linked at the runtime-predicted device address and are the correct choice for SYSEMU +bring-up and debugging. + and we can see traces from the device through dt2json application installed on the docker image: ``` @@ -176,4 +180,3 @@ New documentation will appear as refman.pdf inside each host/build and device/bu - diff --git a/gp-sdk/host/sdk/src/lib/GenericLauncher.cpp b/gp-sdk/host/sdk/src/lib/GenericLauncher.cpp index 988aecbb0..cc9b51220 100644 --- a/gp-sdk/host/sdk/src/lib/GenericLauncher.cpp +++ b/gp-sdk/host/sdk/src/lib/GenericLauncher.cpp @@ -24,12 +24,64 @@ constexpr size_t kNumHarts = 2048; constexpr size_t kTraceBufferSize = kTraceBytesPerHart * kNumHarts; constexpr bool enableKernelTraces = true; +namespace { +std::string getEtSdkHome() { + if (const char* etSdkHome = std::getenv("ET_SDK_HOME")) { + return etSdkHome; + } + return "/opt/et"; +} + +void setIfExists(std::string& dst, const std::filesystem::path& path) { + if (std::filesystem::exists(path)) { + dst = path.string(); + } +} + +std::filesystem::path resolveKernelPath(const std::filesystem::path& kernelPath, Mode mode) { + if (mode != Mode::SYSEMU) { + return kernelPath; + } + + const auto kernelPathStr = kernelPath.string(); + if (kernelPathStr.size() >= 4 && kernelPathStr.compare(kernelPathStr.size() - 4, 4, "_dbg") == 0) { + return kernelPath; + } + + const auto debugKernelPath = std::filesystem::path(kernelPathStr + "_dbg"); + if (std::filesystem::exists(debugKernelPath)) { + std::cout << "loadKernel() sysemu selected, using debug-linked kernel " << debugKernelPath << "\n"; + return debugKernelPath; + } + + return kernelPath; +} +} // namespace + emu::SysEmuOptions getDefaultOptions(std::string const& simulator_params) { constexpr uint64_t kSysEmuMaxCycles = std::numeric_limits::max(); constexpr uint64_t kSysEmuMinionShiresMask = 0x1FFFFFFFFu; emu::SysEmuOptions sysEmuOptions; + const auto etSdkHome = std::filesystem::path(getEtSdkHome()); + + setIfExists( + sysEmuOptions.bootromTrampolineToBL2ElfPath, + etSdkHome / "lib/esperanto-fw/BootromTrampolineToBL2/BootromTrampolineToBL2.elf"); + setIfExists( + sysEmuOptions.spBL2ElfPath, + etSdkHome / "lib/esperanto-fw/ServiceProcessorBL2/fast-boot/ServiceProcessorBL2_fast-boot.elf"); + setIfExists( + sysEmuOptions.machineMinionElfPath, + etSdkHome / "lib/esperanto-fw/MachineMinion/MachineMinion.elf"); + setIfExists( + sysEmuOptions.masterMinionElfPath, + etSdkHome / "lib/esperanto-fw/MasterMinion/MasterMinion.elf"); + setIfExists( + sysEmuOptions.workerMinionElfPath, + etSdkHome / "lib/esperanto-fw/WorkerMinion/WorkerMinion.elf"); + setIfExists(sysEmuOptions.executablePath, etSdkHome / "bin/sys_emu"); sysEmuOptions.runDir = std::filesystem::current_path(); sysEmuOptions.maxCycles = kSysEmuMaxCycles; @@ -147,6 +199,7 @@ void GenericLauncher::initialize() { std::cout << "abortedKernelHandler" << " () rt reports that a kernel has been aborted (EventId: " << static_cast(id) << ")\n"; kernelAbort_++; + freeResources(); }; runtime_->setOnStreamErrorsCallback(streamErrorHandler); @@ -253,7 +306,8 @@ void GenericLauncher::tearDown() { } rt::KernelId GenericLauncher::loadKernel(const std::string& kernelName, uint32_t deviceIdx) { - auto kernelContent = readFile(kernelName); + const auto resolvedKernelPath = resolveKernelPath(kernelName, config_.mode_); + auto kernelContent = readFile(resolvedKernelPath.string()); if (kernelContent.empty()) { exit(-1); } From aec5b82ffe98abda93e96830b4f21c2411434730 Mon Sep 17 00:00:00 2001 From: fclc Date: Mon, 30 Mar 2026 13:59:47 +0000 Subject: [PATCH 02/16] Add initial BLAS kernel scaffold --- blas/CMakeLists.txt | 21 +++++++++++++ blas/README.md | 17 +++++++++++ blas/level1/CMakeLists.txt | 1 + blas/level1/axpy/CMakeLists.txt | 2 ++ blas/level1/axpy/axpy.cpp | 39 ++++++++++++++++++++++++ blas/level1/axpy/axpy_kernel_arguments.h | 13 ++++++++ 6 files changed, 93 insertions(+) create mode 100644 blas/CMakeLists.txt create mode 100644 blas/README.md create mode 100644 blas/level1/CMakeLists.txt create mode 100644 blas/level1/axpy/CMakeLists.txt create mode 100644 blas/level1/axpy/axpy.cpp create mode 100644 blas/level1/axpy/axpy_kernel_arguments.h diff --git a/blas/CMakeLists.txt b/blas/CMakeLists.txt new file mode 100644 index 000000000..bd5b92d14 --- /dev/null +++ b/blas/CMakeLists.txt @@ -0,0 +1,21 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2026 Ainekko, Co. +# SPDX-License-Identifier: Apache-2.0 +#------------------------------------------------------------------------------ + +function(add_etsoc_blas_kernel TARGET_NAME) + set(options) + set(oneValueArgs INSTALL_DESTINATION) + set(multiValueArgs) + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT DEFINED ARGS_INSTALL_DESTINATION) + set(ARGS_INSTALL_DESTINATION kernels/blas) + endif() + + add_etsoc_riscv_executable(${TARGET_NAME} ${ARGS_UNPARSED_ARGUMENTS}) + target_link_libraries(${TARGET_NAME} etsoc_crt0) + install(TARGETS ${TARGET_NAME} ${TARGET_NAME}_dbg DESTINATION ${ARGS_INSTALL_DESTINATION}) +endfunction() + +add_subdirectory(level1) diff --git a/blas/README.md b/blas/README.md new file mode 100644 index 000000000..984d99e44 --- /dev/null +++ b/blas/README.md @@ -0,0 +1,17 @@ +# BLAS Kernels + +This directory holds custom GP-SDK device kernels for the ET-SOC1 BLAS work. + +It is intended to be consumed through the existing `gp-sdk/device` custom-kernel +hook by setting: + +- `CUSTOM_KERNELS_SRC_DIR=/blas` +- `CUSTOM_KERNELS_BIN_DIR=/blas` + +Current layout: + +- `level1/axpy`: scalar single-precision AXPY kernel scaffold + +The first goal here is a minimal, functional BLAS baseline. That means starting +with simple scalar kernels and a clean directory structure before adding vector +or tensor-specialized implementations. diff --git a/blas/level1/CMakeLists.txt b/blas/level1/CMakeLists.txt new file mode 100644 index 000000000..9b8e2609c --- /dev/null +++ b/blas/level1/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(axpy) diff --git a/blas/level1/axpy/CMakeLists.txt b/blas/level1/axpy/CMakeLists.txt new file mode 100644 index 000000000..efac097e4 --- /dev/null +++ b/blas/level1/axpy/CMakeLists.txt @@ -0,0 +1,2 @@ +add_etsoc_blas_kernel(blas_axpy_scalar.elf axpy.cpp) +target_include_directories(blas_axpy_scalar.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/blas/level1/axpy/axpy.cpp b/blas/level1/axpy/axpy.cpp new file mode 100644 index 000000000..f1b938b5e --- /dev/null +++ b/blas/level1/axpy/axpy.cpp @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * Copyright (c) 2026 Ainekko, Co. + * SPDX-License-Identifier: Apache-2.0 + *------------------------------------------------------------------------- + */ + +#include +#include + +#include +#include + +#include "axpy_kernel_arguments.h" +#include "entryPoint.h" + +int entryPoint_0(KernelArguments* args); +DECLARE_KERNEL_ENTRY_POINTS(entryPoint_0, nullptr); + +int entryPoint_0(KernelArguments* args) { + const auto minionId = get_relative_thread_id(); + const size_t numWorkers = SOC_MINIONS_PER_SHIRE; + + size_t elemsPerWorker = (args->numElements + numWorkers - 1) / numWorkers; + if (elemsPerWorker == 0) { + return 0; + } + + const size_t begin = elemsPerWorker * minionId; + const size_t end = std::min(begin + elemsPerWorker, static_cast(args->numElements)); + if (begin >= args->numElements) { + return 0; + } + + for (size_t i = begin; i < end; ++i) { + args->y[i] = args->alpha * args->x[i] + args->y[i]; + } + + return 0; +} diff --git a/blas/level1/axpy/axpy_kernel_arguments.h b/blas/level1/axpy/axpy_kernel_arguments.h new file mode 100644 index 000000000..eb4d2282e --- /dev/null +++ b/blas/level1/axpy/axpy_kernel_arguments.h @@ -0,0 +1,13 @@ +#ifndef ET_BLAS_AXPY_KERNEL_ARGUMENTS_H +#define ET_BLAS_AXPY_KERNEL_ARGUMENTS_H + +#include + +struct KernelArguments { + uint64_t numElements; + const float* x; + float* y; + float alpha; +} __attribute__((packed)); + +#endif From 00004032b954bf1e6eb117d0341df804b50f4ded Mon Sep 17 00:00:00 2001 From: fclc Date: Mon, 30 Mar 2026 15:11:15 +0000 Subject: [PATCH 03/16] Restructure BLAS layout by implementation class --- blas/CMakeLists.txt | 3 ++- blas/README.md | 22 ++++++++++++++----- blas/level1/axpy/CMakeLists.txt | 2 -- blas/optimized/CMakeLists.txt | 1 + blas/optimized/README.md | 4 ++++ blas/optimized/bf16/README.md | 3 +++ blas/optimized/fp16/README.md | 3 +++ blas/optimized/fp32/README.md | 3 +++ blas/optimized/int16/README.md | 3 +++ blas/optimized/int8/README.md | 3 +++ blas/reference/CMakeLists.txt | 1 + blas/reference/README.md | 4 ++++ blas/reference/bf16/README.md | 3 +++ blas/reference/fp16/README.md | 3 +++ blas/reference/fp32/CMakeLists.txt | 1 + .../fp32}/level1/CMakeLists.txt | 0 .../reference/fp32/level1/axpy/CMakeLists.txt | 6 +++++ .../{ => reference/fp32}/level1/axpy/axpy.cpp | 0 .../fp32}/level1/axpy/axpy_kernel_arguments.h | 4 ++-- blas/reference/int16/README.md | 3 +++ blas/reference/int8/README.md | 3 +++ 21 files changed, 65 insertions(+), 10 deletions(-) delete mode 100644 blas/level1/axpy/CMakeLists.txt create mode 100644 blas/optimized/CMakeLists.txt create mode 100644 blas/optimized/README.md create mode 100644 blas/optimized/bf16/README.md create mode 100644 blas/optimized/fp16/README.md create mode 100644 blas/optimized/fp32/README.md create mode 100644 blas/optimized/int16/README.md create mode 100644 blas/optimized/int8/README.md create mode 100644 blas/reference/CMakeLists.txt create mode 100644 blas/reference/README.md create mode 100644 blas/reference/bf16/README.md create mode 100644 blas/reference/fp16/README.md create mode 100644 blas/reference/fp32/CMakeLists.txt rename blas/{ => reference/fp32}/level1/CMakeLists.txt (100%) create mode 100644 blas/reference/fp32/level1/axpy/CMakeLists.txt rename blas/{ => reference/fp32}/level1/axpy/axpy.cpp (100%) rename blas/{ => reference/fp32}/level1/axpy/axpy_kernel_arguments.h (57%) create mode 100644 blas/reference/int16/README.md create mode 100644 blas/reference/int8/README.md diff --git a/blas/CMakeLists.txt b/blas/CMakeLists.txt index bd5b92d14..bf3554d1e 100644 --- a/blas/CMakeLists.txt +++ b/blas/CMakeLists.txt @@ -18,4 +18,5 @@ function(add_etsoc_blas_kernel TARGET_NAME) install(TARGETS ${TARGET_NAME} ${TARGET_NAME}_dbg DESTINATION ${ARGS_INSTALL_DESTINATION}) endfunction() -add_subdirectory(level1) +add_subdirectory(reference) +add_subdirectory(optimized) diff --git a/blas/README.md b/blas/README.md index 984d99e44..b28246455 100644 --- a/blas/README.md +++ b/blas/README.md @@ -8,10 +8,22 @@ hook by setting: - `CUSTOM_KERNELS_SRC_DIR=/blas` - `CUSTOM_KERNELS_BIN_DIR=/blas` -Current layout: +Layout conventions: -- `level1/axpy`: scalar single-precision AXPY kernel scaffold +- `blas/reference/` holds numerically conservative scalar baselines +- `blas/optimized/` holds vector and tensor implementations +- datatype directories sit below those roots +- BLAS level and operation directories sit below the datatype -The first goal here is a minimal, functional BLAS baseline. That means starting -with simple scalar kernels and a clean directory structure before adding vector -or tensor-specialized implementations. +Current datatype plan: + +- `fp32` first +- `fp16`, `bf16`, `int16`, and `int8` after that + +Current active kernel: + +- `reference/fp32/level1/axpy` + +The intent is to always keep a trustworthy reference kernel beside each +optimized family so we can measure error growth as operation ordering and +reduction strategies change. diff --git a/blas/level1/axpy/CMakeLists.txt b/blas/level1/axpy/CMakeLists.txt deleted file mode 100644 index efac097e4..000000000 --- a/blas/level1/axpy/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_etsoc_blas_kernel(blas_axpy_scalar.elf axpy.cpp) -target_include_directories(blas_axpy_scalar.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/blas/optimized/CMakeLists.txt b/blas/optimized/CMakeLists.txt new file mode 100644 index 000000000..69e37b6d3 --- /dev/null +++ b/blas/optimized/CMakeLists.txt @@ -0,0 +1 @@ +# Optimized kernels are added here as vector and tensor implementations land. diff --git a/blas/optimized/README.md b/blas/optimized/README.md new file mode 100644 index 000000000..058f92e32 --- /dev/null +++ b/blas/optimized/README.md @@ -0,0 +1,4 @@ +# Optimized Kernels + +Optimized kernels hold vector and tensor implementations that are validated +against the matching reference kernels. diff --git a/blas/optimized/bf16/README.md b/blas/optimized/bf16/README.md new file mode 100644 index 000000000..d461cb912 --- /dev/null +++ b/blas/optimized/bf16/README.md @@ -0,0 +1,3 @@ +# BF16 Optimized + +Reserved for BF16 vector and tensor kernels. diff --git a/blas/optimized/fp16/README.md b/blas/optimized/fp16/README.md new file mode 100644 index 000000000..441deda98 --- /dev/null +++ b/blas/optimized/fp16/README.md @@ -0,0 +1,3 @@ +# FP16 Optimized + +Reserved for FP16 vector and tensor kernels. diff --git a/blas/optimized/fp32/README.md b/blas/optimized/fp32/README.md new file mode 100644 index 000000000..b846d8490 --- /dev/null +++ b/blas/optimized/fp32/README.md @@ -0,0 +1,3 @@ +# FP32 Optimized + +Reserved for FP32 vector and tensor kernels. diff --git a/blas/optimized/int16/README.md b/blas/optimized/int16/README.md new file mode 100644 index 000000000..bd0fae2f5 --- /dev/null +++ b/blas/optimized/int16/README.md @@ -0,0 +1,3 @@ +# INT16 Optimized + +Reserved for INT16 vector and tensor kernels. diff --git a/blas/optimized/int8/README.md b/blas/optimized/int8/README.md new file mode 100644 index 000000000..7a9454f69 --- /dev/null +++ b/blas/optimized/int8/README.md @@ -0,0 +1,3 @@ +# INT8 Optimized + +Reserved for INT8 vector and tensor kernels. diff --git a/blas/reference/CMakeLists.txt b/blas/reference/CMakeLists.txt new file mode 100644 index 000000000..f18746e78 --- /dev/null +++ b/blas/reference/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(fp32) diff --git a/blas/reference/README.md b/blas/reference/README.md new file mode 100644 index 000000000..3f91993cd --- /dev/null +++ b/blas/reference/README.md @@ -0,0 +1,4 @@ +# Reference Kernels + +Reference kernels prioritize clear operation ordering and predictable numerical +behavior over peak throughput. diff --git a/blas/reference/bf16/README.md b/blas/reference/bf16/README.md new file mode 100644 index 000000000..0252b44fa --- /dev/null +++ b/blas/reference/bf16/README.md @@ -0,0 +1,3 @@ +# BF16 Reference + +Reserved for BF16 scalar reference kernels. diff --git a/blas/reference/fp16/README.md b/blas/reference/fp16/README.md new file mode 100644 index 000000000..08323bc00 --- /dev/null +++ b/blas/reference/fp16/README.md @@ -0,0 +1,3 @@ +# FP16 Reference + +Reserved for FP16 scalar reference kernels. diff --git a/blas/reference/fp32/CMakeLists.txt b/blas/reference/fp32/CMakeLists.txt new file mode 100644 index 000000000..fb691b4f5 --- /dev/null +++ b/blas/reference/fp32/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(level1) diff --git a/blas/level1/CMakeLists.txt b/blas/reference/fp32/level1/CMakeLists.txt similarity index 100% rename from blas/level1/CMakeLists.txt rename to blas/reference/fp32/level1/CMakeLists.txt diff --git a/blas/reference/fp32/level1/axpy/CMakeLists.txt b/blas/reference/fp32/level1/axpy/CMakeLists.txt new file mode 100644 index 000000000..68c7ad1f4 --- /dev/null +++ b/blas/reference/fp32/level1/axpy/CMakeLists.txt @@ -0,0 +1,6 @@ +add_etsoc_blas_kernel( + blas_axpy_reference_fp32.elf + axpy.cpp + INSTALL_DESTINATION kernels/blas/reference/fp32/level1/axpy +) +target_include_directories(blas_axpy_reference_fp32.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/blas/level1/axpy/axpy.cpp b/blas/reference/fp32/level1/axpy/axpy.cpp similarity index 100% rename from blas/level1/axpy/axpy.cpp rename to blas/reference/fp32/level1/axpy/axpy.cpp diff --git a/blas/level1/axpy/axpy_kernel_arguments.h b/blas/reference/fp32/level1/axpy/axpy_kernel_arguments.h similarity index 57% rename from blas/level1/axpy/axpy_kernel_arguments.h rename to blas/reference/fp32/level1/axpy/axpy_kernel_arguments.h index eb4d2282e..e8c5c1bbd 100644 --- a/blas/level1/axpy/axpy_kernel_arguments.h +++ b/blas/reference/fp32/level1/axpy/axpy_kernel_arguments.h @@ -1,5 +1,5 @@ -#ifndef ET_BLAS_AXPY_KERNEL_ARGUMENTS_H -#define ET_BLAS_AXPY_KERNEL_ARGUMENTS_H +#ifndef ET_BLAS_REFERENCE_FP32_AXPY_KERNEL_ARGUMENTS_H +#define ET_BLAS_REFERENCE_FP32_AXPY_KERNEL_ARGUMENTS_H #include diff --git a/blas/reference/int16/README.md b/blas/reference/int16/README.md new file mode 100644 index 000000000..56f92bff1 --- /dev/null +++ b/blas/reference/int16/README.md @@ -0,0 +1,3 @@ +# INT16 Reference + +Reserved for INT16 scalar reference kernels. diff --git a/blas/reference/int8/README.md b/blas/reference/int8/README.md new file mode 100644 index 000000000..686759de4 --- /dev/null +++ b/blas/reference/int8/README.md @@ -0,0 +1,3 @@ +# INT8 Reference + +Reserved for INT8 scalar reference kernels. From 080674dea1783c7c7e15870d96a058b76827a721 Mon Sep 17 00:00:00 2001 From: fclc Date: Mon, 30 Mar 2026 15:22:23 +0000 Subject: [PATCH 04/16] Trim BLAS documentation to policy files --- blas/README.md | 13 +++++++++---- blas/optimized/README.md | 18 ++++++++++++++++++ blas/optimized/bf16/README.md | 3 --- blas/optimized/fp16/README.md | 3 --- blas/optimized/fp32/README.md | 3 --- blas/optimized/int16/README.md | 3 --- blas/optimized/int8/README.md | 3 --- blas/reference/README.md | 12 ++++++++++++ blas/reference/bf16/README.md | 3 --- blas/reference/fp16/README.md | 3 --- blas/reference/int16/README.md | 3 --- blas/reference/int8/README.md | 3 --- 12 files changed, 39 insertions(+), 31 deletions(-) delete mode 100644 blas/optimized/bf16/README.md delete mode 100644 blas/optimized/fp16/README.md delete mode 100644 blas/optimized/fp32/README.md delete mode 100644 blas/optimized/int16/README.md delete mode 100644 blas/optimized/int8/README.md delete mode 100644 blas/reference/bf16/README.md delete mode 100644 blas/reference/fp16/README.md delete mode 100644 blas/reference/int16/README.md delete mode 100644 blas/reference/int8/README.md diff --git a/blas/README.md b/blas/README.md index b28246455..c8bfa8f5b 100644 --- a/blas/README.md +++ b/blas/README.md @@ -15,14 +15,19 @@ Layout conventions: - datatype directories sit below those roots - BLAS level and operation directories sit below the datatype -Current datatype plan: +Datatype rollout order: - `fp32` first -- `fp16`, `bf16`, `int16`, and `int8` after that +- `fp16` +- `bf16` +- `int16` +- `int8` -Current active kernel: +Implementation policy: -- `reference/fp32/level1/axpy` +- every optimized kernel must have a matching reference kernel +- reference and optimized kernels must keep the same external argument contract +- numerical comparisons are always made against the reference implementation The intent is to always keep a trustworthy reference kernel beside each optimized family so we can measure error growth as operation ordering and diff --git a/blas/optimized/README.md b/blas/optimized/README.md index 058f92e32..4be503604 100644 --- a/blas/optimized/README.md +++ b/blas/optimized/README.md @@ -2,3 +2,21 @@ Optimized kernels hold vector and tensor implementations that are validated against the matching reference kernels. + +Allowed here: + +- vector and tensor implementations +- tiling, blocking, fusion, and staging for performance +- controlled operation reordering when justified by performance + +Required here: + +- keep the same external kernel contract as the matching reference kernel +- document any intentional numerical tradeoff in code comments or commit history +- validate against the matching reference implementation + +Not allowed here: + +- silently changing kernel semantics +- changing datatype interpretation relative to the reference path +- landing an optimized kernel before a reference kernel exists diff --git a/blas/optimized/bf16/README.md b/blas/optimized/bf16/README.md deleted file mode 100644 index d461cb912..000000000 --- a/blas/optimized/bf16/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# BF16 Optimized - -Reserved for BF16 vector and tensor kernels. diff --git a/blas/optimized/fp16/README.md b/blas/optimized/fp16/README.md deleted file mode 100644 index 441deda98..000000000 --- a/blas/optimized/fp16/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# FP16 Optimized - -Reserved for FP16 vector and tensor kernels. diff --git a/blas/optimized/fp32/README.md b/blas/optimized/fp32/README.md deleted file mode 100644 index b846d8490..000000000 --- a/blas/optimized/fp32/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# FP32 Optimized - -Reserved for FP32 vector and tensor kernels. diff --git a/blas/optimized/int16/README.md b/blas/optimized/int16/README.md deleted file mode 100644 index bd0fae2f5..000000000 --- a/blas/optimized/int16/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# INT16 Optimized - -Reserved for INT16 vector and tensor kernels. diff --git a/blas/optimized/int8/README.md b/blas/optimized/int8/README.md deleted file mode 100644 index 7a9454f69..000000000 --- a/blas/optimized/int8/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# INT8 Optimized - -Reserved for INT8 vector and tensor kernels. diff --git a/blas/reference/README.md b/blas/reference/README.md index 3f91993cd..84d9b1158 100644 --- a/blas/reference/README.md +++ b/blas/reference/README.md @@ -2,3 +2,15 @@ Reference kernels prioritize clear operation ordering and predictable numerical behavior over peak throughput. + +Allowed here: + +- straightforward scalar implementations +- simple decompositions that preserve obvious operation order +- code written to maximize readability and auditability + +Not allowed here: + +- vector or tensor ISA use +- algorithmic rewrites done only for throughput +- numerically aggressive reordering meant to hide latency or reduce traffic diff --git a/blas/reference/bf16/README.md b/blas/reference/bf16/README.md deleted file mode 100644 index 0252b44fa..000000000 --- a/blas/reference/bf16/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# BF16 Reference - -Reserved for BF16 scalar reference kernels. diff --git a/blas/reference/fp16/README.md b/blas/reference/fp16/README.md deleted file mode 100644 index 08323bc00..000000000 --- a/blas/reference/fp16/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# FP16 Reference - -Reserved for FP16 scalar reference kernels. diff --git a/blas/reference/int16/README.md b/blas/reference/int16/README.md deleted file mode 100644 index 56f92bff1..000000000 --- a/blas/reference/int16/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# INT16 Reference - -Reserved for INT16 scalar reference kernels. diff --git a/blas/reference/int8/README.md b/blas/reference/int8/README.md deleted file mode 100644 index 686759de4..000000000 --- a/blas/reference/int8/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# INT8 Reference - -Reserved for INT8 scalar reference kernels. From 39f8d8cf48cb71b3d93521977658772e3e8ac87b Mon Sep 17 00:00:00 2001 From: fclc Date: Mon, 30 Mar 2026 19:56:29 +0000 Subject: [PATCH 05/16] Add BLAS Level 1 reference kernels and verifier --- blas/reference/device_results.md | 277 ++++++++++ blas/reference/fp32/level1/CMakeLists.txt | 3 + blas/reference/fp32/level1/axpy/axpy.cpp | 12 +- .../reference/fp32/level1/copy/CMakeLists.txt | 6 + blas/reference/fp32/level1/copy/copy.cpp | 43 ++ .../fp32/level1/copy/copy_kernel_arguments.h | 12 + .../reference/fp32/level1/scal/CMakeLists.txt | 6 + blas/reference/fp32/level1/scal/scal.cpp | 43 ++ .../fp32/level1/scal/scal_kernel_arguments.h | 12 + .../reference/fp32/level1/swap/CMakeLists.txt | 6 + blas/reference/fp32/level1/swap/swap.cpp | 45 ++ .../fp32/level1/swap/swap_kernel_arguments.h | 12 + blas/reference/host/CMakeLists.txt | 21 + blas/reference/host/level1_verifier.cpp | 482 ++++++++++++++++++ blas/reference/host_results.md | 277 ++++++++++ 15 files changed, 1253 insertions(+), 4 deletions(-) create mode 100644 blas/reference/device_results.md create mode 100644 blas/reference/fp32/level1/copy/CMakeLists.txt create mode 100644 blas/reference/fp32/level1/copy/copy.cpp create mode 100644 blas/reference/fp32/level1/copy/copy_kernel_arguments.h create mode 100644 blas/reference/fp32/level1/scal/CMakeLists.txt create mode 100644 blas/reference/fp32/level1/scal/scal.cpp create mode 100644 blas/reference/fp32/level1/scal/scal_kernel_arguments.h create mode 100644 blas/reference/fp32/level1/swap/CMakeLists.txt create mode 100644 blas/reference/fp32/level1/swap/swap.cpp create mode 100644 blas/reference/fp32/level1/swap/swap_kernel_arguments.h create mode 100644 blas/reference/host/CMakeLists.txt create mode 100644 blas/reference/host/level1_verifier.cpp create mode 100644 blas/reference/host_results.md diff --git a/blas/reference/device_results.md b/blas/reference/device_results.md new file mode 100644 index 000000000..26775be06 --- /dev/null +++ b/blas/reference/device_results.md @@ -0,0 +1,277 @@ +# BLAS Level 1 Device Results + +- device_type: `sysemu` +- num_elements: `16` +- epsilon: `1e-05` +- kernel_root: `/tmp/blas-device-build/custom-kernels/reference/fp32/level1` + +## axpy + +- status: `ok` +- alpha: `3.000000` + +### input_x + +| index | value | +| ---: | ---: | +| 0 | 1.000000 | +| 1 | 1.250000 | +| 2 | 1.500000 | +| 3 | 1.750000 | +| 4 | 2.000000 | +| 5 | 2.250000 | +| 6 | 2.500000 | +| 7 | 2.750000 | +| 8 | 3.000000 | +| 9 | 3.250000 | +| 10 | 3.500000 | +| 11 | 3.750000 | +| 12 | 4.000000 | +| 13 | 4.250000 | +| 14 | 4.500000 | +| 15 | 4.750000 | + +### input_y + +| index | value | +| ---: | ---: | +| 0 | 100.000000 | +| 1 | 99.500000 | +| 2 | 99.000000 | +| 3 | 98.500000 | +| 4 | 98.000000 | +| 5 | 97.500000 | +| 6 | 97.000000 | +| 7 | 96.500000 | +| 8 | 96.000000 | +| 9 | 95.500000 | +| 10 | 95.000000 | +| 11 | 94.500000 | +| 12 | 94.000000 | +| 13 | 93.500000 | +| 14 | 93.000000 | +| 15 | 92.500000 | + +### output_y + +| index | value | +| ---: | ---: | +| 0 | 103.000000 | +| 1 | 103.250000 | +| 2 | 103.500000 | +| 3 | 103.750000 | +| 4 | 104.000000 | +| 5 | 104.250000 | +| 6 | 104.500000 | +| 7 | 104.750000 | +| 8 | 105.000000 | +| 9 | 105.250000 | +| 10 | 105.500000 | +| 11 | 105.750000 | +| 12 | 106.000000 | +| 13 | 106.250000 | +| 14 | 106.500000 | +| 15 | 106.750000 | + +## copy + +- status: `ok` + +### input_x + +| index | value | +| ---: | ---: | +| 0 | 1.000000 | +| 1 | 1.250000 | +| 2 | 1.500000 | +| 3 | 1.750000 | +| 4 | 2.000000 | +| 5 | 2.250000 | +| 6 | 2.500000 | +| 7 | 2.750000 | +| 8 | 3.000000 | +| 9 | 3.250000 | +| 10 | 3.500000 | +| 11 | 3.750000 | +| 12 | 4.000000 | +| 13 | 4.250000 | +| 14 | 4.500000 | +| 15 | 4.750000 | + +### input_y + +| index | value | +| ---: | ---: | +| 0 | 100.000000 | +| 1 | 99.500000 | +| 2 | 99.000000 | +| 3 | 98.500000 | +| 4 | 98.000000 | +| 5 | 97.500000 | +| 6 | 97.000000 | +| 7 | 96.500000 | +| 8 | 96.000000 | +| 9 | 95.500000 | +| 10 | 95.000000 | +| 11 | 94.500000 | +| 12 | 94.000000 | +| 13 | 93.500000 | +| 14 | 93.000000 | +| 15 | 92.500000 | + +### output_y + +| index | value | +| ---: | ---: | +| 0 | 1.000000 | +| 1 | 1.250000 | +| 2 | 1.500000 | +| 3 | 1.750000 | +| 4 | 2.000000 | +| 5 | 2.250000 | +| 6 | 2.500000 | +| 7 | 2.750000 | +| 8 | 3.000000 | +| 9 | 3.250000 | +| 10 | 3.500000 | +| 11 | 3.750000 | +| 12 | 4.000000 | +| 13 | 4.250000 | +| 14 | 4.500000 | +| 15 | 4.750000 | + +## scal + +- status: `ok` +- alpha: `-2.000000` + +### input_x + +| index | value | +| ---: | ---: | +| 0 | 1.000000 | +| 1 | 1.250000 | +| 2 | 1.500000 | +| 3 | 1.750000 | +| 4 | 2.000000 | +| 5 | 2.250000 | +| 6 | 2.500000 | +| 7 | 2.750000 | +| 8 | 3.000000 | +| 9 | 3.250000 | +| 10 | 3.500000 | +| 11 | 3.750000 | +| 12 | 4.000000 | +| 13 | 4.250000 | +| 14 | 4.500000 | +| 15 | 4.750000 | + +### output_x + +| index | value | +| ---: | ---: | +| 0 | -2.000000 | +| 1 | -2.500000 | +| 2 | -3.000000 | +| 3 | -3.500000 | +| 4 | -4.000000 | +| 5 | -4.500000 | +| 6 | -5.000000 | +| 7 | -5.500000 | +| 8 | -6.000000 | +| 9 | -6.500000 | +| 10 | -7.000000 | +| 11 | -7.500000 | +| 12 | -8.000000 | +| 13 | -8.500000 | +| 14 | -9.000000 | +| 15 | -9.500000 | + +## swap + +- status: `ok` + +### input_x + +| index | value | +| ---: | ---: | +| 0 | 1.000000 | +| 1 | 1.250000 | +| 2 | 1.500000 | +| 3 | 1.750000 | +| 4 | 2.000000 | +| 5 | 2.250000 | +| 6 | 2.500000 | +| 7 | 2.750000 | +| 8 | 3.000000 | +| 9 | 3.250000 | +| 10 | 3.500000 | +| 11 | 3.750000 | +| 12 | 4.000000 | +| 13 | 4.250000 | +| 14 | 4.500000 | +| 15 | 4.750000 | + +### input_y + +| index | value | +| ---: | ---: | +| 0 | 100.000000 | +| 1 | 99.500000 | +| 2 | 99.000000 | +| 3 | 98.500000 | +| 4 | 98.000000 | +| 5 | 97.500000 | +| 6 | 97.000000 | +| 7 | 96.500000 | +| 8 | 96.000000 | +| 9 | 95.500000 | +| 10 | 95.000000 | +| 11 | 94.500000 | +| 12 | 94.000000 | +| 13 | 93.500000 | +| 14 | 93.000000 | +| 15 | 92.500000 | + +### output_x + +| index | value | +| ---: | ---: | +| 0 | 100.000000 | +| 1 | 99.500000 | +| 2 | 99.000000 | +| 3 | 98.500000 | +| 4 | 98.000000 | +| 5 | 97.500000 | +| 6 | 97.000000 | +| 7 | 96.500000 | +| 8 | 96.000000 | +| 9 | 95.500000 | +| 10 | 95.000000 | +| 11 | 94.500000 | +| 12 | 94.000000 | +| 13 | 93.500000 | +| 14 | 93.000000 | +| 15 | 92.500000 | + +### output_y + +| index | value | +| ---: | ---: | +| 0 | 1.000000 | +| 1 | 1.250000 | +| 2 | 1.500000 | +| 3 | 1.750000 | +| 4 | 2.000000 | +| 5 | 2.250000 | +| 6 | 2.500000 | +| 7 | 2.750000 | +| 8 | 3.000000 | +| 9 | 3.250000 | +| 10 | 3.500000 | +| 11 | 3.750000 | +| 12 | 4.000000 | +| 13 | 4.250000 | +| 14 | 4.500000 | +| 15 | 4.750000 | + diff --git a/blas/reference/fp32/level1/CMakeLists.txt b/blas/reference/fp32/level1/CMakeLists.txt index 9b8e2609c..3c368fe8d 100644 --- a/blas/reference/fp32/level1/CMakeLists.txt +++ b/blas/reference/fp32/level1/CMakeLists.txt @@ -1 +1,4 @@ add_subdirectory(axpy) +add_subdirectory(copy) +add_subdirectory(scal) +add_subdirectory(swap) diff --git a/blas/reference/fp32/level1/axpy/axpy.cpp b/blas/reference/fp32/level1/axpy/axpy.cpp index f1b938b5e..a87034d72 100644 --- a/blas/reference/fp32/level1/axpy/axpy.cpp +++ b/blas/reference/fp32/level1/axpy/axpy.cpp @@ -20,14 +20,18 @@ int entryPoint_0(KernelArguments* args) { const auto minionId = get_relative_thread_id(); const size_t numWorkers = SOC_MINIONS_PER_SHIRE; - size_t elemsPerWorker = (args->numElements + numWorkers - 1) / numWorkers; - if (elemsPerWorker == 0) { + if (args->numElements == 0) { return 0; } + size_t elemsPerWorker = (args->numElements + numWorkers - 1) / numWorkers; + if (elemsPerWorker % 16) { + elemsPerWorker += 16 - (elemsPerWorker % 16); + } + const size_t begin = elemsPerWorker * minionId; - const size_t end = std::min(begin + elemsPerWorker, static_cast(args->numElements)); - if (begin >= args->numElements) { + const size_t end = std::min(elemsPerWorker * (minionId + 1), static_cast(args->numElements)); + if (begin > (args->numElements - 1)) { return 0; } diff --git a/blas/reference/fp32/level1/copy/CMakeLists.txt b/blas/reference/fp32/level1/copy/CMakeLists.txt new file mode 100644 index 000000000..b45b7edbc --- /dev/null +++ b/blas/reference/fp32/level1/copy/CMakeLists.txt @@ -0,0 +1,6 @@ +add_etsoc_blas_kernel( + blas_copy_reference_fp32.elf + copy.cpp + INSTALL_DESTINATION kernels/blas/reference/fp32/level1/copy +) +target_include_directories(blas_copy_reference_fp32.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/blas/reference/fp32/level1/copy/copy.cpp b/blas/reference/fp32/level1/copy/copy.cpp new file mode 100644 index 000000000..9869e6ca5 --- /dev/null +++ b/blas/reference/fp32/level1/copy/copy.cpp @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + * Copyright (c) 2026 Ainekko, Co. + * SPDX-License-Identifier: Apache-2.0 + *------------------------------------------------------------------------- + */ + +#include +#include + +#include +#include + +#include "copy_kernel_arguments.h" +#include "entryPoint.h" + +int entryPoint_0(KernelArguments* args); +DECLARE_KERNEL_ENTRY_POINTS(entryPoint_0, nullptr); + +int entryPoint_0(KernelArguments* args) { + const auto minionId = get_relative_thread_id(); + const size_t numWorkers = SOC_MINIONS_PER_SHIRE; + + if (args->numElements == 0) { + return 0; + } + + size_t elemsPerWorker = (args->numElements + numWorkers - 1) / numWorkers; + if (elemsPerWorker % 16) { + elemsPerWorker += 16 - (elemsPerWorker % 16); + } + + const size_t begin = elemsPerWorker * minionId; + const size_t end = std::min(elemsPerWorker * (minionId + 1), static_cast(args->numElements)); + if (begin > (args->numElements - 1)) { + return 0; + } + + for (size_t i = begin; i < end; ++i) { + args->y[i] = args->x[i]; + } + + return 0; +} diff --git a/blas/reference/fp32/level1/copy/copy_kernel_arguments.h b/blas/reference/fp32/level1/copy/copy_kernel_arguments.h new file mode 100644 index 000000000..7350823cd --- /dev/null +++ b/blas/reference/fp32/level1/copy/copy_kernel_arguments.h @@ -0,0 +1,12 @@ +#ifndef ET_BLAS_REFERENCE_FP32_COPY_KERNEL_ARGUMENTS_H +#define ET_BLAS_REFERENCE_FP32_COPY_KERNEL_ARGUMENTS_H + +#include + +struct KernelArguments { + uint64_t numElements; + const float* x; + float* y; +} __attribute__((packed)); + +#endif diff --git a/blas/reference/fp32/level1/scal/CMakeLists.txt b/blas/reference/fp32/level1/scal/CMakeLists.txt new file mode 100644 index 000000000..9cd0401e1 --- /dev/null +++ b/blas/reference/fp32/level1/scal/CMakeLists.txt @@ -0,0 +1,6 @@ +add_etsoc_blas_kernel( + blas_scal_reference_fp32.elf + scal.cpp + INSTALL_DESTINATION kernels/blas/reference/fp32/level1/scal +) +target_include_directories(blas_scal_reference_fp32.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/blas/reference/fp32/level1/scal/scal.cpp b/blas/reference/fp32/level1/scal/scal.cpp new file mode 100644 index 000000000..6aaa423ab --- /dev/null +++ b/blas/reference/fp32/level1/scal/scal.cpp @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + * Copyright (c) 2026 Ainekko, Co. + * SPDX-License-Identifier: Apache-2.0 + *------------------------------------------------------------------------- + */ + +#include +#include + +#include +#include + +#include "entryPoint.h" +#include "scal_kernel_arguments.h" + +int entryPoint_0(KernelArguments* args); +DECLARE_KERNEL_ENTRY_POINTS(entryPoint_0, nullptr); + +int entryPoint_0(KernelArguments* args) { + const auto minionId = get_relative_thread_id(); + const size_t numWorkers = SOC_MINIONS_PER_SHIRE; + + if (args->numElements == 0) { + return 0; + } + + size_t elemsPerWorker = (args->numElements + numWorkers - 1) / numWorkers; + if (elemsPerWorker % 16) { + elemsPerWorker += 16 - (elemsPerWorker % 16); + } + + const size_t begin = elemsPerWorker * minionId; + const size_t end = std::min(elemsPerWorker * (minionId + 1), static_cast(args->numElements)); + if (begin > (args->numElements - 1)) { + return 0; + } + + for (size_t i = begin; i < end; ++i) { + args->x[i] = args->alpha * args->x[i]; + } + + return 0; +} diff --git a/blas/reference/fp32/level1/scal/scal_kernel_arguments.h b/blas/reference/fp32/level1/scal/scal_kernel_arguments.h new file mode 100644 index 000000000..d4fe68fb0 --- /dev/null +++ b/blas/reference/fp32/level1/scal/scal_kernel_arguments.h @@ -0,0 +1,12 @@ +#ifndef ET_BLAS_REFERENCE_FP32_SCAL_KERNEL_ARGUMENTS_H +#define ET_BLAS_REFERENCE_FP32_SCAL_KERNEL_ARGUMENTS_H + +#include + +struct KernelArguments { + uint64_t numElements; + float* x; + float alpha; +} __attribute__((packed)); + +#endif diff --git a/blas/reference/fp32/level1/swap/CMakeLists.txt b/blas/reference/fp32/level1/swap/CMakeLists.txt new file mode 100644 index 000000000..142e73e45 --- /dev/null +++ b/blas/reference/fp32/level1/swap/CMakeLists.txt @@ -0,0 +1,6 @@ +add_etsoc_blas_kernel( + blas_swap_reference_fp32.elf + swap.cpp + INSTALL_DESTINATION kernels/blas/reference/fp32/level1/swap +) +target_include_directories(blas_swap_reference_fp32.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/blas/reference/fp32/level1/swap/swap.cpp b/blas/reference/fp32/level1/swap/swap.cpp new file mode 100644 index 000000000..3aa7cd5d5 --- /dev/null +++ b/blas/reference/fp32/level1/swap/swap.cpp @@ -0,0 +1,45 @@ +/*------------------------------------------------------------------------- + * Copyright (c) 2026 Ainekko, Co. + * SPDX-License-Identifier: Apache-2.0 + *------------------------------------------------------------------------- + */ + +#include +#include + +#include +#include + +#include "entryPoint.h" +#include "swap_kernel_arguments.h" + +int entryPoint_0(KernelArguments* args); +DECLARE_KERNEL_ENTRY_POINTS(entryPoint_0, nullptr); + +int entryPoint_0(KernelArguments* args) { + const auto minionId = get_relative_thread_id(); + const size_t numWorkers = SOC_MINIONS_PER_SHIRE; + + if (args->numElements == 0) { + return 0; + } + + size_t elemsPerWorker = (args->numElements + numWorkers - 1) / numWorkers; + if (elemsPerWorker % 16) { + elemsPerWorker += 16 - (elemsPerWorker % 16); + } + + const size_t begin = elemsPerWorker * minionId; + const size_t end = std::min(elemsPerWorker * (minionId + 1), static_cast(args->numElements)); + if (begin > (args->numElements - 1)) { + return 0; + } + + for (size_t i = begin; i < end; ++i) { + const float tmp = args->x[i]; + args->x[i] = args->y[i]; + args->y[i] = tmp; + } + + return 0; +} diff --git a/blas/reference/fp32/level1/swap/swap_kernel_arguments.h b/blas/reference/fp32/level1/swap/swap_kernel_arguments.h new file mode 100644 index 000000000..16e386518 --- /dev/null +++ b/blas/reference/fp32/level1/swap/swap_kernel_arguments.h @@ -0,0 +1,12 @@ +#ifndef ET_BLAS_REFERENCE_FP32_SWAP_KERNEL_ARGUMENTS_H +#define ET_BLAS_REFERENCE_FP32_SWAP_KERNEL_ARGUMENTS_H + +#include + +struct KernelArguments { + uint64_t numElements; + float* x; + float* y; +} __attribute__((packed)); + +#endif diff --git a/blas/reference/host/CMakeLists.txt b/blas/reference/host/CMakeLists.txt new file mode 100644 index 000000000..4f97b6518 --- /dev/null +++ b/blas/reference/host/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.20) + +project(blas-reference-host LANGUAGES CXX) + +include(GNUInstallDirs) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(ET_PLATFORM_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../.." CACHE PATH "Path to the et-platform source tree") +set(BUILD_TESTS OFF CACHE BOOL "Build GP-SDK example launchers" FORCE) + +list(APPEND CMAKE_MODULE_PATH /opt/et/lib/cmake /opt/et/lib/cmake/cmake-modules) +list(APPEND CMAKE_PREFIX_PATH /opt/et/lib/cmake /opt/et/lib/cmake/cmake-modules) + +add_subdirectory(${ET_PLATFORM_SOURCE_DIR}/gp-sdk/host gp-sdk-host) + +add_executable(blas_reference_level1_verifier level1_verifier.cpp) +target_link_libraries(blas_reference_level1_verifier PRIVATE etsoc_gpsdk) + +install(TARGETS blas_reference_level1_verifier DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/blas/reference/host/level1_verifier.cpp b/blas/reference/host/level1_verifier.cpp new file mode 100644 index 000000000..58c75dc06 --- /dev/null +++ b/blas/reference/host/level1_verifier.cpp @@ -0,0 +1,482 @@ +/*------------------------------------------------------------------------- + * Copyright (c) 2026 Ainekko, Co. + * SPDX-License-Identifier: Apache-2.0 + *------------------------------------------------------------------------- + */ + +#include "GenericLauncher.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +struct AxpyArgs { + uint64_t numElements; + const float* x; + float* y; + float alpha; +} __attribute__((packed)); + +struct CopyArgs { + uint64_t numElements; + const float* x; + float* y; +} __attribute__((packed)); + +struct ScalArgs { + uint64_t numElements; + float* x; + float alpha; +} __attribute__((packed)); + +struct SwapArgs { + uint64_t numElements; + float* x; + float* y; +} __attribute__((packed)); + +struct Options { + fs::path kernel_root = ""; + fs::path host_results_path = "blas/reference/host_results.md"; + fs::path device_results_path = "blas/reference/device_results.md"; + int kernel_launch_timeout = 30; + std::string device_type = "sysemu"; + size_t num_elements = 256; + double epsilon = 1.0e-5; +}; + +struct OperationResult { + std::string name; + std::string output_label_x = "output_x"; + std::string output_label_y = "output_y"; + bool has_alpha = false; + float alpha = 0.0f; + bool has_input_y = true; + bool has_output_x = false; + bool has_output_y = true; + bool ok = false; + std::vector input_x; + std::vector input_y; + std::vector output_x; + std::vector output_y; +}; + +Options parse_args(int argc, char* const* argv, std::vector& nextlevel) { + static constexpr const char* help_msg = + "Usage: [options]\n\n" + "Quick verifier for BLAS reference Level 1 kernels.\n\n" + "Optional switches:\n" + " -k, --kernel_root root containing axpy/copy/scal/swap kernel directories\n" + " --host_results_path markdown file for host reference outputs\n" + " --device_results_path markdown file for device outputs\n" + " -t, --kernel_launch_timeout timeout (in seconds) to wait for kernel completion\n" + " -d, --device_type device type to use (sysemu, fake, silicon)\n" + " -n, --num_elements number of elements in dummy vectors\n" + " -e, --epsilon comparison tolerance for float results\n"; + + static constexpr const char* short_opts = "k:t:d:n:e:h"; + static const std::vector