From 1f2ae46eb877e4591d977df8f20f0edd79d13194 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 28 Jul 2025 20:13:42 +0200 Subject: [PATCH 01/37] Add ROCm backend --- cpp/CMakeLists.txt | 98 +- cpp/main.cpp | 9 + cpp/neuralnet/rocmbackend.cpp | 3077 ++++++++++++++++++++++++++++++++ cpp/neuralnet/rocmerrorcheck.h | 59 + cpp/neuralnet/rocmhelpers.h | 60 + cpp/neuralnet/rocmhelpers.hip | 1905 ++++++++++++++++++++ cpp/neuralnet/rocmincludes.h | 15 + cpp/neuralnet/rocmutils.cpp | 170 ++ cpp/neuralnet/rocmutils.h | 21 + 9 files changed, 5413 insertions(+), 1 deletion(-) create mode 100644 cpp/neuralnet/rocmbackend.cpp create mode 100644 cpp/neuralnet/rocmerrorcheck.h create mode 100644 cpp/neuralnet/rocmhelpers.h create mode 100644 cpp/neuralnet/rocmhelpers.hip create mode 100644 cpp/neuralnet/rocmincludes.h create mode 100644 cpp/neuralnet/rocmutils.cpp create mode 100644 cpp/neuralnet/rocmutils.h diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 2b6da407f5..e12b7e41bf 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -32,7 +32,8 @@ endif() set(BUILD_DISTRIBUTED 0 CACHE BOOL "Build with http support for contributing to distributed training") set(USE_BACKEND CACHE STRING "Neural net backend") string(TOUPPER "${USE_BACKEND}" USE_BACKEND) -set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN) +# set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN) +set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN ROCM) set(USE_TCMALLOC 0 CACHE BOOL "Use TCMalloc") set(NO_GIT_REVISION 0 CACHE BOOL "Disable embedding the git revision into the compiled exe") @@ -139,6 +140,42 @@ elseif(USE_BACKEND STREQUAL "EIGEN") set(NEURALNET_BACKEND_SOURCES neuralnet/eigenbackend.cpp ) +# --------------------------- ROCM 后端(AMD GPU / HIP MIOpen) --------------------------- +elseif(USE_BACKEND STREQUAL "ROCM") + message(STATUS "-DUSE_BACKEND=ROCM, using AMD ROCm backend.") + + # 1) 启用 HIP 语言(.hip / .cpp 均可)并指定 C++17 + enable_language(HIP) + set(CMAKE_HIP_STANDARD 17) + + if(CMAKE_PREFIX_PATH STREQUAL "" OR NOT DEFINED CMAKE_PREFIX_PATH) + if(DEFINED ENV{HIP_PATH}) + # Windows HIP‑SDK 或自定义安装 + list(APPEND CMAKE_PREFIX_PATH $ENV{HIP_PATH}) + message(STATUS "Auto‑detected HIP_PATH=$ENV{HIP_PATH} → CMAKE_PREFIX_PATH") + elseif(EXISTS "/opt/rocm") + # Linux 默认路径 + list(APPEND CMAKE_PREFIX_PATH "/opt/rocm") + message(STATUS "CMAKE_PREFIX_PATH not given; defaulting to /opt/rocm") + endif() + endif() + + # 可让用户用 -DCMAKE_HIP_ARCHITECTURES=gfx90a;gfx942 手动指定 GFX 架构 + if(NOT DEFINED CMAKE_HIP_ARCHITECTURES) + # 默认同时编译常见 MI200 / RDNA3 卡,可按需精简 + set(CMAKE_HIP_ARCHITECTURES 90a 942 908 1100 1101 1200 1201 CACHE STRING "AMD GPU targets") + endif() + + # 2) 指定后端源码。rocmhelpers.hip 里是 GPU‑kernel,别漏了 + set(NEURALNET_BACKEND_SOURCES + neuralnet/rocmbackend.cpp + neuralnet/rocmutils.cpp + neuralnet/rocmhelpers.hip + ) + + # 可选:启用 model-size‑based autotuning等额外宏 + # add_compile_definitions(HIP_SUPPORTS_FP16) + elseif(USE_BACKEND STREQUAL "") message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN to compile with the respective backend.${ColorReset}") set(NEURALNET_BACKEND_SOURCES neuralnet/dummybackend.cpp) @@ -418,6 +455,65 @@ elseif(USE_BACKEND STREQUAL "OPENCL") link_directories(${OpenCL_LIBRARY}) target_link_libraries(katago ${OpenCL_LIBRARY}) endif() +# --------------------------- ROCM 链接阶段 --------------------------- +elseif(USE_BACKEND STREQUAL "ROCM") + # 宏:源代码里用 #ifdef USE_ROCM_BACKEND 判断 + target_compile_definitions(katago PRIVATE USE_ROCM_BACKEND) + target_compile_definitions(katago PRIVATE HIP_TARGET_VERSION=${CMAKE_HIP_COMPILER_VERSION}) + + string(TOLOWER "${CMAKE_HIP_ARCHITECTURES}" _gfxlist) # e.g. "90a;942" + if(_gfxlist MATCHES "803|900|90a|94[0-9]|110[0-9]|120[0-9]") + target_compile_definitions(katago PRIVATE HIP_SUPPORTS_FP16) + message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") + endif() + + # 3) 找到 ROCm 运行时 & 库。自 ROCm 6.x 起都带 CMake config‑mode 包 + # 如若找不到,加 -DCMAKE_PREFIX_PATH=/opt/rocm + find_package(hip QUIET CONFIG) # 导出 hip::device / hip::host + find_package(hipblas QUIET CONFIG) # 导出 roc::hipblas + find_package(miopen QUIET CONFIG) # 导出 roc::miopen + # ---------- fallback:HIP 运行时 ---------- + if(NOT hip_FOUND) + find_path(HIP_INCLUDE_DIR hip/hip_runtime.h + HINTS ${CMAKE_PREFIX_PATH} /opt/rocm + PATH_SUFFIXES include) + find_library(HIP_RUNTIME_LIB amdhip64 + HINTS ${CMAKE_PREFIX_PATH} /opt/rocm + PATH_SUFFIXES lib lib64) + if(NOT HIP_INCLUDE_DIR OR NOT HIP_RUNTIME_LIB) + message(FATAL_ERROR "HIP headers or runtime NOT found; install ROCm or set CMAKE_PREFIX_PATH.") + endif() + add_library(hip::device UNKNOWN IMPORTED) + set_target_properties(hip::device PROPERTIES + IMPORTED_LOCATION "${HIP_RUNTIME_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${HIP_INCLUDE_DIR}") + target_include_directories(katago SYSTEM PRIVATE ${HIP_INCLUDE_DIR}) + endif() + + # ---------- fallback:hipBLAS / MIOpen ---------- + foreach(_pkg hipblas miopen) + if(NOT ${_pkg}_FOUND) + find_library(${_pkg}_LIB ${_pkg} + HINTS ${CMAKE_PREFIX_PATH} /opt/rocm + PATH_SUFFIXES lib lib64) + if(${_pkg}_LIB) + add_library(roc::${_pkg} UNKNOWN IMPORTED) + set_target_properties(roc::${_pkg} PROPERTIES + IMPORTED_LOCATION "${${_pkg}_LIB}") + target_include_directories(katago SYSTEM PRIVATE ${HIP_INCLUDE_DIR}) + else() + message(FATAL_ERROR "Required ROCm component ${_pkg} not found – install it or set CMAKE_PREFIX_PATH.") + endif() + endif() + endforeach() + + # 4) 头文件路径已由 config‑mode target 解决,无需硬编码 + target_link_libraries(katago + hip::device # HIP runtime & kernel offload + roc::hipblas # BLAS + MIOpen + roc::miopen # DNN primitives + ) elseif(USE_BACKEND STREQUAL "EIGEN") target_compile_definitions(katago PRIVATE USE_EIGEN_BACKEND) if(NOT (MSVC)) diff --git a/cpp/main.cpp b/cpp/main.cpp index f86a44a273..24259f984e 100644 --- a/cpp/main.cpp +++ b/cpp/main.cpp @@ -239,6 +239,13 @@ string Version::getKataGoVersionFullInfo() { out << "Using Metal backend" << endl; #elif defined(USE_OPENCL_BACKEND) out << "Using OpenCL backend" << endl; +#elif defined(USE_ROCM_BACKEND) + out << "Using ROCm backend" << endl; +#if defined(HIP_TARGET_VERSION) +#define STRINGIFY(x) #x +#define STRINGIFY2(x) STRINGIFY(x) + out << "Compiled with HIP runtime version " << STRINGIFY2(HIP_TARGET_VERSION) << endl; +#endif #elif defined(USE_EIGEN_BACKEND) out << "Using Eigen(CPU) backend" << endl; #else @@ -271,6 +278,8 @@ string Version::getGitRevisionWithBackend() { s += "-cuda"; #elif defined(USE_TENSORRT_BACKEND) s += "-trt"; +#elif defined(USE_ROCM_BACKEND) + s += "-rocm"; #elif defined(USE_METAL_BACKEND) s += "-metal"; #elif defined(USE_OPENCL_BACKEND) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp new file mode 100644 index 0000000000..11489e85af --- /dev/null +++ b/cpp/neuralnet/rocmbackend.cpp @@ -0,0 +1,3077 @@ +#include "hip/hip_runtime.h" +// #ifdef USE_ROCM_BACKEND +#include +#include +#include +#include + +#include "../neuralnet/rocmerrorcheck.h" +#include "../neuralnet/rocmincludes.h" +#include "../neuralnet/rocmhelpers.h" +#include "../neuralnet/rocmutils.h" + +#include "../neuralnet/modelversion.h" +#include "../neuralnet/nninterface.h" +#include "../neuralnet/nninputs.h" +#include "../neuralnet/sgfmetadata.h" +#include "../neuralnet/nneval.h" +#include "../neuralnet/desc.h" + +#include "../core/simpleallocator.h" +#include "../core/test.h" + +#include "../external/half-2.2.0/include/half.hpp" + +//------------------------ +#include "../core/using.h" +//------------------------ + +using half_t = half_float::half; + +//Define this to print out some of the intermediate values of the neural net +//#define DEBUG_INTERMEDIATE_VALUES + +void NeuralNet::globalInitialize() { + //Empty for cudnn backend +} + +void NeuralNet::globalCleanup() { + hipDeviceReset(); +} + +struct CudaHandles { + hipblasHandle_t cublas; + miopenStatus_t cudnn; + const int majorComputeCapability; + const int minorComputeCapability; + + CudaHandles(int major, int minor) + : majorComputeCapability(major), + minorComputeCapability(minor) + { + CUBLAS_ERR("CudaHandles",hipblasCreate(&cublas)); + CUDNN_ERR("CudaHandles",miopenCreate(&cudnn)); + } + + ~CudaHandles() { + hipblasDestroy(cublas); + miopenDestroy(cudnn); + } + + static CudaHandles* cudaHandlesTesting() { + const int gpuIdxForThisThread = 0; + hipDeviceProp_t prop; + hipGetDeviceProperties(&prop,gpuIdxForThisThread); + return new CudaHandles(prop.major, prop.minor); + } + + CudaHandles(const CudaHandles&) = delete; + CudaHandles& operator=(const CudaHandles&) = delete; +}; + +//--------------------------------------------------------------------------------- + +template +struct ByBatchSize { + const int maxBatchSize; + T* data; + miopenStatus_t (*destroyFunc)(T); + + ByBatchSize() + : maxBatchSize(0), data(nullptr), destroyFunc(nullptr) + {} + + ByBatchSize( + int maxBatchSize_ + ) : maxBatchSize(maxBatchSize_), data(nullptr), destroyFunc(nullptr) { + data = new T[maxBatchSize]; + } + + ByBatchSize(const ByBatchSize&) = delete; + ByBatchSize& operator=(const ByBatchSize&) = delete; + + ~ByBatchSize() { + if(destroyFunc != nullptr && data != nullptr) { + for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { + (*destroyFunc)(data[batchSize-1]); + } + } + if(data != nullptr) { + delete[] data; + data = nullptr; + } + } + T& operator[](int batchSize) { + return data[batchSize-1]; + } + const T& operator[](int batchSize) const { + return data[batchSize-1]; + } +}; + +template +struct ByBatchSizeView { + int maxBatchSize; + T* data; + + ByBatchSizeView() + : maxBatchSize(0), data(nullptr) + {} + + ByBatchSizeView(const ByBatchSize& toView) + : maxBatchSize(toView.maxBatchSize), data(toView.data) + {} + ByBatchSizeView& operator=(const ByBatchSize& toView) { + maxBatchSize = toView.maxBatchSize; + data = toView.data; + } + + ~ByBatchSizeView() { + } + T& operator[](int batchSize) { + return data[batchSize-1]; + } + const T& operator[](int batchSize) const { + return data[batchSize-1]; + } +}; + +//--------------------------------------------------------------------------------- + + +//channels, useFP16, useNHWC +typedef std::tuple CudnnTensorDesc4DKey; + +struct CudnnTensorDesc4DKey { + int channels; + bool useFP16; + bool useNHWC; + bool operator<(const CudnnTensorDesc4DKey& other) const { + return std::tie(channels, useFP16, useNHWC) < + std::tie(other.channels, other.useFP16, other.useNHWC); + } +}; + +template +struct ByBatchSize { + explicit ByBatchSize(int max) + : data(max + 1), destroyFunc(nullptr) {} + ~ByBatchSize() { + if (destroyFunc) { + for (auto& d : data) { + if (d) destroyFunc(d); + } + } + } + T& operator[](int idx) { return data[idx]; } + std::vector data; + miopenStatus_t (*destroyFunc)(T) = nullptr; +}; + +template +struct ByBatchSizeView { + explicit ByBatchSizeView(ByBatchSize& ref) : ref(ref) {} + T& operator[](int idx) { return ref[idx]; } + ByBatchSize& ref; +}; + +// ----------------------------------------------------------------------------- +// CudnnManager +// ----------------------------------------------------------------------------- +struct CudnnManager { + const std::string name; + const int maxBatchSize; + const int nnXLen; + const int nnYLen; + std::map*> + tensorDesc4DByBatchSizeByKey; + + CudnnManager(std::string name_, int maxBatchSize_, int nnXLen_, int nnYLen_) + : name(std::move(name_)), + maxBatchSize(maxBatchSize_), + nnXLen(nnXLen_), + nnYLen(nnYLen_), + tensorDesc4DByBatchSizeByKey() {} + + ~CudnnManager() { + for (auto& iter : tensorDesc4DByBatchSizeByKey) { + delete iter.second; + } + } + + ByBatchSizeView getTensorDesc4DByBatchSize( + int channels, bool useFP16, bool useNHWC) { + auto iter = tensorDesc4DByBatchSizeByKey.find({channels, useFP16, useNHWC}); + if (iter != tensorDesc4DByBatchSizeByKey.end()) { + return ByBatchSizeView(*(iter->second)); + } + + auto* descs = new ByBatchSize(maxBatchSize); + + for (int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { + miopenTensorDescriptor_t& desc = (*descs)[batchSize]; + // Create descriptor + CUDNN_ERR(name.c_str(), miopenCreateTensorDescriptor(&desc)); + + const miopenDataType_t dtype = useFP16 ? miopenHalf : miopenFloat; + + if (!useNHWC) { + // Fully‑supported NCHW fast‑path + CUDNN_ERR(name.c_str(), + miopenSet4dTensorDescriptor(desc, dtype, batchSize, channels, + nnYLen, nnXLen)); + } else { + // NHWC path via generic Nd descriptor + explicit strides + int dims[4] = {batchSize, nnYLen, nnXLen, channels}; // N H W C + int strides[4]; + strides[3] = 1; // C stride + strides[2] = strides[3] * channels; // W stride + strides[1] = strides[2] * nnXLen; // H stride + strides[0] = strides[1] * nnYLen; // N stride + + CUDNN_ERR(name.c_str(), + miopenSetTensorDescriptor(desc, dtype, 4, dims, strides)); + } + } + + descs->destroyFunc = miopenDestroyTensorDescriptor; + tensorDesc4DByBatchSizeByKey[{channels, useFP16, useNHWC}] = descs; + return ByBatchSizeView(*descs); + } +}; + + +//--------------------------------------------------------------------------------- + +struct ScratchBuffers { + + const size_t batchXYFloatBytes; + const size_t batchFloatBytes; + const size_t batchXYBytes; + const size_t batchBytes; + + SimpleAllocator* allocator; + + // Not scratch, but convenient to have here + void* zeroBuf; + void* oneBuf; + + ScratchBuffers() = delete; + ScratchBuffers(const ScratchBuffers&) = delete; + ScratchBuffers& operator=(const ScratchBuffers&) = delete; + + ScratchBuffers(int maxBatchSize, int nnXLen, int nnYLen, bool useFP16) + : batchXYFloatBytes((size_t)maxBatchSize * nnXLen * nnYLen * sizeof(float)), + batchFloatBytes((size_t)maxBatchSize * sizeof(float)), + batchXYBytes((size_t)maxBatchSize * nnXLen * nnYLen * (useFP16 ? sizeof(half_t) : sizeof(float))), + batchBytes((size_t)maxBatchSize * (useFP16 ? sizeof(half_t) : sizeof(float))) + { + std::function allocateFunc = [](size_t size) { + void* buf; + CUDA_ERR("ScratchBuffers",hipMalloc(&buf, size)); + return buf; + }; + std::function releaseFunc = [](void* buf) { + hipFree(buf); + }; + + allocator = new SimpleAllocator(allocateFunc, releaseFunc); + + CudaUtils::hostMallocZeroOneBufs(zeroBuf, oneBuf, useFP16); + } + ~ScratchBuffers() { + delete allocator; + free(zeroBuf); + free(oneBuf); + } + + size_t getBufSizeXY(int channels) const { + return channels * batchXYBytes; + } + size_t getBufSizeXYFloat(int channels) const { + return channels * batchXYFloatBytes; + } + size_t getBufSizeFloat(int channels) const { + return channels * batchFloatBytes; + } + size_t getBufSize(int channels) const { + return channels * batchBytes; + } + +}; + + +//--------------------------------------------------------------------------------- + +struct ConvLayer { + const string name; + const int inChannels; + const int outChannels; + ByBatchSizeView inputDescriptors; + ByBatchSizeView outputDescriptors; + miopenTensorDescriptor_t filterDescriptor; + miopenConvolutionDescriptor_t convolutionDescriptor; + ByBatchSize* convolutionAlgorithms; //array of one for each batch size + void* filterBuf; + + ConvLayer() = delete; + ConvLayer(const ConvLayer&) = delete; + ConvLayer& operator=(const ConvLayer&) = delete; + + ConvLayer( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ConvLayerDesc* desc, + bool useFP16, + bool useNHWC + ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) + {} + + ConvLayer( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ConvLayerDesc* desc, + bool useFP16, + bool useNHWCIn, + bool useNHWCOut + ) : + name(desc->name), + inChannels(desc->inChannels), + outChannels(desc->outChannels) + { + int convYSize = desc->convYSize; + int convXSize = desc->convXSize; + int dilationY = desc->dilationY; + int dilationX = desc->dilationX; + int paddingX = (convXSize / 2) * dilationX; + int paddingY = (convYSize / 2) * dilationY; + + assert(convXSize % 2 == 1); + assert(convYSize % 2 == 1); + + inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); + outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); + int maxBatchSize = manager->maxBatchSize; + + bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; + + CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); + CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( + filterDescriptor, + (useFP16 ? miopenHalf : miopenFloat), + outChannels, + inChannels, + convYSize, + convXSize + )); + + int yStride = 1; + int xStride = 1; + + bool tensorCoresSupported = true; + + CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); + CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( + convolutionDescriptor, + miopenConvolution, + paddingY, + paddingX, + yStride, + xStride, + dilationY, + dilationX + )); + if(useFP16) { + int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs + miopenSetConvolutionAttribute(convolutionDescriptor, + MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL, + alt); + } + + convolutionAlgorithms = new ByBatchSize(maxBatchSize); + + for(int batchSize = 1; batchSize <= maxBatchSize; ++batchSize) { + if(useFP16 && dilationX <= 1 && dilationY <= 1) { + (*convolutionAlgorithms)[batchSize] = miopenConvolutionFwdAlgoImplicitGEMM; + } + else { + (*convolutionAlgorithms)[batchSize] = miopenConvolutionFwdAlgoDirect; + // If desired, call miopenFindConvolutionForwardAlgorithm() here once you + // have real device buffers to auto‑tune. See porting notes. + } + } + + assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); + + if(filterNHWC) { + vector weightsTransposed(desc->weights.size()); + for(int y = 0; y < convYSize; y++) { + for(int x = 0; x < convXSize; x++) { + for(int ic = 0; ic < inChannels; ic++) { + for(int oc = 0; oc < outChannels; oc++) { + weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = + desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; + } + } + } + } + CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); + hipDeviceSynchronize(); + } + else + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + } + + ~ConvLayer() { + hipFree(filterBuf); + miopenDestroyTensorDescriptor(filterDescriptor); + miopenDestroyConvolutionDescriptor(convolutionDescriptor); + delete convolutionAlgorithms; + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t workspaceBytes = 0; + CUDNN_ERR(name.c_str(), miopenConvolutionForwardGetWorkSpaceSize( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptors[batchSize], + convolutionDescriptor, + outputDescriptors[batchSize], + &workspaceBytes)); + return workspaceBytes; + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + bool accumulate, // if true, beta = 1 (unsupported by MIOpen fwd) + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes) const +{ + const float alpha = 1.0f; + const float beta = accumulate ? 1.0f : 0.0f; + + // New MIOpen API order: ... algo, beta, yDesc, y, workSpace, workSpaceSize + CUDNN_ERR(name.c_str(), miopenConvolutionForward( + cudaHandles->cudnn, + &alpha, + inputDescriptors[batchSize], + inputBuf, + filterDescriptor, + filterBuf, + convolutionDescriptor, + (*convolutionAlgorithms)[batchSize], + &beta, + outputDescriptors[batchSize], + outputBuf, + workspaceBuf, + workspaceBytes)); + } + +}; + + +//--------------------------------------------------------------------------------- + +struct BatchNormLayer { + const string name; + const int numChannels; + const float epsilon; + const int activation; + const int nnXLen; + const int nnYLen; + + const bool usingFP16; + const bool usingNHWC; + + void* mergedScaleBuf; + void* mergedBiasBuf; + + BatchNormLayer() = delete; + BatchNormLayer(const BatchNormLayer&) = delete; + BatchNormLayer& operator=(const BatchNormLayer&) = delete; + + BatchNormLayer( + CudaHandles* cudaHandles, + const BatchNormLayerDesc* desc, + const ActivationLayerDesc* actDesc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + numChannels(desc->numChannels), + epsilon(desc->epsilon), + activation(actDesc->activation), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC) + { + (void)cudaHandles; + + assert(desc->mean.size() == numChannels); + assert(desc->variance.size() == numChannels); + assert(desc->scale.size() == numChannels); + assert(desc->bias.size() == numChannels); + assert(desc->mergedScale.size() == numChannels); + assert(desc->mergedBias.size() == numChannels); + CudaUtils::mallocAndCopyToDevice(name,desc->mergedScale,mergedScaleBuf,useFP16); + CudaUtils::mallocAndCopyToDevice(name,desc->mergedBias,mergedBiasBuf,useFP16); + } + ~BatchNormLayer() { + hipFree(mergedScaleBuf); + hipFree(mergedBiasBuf); + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + void* inputBuf, + const void* maskBuf, //ok to be null + void* outputBuf + ) const { + (void)cudaHandles; + if(!usingFP16) { + if(!usingNHWC) + customCudaApplyCScaleBiasNCHW((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, + (const float*)maskBuf, + batchSize,numChannels,nnXLen*nnYLen,activation); + else + customCudaApplyCScaleBiasNHWC((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, + (const float*)maskBuf, + batchSize,nnXLen*nnYLen,numChannels,activation); + } + else { + if(!usingNHWC) + customCudaApplyCScaleBiasNCHW((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, + (const half*)maskBuf, + batchSize,numChannels,nnXLen*nnYLen,activation); + else + customCudaApplyCScaleBiasNHWC((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, + (const half*)maskBuf, + batchSize,nnXLen*nnYLen,numChannels,activation); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + + } + +}; + + +//--------------------------------------------------------------------------------- + +struct MatMulLayer { + const string name; + const int inChannels; + const int outChannels; + const bool usingFP16; + void* matBuf; + + MatMulLayer() = delete; + MatMulLayer(const MatMulLayer&) = delete; + MatMulLayer& operator=(const MatMulLayer&) = delete; + + MatMulLayer( + CudaHandles* cudaHandles, + const MatMulLayerDesc* desc, + bool useFP16 + ) : + name(desc->name), + inChannels(desc->inChannels), + outChannels(desc->outChannels), + usingFP16(useFP16) + { + (void)cudaHandles; + + if(inChannels > 0 && outChannels > 0) { + assert(desc->weights.size() == inChannels * outChannels); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,matBuf,useFP16); + } + else { + matBuf = NULL; + } + } + + ~MatMulLayer() { + if(inChannels > 0 && outChannels > 0) + hipFree(matBuf); + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles + ) const { + (void)cudaHandles; + size_t workspaceBytes = 0; + return workspaceBytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + (void)workspaceBuf; + (void)workspaceBytes; + assert(inChannels > 0 && outChannels > 0); + + if(!usingFP16) { + const float alpha = 1.0f; + const float beta = 0.0f; + CUBLAS_ERR(name.c_str(),hipblasSgemm( + cudaHandles->cublas, + HIPBLAS_OP_N, + HIPBLAS_OP_N, + outChannels, + batchSize, + inChannels, + &alpha, + (const float*)matBuf,outChannels, + (const float*)inputBuf,inChannels, + &beta, + (float*)outputBuf,outChannels + )); + } + else { + const half* alpha = (const half*)scratch->oneBuf; + const half* beta = (const half*)scratch->zeroBuf; + CUBLAS_ERR(name.c_str(),hipblasHgemm( + cudaHandles->cublas, + HIPBLAS_OP_N, + HIPBLAS_OP_N, + outChannels, + batchSize, + inChannels, + alpha, + (const half*)matBuf,outChannels, + (const half*)inputBuf,inChannels, + beta, + (half*)outputBuf,outChannels + )); + } + + } + +}; + +//--------------------------------------------------------------------------------- + +struct MatBiasLayer { + const string name; + const int numChannels; + const bool usingFP16; + const int activation; + + void* biasBuf; + + MatBiasLayer() = delete; + MatBiasLayer(const MatBiasLayer&) = delete; + MatBiasLayer& operator=(const MatBiasLayer&) = delete; + + MatBiasLayer( + CudaHandles* cudaHandles, + const MatBiasLayerDesc* desc, + bool useFP16, + int activation_ + ) : + name(desc->name), + numChannels(desc->numChannels), + usingFP16(useFP16), + activation(activation_) + { + (void)cudaHandles; + if(numChannels > 0) { + assert(desc->weights.size() == numChannels); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,biasBuf,useFP16); + } + else + biasBuf = NULL; + } + + ~MatBiasLayer() { + if(numChannels > 0) + hipFree(biasBuf); + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + void* matBuf + ) const { + (void)cudaHandles; + assert(numChannels > 0); + if(!usingFP16) { + customCudaAddCBiasInplaceNC((float*)matBuf,(const float*)biasBuf,batchSize,numChannels,activation); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + else { + customCudaAddCBiasInplaceNC((half*)matBuf,(const half*)biasBuf,batchSize,numChannels,activation); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + } + +}; + +//--------------------------------------------------------------------------------- + +struct NormActConv { + const BatchNormLayer norm; + const ConvLayer conv; + + const int inChannels; + const int outChannels; + const int nnXLen; + const int nnYLen; + const bool usingFP16; + const bool usingNHWC; + + NormActConv() = delete; + NormActConv(const NormActConv&) = delete; + NormActConv& operator=(const NormActConv&) = delete; + + NormActConv( + CudaHandles* cudaHandles, + CudnnManager* manager, + const BatchNormLayerDesc* normDesc, + const ActivationLayerDesc* actDesc, + const ConvLayerDesc* convDesc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): norm(cudaHandles,normDesc,actDesc,nnX,nnY,useFP16,useNHWC), + conv(cudaHandles,manager,convDesc,useFP16,useNHWC), + inChannels(norm.numChannels), + outChannels(conv.outChannels), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC) + { + assert(norm.numChannels == conv.inChannels); + } + + ~NormActConv() + {} + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + bool accumulate, + void* inBuf, + void* inScratchBuf, + void* outBuf, + void* maskBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + norm.apply(cudaHandles,batchSize,inBuf,maskBuf,inScratchBuf); +#ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("AFTER NORM "), inScratchBuf, batchSize, inChannels, nnXLen, nnYLen, usingNHWC, usingFP16); +#endif + conv.apply(cudaHandles,batchSize,accumulate,inScratchBuf,outBuf,workspaceBuf,workspaceBytes); + } + +}; + + +//--------------------------------------------------------------------------------- + +struct ResidualBlock { + const string name; + const NormActConv normActConv1; + const NormActConv normActConv2; + + ResidualBlock() = delete; + ResidualBlock(const ResidualBlock&) = delete; + ResidualBlock& operator=(const ResidualBlock&) = delete; + + ResidualBlock( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ResidualBlockDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): name(desc->name), + normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->regularConv,nnX,nnY,useFP16,useNHWC), + normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC) + { + } + + ~ResidualBlock() + {} + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* trunkBuf, + void* trunkScratchBuf, + void* maskBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf midIn(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,midIn.buf,maskBuf,workspaceBuf,workspaceBytes); + normActConv2.apply(cudaHandles,batchSize,true,midIn.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); + } + +}; + + +//---------------------------------------------------------------------------- + + +struct GlobalPoolingResidualBlock { + const string name; + const BatchNormLayer preBN; + const ConvLayer regularConv; + const ConvLayer gpoolConv; + const BatchNormLayer gpoolBN; + const MatMulLayer gpoolToBiasMul; + const NormActConv normActConv2; + + const int nnXLen; + const int nnYLen; + const int regularChannels; + const int gpoolChannels; + const bool usingFP16; + const bool usingNHWC; + + GlobalPoolingResidualBlock() = delete; + GlobalPoolingResidualBlock(const GlobalPoolingResidualBlock&) = delete; + GlobalPoolingResidualBlock& operator=(const GlobalPoolingResidualBlock&) = delete; + + GlobalPoolingResidualBlock( + CudaHandles* cudaHandles, + CudnnManager* manager, + const GlobalPoolingResidualBlockDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): name(desc->name), + preBN(cudaHandles,&desc->preBN,&desc->preActivation,nnX,nnY,useFP16,useNHWC), + regularConv(cudaHandles,manager,&desc->regularConv,useFP16,useNHWC), + gpoolConv(cudaHandles,manager,&desc->gpoolConv,useFP16,useNHWC), + gpoolBN(cudaHandles,&desc->gpoolBN,&desc->gpoolActivation,nnX,nnY,useFP16,useNHWC), + gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,useFP16), + normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC), + nnXLen(nnX), + nnYLen(nnY), + regularChannels(desc->regularConv.outChannels), + gpoolChannels(desc->gpoolConv.outChannels), + usingFP16(useFP16), + usingNHWC(useNHWC) + { + } + + ~GlobalPoolingResidualBlock() { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = regularConv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolConv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*gpoolChannels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* trunkBuf, + void* trunkScratchBuf, + void* maskBuf, + float* maskSumBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf regularOut(scratch->allocator, scratch->getBufSizeXY(regularChannels)); + SizedBuf regularScratch(scratch->allocator, scratch->getBufSizeXY(regularChannels)); + SizedBuf gpoolOut(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); + SizedBuf gpoolOut2(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); + SizedBuf gpoolConcat(scratch->allocator, scratch->getBufSize(gpoolChannels*3)); + SizedBuf gpoolBias(scratch->allocator, scratch->getBufSize(regularChannels)); + + preBN.apply(cudaHandles,batchSize,trunkBuf,maskBuf,trunkScratchBuf); + regularConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,regularOut.buf,workspaceBuf,workspaceBytes); + gpoolConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,gpoolOut.buf,workspaceBuf,workspaceBytes); + gpoolBN.apply(cudaHandles,batchSize,gpoolOut.buf,maskBuf,gpoolOut2.buf); + + if(!usingFP16) { + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const float*)maskBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const float*)maskBuf,maskSumBuf); + } + else { + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const half*)maskBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const half*)maskBuf,maskSumBuf); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,gpoolConcat.buf,gpoolBias.buf,workspaceBuf,workspaceBytes); + + if(!usingFP16) { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); + } + else { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + normActConv2.apply(cudaHandles,batchSize,true,regularOut.buf,regularScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); + } + +}; + +//------------------------------------------------------------------------------ + +struct BlockStack { + const int numBlocks; + const int trunkNumChannels; + const int nnXLen; + const int nnYLen; + const bool usingFP16; + const bool usingNHWC; + vector> blocks; + + BlockStack() = delete; + BlockStack(const BlockStack&) = delete; + BlockStack& operator=(const BlockStack&) = delete; + + BlockStack( + CudaHandles* cudaHandles, + CudnnManager* manager, + int nBlocks, + int trunkChannels, + const std::vector>& descBlocks, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ); + ~BlockStack(); + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const; + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + void* trunkScratchBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const; + +}; + +//------------------------------------------------------------------------------ + +struct NestedBottleneckResidualBlock { + const string name; + const NormActConv normActConv1; + const BlockStack blocks; + const NormActConv normActConv2; + + NestedBottleneckResidualBlock() = delete; + NestedBottleneckResidualBlock(const NestedBottleneckResidualBlock&) = delete; + NestedBottleneckResidualBlock& operator=(const NestedBottleneckResidualBlock&) = delete; + + NestedBottleneckResidualBlock( + CudaHandles* cudaHandles, + CudnnManager* manager, + const NestedBottleneckResidualBlockDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): name(desc->name), + normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->preConv,nnX,nnY,useFP16,useNHWC), + blocks(cudaHandles,manager,desc->numBlocks,desc->preConv.outChannels,desc->blocks,nnX,nnY,useFP16,useNHWC), + normActConv2(cudaHandles,manager,&desc->postBN,&desc->postActivation,&desc->postConv,nnX,nnY,useFP16,useNHWC) + { + } + + ~NestedBottleneckResidualBlock() + {} + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* trunkBuf, + void* trunkScratchBuf, + void* maskBuf, + float* maskSumBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf mid(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + assert(normActConv1.outChannels == normActConv2.inChannels); + normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,mid.buf,maskBuf,workspaceBuf,workspaceBytes); + blocks.apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskSumBuf, + mid.buf, + midScratch.buf, + workspaceBuf, + workspaceBytes + ); + normActConv2.apply(cudaHandles,batchSize,true,mid.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); + } + +}; + +//------------------------------------------------------------------------------ + +BlockStack::BlockStack( + CudaHandles* cudaHandles, + CudnnManager* manager, + int nBlocks, + int trunkChannels, + const std::vector>& descBlocks, + int nnX, + int nnY, + bool useFP16, + bool useNHWC +) : + numBlocks(nBlocks), + trunkNumChannels(trunkChannels), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC) +{ + assert(numBlocks == descBlocks.size()); + for(int i = 0; irequiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { + GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); + b = block->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { + NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); + b = block->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + else { + ASSERT_UNREACHABLE; + } + } + return bytes; +} + +void BlockStack::apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + void* trunkScratchBuf, + void* workspaceBuf, + size_t workspaceBytes +) const { + + for(int i = 0; iapply( + cudaHandles, + scratch, + batchSize, + trunkBuf, + trunkScratchBuf, + maskBuf, + workspaceBuf, + workspaceBytes + ); + } + else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { + GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); + block->apply( + cudaHandles, + scratch, + batchSize, + trunkBuf, + trunkScratchBuf, + maskBuf, + maskSumBuf, + workspaceBuf, + workspaceBytes + ); + } + else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { + NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); + block->apply( + cudaHandles, + scratch, + batchSize, + trunkBuf, + trunkScratchBuf, + maskBuf, + maskSumBuf, + workspaceBuf, + workspaceBytes + ); + } + else { + ASSERT_UNREACHABLE; + } + } +} +//------------------------------------------------------------------------------ + +struct SGFMetadataEncoder { + const string name; + + const bool usingFP16; + + const MatMulLayer mul1; + const MatBiasLayer bias1; + const MatMulLayer mul2; + const MatBiasLayer bias2; + const MatMulLayer mul3; + + SGFMetadataEncoder() = delete; + SGFMetadataEncoder(const SGFMetadataEncoder&) = delete; + SGFMetadataEncoder& operator=(const SGFMetadataEncoder&) = delete; + + SGFMetadataEncoder( + CudaHandles* cudaHandles, + const SGFMetadataEncoderDesc* desc, + bool useFP16 + ) : + name(desc->name), + usingFP16(useFP16), + mul1(cudaHandles,&desc->mul1,useFP16), + bias1(cudaHandles,&desc->bias1,useFP16,desc->act1.activation), + mul2(cudaHandles,&desc->mul2,useFP16), + bias2(cudaHandles,&desc->bias2,useFP16,desc->act2.activation), + mul3(cudaHandles,&desc->mul3,useFP16) + { + } + + ~SGFMetadataEncoder() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + (void)batchSize; + size_t bytes = 0; + size_t b; + + b = mul1.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = mul2.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = mul3.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf internalBuf1(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); + SizedBuf internalBuf2(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); + + mul1.apply(cudaHandles,scratch,batchSize,inputBuf,internalBuf1.buf,workspaceBuf,workspaceBytes); + bias1.apply(cudaHandles,batchSize,internalBuf1.buf); + mul2.apply(cudaHandles,scratch,batchSize,internalBuf1.buf,internalBuf2.buf,workspaceBuf,workspaceBytes); + bias2.apply(cudaHandles,batchSize,internalBuf2.buf); + mul3.apply(cudaHandles,scratch,batchSize,internalBuf2.buf,outputBuf,workspaceBuf,workspaceBytes); + } + +}; + + +//---------------------------------------------------------------------------- + +struct Trunk { + const string name; + const int modelVersion; + const int numBlocks; + const int trunkNumChannels; + + const int nnXLen; + const int nnYLen; + const bool usingFP16; + const bool usingNHWC; + + std::unique_ptr initialConv; + std::unique_ptr initialMatMul; + std::unique_ptr sgfMetadataEncoder; + const BlockStack blocks; + std::unique_ptr trunkTipBN; + + Trunk() = delete; + Trunk(const Trunk&) = delete; + Trunk& operator=(const Trunk&) = delete; + + Trunk( + CudaHandles* cudaHandles, + CudnnManager* manager, + const TrunkDesc* desc, + int nnX, + int nnY, + bool inputsUseNHWC, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + numBlocks(desc->numBlocks), + trunkNumChannels(desc->trunkNumChannels), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC), + blocks(cudaHandles,manager,desc->numBlocks,desc->trunkNumChannels,desc->blocks,nnX,nnY,useFP16,useNHWC) + { + int midNumChannels = desc->midNumChannels; + int regularNumChannels = desc->regularNumChannels; + int gpoolNumChannels = desc->gpoolNumChannels; + + int maxBatchSize = manager->maxBatchSize; + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,trunkNumChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,midNumChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,regularNumChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,gpoolNumChannels); + + initialConv = std::make_unique(cudaHandles,manager,&desc->initialConv,useFP16,inputsUseNHWC,useNHWC); + initialMatMul = std::make_unique(cudaHandles,&desc->initialMatMul,useFP16); + if(desc->metaEncoderVersion > 0) { + sgfMetadataEncoder = std::make_unique(cudaHandles,&desc->sgfMetadataEncoder,useFP16); + testAssert(sgfMetadataEncoder->mul3.outChannels == initialMatMul->outChannels); + } + + trunkTipBN = std::make_unique(cudaHandles,&desc->trunkTipBN,&desc->trunkTipActivation,nnXLen,nnYLen,useFP16,useNHWC); + assert(desc->blocks.size() == numBlocks); + } + + ~Trunk() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = initialConv->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + + b = initialMatMul->requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + + if(sgfMetadataEncoder != nullptr) { + b = sgfMetadataEncoder->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + + b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* inputBuf, + void* inputGlobalBuf, + void* inputMetaBuf, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + + SizedBuf trunkScratch(scratch->allocator, scratch->getBufSizeXY(trunkNumChannels)); + + //Feed the conv into trunkScratch.buf, not trunkBuf + initialConv->apply(cudaHandles,batchSize,false,inputBuf,trunkScratch.buf,workspaceBuf,workspaceBytes); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("After initial conv"), trunkScratch.buf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); + #endif + + //Feed the matmul into trunkBuf + initialMatMul->apply(cudaHandles,scratch,batchSize,inputGlobalBuf,trunkBuf,workspaceBuf,workspaceBytes); + //Then accumulate it into trunkScratch.buf, broadcasting during the process + if(!usingFP16) { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + else { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + if(sgfMetadataEncoder != nullptr) { + testAssert(inputMetaBuf != NULL); + //Feed the result into trunkBuf + sgfMetadataEncoder->apply(cudaHandles,scratch,batchSize,inputMetaBuf,trunkBuf,workspaceBuf,workspaceBytes); + //Then accumulate it into trunkScratch.buf, broadcasting during the process + if(!usingFP16) { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + else { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + else { + testAssert(inputMetaBuf == NULL); + } + + //Flip trunkBuf and trunkScratch.buf so that the result gets accumulated in trunkScratch.buf + blocks.apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskSumBuf, + trunkScratch.buf, + trunkBuf, + workspaceBuf, + workspaceBytes + ); + + //And now with the final BN port it from trunkScratch.buf to trunkBuf. + trunkTipBN->apply(cudaHandles,batchSize,trunkScratch.buf,maskBuf,trunkBuf); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("Trunk tip"), trunkBuf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); + #endif + } + +}; + +//------------------------------------------------------------------------------ + +static void fillMaskFloatBufAndMaskSumBuf(void* maskBuf, float*& maskFloatBuf, float*& maskSumBuf, bool usingFP16, int batchSize, int nnXLen, int nnYLen) { + if(!usingFP16) { + maskFloatBuf = (float*)maskBuf; + customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); + CUDA_ERR("sumMask",hipPeekAtLastError()); + } + else { + customCudaCopyFromHalf((const half*)maskBuf,maskFloatBuf,batchSize*nnXLen*nnYLen); + CUDA_ERR("copyMaskFromHalf",hipPeekAtLastError()); + customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); + CUDA_ERR("sumMask",hipPeekAtLastError()); + } +} + + +//------------------------------------------------------------------------------ + +struct PolicyHead { + const string name; + const int modelVersion; + const int nnXLen; + const int nnYLen; + const int p1Channels; + const int g1Channels; + const int p2Channels; + const bool usingFP16; + const bool usingNHWC; + + const ConvLayer p1Conv; + const ConvLayer g1Conv; + const BatchNormLayer g1BN; + const MatMulLayer gpoolToBiasMul; + const BatchNormLayer p1BN; + const ConvLayer p2Conv; + const MatMulLayer gpoolToPassMul; + const MatBiasLayer gpoolToPassBias; + const MatMulLayer gpoolToPassMul2; + + PolicyHead() = delete; + PolicyHead(const PolicyHead&) = delete; + PolicyHead& operator=(const PolicyHead&) = delete; + + PolicyHead( + CudaHandles* cudaHandles, + CudnnManager* manager, + const PolicyHeadDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + nnXLen(nnX), + nnYLen(nnY), + p1Channels(desc->p1Conv.outChannels), + g1Channels(desc->g1Conv.outChannels), + p2Channels(desc->p2Conv.outChannels), + usingFP16(useFP16), + usingNHWC(useNHWC), + p1Conv(cudaHandles,manager,&desc->p1Conv,useFP16,useNHWC), + g1Conv(cudaHandles,manager,&desc->g1Conv,useFP16,useNHWC), + g1BN(cudaHandles,&desc->g1BN,&desc->g1Activation,nnX,nnY,useFP16,useNHWC), + gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,false), + p1BN(cudaHandles,&desc->p1BN,&desc->p1Activation,nnX,nnY,false,useNHWC), + p2Conv(cudaHandles,manager,&desc->p2Conv,false,useNHWC), + gpoolToPassMul(cudaHandles,&desc->gpoolToPassMul,false), + gpoolToPassBias(cudaHandles,&desc->gpoolToPassBias,false,desc->passActivation.activation), + gpoolToPassMul2(cudaHandles,&desc->gpoolToPassMul2,false) + { + } + + ~PolicyHead() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = p1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = g1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = p2Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolToPassMul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = gpoolToPassMul2.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*g1Channels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskFloatBuf, + float* maskSumBuf, + void* trunkBuf, + float* policyPassBuf, + float* policyBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + + SizedBuf p1Out(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs + SizedBuf p1Out2(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs + SizedBuf g1Out(scratch->allocator, scratch->getBufSizeXY(g1Channels)); + SizedBuf g1Out2(scratch->allocator, scratch->getBufSizeXY(g1Channels)); + SizedBuf g1Concat(scratch->allocator, scratch->getBufSizeFloat(g1Channels*3)); + SizedBuf g1Bias(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); + SizedBuf p1Pass(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); + + p1Conv.apply(cudaHandles,batchSize,false,trunkBuf,p1Out.buf,workspaceBuf,workspaceBytes); + g1Conv.apply(cudaHandles,batchSize,false,trunkBuf,g1Out.buf,workspaceBuf,workspaceBytes); + g1BN.apply(cudaHandles,batchSize,g1Out.buf,maskBuf,g1Out2.buf); + + if(!usingFP16) { + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + else { + customCudaCopyFromHalf((const half*)g1Out2.buf,(float*)workspaceBuf,batchSize*g1Channels*nnXLen*nnYLen); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + + gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,g1Bias.buf,workspaceBuf,workspaceBytes); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("p1 pre-gpool-sum"), p1Out.buf, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); + CudaUtils::debugPrint4D(string("g1 pre-gpool"), g1Out.buf, batchSize, g1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); + CudaUtils::debugPrint2D(string("g1 pooled"), g1Concat.buf, batchSize, g1Channels*3, false); + CudaUtils::debugPrint2D(string("g1 biases"), g1Bias.buf, batchSize, p1Channels, false); + #endif + + float* p1OutBufA; + float* p1OutBufB; + if(!usingFP16) { + p1OutBufA = (float*)p1Out.buf; + p1OutBufB = (float*)p1Out2.buf; + } + else { + customCudaCopyFromHalf((const half*)p1Out.buf,(float*)p1Out2.buf,batchSize*p1Channels*nnXLen*nnYLen); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + p1OutBufA = (float*)p1Out2.buf; + p1OutBufB = (float*)p1Out.buf; + } + + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW(p1OutBufA,(float*)g1Bias.buf,batchSize,p1Channels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC(p1OutBufA,(float*)g1Bias.buf,batchSize,nnXLen*nnYLen,p1Channels); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + p1BN.apply(cudaHandles,batchSize,p1OutBufA,maskFloatBuf,p1OutBufB); + p2Conv.apply(cudaHandles,batchSize,false,p1OutBufB,(float*)policyBuf,workspaceBuf,workspaceBytes); + + if(modelVersion >= 15) { + gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,p1Pass.buf,workspaceBuf,workspaceBytes); + gpoolToPassBias.apply(cudaHandles,batchSize,p1Pass.buf); + gpoolToPassMul2.apply(cudaHandles,scratch,batchSize,p1Pass.buf,policyPassBuf,workspaceBuf,workspaceBytes); + } + else { + gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,policyPassBuf,workspaceBuf,workspaceBytes); + } + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("p1 after-gpool-sum"), p1OutBufA, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, false); + CudaUtils::debugPrint2D(string("policypass"), policyPassBuf, batchSize, 1, false); + CudaUtils::debugPrint4D(string("policy"), policyBuf, batchSize, p2Channels, nnXLen, nnYLen, usingNHWC, false); + #endif + + } + +}; + +//------------------------------------------------------------------------------ + +struct ValueHead { + const string name; + const int modelVersion; + const int nnXLen; + const int nnYLen; + const int v1Channels; + const int v2Channels; + const int valueChannels; + const int scoreValueChannels; + const int ownershipChannels; + const bool usingFP16; + const bool usingNHWC; + + const ConvLayer v1Conv; + const BatchNormLayer v1BN; + const MatMulLayer v2Mul; + const MatBiasLayer v2Bias; + const MatMulLayer v3Mul; + const MatBiasLayer v3Bias; + const MatMulLayer sv3Mul; + const MatBiasLayer sv3Bias; + const ConvLayer vOwnershipConv; + + ValueHead() = delete; + ValueHead(const ValueHead&) = delete; + ValueHead& operator=(const ValueHead&) = delete; + + ValueHead( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ValueHeadDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + nnXLen(nnX), + nnYLen(nnY), + v1Channels(desc->v1Conv.outChannels), + v2Channels(desc->v2Mul.outChannels), + valueChannels(desc->v3Mul.outChannels), + scoreValueChannels(desc->sv3Mul.outChannels), + ownershipChannels(desc->vOwnershipConv.outChannels), + usingFP16(useFP16), + usingNHWC(useNHWC), + v1Conv(cudaHandles,manager,&desc->v1Conv,useFP16,useNHWC), + v1BN(cudaHandles,&desc->v1BN,&desc->v1Activation,nnX,nnY,useFP16,useNHWC), + v2Mul(cudaHandles,&desc->v2Mul,false), + v2Bias(cudaHandles,&desc->v2Bias,false,desc->v2Activation.activation), + v3Mul(cudaHandles,&desc->v3Mul,false), + v3Bias(cudaHandles,&desc->v3Bias,false,ACTIVATION_IDENTITY), + sv3Mul(cudaHandles,&desc->sv3Mul,false), + sv3Bias(cudaHandles,&desc->sv3Bias,false,ACTIVATION_IDENTITY), + vOwnershipConv(cudaHandles,manager,&desc->vOwnershipConv,useFP16,useNHWC) + { + } + + ~ValueHead() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = v1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = v2Mul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = v3Mul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*v1Channels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + + b = sv3Mul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = vOwnershipConv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*ownershipChannels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + + return bytes; + } + + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + float* valueBuf, + float* scoreValueBuf, + void* ownershipBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf v1Out(scratch->allocator, scratch->getBufSizeXY(v1Channels)); + SizedBuf v1Out2(scratch->allocator, scratch->getBufSizeXY(v1Channels)); + SizedBuf v1Mean(scratch->allocator, scratch->getBufSizeFloat(v1Channels*3)); + SizedBuf v2Out(scratch->allocator, scratch->getBufSizeFloat(v2Channels)); + SizedBuf ownershipScratch(scratch->allocator, scratch->getBufSizeXYFloat(ownershipChannels)); + + v1Conv.apply(cudaHandles,batchSize,false,trunkBuf,v1Out.buf,workspaceBuf,workspaceBytes); + v1BN.apply(cudaHandles,batchSize,v1Out.buf,maskBuf,v1Out2.buf); + + void* bufToBePooled = v1Out2.buf; + if(usingFP16) { + customCudaCopyFromHalf((const half*)v1Out2.buf,(float*)workspaceBuf,batchSize*v1Channels*nnXLen*nnYLen); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + bufToBePooled = workspaceBuf; + } + + if(!usingNHWC) + customCudaValueHeadPoolNCHW((float*)bufToBePooled,(float*)v1Mean.buf,batchSize,v1Channels,nnXLen*nnYLen,maskSumBuf); + else + customCudaValueHeadPoolNHWC((const float*)bufToBePooled,(float*)v1Mean.buf,batchSize,nnXLen*nnYLen,v1Channels,maskSumBuf); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + v2Mul.apply(cudaHandles,scratch,batchSize,v1Mean.buf,v2Out.buf,workspaceBuf,workspaceBytes); + v2Bias.apply(cudaHandles,batchSize,v2Out.buf); + v3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,valueBuf,workspaceBuf,workspaceBytes); + v3Bias.apply(cudaHandles,batchSize,valueBuf); + + sv3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,scoreValueBuf,workspaceBuf,workspaceBytes); + sv3Bias.apply(cudaHandles,batchSize,scoreValueBuf); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("v1"), v1Out.buf, batchSize, v1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); + CudaUtils::debugPrint2D(string("v1 pooled"), v1Mean.buf, batchSize, v1Channels, false); + CudaUtils::debugPrint2D(string("v2"), v2Out.buf, batchSize, v1Channels, false); + #endif + + if(!usingFP16) { + vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipBuf,workspaceBuf,workspaceBytes); + } + else { + vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipScratch.buf,workspaceBuf,workspaceBytes); + customCudaCopyFromHalf((const half*)ownershipScratch.buf,(float*)ownershipBuf,batchSize*ownershipChannels*nnXLen*nnYLen); + CUDA_ERR("vOwnership copy",hipPeekAtLastError()); + } + + } + +}; + +//------------------------------------------------------------------------------ + +struct Model { + const string name; + const int modelVersion; + const int maxBatchSize; + const int nnXLen; + const int nnYLen; + const int numInputChannels; + const int numInputGlobalChannels; + const int numInputMetaChannels; + const int numPolicyChannels; + const int numValueChannels; + const int numScoreValueChannels; + const int numOwnershipChannels; + const bool usingFP16; + const bool usingNHWC; + const bool inputsUsingNHWC; + + std::unique_ptr trunk; + std::unique_ptr policyHead; + std::unique_ptr valueHead; + std::unique_ptr manager; + + Model() = delete; + Model(const Model&) = delete; + Model& operator=(const Model&) = delete; + + Model( + CudaHandles* cudaHandles, + const ModelDesc* desc, + int maxBatchSz, + int nnX, + int nnY, + bool inputsUseNHWC, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + maxBatchSize(maxBatchSz), + nnXLen(nnX), + nnYLen(nnY), + numInputChannels(desc->numInputChannels), + numInputGlobalChannels(desc->numInputGlobalChannels), + numInputMetaChannels(desc->numInputMetaChannels), + numPolicyChannels(desc->numPolicyChannels), + numValueChannels(desc->numValueChannels), + numScoreValueChannels(desc->numScoreValueChannels), + numOwnershipChannels(desc->numOwnershipChannels), + usingFP16(useFP16), + usingNHWC(useNHWC), + inputsUsingNHWC(inputsUseNHWC) + { + if(nnXLen > NNPos::MAX_BOARD_LEN) + throw StringError(Global::strprintf("nnXLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", + nnXLen, NNPos::MAX_BOARD_LEN + )); + if(nnYLen > NNPos::MAX_BOARD_LEN) + throw StringError(Global::strprintf("nnYLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", + nnYLen, NNPos::MAX_BOARD_LEN + )); + + int numFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); + if(numInputChannels != numFeatures) + throw StringError(Global::strprintf("Neural net numInputChannels (%d) was not the expected number based on version (%d)", + numInputChannels, numFeatures + )); + int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); + if(numInputGlobalChannels != numGlobalFeatures) + throw StringError(Global::strprintf("Neural net numInputGlobalChannels (%d) was not the expected number based on version (%d)", + numInputGlobalChannels, numGlobalFeatures + )); + if(numInputMetaChannels > 0) { + if(numInputMetaChannels != SGFMetadata::METADATA_INPUT_NUM_CHANNELS) + throw StringError(Global::strprintf("Neural net numInputMetaChannels (%d) was not the expected number (%d)", + numInputMetaChannels, SGFMetadata::METADATA_INPUT_NUM_CHANNELS + )); + } + + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputGlobalChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputMetaChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numPolicyChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numValueChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numScoreValueChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numOwnershipChannels); + + manager = std::make_unique(name, maxBatchSize, nnXLen, nnYLen); + trunk = std::make_unique(cudaHandles,manager.get(),&desc->trunk,nnXLen,nnYLen,inputsUseNHWC,useFP16,useNHWC); + policyHead = std::make_unique(cudaHandles,manager.get(),&desc->policyHead,nnXLen,nnYLen,useFP16,useNHWC); + valueHead = std::make_unique(cudaHandles,manager.get(),&desc->valueHead,nnXLen,nnYLen,useFP16,useNHWC); + } + + ~Model() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = trunk->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = policyHead->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = valueHead->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + bool requireExactNNLen, + + void* inputBuf, + void* inputGlobalBuf, + void* inputMetaBuf, + + float* policyPassBuf, + float* policyBuf, + + float* valueBuf, + float* scoreValueBuf, + void* ownershipBuf, + + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf mask(scratch->allocator, scratch->getBufSizeXY(1)); + SizedBuf maskFloat(scratch->allocator, scratch->getBufSizeXYFloat(1)); + SizedBuf maskSum(scratch->allocator, scratch->getBufSizeFloat(1)); + + void* maskBuf = mask.buf; + float* maskFloatBuf = (float*)maskFloat.buf; + float* maskSumBuf = (float*)maskSum.buf; + + if(!usingFP16) { + if(inputsUsingNHWC) + customCudaChannel0ExtractNHWC((const float*)inputBuf, (float*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); + else + customCudaChannel0ExtractNCHW((const float*)inputBuf, (float*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); + CUDA_ERR("modelExtractMask",hipPeekAtLastError()); + } + else { + if(inputsUsingNHWC) + customCudaChannel0ExtractNHWC((const half*)inputBuf, (half*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); + else + customCudaChannel0ExtractNCHW((const half*)inputBuf, (half*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); + CUDA_ERR("modelExtractMask",hipPeekAtLastError()); + } + + fillMaskFloatBufAndMaskSumBuf(maskBuf,maskFloatBuf,maskSumBuf,usingFP16,batchSize,nnXLen,nnYLen); + + //Don't do any masking if we know the board is exactly the desired size + if(requireExactNNLen) { + //Set to NULL to signal downstream that this buf doesn't need to be used + maskBuf = NULL; + maskFloatBuf = NULL; + //The global pooling structures need this no matter what, for normalizing based on this and its sqrt. + //maskSumBuf = NULL; + } + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("Initial bin features"), inputBuf, batchSize, trunk->initialConv->inChannels, nnXLen, nnYLen, inputsUsingNHWC, usingFP16); + CudaUtils::debugPrint2D(string("Initial global features"), inputGlobalBuf, batchSize, trunk->initialMatMul->inChannels, usingFP16); + if(trunk->sgfMetadataEncoder != nullptr) { + assert(inputMetaBuf != NULL); + CudaUtils::debugPrint2D(string("Initial meta features"), inputMetaBuf, batchSize, trunk->sgfMetadataEncoder->mul1.inChannels, usingFP16); + } + #endif + + SizedBuf trunkBuf(scratch->allocator, scratch->getBufSizeXY(trunk->trunkNumChannels)); + + trunk->apply( + cudaHandles, + scratch, + batchSize, + inputBuf, + inputGlobalBuf, + inputMetaBuf, + maskBuf, + maskSumBuf, + trunkBuf.buf, + workspaceBuf, + workspaceBytes + ); + policyHead->apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskFloatBuf, + maskSumBuf, + trunkBuf.buf, + policyPassBuf, + policyBuf, + workspaceBuf, + workspaceBytes + ); + valueHead->apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskSumBuf, + trunkBuf.buf, + valueBuf, + scoreValueBuf, + ownershipBuf, + workspaceBuf, + workspaceBytes + ); + } + +}; + + +//------------------------------------------------------------------------------ + +struct LoadedModel { + ModelDesc modelDesc; + + LoadedModel(const string& fileName, const string& expectedSha256) { + ModelDesc::loadFromFileMaybeGZipped(fileName,modelDesc,expectedSha256); + modelDesc.applyScale8ToReduceActivations(); + } + + LoadedModel() = delete; + LoadedModel(const LoadedModel&) = delete; + LoadedModel& operator=(const LoadedModel&) = delete; +}; + +LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { + LoadedModel* loadedModel = new LoadedModel(file,expectedSha256); + return loadedModel; +} + +void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { + delete loadedModel; +} + +const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { + return loadedModel->modelDesc; +} + +//------------------------------------------------------------------------------ + +struct Buffers { + //All of these are device pointers + + float* inputBufFloat; + void* inputBuf; + float* inputGlobalBufFloat; + void* inputGlobalBuf; + float* inputMetaBufFloat; + void* inputMetaBuf; + size_t inputBufBytesFloat; + size_t inputBufBytes; + size_t inputGlobalBufBytesFloat; + size_t inputGlobalBufBytes; + size_t inputMetaBufBytesFloat; + size_t inputMetaBufBytes; + + float* policyPassBuf; + size_t policyPassBufBytes; + float* policyBuf; + size_t policyBufBytes; + + float* valueBuf; + size_t valueBufBytes; + float* scoreValueBuf; + size_t scoreValueBufBytes; + void* ownershipBuf; + size_t ownershipBufBytes; + + void* workspaceBuf; + size_t workspaceBytes; + + Buffers() = delete; + Buffers(const Buffers&) = delete; + Buffers& operator=(const Buffers&) = delete; + + Buffers(CudaHandles* cudaHandles, const Model& m, const ScratchBuffers& scratch) { + size_t batchXYFloatBytes = (size_t)scratch.batchXYFloatBytes; + size_t batchFloatBytes = (size_t)scratch.batchFloatBytes; + size_t batchXYBytes = (size_t)scratch.batchXYBytes; + size_t batchBytes = (size_t)scratch.batchBytes; + + inputBufBytesFloat = m.numInputChannels * batchXYFloatBytes; + inputBufBytes = m.numInputChannels * batchXYBytes; + inputGlobalBufBytesFloat = m.numInputGlobalChannels * batchFloatBytes; + inputGlobalBufBytes = m.numInputGlobalChannels * batchBytes; + inputMetaBufBytesFloat = m.numInputMetaChannels * batchFloatBytes; + inputMetaBufBytes = m.numInputMetaChannels * batchBytes; + + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputBufFloat), inputBufBytesFloat)); + CUDA_ERR("Buffers",hipMalloc(&inputBuf, inputBufBytes)); + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputGlobalBufFloat), inputGlobalBufBytesFloat)); + CUDA_ERR("Buffers",hipMalloc(&inputGlobalBuf, inputGlobalBufBytes)); + if(m.numInputMetaChannels > 0) { + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputMetaBufFloat), inputMetaBufBytesFloat)); + CUDA_ERR("Buffers",hipMalloc(&inputMetaBuf, inputMetaBufBytes)); + } + else { + inputMetaBufFloat = NULL; + inputMetaBuf = NULL; + } + + if(m.modelVersion >= 16) + testAssert(m.policyHead->p2Channels == 4); + else if(m.modelVersion >= 12) + testAssert(m.policyHead->p2Channels == 2); + else + testAssert(m.policyHead->p2Channels == 1); + + policyPassBufBytes = m.policyHead->p2Channels * batchFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyPassBuf), policyPassBufBytes)); + policyBufBytes = m.policyHead->p2Channels * batchXYFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyBuf), policyBufBytes)); + + valueBufBytes = m.valueHead->valueChannels * batchFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&valueBuf), valueBufBytes)); + + scoreValueBufBytes = m.valueHead->scoreValueChannels * batchFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&scoreValueBuf), scoreValueBufBytes)); + + //This buf is used for both an intermdiate fp16 result in fp16 mode, and ALSO the final fp32 output, so always must be fp32-sized + ownershipBufBytes = m.valueHead->ownershipChannels * batchXYFloatBytes; + CUDA_ERR("Buffers",hipMalloc(&ownershipBuf, ownershipBufBytes)); + + //In theory the requiredWorkspaceBytes calls could give us values non-monotone in batch size + //such as if the convolution algorithm changes between batch size 1 and larger. + //So we call it for all the batch sizes. + size_t bytes = 0; + size_t b; + for(int batchSize = 1; batchSize <= m.maxBatchSize; batchSize++) { + b = m.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + + CUDA_ERR("Buffers",hipMalloc(&workspaceBuf, bytes)); + workspaceBytes = bytes; + } + + ~Buffers() { + hipFree(inputBufFloat); + hipFree(inputBuf); + hipFree(inputGlobalBufFloat); + hipFree(inputGlobalBuf); + if(inputMetaBufFloat != NULL) + hipFree(inputMetaBufFloat); + if(inputMetaBuf != NULL) + hipFree(inputMetaBuf); + + hipFree(policyPassBuf); + hipFree(policyBuf); + + hipFree(valueBuf); + hipFree(scoreValueBuf); + hipFree(ownershipBuf); + + hipFree(workspaceBuf); + } + +}; + +//------------------------------------------------------------------------------ + +struct ComputeContext { + int nnXLen; + int nnYLen; + enabled_t useFP16Mode; + enabled_t useNHWCMode; +}; + +ComputeContext* NeuralNet::createComputeContext( + const std::vector& gpuIdxs, + Logger* logger, + int nnXLen, + int nnYLen, + const string& openCLTunerFile, + const string& homeDataDirOverride, + bool openCLReTunePerBoardSize, + enabled_t useFP16Mode, + enabled_t useNHWCMode, + const LoadedModel* loadedModel +) { + (void)gpuIdxs; + (void)logger; + (void)openCLTunerFile; + (void)homeDataDirOverride; + (void)openCLReTunePerBoardSize; + (void)loadedModel; + + ComputeContext* context = new ComputeContext(); + context->nnXLen = nnXLen; + context->nnYLen = nnYLen; + context->useFP16Mode = useFP16Mode; + context->useNHWCMode = useNHWCMode; + return context; +} + +void NeuralNet::freeComputeContext(ComputeContext* computeContext) { + delete computeContext; +} + +//------------------------------------------------------------------------------ + +struct ComputeHandle { + std::unique_ptr cudaHandles; + std::unique_ptr model; + std::unique_ptr scratch; + std::unique_ptr buffers; + const bool usingFP16; + const int nnXLen; + const int nnYLen; + const bool requireExactNNLen; + const bool inputsUseNHWC; + const bool usingNHWC; + + ComputeHandle( + const ComputeContext* context, + const LoadedModel* loadedModel, + int majorComputeCapability, + int minorComputeCapability, + int maxBatchSize, + bool requireExactNNLen_, + bool inputsUseNHWC_, + bool useFP16, + bool useNHWC + ) : + usingFP16(useFP16), + nnXLen(context->nnXLen), + nnYLen(context->nnYLen), + requireExactNNLen(requireExactNNLen_), + inputsUseNHWC(inputsUseNHWC_), + usingNHWC(useNHWC) + { + cudaHandles = std::make_unique(majorComputeCapability,minorComputeCapability); + model = std::make_unique( + cudaHandles.get(), &(loadedModel->modelDesc), maxBatchSize, + nnXLen, nnYLen, inputsUseNHWC, useFP16, useNHWC + ); + scratch = std::make_unique(maxBatchSize, nnXLen, nnYLen, useFP16); + buffers = std::make_unique(cudaHandles.get(), *model, *scratch); + + //Synchronize after creating buffers and copying all the weights, just in case + CUDA_ERR("ComputeHandle", hipDeviceSynchronize()); + } + ~ComputeHandle() { + } + + ComputeHandle() = delete; + ComputeHandle(const ComputeHandle&) = delete; + ComputeHandle& operator=(const ComputeHandle&) = delete; +}; + +ComputeHandle* NeuralNet::createComputeHandle( + ComputeContext* context, + const LoadedModel* loadedModel, + Logger* logger, + int maxBatchSize, + bool requireExactNNLen, + bool inputsUseNHWC, + int gpuIdxForThisThread, + int serverThreadIdx +) { + //Use whatever CUDA believes GPU 0 to be. + if(gpuIdxForThisThread == -1) + gpuIdxForThisThread = 0; + + CUDA_ERR("createComputeHandle",hipSetDevice(gpuIdxForThisThread)); + + hipDeviceProp_t prop; + hipGetDeviceProperties(&prop,gpuIdxForThisThread); + + bool useFP16 = false; + bool useNHWC = false; + //Old GPUs - use FP32 and explicitly fail if FP16 enabled + if(prop.major < 5 || (prop.major == 5 && prop.minor < 3)) { + if(context->useFP16Mode == enabled_t::True) + throw StringError("Cuda device versions below 5.3 do not support useFP16=true"); + if(context->useNHWCMode == enabled_t::True) + useNHWC = true; + } + //In theory these GPUs support FP16, so allow if the user wants. + else if(prop.major < 6) { + if(context->useFP16Mode == enabled_t::True) + useFP16 = true; + if(context->useNHWCMode == enabled_t::True) + useNHWC = true; + } + //On Pascal architecture, default to using FP16 operations + //Actually, just use FP32 - there's a risk that on certain cards this might just be a lot worse. + //A user manually fine-tuning for performance can just enable it themselves if they know how. + else if(prop.major < 7) { + if(context->useFP16Mode == enabled_t::True) + useFP16 = true; + if(context->useNHWCMode == enabled_t::True) + useNHWC = true; + } + //On Volta and higher, use FP16 and NHWC together because we have tensor cores. + else { + if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) + useFP16 = true; + if(context->useNHWCMode == enabled_t::True || (context->useNHWCMode == enabled_t::Auto && useFP16)) + useNHWC = true; + } + + if(logger != NULL) { + logger->write( + "Cuda backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) + + " memory " + Global::uint64ToString(prop.totalGlobalMem) + + " compute capability major " + Global::intToString(prop.major) + + " minor " + Global::intToString(prop.minor) + ); + logger->write( + "Cuda backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion) + + " useFP16 = " + Global::boolToString(useFP16) + + " useNHWC = " + Global::boolToString(useNHWC) + ); + logger->write( + "Cuda backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name + ); + } + + ComputeHandle* gpuHandle = new ComputeHandle( + context,loadedModel,prop.major,prop.minor,maxBatchSize,requireExactNNLen,inputsUseNHWC,useFP16,useNHWC + ); + return gpuHandle; +} + +void NeuralNet::freeComputeHandle(ComputeHandle* gpuHandle) { + delete gpuHandle; +} + +bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { + return handle->usingFP16; +} + +//------------------------------------------------------------------------------ + +void NeuralNet::printDevices() { + int numDevices = 0; + hipGetDeviceCount(&numDevices); + for(int i = 0; imodelDesc; + + maxBatchSize = maxBatchSz; + singleInputElts = (size_t)m.numInputChannels * nnXLen * nnYLen; + singleInputBytes = (size_t)m.numInputChannels * nnXLen * nnYLen * sizeof(float); + singleInputGlobalElts = (size_t)m.numInputGlobalChannels; + singleInputGlobalBytes = (size_t)m.numInputGlobalChannels * sizeof(float); + singleInputMetaElts = (size_t)m.numInputMetaChannels; + singleInputMetaBytes = (size_t)m.numInputMetaChannels * sizeof(float); + singlePolicyPassResultElts = (size_t)(m.numPolicyChannels); + singlePolicyPassResultBytes = (size_t)(m.numPolicyChannels) * sizeof(float); + singlePolicyResultElts = (size_t)(m.numPolicyChannels * nnXLen * nnYLen); + singlePolicyResultBytes = (size_t)(m.numPolicyChannels * nnXLen * nnYLen) * sizeof(float); + singleValueResultElts = (size_t)m.numValueChannels; + singleValueResultBytes = (size_t)m.numValueChannels * sizeof(float); + singleScoreValueResultElts = (size_t)m.numScoreValueChannels; + singleScoreValueResultBytes = (size_t)m.numScoreValueChannels * sizeof(float); + singleOwnershipResultElts = (size_t)m.numOwnershipChannels * nnXLen * nnYLen; + singleOwnershipResultBytes = (size_t)m.numOwnershipChannels * nnXLen * nnYLen * sizeof(float); + + assert(NNModelVersion::getNumSpatialFeatures(m.modelVersion) == m.numInputChannels); + assert(NNModelVersion::getNumGlobalFeatures(m.modelVersion) == m.numInputGlobalChannels); + if(m.numInputMetaChannels > 0) { + assert(SGFMetadata::METADATA_INPUT_NUM_CHANNELS == m.numInputMetaChannels); + } + + userInputBufferBytes = (size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen * sizeof(float); + userInputGlobalBufferBytes = (size_t)m.numInputGlobalChannels * maxBatchSize * sizeof(float); + userInputMetaBufferBytes = (size_t)m.numInputMetaChannels * maxBatchSize * sizeof(float); + policyPassResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * sizeof(float); + policyResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen * sizeof(float); + valueResultBufferBytes = (size_t)maxBatchSize * m.numValueChannels * sizeof(float); + scoreValueResultBufferBytes = (size_t)maxBatchSize * m.numScoreValueChannels * sizeof(float); + ownershipResultBufferBytes = (size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels * sizeof(float); + + userInputBuffer = new float[(size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen]; + userInputGlobalBuffer = new float[(size_t)m.numInputGlobalChannels * maxBatchSize]; + if(m.numInputMetaChannels > 0) + userInputMetaBuffer = new float[(size_t)m.numInputMetaChannels * maxBatchSize]; + else + userInputMetaBuffer = NULL; + + policyPassResults = new float[(size_t)maxBatchSize * m.numPolicyChannels]; + policyResults = new float[(size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen]; + valueResults = new float[(size_t)maxBatchSize * m.numValueChannels]; + + scoreValueResults = new float[(size_t)maxBatchSize * m.numScoreValueChannels]; + ownershipResults = new float[(size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels]; + } + + ~InputBuffers() { + delete[] userInputBuffer; + delete[] userInputGlobalBuffer; + if(userInputMetaBuffer != NULL) + delete[] userInputMetaBuffer; + delete[] policyPassResults; + delete[] policyResults; + delete[] valueResults; + delete[] scoreValueResults; + delete[] ownershipResults; + } + + InputBuffers() = delete; + InputBuffers(const InputBuffers&) = delete; + InputBuffers& operator=(const InputBuffers&) = delete; + +}; + +InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { + return new InputBuffers(loadedModel,maxBatchSize,nnXLen,nnYLen); +} +void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { + delete inputBuffers; +} + +//--------------------------------------------------------------------------------------- + + +void NeuralNet::getOutput( + ComputeHandle* gpuHandle, + InputBuffers* inputBuffers, + int numBatchEltsFilled, + NNResultBuf** inputBufs, + vector& outputs +) { + assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); + assert(numBatchEltsFilled > 0); + const int batchSize = numBatchEltsFilled; + const int nnXLen = gpuHandle->nnXLen; + const int nnYLen = gpuHandle->nnYLen; + const int modelVersion = gpuHandle->model->modelVersion; + + const int numSpatialFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); + const int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); + const int numMetaFeatures = inputBuffers->singleInputMetaElts; + assert(numSpatialFeatures == gpuHandle->model->numInputChannels); + assert(numSpatialFeatures * nnXLen * nnYLen == inputBuffers->singleInputElts); + assert(numGlobalFeatures == inputBuffers->singleInputGlobalElts); + const int numPolicyChannels = gpuHandle->model->numPolicyChannels; + + for(int nIdx = 0; nIdxuserInputBuffer + (inputBuffers->singleInputElts * nIdx); + float* rowGlobalInput = inputBuffers->userInputGlobalBuffer + (inputBuffers->singleInputGlobalElts * nIdx); + float* rowMetaInput = inputBuffers->userInputMetaBuffer + (inputBuffers->singleInputMetaElts * nIdx); + + const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); + const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); + const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); + bool hasRowMeta = inputBufs[nIdx]->hasRowMeta; + std::copy(rowGlobal,rowGlobal+numGlobalFeatures,rowGlobalInput); + if(numMetaFeatures > 0) { + testAssert(rowMeta != NULL); + testAssert(hasRowMeta); + std::copy(rowMeta,rowMeta+numMetaFeatures,rowMetaInput); + } + else { + testAssert(!hasRowMeta); + } + SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, gpuHandle->inputsUseNHWC, inputBufs[nIdx]->symmetry); + } + + Buffers* buffers = gpuHandle->buffers.get(); + ScratchBuffers* scratch = gpuHandle->scratch.get(); + + if(!gpuHandle->usingFP16) { + assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes); + assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes); + assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes); + assert(inputBuffers->policyPassResultBufferBytes == buffers->policyPassBufBytes); + assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); + assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); + assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); + assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); + assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); + assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); + assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); + assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); + assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); + assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); + assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); + assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); + assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); + + CUDA_ERR("getOutput",hipMemcpy(buffers->inputBuf, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); + CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBuf, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); + if(numMetaFeatures > 0) { + CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBuf, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); + } + } + else { + assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytesFloat); + assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytesFloat); + assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytesFloat); + assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); + assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); + assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes*2); + assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes*2); + assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes*2); + assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); + assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); + assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); + assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); + assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); + assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); + assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); + assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); + assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); + assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); + assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); + + CUDA_ERR("getOutput",hipMemcpy(buffers->inputBufFloat, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); + CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBufFloat, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); + if(numMetaFeatures > 0) { + CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBufFloat, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); + } + + customCudaCopyToHalf((const float*)buffers->inputBufFloat,(half*)buffers->inputBuf,inputBuffers->singleInputElts*batchSize); + CUDA_ERR("getOutput",hipPeekAtLastError()); + customCudaCopyToHalf((const float*)buffers->inputGlobalBufFloat,(half*)buffers->inputGlobalBuf,inputBuffers->singleInputGlobalElts*batchSize); + CUDA_ERR("getOutput",hipPeekAtLastError()); + if(numMetaFeatures > 0) { + customCudaCopyToHalf((const float*)buffers->inputMetaBufFloat,(half*)buffers->inputMetaBuf,inputBuffers->singleInputMetaElts*batchSize); + CUDA_ERR("getOutput",hipPeekAtLastError()); + } + } + + gpuHandle->model->apply( + gpuHandle->cudaHandles.get(), + scratch, + batchSize, + gpuHandle->requireExactNNLen, + + buffers->inputBuf, + buffers->inputGlobalBuf, + buffers->inputMetaBuf, + + buffers->policyPassBuf, + buffers->policyBuf, + + buffers->valueBuf, + buffers->scoreValueBuf, + buffers->ownershipBuf, + + buffers->workspaceBuf, + buffers->workspaceBytes + ); + + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyPassResults, buffers->policyPassBuf, inputBuffers->singlePolicyPassResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyResults, buffers->policyBuf, inputBuffers->singlePolicyResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->valueResults, buffers->valueBuf, inputBuffers->singleValueResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->scoreValueResults, buffers->scoreValueBuf, inputBuffers->singleScoreValueResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->ownershipResults, buffers->ownershipBuf, inputBuffers->singleOwnershipResultBytes*batchSize, hipMemcpyDeviceToHost)); + + assert(outputs.size() == batchSize); + + float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; + + for(int row = 0; row < batchSize; row++) { + NNOutput* output = outputs[row]; + assert(output->nnXLen == nnXLen); + assert(output->nnYLen == nnYLen); + float policyOptimism = (float)inputBufs[row]->policyOptimism; + + const float* policyPassSrcBuf = inputBuffers->policyPassResults + row * numPolicyChannels; + const float* policySrcBuf = inputBuffers->policyResults + row * numPolicyChannels * nnXLen * nnYLen; + float* policyProbs = output->policyProbs; + + // These are in logits, the client does the postprocessing to turn them into + // policy probabilities and white game outcome probabilities + // Also we don't fill in the nnHash here either + // Handle version >= 12 policy optimism + if(numPolicyChannels == 2 || (numPolicyChannels == 4 && modelVersion >= 16)) { + if(gpuHandle->usingNHWC) { + for(int i = 0; isymmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; + } + else { + for(int i = 0; isymmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; + } + } + else { + assert(numPolicyChannels == 1); + SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0]; + } + + int numValueChannels = gpuHandle->model->numValueChannels; + assert(numValueChannels == 3); + output->whiteWinProb = inputBuffers->valueResults[row * numValueChannels]; + output->whiteLossProb = inputBuffers->valueResults[row * numValueChannels + 1]; + output->whiteNoResultProb = inputBuffers->valueResults[row * numValueChannels + 2]; + + //As above, these are NOT actually from white's perspective, but rather the player to move. + //As usual the client does the postprocessing. + if(output->whiteOwnerMap != NULL) { + const float* ownershipSrcBuf = inputBuffers->ownershipResults + row * nnXLen * nnYLen; + assert(gpuHandle->model->numOwnershipChannels == 1); + SymmetryHelpers::copyOutputsWithSymmetry(ownershipSrcBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + } + + if(modelVersion >= 9) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 6); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; + output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; + output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 4]; + output->shorttermScoreError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 5]; + } + else if(modelVersion >= 8) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 4); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; + output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; + output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(modelVersion >= 4) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 2); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(modelVersion >= 3) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 1); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + //Version 3 neural nets don't have any second moment output, implicitly already folding it in, so we just use the mean squared + output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else { + ASSERT_UNREACHABLE; + } + } + +} + +//TESTING ---------------------------------------------------------------------------------- + + +bool NeuralNet::testEvaluateConv( + const ConvLayerDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->inChannels; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->outChannels; + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateConv: unexpected input buffer size"); + + void* deviceInput; + void* deviceOutput; + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); + + int maxBatchSize = desiredBatchSize; + + CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); + ConvLayer* convLayer = new ConvLayer(cudaHandles,manager,desc,useFP16,useNHWC); + + size_t workspaceBytes = + convLayer->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); + void* deviceWorkspace; + CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); + + + bool accumulate = false; + convLayer->apply( + cudaHandles, + desiredBatchSize, + accumulate, + deviceInput, + deviceOutput, + deviceWorkspace, + workspaceBytes + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); + + hipFree(deviceWorkspace); + + delete convLayer; + delete manager; + hipFree(deviceInput); + hipFree(deviceOutput); + delete cudaHandles; + + return true; +} + + +bool NeuralNet::testEvaluateBatchNorm( + const BatchNormLayerDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + const vector& maskBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; + size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateBatchNorm: unexpected input buffer size"); + if(numMaskFloats != maskBuffer.size()) + throw StringError("testEvaluateBatchNorm: unexpected mask buffer size"); + + ActivationLayerDesc actDesc; + actDesc.activation = ACTIVATION_IDENTITY; + + void* deviceInput; + void* deviceMask; + void* deviceOutput; + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); + CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); + + BatchNormLayer* batchNormLayer = new BatchNormLayer(cudaHandles,desc,&actDesc,nnXLen,nnYLen,useFP16,useNHWC); + + batchNormLayer->apply( + cudaHandles, + desiredBatchSize, + deviceInput, + deviceMask, + deviceOutput + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); + + delete batchNormLayer; + + hipFree(deviceInput); + hipFree(deviceMask); + hipFree(deviceOutput); + delete cudaHandles; + + return true; +} + + +bool NeuralNet::testEvaluateResidualBlock( + const ResidualBlockDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + const vector& maskBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; + size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateResidualBlock: unexpected input buffer size"); + if(numMaskFloats != maskBuffer.size()) + throw StringError("testEvaluateResidualBlock: unexpected mask buffer size"); + + ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); + + void* deviceInput; + void* deviceMask; + void* deviceScratch; + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); + CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); + + int maxBatchSize = desiredBatchSize; + + CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); + ResidualBlock* residualBlock = new ResidualBlock(cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC); + + size_t workspaceBytes = + residualBlock->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); + void* deviceWorkspace; + CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); + + residualBlock->apply( + cudaHandles, + scratch, + desiredBatchSize, + deviceInput, + deviceScratch, + deviceMask, + deviceWorkspace, + workspaceBytes + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); + + hipFree(deviceWorkspace); + + delete residualBlock; + delete manager; + hipFree(deviceInput); + hipFree(deviceMask); + hipFree(deviceScratch); + delete scratch; + delete cudaHandles; + + return true; +} + +bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( + const GlobalPoolingResidualBlockDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + const vector& maskBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; + size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; + size_t numMaskSumFloats = (size_t)desiredBatchSize; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; + + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected input buffer size"); + if(numMaskFloats != maskBuffer.size()) + throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected mask buffer size"); + + ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); + + void* deviceInput; + void* deviceMask; + float* deviceMaskFloatOrig; + float* deviceMaskFloat; + float* deviceMaskSum; + void* deviceScratch; + + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); + CUDA_ERR("deviceMaskFloat",hipMalloc(reinterpret_cast(&deviceMaskFloat), numMaskFloats * sizeof(float))); + CUDA_ERR("deviceMaskSum",hipMalloc(reinterpret_cast(&deviceMaskSum), numMaskSumFloats * sizeof(float))); + deviceMaskFloatOrig = deviceMaskFloat; + CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); + + fillMaskFloatBufAndMaskSumBuf(deviceMask, deviceMaskFloat, deviceMaskSum, useFP16, desiredBatchSize, nnXLen, nnYLen); + + int maxBatchSize = desiredBatchSize; + + CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); + GlobalPoolingResidualBlock* residualBlock = new GlobalPoolingResidualBlock( + cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC + ); + + size_t workspaceBytes = + residualBlock->requiredWorkspaceBytes( + cudaHandles,desiredBatchSize + ); + + void* deviceWorkspace; + CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); + + residualBlock->apply( + cudaHandles, + scratch, + desiredBatchSize, + deviceInput, + deviceScratch, + deviceMask, + deviceMaskSum, + deviceWorkspace, + workspaceBytes + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); + + hipFree(deviceWorkspace); + + delete residualBlock; + delete manager; + + hipFree(deviceInput); + hipFree(deviceMask); + hipFree(deviceMaskFloatOrig); + hipFree(deviceMaskSum); + hipFree(deviceScratch); + delete scratch; + delete cudaHandles; + + return true; +} + + +#endif // USE_ROCM_BACKEND diff --git a/cpp/neuralnet/rocmerrorcheck.h b/cpp/neuralnet/rocmerrorcheck.h new file mode 100644 index 0000000000..049f1ae95c --- /dev/null +++ b/cpp/neuralnet/rocmerrorcheck.h @@ -0,0 +1,59 @@ +#ifndef NEURALNET_ROCMERRORCHECK_H_ +#define NEURALNET_ROCMERRORCHECK_H_ + +#include "../neuralnet/rocmincludes.h" +#include "../core/global.h" + +// ---------- HIP runtime ---------- +static inline void checkCudaError(hipError_t status, + const char* opName, + const char* file, + const char* func, + int line) { + if(status != hipSuccess) + throw StringError(std::string("HIP Error @") + opName + " " + + file + ":" + func + ":" + Global::intToString(line) + + " : " + cudaGetErrorString(status)); +} +#define CUDA_ERR(opName,x) checkCudaError((x),opName,__FILE__,#x,__LINE__) + +// ---------- hipBLAS ---------- +static inline const char* cublasGetErrorString(hipblasStatus_t s) { + switch(s) { + case HIPBLAS_STATUS_SUCCESS: return "HIPBLAS_STATUS_SUCCESS"; + case HIPBLAS_STATUS_ALLOC_FAILED: return "HIPBLAS_STATUS_ALLOC_FAILED"; + case HIPBLAS_STATUS_MAPPING_ERROR: return "HIPBLAS_STATUS_MAPPING_ERROR"; + case HIPBLAS_STATUS_EXECUTION_FAILED: return "HIPBLAS_STATUS_EXECUTION_FAILED"; + case HIPBLAS_STATUS_INTERNAL_ERROR: return "HIPBLAS_STATUS_INTERNAL_ERROR"; + case HIPBLAS_STATUS_INVALID_VALUE: return "HIPBLAS_STATUS_INVALID_VALUE"; + case HIPBLAS_STATUS_NOT_INITIALIZED: return "HIPBLAS_STATUS_NOT_INITIALIZED"; + case HIPBLAS_STATUS_NOT_SUPPORTED: return "HIPBLAS_STATUS_NOT_SUPPORTED"; + default: return "HIPBLAS_STATUS_UNKNOWN"; + } +} +static inline void checkCublasError(hipblasStatus_t status, + const char* opName, + const char* file, + const char* func, + int line) { + if(status != HIPBLAS_STATUS_SUCCESS) + throw StringError(std::string("hipBLAS Error @") + opName + " " + + file + ":" + func + ":" + Global::intToString(line) + + " : " + cublasGetErrorString(status)); +} +#define CUBLAS_ERR(opName,x) checkCublasError((x),opName,__FILE__,#x,__LINE__) + +// ---------- MIOpen ---------- +static inline void checkCudnnError(miopenStatus_t status, + const char* opName, + const char* file, + const char* func, + int line) { + if(status != miopenStatusSuccess) + throw StringError(std::string("MIOpen Error @") + opName + " " + + file + ":" + func + ":" + Global::intToString(line) + + " : " + cudnnGetErrorString(status)); +} +#define CUDNN_ERR(opName,x) checkCudnnError((x),opName,__FILE__,#x,__LINE__) + +#endif // NEURALNET_ROCMERRORCHECK_H_ diff --git a/cpp/neuralnet/rocmhelpers.h b/cpp/neuralnet/rocmhelpers.h new file mode 100644 index 0000000000..215b1e9fd4 --- /dev/null +++ b/cpp/neuralnet/rocmhelpers.h @@ -0,0 +1,60 @@ +#include "hip/hip_runtime.h" +#ifndef NEURALNET_ROCMHELPERS_H_ +#define NEURALNET_ROCMHELPERS_H_ + +#include "../neuralnet/rocmincludes.h" +#include "../neuralnet/activations.h" + +//Given two tensors with shapes inA: [n,cA,h,w] and inB: [n,cB,h,w], that are on the GPU +//Copy them into a single tensor out: [n,cA+cB,h,w] that is also allocated on the gpu +void customCudaChannelConcat(const float* inA, const float* inB, float* out, int chwA, int chwB, int n); +void customCudaChannelConcat(const half* inA, const half* inB, half* out, int chwA, int chwB, int n); + +//Given a tensor [n,c,hw], extract out channel 0 to [n,hw] +void customCudaChannel0ExtractNCHW(const float* in, float* out, int n, int c, int hw); +void customCudaChannel0ExtractNCHW(const half* in, half* out, int n, int c, int hw); +//Given a tensor [n,hw,c], extract out channel 0 to [n,hw] +void customCudaChannel0ExtractNHWC(const float* in, float* out, int n, int hw, int c); +void customCudaChannel0ExtractNHWC(const half* in, half* out, int n, int hw, int c); + +//Given an input tensor and an output buffer of shape [n,c], fill output buffer with sum or max over c. +void customCudaPoolRowsSumNCHW(const float* in, float* out, int nSize, int cSize, int xySize, float scaleSum); +void customCudaPoolRowsSumNHWC(const float* in, float* out, int nSize, int xySize, int cSize, float scaleSum); + +//Specialized operations for value head and general global pooling. Same as the other pooling, but fusedly fills +//an output buffer of shape [n,c*3]. +void customCudaValueHeadPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* maskSum); +void customCudaValueHeadPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* maskSum); +void customCudaPoolRowsGPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* mask, const float* maskSum); +void customCudaPoolRowsGPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* mask, const float* maskSum); +void customCudaPoolRowsGPoolNCHW(const half* in, half* out, int nSize, int cSize, int xySize, const half* mask, const float* maskSum); +void customCudaPoolRowsGPoolNHWC(const half* in, half* out, int nSize, int xySize, int cSize, const half* mask, const float* maskSum); + +void customCudaCopyToHalf(const float* in, half* out, int n); +void customCudaCopyFromHalf(const half* in, float* out, int n); + +//Given a tensor, add another tensor to it. +void customCudaAddTensorInplace(half* buf, const half* biases, int n); +//Given an input with shape [n,c] and biases of shape [c], add the biases in-place. +void customCudaAddCBiasInplaceNC(float* buf, const float* biases, int n, int c, int activation); +void customCudaAddCBiasInplaceNC(half* buf, const half* biases, int n, int c, int activation); +//Given an input with shape [n,c,xy] and biases of shape [n,c], add the biases in-place. +void customCudaAddNCBiasInplaceNCHW(float *buf, const float* biases, int nSize, int cSize, int xySize); +void customCudaAddNCBiasInplaceNCHW(half *buf, const half* biases, int nSize, int cSize, int xySize); +//Given an input with shape [n,xy,c] and biases of shape [n,c], add the biases in-place. +void customCudaAddNCBiasInplaceNHWC(float *buf, const float* biases, int nSize, int xySize, int cSize); +void customCudaAddNCBiasInplaceNHWC(half *buf, const half* biases, int nSize, int xySize, int cSize); + +//Given an input with shape [n,c,xy] and scale and biases of shape [c], multiply by scale and add the biases +//Optionally also apply an activation. +//Optionally also multiply by mask (can be null), with shape [n,xy] +void customCudaApplyCScaleBiasNCHW(const float* in, float* out, const float* scale, const float* biases, const float* mask, int n, int c, int xy, int activation); +void customCudaApplyCScaleBiasNCHW(const half* in, half* out, const half* scale, const half* biases, const half* mask, int n, int c, int xy, int activation); +//Given an input with shape [n,xy,c] and scale and biases of shape [c], multiply by scale and add the biases +//Optionally also apply relu. +//Optionally also multiply by mask (can be null), with shape [n,xy] +void customCudaApplyCScaleBiasNHWC(const float* in, float* out, const float* scale, const float* biases, const float* mask, int n, int xy, int c, int activation); +void customCudaApplyCScaleBiasNHWC(const half* in, half* out, const half* scale, const half* biases, const half* mask, int n, int xy, int c, int activation); + + +#endif // NEURALNET_ROCMHELPERS_H_ diff --git a/cpp/neuralnet/rocmhelpers.hip b/cpp/neuralnet/rocmhelpers.hip new file mode 100644 index 0000000000..2f9b94951e --- /dev/null +++ b/cpp/neuralnet/rocmhelpers.hip @@ -0,0 +1,1905 @@ +#include "hip/hip_runtime.h" + +#include "../neuralnet/rocmhelpers.h" + +#include + +#if defined(__HIP_ARCH_HAS_FP16__) || (defined(__HIP_DEVICE_COMPILE__) && (__HIP_ARCH_GFX803__ || __HIP_ARCH_GFX900__ || ...)) +#define HIP_SUPPORTS_FP16 +#endif + +//TODO maybe tune this number, it varies by GPU +static const int targetNumThreads = 512; + +void splitThreadsAcrossDim01(int dim0Size, int dim1Size, int& threads0, int& blocks0, int& threads1, int& blocks1) { + if(dim0Size > targetNumThreads) { + threads0 = targetNumThreads/2; + blocks0 = (dim0Size + threads0 - 1) / threads0; + threads1 = 1; + blocks1 = dim1Size; + } + else if(dim0Size > targetNumThreads/2) { + threads0 = dim0Size; + blocks0 = 1; + threads1 = 1; + blocks1 = dim1Size; + } + else { + threads0 = dim0Size; + blocks0 = 1; + threads1 = targetNumThreads / dim0Size; + blocks1 = (dim1Size + threads1 - 1) / threads1; + } +} + +__forceinline__ __device__ float mishf(float a) { + return a * tanhf(a < 20.0f ? log1pf(expf(a)) : a); +} +__forceinline__ __device__ float mishf_scale8(float a) { + return a < 2.5f ? a * tanhf(log1pf(expf(a*8.0f))) : a; +} + +#ifdef HIP_SUPPORTS_FP16 +__forceinline__ __device__ half mishh(half h) { + float a = __half2float(h); + return __float2half(a * tanhf(a < 20.0f ? log1pf(expf(a)) : a)); +} +__forceinline__ __device__ half mishh_scale8(half h) { + float a = __half2float(h); + return __float2half(a < 2.5f ? a * tanhf(log1pf(expf(a*8.0f))) : a); +} +#endif + +//-------------------------------------------------------------------------------------------------------------- + +template +__global__ +void channelConcatKernel( + const T* inA, + const T* inB, + T* out, + int chwA, + int chwB, + int numBlocksA, + int numBlocksB, + int n +) { + if(blockIdx.x < numBlocksA) { + int index = blockIdx.x * blockDim.x + threadIdx.x; + if(index < chwA) { + int nchwA = n*chwA; + int chwOut = (chwA+chwB); + + int aIdx = index; + int outIdx = index; + while(aIdx < nchwA) { + out[outIdx] = inA[aIdx]; + aIdx += chwA; + outIdx += chwOut; + } + } + } + else { + int index = (blockIdx.x - numBlocksA) * blockDim.x + threadIdx.x; + if(index < chwB) { + int nchwB = n*chwB; + int chwOut = (chwA+chwB); + + int bIdx = index; + int outIdx = chwA+index; + while(bIdx < nchwB) { + out[outIdx] = inB[bIdx]; + bIdx += chwB; + outIdx += chwOut; + } + } + } +} + +template +void customCudaChannelConcatTemplate(const T* inA, const T* inB, T* out, int chwA, int chwB, int n) { + int blockSize = targetNumThreads; + int numBlocksA = (chwA + blockSize-1) / blockSize; + int numBlocksB = (chwB + blockSize-1) / blockSize; + int numBlocks = numBlocksA + numBlocksB; + channelConcatKernel<<>>(inA,inB,out,chwA,chwB,numBlocksA,numBlocksB,n); +} +template void customCudaChannelConcatTemplate(const float* inA, const float* inB, float* out, int chwA, int chwB, int n); +template void customCudaChannelConcatTemplate(const half* inA, const half* inB, half* out, int chwA, int chwB, int n); + +void customCudaChannelConcat(const float* inA, const float* inB, float* out, int chwA, int chwB, int n) { + customCudaChannelConcatTemplate(inA,inB,out,chwA,chwB,n); +} +void customCudaChannelConcat(const half* inA, const half* inB, half* out, int chwA, int chwB, int n) { + customCudaChannelConcatTemplate(inA,inB,out,chwA,chwB,n); +} + +//-------------------------------------------------------------------------------------------------------------- + +template +__global__ +void extractChannel0KernelNHWC(const T *in, T* out, int nhwSize, int cSize) +{ + int nhwIdx = blockIdx.x * blockDim.x + threadIdx.x; + if(nhwIdx < nhwSize) { + out[nhwIdx] = in[nhwIdx*cSize]; + } +} +template +void customCudaChannel0ExtractNHWCTemplate(const T *in, T* out, int n, int hw, int c) { + int nhw = n*hw; + int blockSize = targetNumThreads; + int numBlocks = (nhw+blockSize-1)/blockSize; + extractChannel0KernelNHWC<<>>(in,out,nhw,c); +} + +template +__global__ +void extractChannel0KernelNCHW(const T *in, T* out, int nSize, int cSize, int hwSize) +{ + int hwIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(hwIdx < hwSize && nIdx < nSize) { + out[nIdx * hwSize + hwIdx] = in[nIdx * cSize * hwSize + hwIdx]; + } +} +template +void customCudaChannel0ExtractNCHWTemplate(const T *in, T* out, int nSize, int cSize, int hwSize) { + int hwThreads; + int hwBlocks; + int nThreads; + int nBlocks; + splitThreadsAcrossDim01(hwSize, nSize, hwThreads, hwBlocks, nThreads, nBlocks); + + if(nBlocks > 65536) + throw std::runtime_error("customCudaChannel0ExtractNCHW: nSize too large given hwSize"); + + dim3 grid(hwBlocks,nBlocks,1); + dim3 threads(hwThreads,nThreads,1); + extractChannel0KernelNCHW<<>>(in,out,nSize,cSize,hwSize); +} + +void customCudaChannel0ExtractNCHW(const float* in, float* out, int n, int c, int hw) { + customCudaChannel0ExtractNCHWTemplate(in,out,n,c,hw); +} +void customCudaChannel0ExtractNCHW(const half* in, half* out, int n, int c, int hw) { + customCudaChannel0ExtractNCHWTemplate(in,out,n,c,hw); +} +void customCudaChannel0ExtractNHWC(const float* in, float* out, int n, int hw, int c) { + customCudaChannel0ExtractNHWCTemplate(in,out,n,hw,c); +} +void customCudaChannel0ExtractNHWC(const half* in, half* out, int n, int hw, int c) { + customCudaChannel0ExtractNHWCTemplate(in,out,n,hw,c); +} + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void sumChannelsNCHWKernel(const float* in, float* out, int cSize, int xySize, float scaleSum) +{ + extern __shared__ float sumPoolNCHWShared[]; + int xyId = threadIdx.x; + int xyBlockDim = blockDim.x; + int cId = threadIdx.y; + int cBlockDim = blockDim.y; + int cIdx = blockIdx.y * cBlockDim + cId; + int nIdx = blockIdx.z; + + int xycSize = xySize*cSize; + int sharedIdx = xyId + cId * xyBlockDim; + + float acc = 0.0f; + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + acc += in[xyIdx + cIdx * xySize + nIdx * xycSize]; + xyIdx += xyBlockDim; + } + sumPoolNCHWShared[sharedIdx] = acc; + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumPoolNCHWShared[sharedIdx] += sumPoolNCHWShared[sharedIdx + s]; + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) + out[cIdx + nIdx * cSize] = sumPoolNCHWShared[sharedIdx] * scaleSum; +} +__global__ +void valueHeadPoolChannelsNCHWKernel(const float* in, float* out, int nSize, int cSize, int xySize, const float* maskSum) +{ + extern __shared__ float sumPoolNCHWShared[]; + int xyId = threadIdx.x; + int xyBlockDim = blockDim.x; + int cId = threadIdx.y; + int cBlockDim = blockDim.y; + int cIdx = blockIdx.y * cBlockDim + cId; + int nIdx = blockIdx.z; + + int xycSize = xySize*cSize; + int sharedIdx = xyId + cId * xyBlockDim; + + float acc = 0.0f; + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + acc += in[xyIdx + cIdx * xySize + nIdx * xycSize]; + xyIdx += xyBlockDim; + } + sumPoolNCHWShared[sharedIdx] = acc; + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumPoolNCHWShared[sharedIdx] += sumPoolNCHWShared[sharedIdx + s]; + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumPoolNCHWShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + out[cIdx + nIdx * cSize*3] = mean; + out[cIdx + nIdx * cSize*3 + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; + out[cIdx + nIdx * cSize*3 + cSize*2] = mean * ((sqrtdiv - 14.0f) * (sqrtdiv - 14.0f) * 0.01f - 0.1f); + } +} +__global__ +void gPoolChannelsNCHWKernel(const float* in, float* out, int cSize, int xySize, const float* maskSum, int sharedMemElts) +{ + extern __shared__ float poolNCHWShared[]; + float* sumShared = (float*)poolNCHWShared; + float* maxShared = (float*)poolNCHWShared + sharedMemElts; + + int xyId = threadIdx.x; + int xyBlockDim = blockDim.x; + int cId = threadIdx.y; + int cBlockDim = blockDim.y; + int cIdx = blockIdx.y * cBlockDim + cId; + int nIdx = blockIdx.z; + + int xycSize = xySize*cSize; + int sharedIdx = xyId + cId * xyBlockDim; + + if(cIdx < cSize) { + float accSum = 0.0f; + float accMax = -1.0f; + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = in[xyIdx + cIdx * xySize + nIdx * xycSize]; + accSum += a; + accMax = fmaxf(accMax, a); + xyIdx += xyBlockDim; + } + sumShared[sharedIdx] = accSum; + maxShared[sharedIdx] = accMax; + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = mean; + out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; + out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; + } +} +__global__ +void gPoolChannelsNCHWMaskKernel(const float* in, float* out, int cSize, int xySize, const float* mask, const float* maskSum, int sharedMemElts) +{ + extern __shared__ float poolNCHWShared[]; + float* sumShared = (float*)poolNCHWShared; + float* maxShared = (float*)poolNCHWShared + sharedMemElts; + + int xyId = threadIdx.x; + int xyBlockDim = blockDim.x; + int cId = threadIdx.y; + int cBlockDim = blockDim.y; + int cIdx = blockIdx.y * cBlockDim + cId; + int nIdx = blockIdx.z; + + int xycSize = xySize*cSize; + int sharedIdx = xyId + cId * xyBlockDim; + + if(cIdx < cSize) { + float accSum = 0.0f; + float accMax = -1.0f; + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = in[xyIdx + cIdx * xySize + nIdx * xycSize]; + accSum += a; + // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 + // which is lower than the lowest value that any current activation function will produce. + // so the max over all valid spaces will the same as the mask over all spaces including padding + // We're relying on all padded space being equal to 0 because this gpool only ever follows a BN+Activate with a mask. + accMax = fmaxf(accMax, a + (mask[xyIdx + nIdx * xySize] - 1.0f)); + xyIdx += xyBlockDim; + } + sumShared[sharedIdx] = accSum; + maxShared[sharedIdx] = accMax; + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = mean; + out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; + out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; + } +} + +void customCudaPoolRowsSumNCHW(const float* in, float* out, int nSize, int cSize, int xySize, float scaleSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaPoolRowsSumNCHW: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaPoolRowsSumNCHW: cSize too large"); + + //Use up as many threads as possible along the xy dimension. + int xyThreads = 1; + while(xyThreads < targetNumThreads && xyThreads < xySize/2) + xyThreads *= 2; + + //Distribute the extra threads along the c dimension. + int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //We need one shared memory spot per thread + int sharedMemSize = sizeof(float) * cThreads * xyThreads; + + dim3 grid(1,cBlocks,nSize); + dim3 threads(xyThreads,cThreads,1); + sumChannelsNCHWKernel<<>>(in,out,cSize,xySize,scaleSum); +} +void customCudaValueHeadPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* maskSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaValueHeadPoolNCHW: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaValueHeadPoolNCHW: cSize too large"); + + //Use up as many threads as possible along the xy dimension. + int xyThreads = 1; + while(xyThreads < targetNumThreads && xyThreads < xySize/2) + xyThreads *= 2; + + //Distribute the extra threads along the c dimension. + int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //We need one shared memory spot per thread + int sharedMemSize = sizeof(float) * cThreads * xyThreads; + + dim3 grid(1,cBlocks,nSize); + dim3 threads(xyThreads,cThreads,1); + valueHeadPoolChannelsNCHWKernel<<>>(in,out,nSize,cSize,xySize,maskSum); +} +void customCudaPoolRowsGPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* mask, const float* maskSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNCHW: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNCHW: cSize too large"); + + //Use up as many threads as possible along the xy dimension. + int xyThreads = 1; + while(xyThreads < targetNumThreads && xyThreads < xySize/2) + xyThreads *= 2; + + //Distribute the extra threads along the c dimension. + int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //We need one shared memory spot per thread, and then we double it because we need both sum and max. + //We also make sure it's a power of two to address any alignment concerns. + int sharedMemElts = 128; + while(sharedMemElts < cThreads * xyThreads) + sharedMemElts *= 2; + int sharedMemSize = sizeof(float) * sharedMemElts * 2; + + dim3 grid(1,cBlocks,nSize); + dim3 threads(xyThreads,cThreads,1); + if(mask != NULL) + gPoolChannelsNCHWMaskKernel<<>>(in,out,cSize,xySize,mask,maskSum,sharedMemElts); + else + gPoolChannelsNCHWKernel<<>>(in,out,cSize,xySize,maskSum,sharedMemElts); +} + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void gPoolChannelsNCHWHalfKernel(const half* in, half* out, int cSize, int xySize, const float* maskSum, int sharedMemElts) +{ +#ifdef HIP_SUPPORTS_FP16 + extern __shared__ float poolNCHWShared[]; + float* sumShared = (float*)poolNCHWShared; + float* maxShared = (float*)poolNCHWShared + sharedMemElts; + + int xyId = threadIdx.x; + int xyBlockDim = blockDim.x; + int cId = threadIdx.y; + int cBlockDim = blockDim.y; + int cIdx = blockIdx.y * cBlockDim + cId; + int nIdx = blockIdx.z; + + int xycSize = xySize*cSize; + int sharedIdx = xyId + cId * xyBlockDim; + + if(cIdx < cSize) { + float accSum = 0.0f; + float accMax = -1.0f; + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = __half2float(in[xyIdx + cIdx * xySize + nIdx * xycSize]); + accSum += a; + accMax = fmaxf(accMax, a); + xyIdx += xyBlockDim; + } + sumShared[sharedIdx] = accSum; + maxShared[sharedIdx] = accMax; + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = __float2half(mean); + out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); + out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void gPoolChannelsNCHWHalfMaskKernel(const half* in, half* out, int cSize, int xySize, const half* mask, const float* maskSum, int sharedMemElts) +{ +#ifdef HIP_SUPPORTS_FP16 + extern __shared__ float poolNCHWShared[]; + float* sumShared = (float*)poolNCHWShared; + float* maxShared = (float*)poolNCHWShared + sharedMemElts; + + int xyId = threadIdx.x; + int xyBlockDim = blockDim.x; + int cId = threadIdx.y; + int cBlockDim = blockDim.y; + int cIdx = blockIdx.y * cBlockDim + cId; + int nIdx = blockIdx.z; + + int xycSize = xySize*cSize; + int sharedIdx = xyId + cId * xyBlockDim; + + if(cIdx < cSize) { + float accSum = 0.0f; + float accMax = -1.0f; + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = __half2float(in[xyIdx + cIdx * xySize + nIdx * xycSize]); + accSum += a; + // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 + // which is lower than the lowest value that any current activation function will produce. + // so the max over all valid spaces will the same as the mask over all spaces including padding + accMax = fmaxf(accMax, a + (__half2float(mask[xyIdx + nIdx * xySize]) - 1.0f)); + xyIdx += xyBlockDim; + } + sumShared[sharedIdx] = accSum; + maxShared[sharedIdx] = accMax; + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = __float2half(mean); + out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); + out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void customCudaPoolRowsGPoolNCHW(const half* in, half* out, int nSize, int cSize, int xySize, const half* mask, const float* maskSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNCHW: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNCHW: cSize too large"); + + //Use up as many threads as possible along the xy dimension. + int xyThreads = 1; + while(xyThreads < targetNumThreads && xyThreads < xySize/2) + xyThreads *= 2; + + //Distribute the extra threads along the c dimension. + int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //We need one shared memory spot per thread, and then we double it because we need both sum and max. + //We also make sure it's a power of two to address any alignment concerns. + int sharedMemElts = 128; + while(sharedMemElts < cThreads * xyThreads) + sharedMemElts *= 2; + int sharedMemSize = sizeof(float) * sharedMemElts * 2; + + dim3 grid(1,cBlocks,nSize); + dim3 threads(xyThreads,cThreads,1); + if(mask != NULL) + gPoolChannelsNCHWHalfMaskKernel<<>>(in,out,cSize,xySize,mask,maskSum,sharedMemElts); + else + gPoolChannelsNCHWHalfKernel<<>>(in,out,cSize,xySize,maskSum,sharedMemElts); +} + + + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void sumChannelsNHWCKernel(const float* in, float* out, int xySize, int cSize, float scaleSum) +{ + extern __shared__ float sumPoolNHWCShared[]; + int cId = threadIdx.x; + int cBlockDim = blockDim.x; + int xyId = threadIdx.y; + int xyBlockDim = blockDim.y; + + int cIdx = blockIdx.x * cBlockDim + cId; + int nIdx = blockIdx.z; + int sharedIdx = cId + cBlockDim * xyId; + int xycSize = xySize*cSize; + + sumPoolNHWCShared[sharedIdx] = 0; + + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + sumPoolNHWCShared[sharedIdx] += in[cIdx + xyIdx * cSize + nIdx * xycSize]; + xyIdx += xyBlockDim; + } + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumPoolNHWCShared[sharedIdx] += sumPoolNHWCShared[sharedIdx + cBlockDim * s]; + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) + out[cIdx + nIdx * cSize] = sumPoolNHWCShared[sharedIdx] * scaleSum; +} +__global__ +void valueHeadPoolChannelsNHWCKernel(const float* in, float* out, int nSize, int xySize, int cSize, const float* maskSum) +{ + extern __shared__ float sumPoolNHWCShared[]; + int cId = threadIdx.x; + int cBlockDim = blockDim.x; + int xyId = threadIdx.y; + int xyBlockDim = blockDim.y; + + int cIdx = blockIdx.x * cBlockDim + cId; + int nIdx = blockIdx.z; + int sharedIdx = cId + cBlockDim * xyId; + int xycSize = xySize*cSize; + + sumPoolNHWCShared[sharedIdx] = 0; + + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + sumPoolNHWCShared[sharedIdx] += in[cIdx + xyIdx * cSize + nIdx * xycSize]; + xyIdx += xyBlockDim; + } + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumPoolNHWCShared[sharedIdx] += sumPoolNHWCShared[sharedIdx + cBlockDim * s]; + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumPoolNHWCShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + out[cIdx + nIdx * cSize*3] = mean; + out[cIdx + nIdx * cSize*3 + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; + out[cIdx + nIdx * cSize*3 + cSize*2] = mean * ((sqrtdiv - 14.0f) * (sqrtdiv - 14.0f) * 0.01f - 0.1f); + } +} +__global__ +void gPoolChannelsNHWCKernel(const float* in, float* out, int xySize, int cSize, const float* maskSum, int sharedMemElts) +{ + extern __shared__ float poolNHWCShared[]; + float* sumShared = (float*)poolNHWCShared; + float* maxShared = (float*)poolNHWCShared + sharedMemElts; + + int cId = threadIdx.x; + int cBlockDim = blockDim.x; + int xyId = threadIdx.y; + int xyBlockDim = blockDim.y; + + int cIdx = blockIdx.x * cBlockDim + cId; + int nIdx = blockIdx.z; + int sharedIdx = cId + cBlockDim * xyId; + int xycSize = xySize*cSize; + + sumShared[sharedIdx] = 0; + maxShared[sharedIdx] = -1.0f; + + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = in[cIdx + xyIdx * cSize + nIdx * xycSize]; + sumShared[sharedIdx] += a; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a); + xyIdx += xyBlockDim; + } + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = mean; + out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; + out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; + } +} +__global__ +void gPoolChannelsNHWCMaskKernel(const float* in, float* out, int xySize, int cSize, const float* mask, const float* maskSum, int sharedMemElts) +{ + extern __shared__ float poolNHWCShared[]; + float* sumShared = (float*)poolNHWCShared; + float* maxShared = (float*)poolNHWCShared + sharedMemElts; + + int cId = threadIdx.x; + int cBlockDim = blockDim.x; + int xyId = threadIdx.y; + int xyBlockDim = blockDim.y; + + int cIdx = blockIdx.x * cBlockDim + cId; + int nIdx = blockIdx.z; + int sharedIdx = cId + cBlockDim * xyId; + int xycSize = xySize*cSize; + + sumShared[sharedIdx] = 0; + maxShared[sharedIdx] = -1.0f; + + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = in[cIdx + xyIdx * cSize + nIdx * xycSize]; + sumShared[sharedIdx] += a; + // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 + // which is lower than the lowest value that any current activation function will produce. + // so the max over all valid spaces will the same as the mask over all spaces including padding + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a + (mask[xyIdx + nIdx * xySize] - 1.0f)); + xyIdx += xyBlockDim; + } + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = mean; + out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; + out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; + } +} + + +void customCudaPoolRowsSumNHWC(const float* in, float* out, int nSize, int xySize, int cSize, float scaleSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaPoolRowsSumNHWC: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaPoolRowsSumNHWC: cSize too large"); + + //Use up to two warps worth of threads along the channel dimension, which is the + //most compact + int cThreads = 1; + while(cThreads < 64 && cThreads < cSize/2) + cThreads *= 2; + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //Distribute the extra threads to perform parallel reduction along the xy dimension. + int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); + + //We need one shared memory spot per thread + int sharedMemSize = sizeof(float) * cThreads * xyThreads; + + dim3 grid(cBlocks,1,nSize); + dim3 threads(cThreads,xyThreads,1); + sumChannelsNHWCKernel<<>>(in,out,xySize,cSize,scaleSum); +} + +void customCudaValueHeadPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* maskSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaValueHeadPoolNHWC: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaValueHeadPoolNHWC: cSize too large"); + + //Use up to two warps worth of threads along the channel dimension, which is the + //most compact + int cThreads = 1; + while(cThreads < 64 && cThreads < cSize/2) + cThreads *= 2; + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //Distribute the extra threads to perform parallel reduction along the xy dimension. + int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); + + //We need one shared memory spot per thread + int sharedMemSize = sizeof(float) * cThreads * xyThreads; + + dim3 grid(cBlocks,1,nSize); + dim3 threads(cThreads,xyThreads,1); + valueHeadPoolChannelsNHWCKernel<<>>(in,out,nSize,xySize,cSize,maskSum); +} + +void customCudaPoolRowsGPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* mask, const float* maskSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNHWC: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNHWC: cSize too large"); + + //Use up to two warps worth of threads along the channel dimension, which is the + //most compact + int cThreads = 1; + while(cThreads < 64 && cThreads < cSize/2) + cThreads *= 2; + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //Distribute the extra threads to perform parallel reduction along the xy dimension. + int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); + + //We need one shared memory spot per thread, and then we double it because we need both sum and max. + //We also make sure it's a power of two to address any alignment concerns. + int sharedMemElts = 128; + while(sharedMemElts < cThreads * xyThreads) + sharedMemElts *= 2; + int sharedMemSize = sizeof(float) * sharedMemElts * 2; + + dim3 grid(cBlocks,1,nSize); + dim3 threads(cThreads,xyThreads,1); + if(mask != NULL) + gPoolChannelsNHWCMaskKernel<<>>(in,out,xySize,cSize,mask,maskSum,sharedMemElts); + else + gPoolChannelsNHWCKernel<<>>(in,out,xySize,cSize,maskSum,sharedMemElts); +} + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void gPoolChannelsNHWCHalfKernel(const half* in, half* out, int xySize, int cSize, const float* maskSum, int sharedMemElts) +{ +#ifdef HIP_SUPPORTS_FP16 + extern __shared__ float poolNHWCShared[]; + float* sumShared = (float*)poolNHWCShared; + float* maxShared = (float*)poolNHWCShared + sharedMemElts; + + int cId = threadIdx.x; + int cBlockDim = blockDim.x; + int xyId = threadIdx.y; + int xyBlockDim = blockDim.y; + + int cIdx = blockIdx.x * cBlockDim + cId; + int nIdx = blockIdx.z; + int sharedIdx = cId + cBlockDim * xyId; + int xycSize = xySize*cSize; + + sumShared[sharedIdx] = 0; + maxShared[sharedIdx] = -1.0f; + + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = __half2float(in[cIdx + xyIdx * cSize + nIdx * xycSize]); + sumShared[sharedIdx] += a; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a); + xyIdx += xyBlockDim; + } + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = __float2half(mean); + out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); + out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void gPoolChannelsNHWCHalfMaskKernel(const half* in, half* out, int xySize, int cSize, const half* mask, const float* maskSum, int sharedMemElts) +{ +#ifdef HIP_SUPPORTS_FP16 + extern __shared__ float poolNHWCShared[]; + float* sumShared = (float*)poolNHWCShared; + float* maxShared = (float*)poolNHWCShared + sharedMemElts; + + int cId = threadIdx.x; + int cBlockDim = blockDim.x; + int xyId = threadIdx.y; + int xyBlockDim = blockDim.y; + + int cIdx = blockIdx.x * cBlockDim + cId; + int nIdx = blockIdx.z; + int sharedIdx = cId + cBlockDim * xyId; + int xycSize = xySize*cSize; + + sumShared[sharedIdx] = 0; + maxShared[sharedIdx] = -1.0f; + + if(cIdx < cSize) { + int xyIdx = xyId; + while(xyIdx < xySize) { + float a = __half2float(in[cIdx + xyIdx * cSize + nIdx * xycSize]); + sumShared[sharedIdx] += a; + // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 + // which is lower than the lowest value that any current activation function will produce. + // so the max over all valid spaces will the same as the mask over all spaces including padding + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a + (__half2float(mask[xyIdx + nIdx * xySize]) - 1.0f)); + xyIdx += xyBlockDim; + } + } + __syncthreads(); + + for(int s = xyBlockDim>>1; s > 0; s >>= 1) { + if(xyId < s) { + sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; + maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); + } + __syncthreads(); + } + if(xyId == 0 && cIdx < cSize) { + float sum = sumShared[sharedIdx]; + float div = maskSum[nIdx]; + float sqrtdiv = sqrt(div); + float mean = sum/div; + + out[cIdx + nIdx * (cSize*3)] = __float2half(mean); + out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); + out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void customCudaPoolRowsGPoolNHWC(const half* in, half* out, int nSize, int xySize, int cSize, const half* mask, const float* maskSum) { + if(nSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNHWC: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaPoolRowsGPoolNHWC: cSize too large"); + + //Use up to two warps worth of threads along the channel dimension, which is the + //most compact + int cThreads = 1; + while(cThreads < 64 && cThreads < cSize/2) + cThreads *= 2; + int cBlocks = (cSize + cThreads - 1) / cThreads; + + //Distribute the extra threads to perform parallel reduction along the xy dimension. + int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); + + //We need one shared memory spot per thread, and then we double it because we need both sum and max. + //We also make sure it's a power of two to address any alignment concerns. + int sharedMemElts = 128; + while(sharedMemElts < cThreads * xyThreads) + sharedMemElts *= 2; + int sharedMemSize = sizeof(float) * sharedMemElts * 2; + + dim3 grid(cBlocks,1,nSize); + dim3 threads(cThreads,xyThreads,1); + if(mask != NULL) + gPoolChannelsNHWCHalfMaskKernel<<>>(in,out,xySize,cSize,mask,maskSum,sharedMemElts); + else + gPoolChannelsNHWCHalfKernel<<>>(in,out,xySize,cSize,maskSum,sharedMemElts); +} + + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void copyToHalfKernel(const float *in, half* out, int n) +{ + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if(idx < n) { + out[idx] = __float2half(in[idx]); + } +} +__global__ +void copyFromHalfKernel(const half *in, float* out, int n) +{ + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if(idx < n) { + out[idx] = __half2float(in[idx]); + } +} + +void customCudaCopyToHalf(const float* in, half* out, int n) { + int blockSize = targetNumThreads; + int numBlocks = (n+blockSize-1)/blockSize; + copyToHalfKernel<<>>(in,out,n); +} +void customCudaCopyFromHalf(const half* in, float* out, int n) { + int blockSize = targetNumThreads; + int numBlocks = (n+blockSize-1)/blockSize; + copyFromHalfKernel<<>>(in,out,n); +} + +//-------------------------------------------------------------------------------------------------------------- + + +__global__ +void addTensorInplaceHalfKernel(half *buf, const half* biases, int nSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int idx = blockIdx.x * blockDim.x + threadIdx.x; + if(idx < nSize) { + buf[idx] = __hadd(buf[idx],biases[idx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +void customCudaAddTensorInplace(half* buf, const half* biases, int nSize) { + int blockSize = targetNumThreads; + int numBlocks = (nSize+blockSize-1)/blockSize; + addTensorInplaceHalfKernel<<>>(buf,biases,nSize); +} + +//-------------------------------------------------------------------------------------------------------------- + + +__global__ +void addCBiasInplaceNCKernel(float *buf, const float* biases, int nSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + buf[idx] = buf[idx] + biases[cIdx]; + } +} +__global__ +void addCBiasInplaceNCHalfKernel(half *buf, const half* biases, int nSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + buf[idx] = __hadd(buf[idx],biases[cIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} + +__global__ +void addCBiasInplaceNCKernelRelu(float *buf, const float* biases, int nSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + buf[idx] = fmaxf(buf[idx] + biases[cIdx],0.0f); + } +} +__global__ +void addCBiasInplaceNCHalfKernelRelu(half *buf, const half* biases, int nSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + const half halfzero = __float2half(0.0f); + half a = __hadd(buf[idx],biases[cIdx]); + buf[idx] = __hgt(a,halfzero) ? a : halfzero; + } +#else + //Do nothing, FP16 not supported +#endif +} + +__global__ +void addCBiasInplaceNCKernelMish(float *buf, const float* biases, int nSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + buf[idx] = mishf(buf[idx] + biases[cIdx]); + } +} +__global__ +void addCBiasInplaceNCHalfKernelMish(half *buf, const half* biases, int nSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + half a = __hadd(buf[idx],biases[cIdx]); + buf[idx] = mishh(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void addCBiasInplaceNCKernelMishScale8(float *buf, const float* biases, int nSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + buf[idx] = mishf_scale8(buf[idx] + biases[cIdx]); + } +} +__global__ +void addCBiasInplaceNCHalfKernelMishScale8(half *buf, const half* biases, int nSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int nIdx = blockIdx.y * blockDim.y + threadIdx.y; + if(cIdx < cSize && nIdx < nSize) { + int idx = nIdx * cSize + cIdx; + half a = __hadd(buf[idx],biases[cIdx]); + buf[idx] = mishh_scale8(a); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void sharedAddCBiasInplaceNC(void* buf, const void* biases, int nSize, int cSize, bool isHalf, int activation) { + int cThreads; + int cBlocks; + int nThreads; + int nBlocks; + splitThreadsAcrossDim01(cSize, nSize, cThreads, cBlocks, nThreads, nBlocks); + + if(nBlocks > 65536) + throw std::runtime_error("customCudaAddCBiasInplaceNC: nSize too large given cSize"); + + dim3 grid(cBlocks,nBlocks,1); + dim3 threads(cThreads,nThreads,1); + + if(activation == ACTIVATION_IDENTITY) { + if(isHalf) + addCBiasInplaceNCHalfKernel<<>>((half*)buf,(const half*)biases,nSize,cSize); + else + addCBiasInplaceNCKernel<<>>((float*)buf,(const float*)biases,nSize,cSize); + } + else if(activation == ACTIVATION_RELU) { + if(isHalf) + addCBiasInplaceNCHalfKernelRelu<<>>((half*)buf,(const half*)biases,nSize,cSize); + else + addCBiasInplaceNCKernelRelu<<>>((float*)buf,(const float*)biases,nSize,cSize); + } + else if(activation == ACTIVATION_MISH) { + if(isHalf) + addCBiasInplaceNCHalfKernelMish<<>>((half*)buf,(const half*)biases,nSize,cSize); + else + addCBiasInplaceNCKernelMish<<>>((float*)buf,(const float*)biases,nSize,cSize); + } + else if(activation == ACTIVATION_MISH_SCALE8) { + if(isHalf) + addCBiasInplaceNCHalfKernelMishScale8<<>>((half*)buf,(const half*)biases,nSize,cSize); + else + addCBiasInplaceNCKernelMishScale8<<>>((float*)buf,(const float*)biases,nSize,cSize); + } + else { + throw std::runtime_error("customCudaAddCBiasInplaceNC: unsupported activation"); + } +} + +void customCudaAddCBiasInplaceNC(float* buf, const float* biases, int nSize, int cSize, int activation) { + sharedAddCBiasInplaceNC(buf,biases,nSize,cSize,false,activation); +} +void customCudaAddCBiasInplaceNC(half* buf, const half* biases, int nSize, int cSize, int activation) { + sharedAddCBiasInplaceNC(buf,biases,nSize,cSize,true,activation); +} + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void addNCBiasInplaceNCHWKernel(float *buf, const float* biases, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int ncIdx = nIdx * cSize + cIdx; + int idx = ncIdx * sSize + sIdx; + buf[idx] = buf[idx] + biases[ncIdx]; + } +} +__global__ +void addNCBiasInplaceNCHWHalfKernel(half *buf, const half* biases, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int ncIdx = nIdx * cSize + cIdx; + int idx = ncIdx * sSize + sIdx; + buf[idx] = __hadd(buf[idx],biases[ncIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void sharedAddNCBiasInplaceNCHW(void *buf, const void* biases, int nSize, int cSize, int xySize, bool isHalf) { + if(nSize > 65536) + throw std::runtime_error("customCudaAddNCBiasInplaceNCHW: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaAddNCBiasInplaceNCHW: cSize too large"); + + int sSize = xySize; + int sThreads; + int sBlocks; + int cThreads; + int cBlocks; + splitThreadsAcrossDim01(sSize, cSize, sThreads, sBlocks, cThreads, cBlocks); + + dim3 grid(sBlocks,cBlocks,nSize); + dim3 threads(sThreads,cThreads,1); + if(isHalf) + addNCBiasInplaceNCHWHalfKernel<<>>((half*)buf,(const half*)biases,cSize,sSize); + else + addNCBiasInplaceNCHWKernel<<>>((float*)buf,(const float*)biases,cSize,sSize); +} + +void customCudaAddNCBiasInplaceNCHW(float *buf, const float* biases, int nSize, int cSize, int xySize) { + sharedAddNCBiasInplaceNCHW(buf,biases,nSize,cSize,xySize,false); +} +void customCudaAddNCBiasInplaceNCHW(half *buf, const half* biases, int nSize, int cSize, int xySize) { + sharedAddNCBiasInplaceNCHW(buf,biases,nSize,cSize,xySize,true); +} + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void addNCBiasInplaceNHWCKernel(float *buf, const float* biases, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int ncIdx = nIdx * cSize + cIdx; + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + buf[idx] = buf[idx] + biases[ncIdx]; + } +} +__global__ +void addNCBiasInplaceNHWCHalfKernel(half *buf, const half* biases, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int ncIdx = nIdx * cSize + cIdx; + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + buf[idx] = __hadd(buf[idx],biases[ncIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void sharedAddNCBiasInplaceNHWC(void *buf, const void* biases, int nSize, int xySize, int cSize, bool isHalf) { + if(nSize > 65536) + throw std::runtime_error("customCudaAddNCBiasInplaceNHWC: nSize too large"); + if(xySize > 65536) + throw std::runtime_error("customCudaAddNCBiasInplaceNHWC: xySize too large"); + + int sSize = xySize; + int cThreads; + int cBlocks; + int sThreads; + int sBlocks; + splitThreadsAcrossDim01(cSize, sSize, cThreads, cBlocks, sThreads, sBlocks); + + dim3 grid(cBlocks,sBlocks,nSize); + dim3 threads(cThreads,sThreads,1); + if(isHalf) + addNCBiasInplaceNHWCHalfKernel<<>>((half*)buf,(const half*)biases,sSize,cSize); + else + addNCBiasInplaceNHWCKernel<<>>((float*)buf,(const float*)biases,sSize,cSize); +} + +void customCudaAddNCBiasInplaceNHWC(float *buf, const float* biases, int nSize, int xySize, int cSize) { + sharedAddNCBiasInplaceNHWC(buf,biases,nSize,xySize,cSize,false); +} +void customCudaAddNCBiasInplaceNHWC(half *buf, const half* biases, int nSize, int xySize, int cSize) { + sharedAddNCBiasInplaceNHWC(buf,biases,nSize,xySize,cSize,true); +} + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void applyCScaleBiasNCHWKernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = in[idx] * scale[cIdx] + biases[cIdx]; + } +} +__global__ +void applyCScaleBiasNCHWReluKernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f); + } +} +__global__ +void applyCScaleBiasNCHWMishKernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]); + } +} +__global__ +void applyCScaleBiasNCHWMishScale8Kernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]); + } +} +__global__ +void applyCScaleBiasNCHWMaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = (in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNCHWReluMaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNCHWMishMaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNCHWMishScale8MaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) +{ + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNCHWHalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = __hfma(in[idx],scale[cIdx],biases[cIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWReluHalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); + const half halfzero = __float2half(0.0f); + out[idx] = __hgt(a,halfzero) ? a : halfzero; + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWMishHalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); + out[idx] = mishh(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWMishScale8HalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); + out[idx] = mishh_scale8(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWMaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + out[idx] = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWReluMaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + const half halfzero = __float2half(0.0f); + out[idx] = __hgt(a,halfzero) ? a : halfzero; + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWMishMaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + out[idx] = mishh(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNCHWMishScale8MaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int sIdx = blockIdx.x * blockDim.x + threadIdx.x; + int cIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * cSize + cIdx) * sSize + sIdx; + half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + out[idx] = mishh_scale8(a); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void sharedApplyCScaleBiasNCHW(const void* in, void* out, const void* scale, const void* biases, const void* mask, int nSize, int cSize, int xySize, bool isHalf, int activation) { + if(nSize > 65536) + throw std::runtime_error("customCudaApplyCScaleBiasNCHW: nSize too large"); + if(cSize > 65536) + throw std::runtime_error("customCudaApplyCScaleBiasNCHW: cSize too large"); + + int sSize = xySize; + int sThreads; + int sBlocks; + int cThreads; + int cBlocks; + splitThreadsAcrossDim01(sSize, cSize, sThreads, sBlocks, cThreads, cBlocks); + + dim3 grid(sBlocks,cBlocks,nSize); + dim3 threads(sThreads,cThreads,1); + if(mask == NULL) { + if(activation == ACTIVATION_IDENTITY) { + if(isHalf) + applyCScaleBiasNCHWHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); + else + applyCScaleBiasNCHWKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); + } + else if(activation == ACTIVATION_RELU) { + if(isHalf) + applyCScaleBiasNCHWReluHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); + else + applyCScaleBiasNCHWReluKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); + } + else if(activation == ACTIVATION_MISH) { + if(isHalf) + applyCScaleBiasNCHWMishHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); + else + applyCScaleBiasNCHWMishKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); + } + else if(activation == ACTIVATION_MISH_SCALE8) { + if(isHalf) + applyCScaleBiasNCHWMishScale8HalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); + else + applyCScaleBiasNCHWMishScale8Kernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); + } + else { + throw std::runtime_error("customCudaApplyCScaleBiasNCHW: unsupported activation"); + } + } + else { + if(activation == ACTIVATION_IDENTITY) { + if(isHalf) + applyCScaleBiasNCHWMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); + else + applyCScaleBiasNCHWMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); + } + else if(activation == ACTIVATION_RELU) { + if(isHalf) + applyCScaleBiasNCHWReluMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); + else + applyCScaleBiasNCHWReluMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); + } + else if(activation == ACTIVATION_MISH) { + if(isHalf) + applyCScaleBiasNCHWMishMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); + else + applyCScaleBiasNCHWMishMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); + } + else if(activation == ACTIVATION_MISH_SCALE8) { + if(isHalf) + applyCScaleBiasNCHWMishScale8MaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); + else + applyCScaleBiasNCHWMishScale8MaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); + } + else { + throw std::runtime_error("customCudaApplyCScaleBiasNCHW: unsupported activation"); + } + } +} + +void customCudaApplyCScaleBiasNCHW(const float* in, float* out, const float* scale, const float* biases, const float* mask, int nSize, int cSize, int xySize, int activation) { + sharedApplyCScaleBiasNCHW(in,out,scale,biases,mask,nSize,cSize,xySize,false,activation); +} +void customCudaApplyCScaleBiasNCHW(const half* in, half* out, const half* scale, const half* biases, const half* mask, int nSize, int cSize, int xySize, int activation) { + sharedApplyCScaleBiasNCHW(in,out,scale,biases,mask,nSize,cSize,xySize,true,activation); +} + + +//-------------------------------------------------------------------------------------------------------------- + +__global__ +void applyCScaleBiasNHWCKernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = in[idx] * scale[cIdx] + biases[cIdx]; + } +} +__global__ +void applyCScaleBiasNHWCReluKernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f); + } +} +__global__ +void applyCScaleBiasNHWCMishKernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]); + } +} +__global__ +void applyCScaleBiasNHWCMishScale8Kernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]); + } +} +__global__ +void applyCScaleBiasNHWCMaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = (in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNHWCReluMaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNHWCMishMaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNHWCMishScale8MaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) +{ + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; + } +} +__global__ +void applyCScaleBiasNHWCHalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = __hfma(in[idx],scale[cIdx],biases[cIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCReluHalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); + const half halfzero = __float2half(0.0f); + out[idx] = __hgt(a,halfzero) ? a : halfzero; + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCMishHalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); + out[idx] = mishh(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCMishScale8HalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); + out[idx] = mishh_scale8(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCMaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + out[idx] = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCReluMaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + const half halfzero = __float2half(0.0f); + out[idx] = __hgt(a,halfzero) ? a : halfzero; + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCMishMaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + out[idx] = mishh(a); + } +#else + //Do nothing, FP16 not supported +#endif +} +__global__ +void applyCScaleBiasNHWCMishScale8MaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) +{ +#ifdef HIP_SUPPORTS_FP16 + int cIdx = blockIdx.x * blockDim.x + threadIdx.x; + int sIdx = blockIdx.y * blockDim.y + threadIdx.y; + int nIdx = blockIdx.z; + if(cIdx < cSize && sIdx < sSize) { + int idx = (nIdx * sSize + sIdx) * cSize + cIdx; + half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); + out[idx] = mishh_scale8(a); + } +#else + //Do nothing, FP16 not supported +#endif +} + +void sharedApplyCScaleBiasNHWC(const void* in, void* out, const void* scale, const void* biases, const void* mask, int nSize, int xySize, int cSize, bool isHalf, int activation) { + if(nSize > 65536) + throw std::runtime_error("customCudaApplyCScaleBiasNHWC: nSize too large"); + if(xySize > 65536) + throw std::runtime_error("customCudaApplyCScaleBiasNHWC: xySize too large"); + + int sSize = xySize; + int cThreads; + int cBlocks; + int sThreads; + int sBlocks; + splitThreadsAcrossDim01(cSize, sSize, cThreads, cBlocks, sThreads, sBlocks); + + dim3 grid(cBlocks,sBlocks,nSize); + dim3 threads(cThreads,sThreads,1); + if(mask == NULL) { + if(activation == ACTIVATION_IDENTITY) { + if(isHalf) + applyCScaleBiasNHWCHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); + else + applyCScaleBiasNHWCKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); + } + else if(activation == ACTIVATION_RELU) { + if(isHalf) + applyCScaleBiasNHWCReluHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); + else + applyCScaleBiasNHWCReluKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); + } + else if(activation == ACTIVATION_MISH) { + if(isHalf) + applyCScaleBiasNHWCMishHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); + else + applyCScaleBiasNHWCMishKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); + } + else if(activation == ACTIVATION_MISH_SCALE8) { + if(isHalf) + applyCScaleBiasNHWCMishScale8HalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); + else + applyCScaleBiasNHWCMishScale8Kernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); + } + else { + throw std::runtime_error("customCudaApplyCScaleBiasNHWC: unsupported activation"); + } + } + else { + if(activation == ACTIVATION_IDENTITY) { + if(isHalf) + applyCScaleBiasNHWCMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); + else + applyCScaleBiasNHWCMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); + } + else if(activation == ACTIVATION_RELU) { + if(isHalf) + applyCScaleBiasNHWCReluMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); + else + applyCScaleBiasNHWCReluMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); + } + else if(activation == ACTIVATION_MISH) { + if(isHalf) + applyCScaleBiasNHWCMishMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); + else + applyCScaleBiasNHWCMishMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); + } + else if(activation == ACTIVATION_MISH_SCALE8) { + if(isHalf) + applyCScaleBiasNHWCMishScale8MaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); + else + applyCScaleBiasNHWCMishScale8MaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); + } + else { + throw std::runtime_error("customCudaApplyCScaleBiasNHWC: unsupported activation"); + } + } +} + +void customCudaApplyCScaleBiasNHWC(const float* in, float* out, const float* scale, const float* biases, const float* mask, int nSize, int xySize, int cSize, int activation) { + sharedApplyCScaleBiasNHWC(in,out,scale,biases,mask,nSize,xySize,cSize,false,activation); +} +void customCudaApplyCScaleBiasNHWC(const half* in, half* out, const half* scale, const half* biases, const half* mask, int nSize, int xySize, int cSize, int activation) { + sharedApplyCScaleBiasNHWC(in,out,scale,biases,mask,nSize,xySize,cSize,true,activation); +} diff --git a/cpp/neuralnet/rocmincludes.h b/cpp/neuralnet/rocmincludes.h new file mode 100644 index 0000000000..8b494a37e1 --- /dev/null +++ b/cpp/neuralnet/rocmincludes.h @@ -0,0 +1,15 @@ +#ifndef NEURALNET_ROCMINCLUDES_H +#define NEURALNET_ROCMINCLUDES_H + +//Ensure that CUDA_API_PER_THREAD_DEFAULT_STREAM is always defined +//before any cuda headers are included so that we get the desired threading behavior for CUDA. + +#define CUDA_API_PER_THREAD_DEFAULT_STREAM +#include +#include + +#include +#include + + +#endif //NEURALNET_ROCMINCLUDES_H diff --git a/cpp/neuralnet/rocmutils.cpp b/cpp/neuralnet/rocmutils.cpp new file mode 100644 index 0000000000..752298b7ff --- /dev/null +++ b/cpp/neuralnet/rocmutils.cpp @@ -0,0 +1,170 @@ +#include "../neuralnet/rocmutils.h" + +#include +#include "../neuralnet/rocmerrorcheck.h" +#include "../neuralnet/rocmincludes.h" +#include "../neuralnet/rocmhelpers.h" + +#include "../external/half-2.2.0/include/half.hpp" + +//------------------------ +#include "../core/using.h" +//------------------------ + +using half_t = half_float::half; + +void CudaUtils::mallocOnDevice(const string& name, int numWeights, void*& deviceBuf, bool useFP16) { + if(useFP16) { + size_t halfBytes = numWeights * sizeof(half_t); + CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, halfBytes)); + } + else { + size_t floatBytes = numWeights * sizeof(float); + CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, floatBytes)); + } +} + +void CudaUtils::mallocAndCopyToDevice(const string& name, const vector& weights, void*& deviceBuf, bool useFP16) { + size_t numWeights = weights.size(); + if(useFP16) { + size_t halfBytes = numWeights * sizeof(half_t); + vector weightsHalf(weights.size()); + for(size_t i = 0; i(weights[i]); + CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, halfBytes)); + CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weightsHalf.data(), halfBytes, hipMemcpyHostToDevice)); + } + else { + size_t floatBytes = numWeights * sizeof(float); + CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, floatBytes)); + CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weights.data(), floatBytes, hipMemcpyHostToDevice)); + } +} + +void CudaUtils::mallocAndCopyToDevice(const string& name, const float* weights, int numWeights, void*& deviceBuf, bool useFP16) { + if(useFP16) { + size_t halfBytes = numWeights * sizeof(half_t); + vector weightsHalf(numWeights); + for(int i = 0; i(weights[i]); + CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, halfBytes)); + CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weightsHalf.data(), halfBytes, hipMemcpyHostToDevice)); + } + else { + size_t floatBytes = numWeights * sizeof(float); + CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, floatBytes)); + CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weights, floatBytes, hipMemcpyHostToDevice)); + } +} + +//Only use in testing, allocates an intermediate buffer in the case of FP16 which will be very slow. +void CudaUtils::expensiveCopyFromDevice(const string& name, float* weights, int numWeights, const void* deviceBuf, bool useFP16) { + if(useFP16) { + vector weightsHalf(numWeights); + size_t halfBytes = numWeights * sizeof(half_t); + CUDA_ERR(name.c_str(),hipMemcpy(weightsHalf.data(), deviceBuf, halfBytes, hipMemcpyDeviceToHost)); + for(int i = 0; i values(batchSize * cSize); + expensiveCopyFromDevice(name, values.data(), values.size(), deviceBuf, useFP16); + cout << "=========================================================" << endl; + cout << "TENSOR" << endl; + cout << name << endl; + cout << std::setprecision(8); + int i = 0; + for(int n = 0; n values(batchSize * cSize * xSize * ySize); + expensiveCopyFromDevice(name, values.data(), values.size(), deviceBuf, useFP16); + cout << "=========================================================" << endl; + cout << "TENSOR" << endl; + cout << name << endl; + cout << std::setprecision(8); + int i = 0; + double total1 = 0; + double total2 = 0; + double total3 = 0; + for(int n = 0; n= (int64_t)1 << 31) + throw StringError("Batch size too large, resulting GPU buffers might exceed 2^31 entries which is not currently supported"); +} + +void CudaUtils::hostMallocZeroOneBufs(void*& zeroBuf, void*& oneBuf, bool useFP16) { + if(!useFP16) { + zeroBuf = malloc(sizeof(float)); + oneBuf = malloc(sizeof(float)); + *((float*)zeroBuf) = 0.0f; + *((float*)oneBuf) = 1.0f; + } + else { + //Convert to FP16 on the device, then copy back so we have it in host memory + float zero = 0.0f; + float one = 1.0f; + void* zeroTmp; + void* oneTmp; + mallocAndCopyToDevice("Buffers",&zero,1,zeroTmp,useFP16); + mallocAndCopyToDevice("Buffers",&one,1,oneTmp,useFP16); + zeroBuf = malloc(sizeof(half_t)); + oneBuf = malloc(sizeof(half_t)); + CUDA_ERR("Buffers",hipMemcpy(zeroBuf,zeroTmp,sizeof(half_t),hipMemcpyDeviceToHost)); + CUDA_ERR("Buffers",hipMemcpy(oneBuf,oneTmp,sizeof(half_t),hipMemcpyDeviceToHost)); + hipFree(zeroTmp); + hipFree(oneTmp); + } +} diff --git a/cpp/neuralnet/rocmutils.h b/cpp/neuralnet/rocmutils.h new file mode 100644 index 0000000000..d438684026 --- /dev/null +++ b/cpp/neuralnet/rocmutils.h @@ -0,0 +1,21 @@ +#ifndef NEURALNET_ROCMUTILS_H +#define NEURALNET_ROCMUTILS_H + +#include "../core/global.h" + +namespace CudaUtils { + void mallocOnDevice(const std::string& name, int numWeights, void*& deviceBuf, bool useFP16); + void mallocAndCopyToDevice(const std::string& name, const std::vector& weights, void*& deviceBuf, bool useFP16); + void mallocAndCopyToDevice(const std::string& name, const float* weights, int numWeights, void*& deviceBuf, bool useFP16); + + //Only use in testing, allocates an intermediate buffer in the case of FP16 which will be very slow. + void expensiveCopyFromDevice(const std::string& name, float* weights, int numWeights, const void* deviceBuf, bool useFP16); + + void debugPrint2D(const std::string& name, const void* deviceBuf, int batchSize, int cSize, bool useFP16); + void debugPrint4D(const std::string& name, const void* deviceBuf, int batchSize, int cSize, int xSize, int ySize, bool useNHWC, bool useFP16); + + void checkBufferSize(int batchSize, int xSize, int ySize, int channels); + void hostMallocZeroOneBufs(void*& zeroBuf, void*& oneBuf, bool useFP16); +} + +#endif // NEURALNET_ROCMUTILS_H From b4555304ee827059fda2ee1fbbad323e0e18e717 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 28 Jul 2025 20:28:51 +0200 Subject: [PATCH 02/37] Fix bugs --- cpp/CMakeLists.txt | 33 +++++++++++++++------------------ cpp/neuralnet/rocmbackend.cpp | 2 +- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index e12b7e41bf..13c1f39551 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -32,7 +32,6 @@ endif() set(BUILD_DISTRIBUTED 0 CACHE BOOL "Build with http support for contributing to distributed training") set(USE_BACKEND CACHE STRING "Neural net backend") string(TOUPPER "${USE_BACKEND}" USE_BACKEND) -# set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN) set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN ROCM) set(USE_TCMALLOC 0 CACHE BOOL "Use TCMalloc") @@ -140,40 +139,39 @@ elseif(USE_BACKEND STREQUAL "EIGEN") set(NEURALNET_BACKEND_SOURCES neuralnet/eigenbackend.cpp ) -# --------------------------- ROCM 后端(AMD GPU / HIP MIOpen) --------------------------- +# --------------------------- ROCM backend(AMD GPU / HIP MIOpen) --------------------------- elseif(USE_BACKEND STREQUAL "ROCM") message(STATUS "-DUSE_BACKEND=ROCM, using AMD ROCm backend.") - # 1) 启用 HIP 语言(.hip / .cpp 均可)并指定 C++17 enable_language(HIP) set(CMAKE_HIP_STANDARD 17) if(CMAKE_PREFIX_PATH STREQUAL "" OR NOT DEFINED CMAKE_PREFIX_PATH) if(DEFINED ENV{HIP_PATH}) - # Windows HIP‑SDK 或自定义安装 + # Windows HIP‑SDK list(APPEND CMAKE_PREFIX_PATH $ENV{HIP_PATH}) message(STATUS "Auto‑detected HIP_PATH=$ENV{HIP_PATH} → CMAKE_PREFIX_PATH") elseif(EXISTS "/opt/rocm") - # Linux 默认路径 + # Linux list(APPEND CMAKE_PREFIX_PATH "/opt/rocm") message(STATUS "CMAKE_PREFIX_PATH not given; defaulting to /opt/rocm") endif() endif() - # 可让用户用 -DCMAKE_HIP_ARCHITECTURES=gfx90a;gfx942 手动指定 GFX 架构 + # Users can -DCMAKE_HIP_ARCHITECTURES=gfx90a;gfx942 manually specify GFX architectures if(NOT DEFINED CMAKE_HIP_ARCHITECTURES) - # 默认同时编译常见 MI200 / RDNA3 卡,可按需精简 + # Default compile MI200 / RDNA3 cards, can be simplified as needed set(CMAKE_HIP_ARCHITECTURES 90a 942 908 1100 1101 1200 1201 CACHE STRING "AMD GPU targets") endif() - # 2) 指定后端源码。rocmhelpers.hip 里是 GPU‑kernel,别漏了 + # 2) Specify backend source code. rocmhelpers.hip contains GPU kernels, don't forget it set(NEURALNET_BACKEND_SOURCES neuralnet/rocmbackend.cpp neuralnet/rocmutils.cpp neuralnet/rocmhelpers.hip ) - # 可选:启用 model-size‑based autotuning等额外宏 + # Optional: Enable model-size‑based autotuning and other macros # add_compile_definitions(HIP_SUPPORTS_FP16) elseif(USE_BACKEND STREQUAL "") @@ -455,9 +453,9 @@ elseif(USE_BACKEND STREQUAL "OPENCL") link_directories(${OpenCL_LIBRARY}) target_link_libraries(katago ${OpenCL_LIBRARY}) endif() -# --------------------------- ROCM 链接阶段 --------------------------- +# --------------------------- ROCM linking stage --------------------------- elseif(USE_BACKEND STREQUAL "ROCM") - # 宏:源代码里用 #ifdef USE_ROCM_BACKEND 判断 + # Macro: used in source code with #ifdef USE_ROCM_BACKEND target_compile_definitions(katago PRIVATE USE_ROCM_BACKEND) target_compile_definitions(katago PRIVATE HIP_TARGET_VERSION=${CMAKE_HIP_COMPILER_VERSION}) @@ -467,12 +465,11 @@ elseif(USE_BACKEND STREQUAL "ROCM") message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") endif() - # 3) 找到 ROCm 运行时 & 库。自 ROCm 6.x 起都带 CMake config‑mode 包 - # 如若找不到,加 -DCMAKE_PREFIX_PATH=/opt/rocm - find_package(hip QUIET CONFIG) # 导出 hip::device / hip::host - find_package(hipblas QUIET CONFIG) # 导出 roc::hipblas - find_package(miopen QUIET CONFIG) # 导出 roc::miopen - # ---------- fallback:HIP 运行时 ---------- + # 3) Find ROCm runtime & libraries. Since ROCm 6.x, CMake config-mode packages are included. If not found, add -DCMAKE_PREFIX_PATH=/opt/rocm + find_package(hip QUIET CONFIG) # Export hip::device / hip::host + find_package(hipblas QUIET CONFIG) # Export roc::hipblas + find_package(miopen QUIET CONFIG) # Export roc::miopen + # ---------- fallback:HIP Runtime ---------- if(NOT hip_FOUND) find_path(HIP_INCLUDE_DIR hip/hip_runtime.h HINTS ${CMAKE_PREFIX_PATH} /opt/rocm @@ -507,7 +504,7 @@ elseif(USE_BACKEND STREQUAL "ROCM") endif() endforeach() - # 4) 头文件路径已由 config‑mode target 解决,无需硬编码 + # 4) Header file paths are resolved by config-mode targets, no need to hard-code target_link_libraries(katago hip::device # HIP runtime & kernel offload roc::hipblas # BLAS diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 11489e85af..f8f80a9a1e 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -1,5 +1,5 @@ #include "hip/hip_runtime.h" -// #ifdef USE_ROCM_BACKEND +#ifdef USE_ROCM_BACKEND #include #include #include From 8b30cb965f3586151a0cd517ec6cc63bd8ac0946 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Thu, 31 Jul 2025 23:53:18 +0200 Subject: [PATCH 03/37] Update --- cpp/CMakeLists.txt | 8 +- cpp/command/benchmark.cpp | 5 + cpp/neuralnet/rocmbackend.cpp | 178 ++++++++++++++++++++------------- cpp/neuralnet/rocmerrorcheck.h | 4 +- cpp/neuralnet/rocmhelpers.hip | 2 +- cpp/program/gtpconfig.cpp | 3 + cpp/program/setup.cpp | 3 + 7 files changed, 131 insertions(+), 72 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 13c1f39551..471a67a5f5 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.18.2) if(USE_BACKEND STREQUAL "METAL") project(katago LANGUAGES CXX Swift) +elseif(USE_BACKEND STREQUAL "ROCM") + set(CMAKE_C_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) + set(CMAKE_CXX_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) + project(katago LANGUAGES C CXX HIP) else() project(katago) endif() @@ -509,7 +513,7 @@ elseif(USE_BACKEND STREQUAL "ROCM") hip::device # HIP runtime & kernel offload roc::hipblas # BLAS MIOpen - roc::miopen # DNN primitives + # roc::miopen # DNN primitives ) elseif(USE_BACKEND STREQUAL "EIGEN") target_compile_definitions(katago PRIVATE USE_EIGEN_BACKEND) @@ -640,7 +644,7 @@ if(MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") message(STATUS "Setting up build for GNU, Clang or MinGW.") - if(NOT (${CMAKE_SYSTEM_PROCESSOR} MATCHES "(arm|aarch32|aarch64)")) + if(NOT (${CMAKE_SYSTEM_PROCESSOR} MATCHES "(arm|aarch32|aarch64)") AND NOT USE_BACKEND STREQUAL "ROCM") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse") else() # For ARM architecture, as a hack, ensure that char is signed diff --git a/cpp/command/benchmark.cpp b/cpp/command/benchmark.cpp index 949a436fc5..cf87303ebf 100644 --- a/cpp/command/benchmark.cpp +++ b/cpp/command/benchmark.cpp @@ -265,6 +265,11 @@ int MainCmds::benchmark(const vector& args) { cout << "If you have a strong GPU capable of FP16 tensor cores (e.g. RTX2080), " << "using the Cuda version of KataGo instead may give a mild performance boost." << endl; #endif +#ifdef USE_ROCM_BACKEND + cout << "You are currently using the ROCm version of KataGo." << endl; + cout << "If you have a strong GPU capable of FP16 tensor cores (e.g. RX6900XT), " + << "using the ROCm version of KataGo instead may give a mild performance boost." << endl; +#endif #ifdef USE_EIGEN_BACKEND cout << "You are currently using the Eigen (CPU) version of KataGo. Due to having no GPU, it may be slow." << endl; #endif diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index f8f80a9a1e..59022e2b74 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -1,5 +1,5 @@ -#include "hip/hip_runtime.h" #ifdef USE_ROCM_BACKEND +#include "hip/hip_runtime.h" #include #include #include @@ -41,7 +41,7 @@ void NeuralNet::globalCleanup() { struct CudaHandles { hipblasHandle_t cublas; - miopenStatus_t cudnn; + miopenHandle_t cudnn; const int majorComputeCapability; const int minorComputeCapability; @@ -142,38 +142,38 @@ struct ByBatchSizeView { //channels, useFP16, useNHWC typedef std::tuple CudnnTensorDesc4DKey; -struct CudnnTensorDesc4DKey { - int channels; - bool useFP16; - bool useNHWC; - bool operator<(const CudnnTensorDesc4DKey& other) const { - return std::tie(channels, useFP16, useNHWC) < - std::tie(other.channels, other.useFP16, other.useNHWC); - } -}; - -template -struct ByBatchSize { - explicit ByBatchSize(int max) - : data(max + 1), destroyFunc(nullptr) {} - ~ByBatchSize() { - if (destroyFunc) { - for (auto& d : data) { - if (d) destroyFunc(d); - } - } - } - T& operator[](int idx) { return data[idx]; } - std::vector data; - miopenStatus_t (*destroyFunc)(T) = nullptr; -}; - -template -struct ByBatchSizeView { - explicit ByBatchSizeView(ByBatchSize& ref) : ref(ref) {} - T& operator[](int idx) { return ref[idx]; } - ByBatchSize& ref; -}; +// struct CudnnTensorDesc4DKey { +// int channels; +// bool useFP16; +// bool useNHWC; +// bool operator<(const CudnnTensorDesc4DKey& other) const { +// return std::tie(channels, useFP16, useNHWC) < +// std::tie(other.channels, other.useFP16, other.useNHWC); +// } +// }; + +// template +// struct ByBatchSize { +// explicit ByBatchSize(int max) +// : data(max + 1), destroyFunc(nullptr) {} +// ~ByBatchSize() { +// if (destroyFunc) { +// for (auto& d : data) { +// if (d) destroyFunc(d); +// } +// } +// } +// T& operator[](int idx) { return data[idx]; } +// std::vector data; +// miopenStatus_t (*destroyFunc)(T) = nullptr; +// }; + +// template +// struct ByBatchSizeView { +// explicit ByBatchSizeView(ByBatchSize& ref) : ref(ref) {} +// T& operator[](int idx) { return ref[idx]; } +// ByBatchSize& ref; +// }; // ----------------------------------------------------------------------------- // CudnnManager @@ -356,14 +356,28 @@ struct ConvLayer { bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); - CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( - filterDescriptor, - (useFP16 ? miopenHalf : miopenFloat), - outChannels, - inChannels, - convYSize, - convXSize - )); + int lens[4]; + if (filterNHWC) { // cuDNN 的 OHWI + lens[0] = outChannels; // O + lens[1] = convYSize; // H + lens[2] = convXSize; // W + lens[3] = inChannels; // I + CUDNN_ERR(name.c_str(),miopenSetNdTensorDescriptorWithLayout( + filterDescriptor, + useFP16 ? miopenHalf : miopenFloat, + miopenTensorNHWC, // 指定布局 + lens, + 4)); + } else { + CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( + filterDescriptor, + (useFP16 ? miopenHalf : miopenFloat), + outChannels, + inChannels, + convYSize, + convXSize + )); // cuDNN 的 OIHW + }// cuDNN 的 OIHW int yStride = 1; int xStride = 1; @@ -383,21 +397,38 @@ struct ConvLayer { )); if(useFP16) { int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs - miopenSetConvolutionAttribute(convolutionDescriptor, + CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor, MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL, - alt); + alt)); } convolutionAlgorithms = new ByBatchSize(maxBatchSize); for(int batchSize = 1; batchSize <= maxBatchSize; ++batchSize) { if(useFP16 && dilationX <= 1 && dilationY <= 1) { - (*convolutionAlgorithms)[batchSize] = miopenConvolutionFwdAlgoImplicitGEMM; + // 手动填充最简单的 Perf 结构体 + miopenConvAlgoPerf_t perf = {}; + perf.fwd_algo = miopenConvolutionFwdAlgoImplicitGEMM; // 固定算法 + perf.memory = 0; // 需 0 workspace + perf.time = 0.0f; // 不做基准 + (*convolutionAlgorithms)[batchSize] = perf; + continue; } else { - (*convolutionAlgorithms)[batchSize] = miopenConvolutionFwdAlgoDirect; - // If desired, call miopenFindConvolutionForwardAlgorithm() here once you - // have real device buffers to auto‑tune. See porting notes. + miopenConvAlgoPerf_t perfResults[4]; + int returnedAlgoCount = 0; + CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( + handle, + xDesc, inputBuf, + wDesc, filterBuf, + convDesc, + yDesc, outputBuf, + /*requestAlgoCount=*/1, // 只要最快 + &returnedAlgoCount, + perfResults, + workspaceBuf, + wsSize, + /*exhaustiveSearch=*/true)); } } @@ -643,21 +674,34 @@ struct MatMulLayer { )); } else { - const half* alpha = (const half*)scratch->oneBuf; - const half* beta = (const half*)scratch->zeroBuf; - CUBLAS_ERR(name.c_str(),hipblasHgemm( + // const half* alpha = (const half*)scratch->oneBuf; + // const half* beta = (const half*)scratch->zeroBuf; + // CUBLAS_ERR(name.c_str(),hipblasHgemm( + // cudaHandles->cublas, + // HIPBLAS_OP_N, + // HIPBLAS_OP_N, + // outChannels, + // batchSize, + // inChannels, + // alpha, + // (const half*)matBuf,outChannels, + // (const half*)inputBuf,inChannels, + // beta, + // (half*)outputBuf,outChannels + // )); + static const half alpha_h = half(1.0f); + static const half beta_h = half(0.0f); + CUBLAS_ERR(name.c_str(), hipblasGemmEx( cudaHandles->cublas, - HIPBLAS_OP_N, - HIPBLAS_OP_N, - outChannels, - batchSize, - inChannels, - alpha, - (const half*)matBuf,outChannels, - (const half*)inputBuf,inChannels, - beta, - (half*)outputBuf,outChannels - )); + HIPBLAS_OP_N, HIPBLAS_OP_N, + outChannels, batchSize, inChannels, + &alpha_h, + (const half*)matBuf, HIPBLAS_R_16F, outChannels, + (const half*)inputBuf, HIPBLAS_R_16F, inChannels, + &beta_h, + (half*)outputBuf, HIPBLAS_R_16F, outChannels, + HIPBLAS_R_16F, /* compute_type */ + HIPBLAS_GEMM_DEFAULT)); /* algo */ } } @@ -2365,7 +2409,7 @@ ComputeHandle* NeuralNet::createComputeHandle( //Old GPUs - use FP32 and explicitly fail if FP16 enabled if(prop.major < 5 || (prop.major == 5 && prop.minor < 3)) { if(context->useFP16Mode == enabled_t::True) - throw StringError("Cuda device versions below 5.3 do not support useFP16=true"); + throw StringError("ROCm device versions below 6.0 do not support useFP16=true"); if(context->useNHWCMode == enabled_t::True) useNHWC = true; } @@ -2395,18 +2439,18 @@ ComputeHandle* NeuralNet::createComputeHandle( if(logger != NULL) { logger->write( - "Cuda backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) + " memory " + Global::uint64ToString(prop.totalGlobalMem) + " compute capability major " + Global::intToString(prop.major) + " minor " + Global::intToString(prop.minor) ); logger->write( - "Cuda backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion) + + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion) + " useFP16 = " + Global::boolToString(useFP16) + " useNHWC = " + Global::boolToString(useNHWC) ); logger->write( - "Cuda backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name ); } @@ -2432,7 +2476,7 @@ void NeuralNet::printDevices() { for(int i = 0; i -#if defined(__HIP_ARCH_HAS_FP16__) || (defined(__HIP_DEVICE_COMPILE__) && (__HIP_ARCH_GFX803__ || __HIP_ARCH_GFX900__ || ...)) +#if defined(__HIP_ARCH_HAS_FP16__) || (defined(__HIP_DEVICE_COMPILE__) && (__HIP_ARCH_GFX803__ || __HIP_ARCH_GFX900__)) #define HIP_SUPPORTS_FP16 #endif diff --git a/cpp/program/gtpconfig.cpp b/cpp/program/gtpconfig.cpp index 7a45c02ded..d8f1decf3b 100644 --- a/cpp/program/gtpconfig.cpp +++ b/cpp/program/gtpconfig.cpp @@ -535,6 +535,9 @@ string GTPConfig::makeConfig( #endif #ifdef USE_OPENCL_BACKEND replacement += "openclDeviceToUseThread" + Global::intToString(i) + " = " + Global::intToString(deviceIdxs[i]) + "\n"; +#endif +#ifdef USE_ROCM_BACKEND + replacement += "rocmDeviceToUseThread" + Global::intToString(i) + " = " + Global::intToString(deviceIdxs[i]) + "\n"; #endif } replace("$$MULTIPLE_GPUS", replacement); diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index e0f6e6ced4..9c423771b0 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -19,6 +19,7 @@ std::vector Setup::getBackendPrefixes() { prefixes.push_back("trt"); prefixes.push_back("metal"); prefixes.push_back("opencl"); + prefixes.push_back("rocm"); prefixes.push_back("eigen"); prefixes.push_back("dummybackend"); return prefixes; @@ -86,6 +87,8 @@ vector Setup::initializeNNEvaluators( string backendPrefix = "metal"; #elif defined(USE_OPENCL_BACKEND) string backendPrefix = "opencl"; + #elif defined(USE_ROCM_BACKEND) + string backendPrefix = "rocm"; #elif defined(USE_EIGEN_BACKEND) string backendPrefix = "eigen"; #else From 570ced01af2dc02cc09bbef6ec0bc51c8dcf6c10 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Fri, 1 Aug 2025 18:48:11 +0200 Subject: [PATCH 04/37] Fix bugs --- cpp/neuralnet/rocmbackend.cpp | 348 +++++++++++++--------------------- cpp/program/setup.cpp | 2 +- 2 files changed, 134 insertions(+), 216 deletions(-) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 59022e2b74..a6bc8862c4 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -7,9 +7,9 @@ #include "../neuralnet/rocmerrorcheck.h" #include "../neuralnet/rocmincludes.h" + #include "../neuralnet/rocmhelpers.h" #include "../neuralnet/rocmutils.h" - #include "../neuralnet/modelversion.h" #include "../neuralnet/nninterface.h" #include "../neuralnet/nninputs.h" @@ -142,105 +142,54 @@ struct ByBatchSizeView { //channels, useFP16, useNHWC typedef std::tuple CudnnTensorDesc4DKey; -// struct CudnnTensorDesc4DKey { -// int channels; -// bool useFP16; -// bool useNHWC; -// bool operator<(const CudnnTensorDesc4DKey& other) const { -// return std::tie(channels, useFP16, useNHWC) < -// std::tie(other.channels, other.useFP16, other.useNHWC); -// } -// }; - -// template -// struct ByBatchSize { -// explicit ByBatchSize(int max) -// : data(max + 1), destroyFunc(nullptr) {} -// ~ByBatchSize() { -// if (destroyFunc) { -// for (auto& d : data) { -// if (d) destroyFunc(d); -// } -// } -// } -// T& operator[](int idx) { return data[idx]; } -// std::vector data; -// miopenStatus_t (*destroyFunc)(T) = nullptr; -// }; - -// template -// struct ByBatchSizeView { -// explicit ByBatchSizeView(ByBatchSize& ref) : ref(ref) {} -// T& operator[](int idx) { return ref[idx]; } -// ByBatchSize& ref; -// }; - -// ----------------------------------------------------------------------------- -// CudnnManager -// ----------------------------------------------------------------------------- struct CudnnManager { - const std::string name; + const string name; const int maxBatchSize; const int nnXLen; const int nnYLen; - std::map*> - tensorDesc4DByBatchSizeByKey; - - CudnnManager(std::string name_, int maxBatchSize_, int nnXLen_, int nnYLen_) - : name(std::move(name_)), - maxBatchSize(maxBatchSize_), - nnXLen(nnXLen_), - nnYLen(nnYLen_), - tensorDesc4DByBatchSizeByKey() {} + std::map*> tensorDesc4DByBatchSizeByKey; + + CudnnManager(string name_, int maxBatchSize_, int nnXLen_, int nnYLen_) + :name(name_), + maxBatchSize(maxBatchSize_), + nnXLen(nnXLen_), + nnYLen(nnYLen_), + tensorDesc4DByBatchSizeByKey() + { + } ~CudnnManager() { - for (auto& iter : tensorDesc4DByBatchSizeByKey) { + for(auto& iter: tensorDesc4DByBatchSizeByKey) { delete iter.second; } } ByBatchSizeView getTensorDesc4DByBatchSize( - int channels, bool useFP16, bool useNHWC) { + int channels, bool useFP16, bool useNHWC + ) { auto iter = tensorDesc4DByBatchSizeByKey.find({channels, useFP16, useNHWC}); - if (iter != tensorDesc4DByBatchSizeByKey.end()) { + if(iter != tensorDesc4DByBatchSizeByKey.end()) { return ByBatchSizeView(*(iter->second)); } - - auto* descs = new ByBatchSize(maxBatchSize); - - for (int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { + ByBatchSize* descs = new ByBatchSize(maxBatchSize); + for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { miopenTensorDescriptor_t& desc = (*descs)[batchSize]; - // Create descriptor - CUDNN_ERR(name.c_str(), miopenCreateTensorDescriptor(&desc)); - - const miopenDataType_t dtype = useFP16 ? miopenHalf : miopenFloat; - - if (!useNHWC) { - // Fully‑supported NCHW fast‑path - CUDNN_ERR(name.c_str(), - miopenSet4dTensorDescriptor(desc, dtype, batchSize, channels, - nnYLen, nnXLen)); - } else { - // NHWC path via generic Nd descriptor + explicit strides - int dims[4] = {batchSize, nnYLen, nnXLen, channels}; // N H W C - int strides[4]; - strides[3] = 1; // C stride - strides[2] = strides[3] * channels; // W stride - strides[1] = strides[2] * nnXLen; // H stride - strides[0] = strides[1] * nnYLen; // N stride - - CUDNN_ERR(name.c_str(), - miopenSetTensorDescriptor(desc, dtype, 4, dims, strides)); - } + CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&desc)); + CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( + desc, + (useFP16 ? miopenHalf : miopenFloat), + batchSize, + channels, + nnYLen, + nnXLen + )); } - descs->destroyFunc = miopenDestroyTensorDescriptor; tensorDesc4DByBatchSizeByKey[{channels, useFP16, useNHWC}] = descs; return ByBatchSizeView(*descs); } }; - //--------------------------------------------------------------------------------- struct ScratchBuffers { @@ -311,7 +260,7 @@ struct ConvLayer { ByBatchSizeView outputDescriptors; miopenTensorDescriptor_t filterDescriptor; miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size + ByBatchSize* convolutionAlgorithms; //array of one for each batch size void* filterBuf; ConvLayer() = delete; @@ -356,33 +305,18 @@ struct ConvLayer { bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); - int lens[4]; - if (filterNHWC) { // cuDNN 的 OHWI - lens[0] = outChannels; // O - lens[1] = convYSize; // H - lens[2] = convXSize; // W - lens[3] = inChannels; // I - CUDNN_ERR(name.c_str(),miopenSetNdTensorDescriptorWithLayout( - filterDescriptor, - useFP16 ? miopenHalf : miopenFloat, - miopenTensorNHWC, // 指定布局 - lens, - 4)); - } else { - CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( - filterDescriptor, - (useFP16 ? miopenHalf : miopenFloat), - outChannels, - inChannels, - convYSize, - convXSize - )); // cuDNN 的 OIHW - }// cuDNN 的 OIHW + CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( + filterDescriptor, + (useFP16 ? miopenHalf : miopenFloat), + outChannels, + inChannels, + convYSize, + convXSize + )); int yStride = 1; int xStride = 1; - bool tensorCoresSupported = true; CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( @@ -397,38 +331,64 @@ struct ConvLayer { )); if(useFP16) { int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs - CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor, - MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL, - alt)); + CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); } - convolutionAlgorithms = new ByBatchSize(maxBatchSize); + convolutionAlgorithms = new ByBatchSize(maxBatchSize); - for(int batchSize = 1; batchSize <= maxBatchSize; ++batchSize) { + for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { if(useFP16 && dilationX <= 1 && dilationY <= 1) { - // 手动填充最简单的 Perf 结构体 - miopenConvAlgoPerf_t perf = {}; - perf.fwd_algo = miopenConvolutionFwdAlgoImplicitGEMM; // 固定算法 - perf.memory = 0; // 需 0 workspace - perf.time = 0.0f; // 不做基准 - (*convolutionAlgorithms)[batchSize] = perf; + (*convolutionAlgorithms)[batchSize].fwd_algo = miopenConvolutionFwdAlgoImplicitGEMM; continue; } else { - miopenConvAlgoPerf_t perfResults[4]; - int returnedAlgoCount = 0; - CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( - handle, - xDesc, inputBuf, - wDesc, filterBuf, - convDesc, - yDesc, outputBuf, - /*requestAlgoCount=*/1, // 只要最快 + const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; + const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; + int requestedAlgoCount = 8; + int returnedAlgoCount = -1; + miopenConvFwdAlgorithm_t results[2 * requestedAlgoCount]; + miopenConvSolution_t solutions[2 * requestedAlgoCount]; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + &requestedAlgoCount + )); + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + requestedAlgoCount, &returnedAlgoCount, - perfResults, - workspaceBuf, - wsSize, - /*exhaustiveSearch=*/true)); + solutions + )); + if(returnedAlgoCount <= 0) + throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); + for (size_t i = 0; i < returnedAlgoCount; i++) { + if(solutions[i].algorithm == miopenConvolutionAlgoGEMM) { + results[i] = miopenConvolutionFwdAlgoGEMM; + } + else if(solutions[i].algorithm == miopenConvolutionAlgoDirect) { + results[i] = miopenConvolutionFwdAlgoDirect; + } + else if(solutions[i].algorithm == miopenConvolutionAlgoFFT) { + results[i] = miopenConvolutionFwdAlgoFFT; + } + else if(solutions[i].algorithm == miopenConvolutionAlgoWinograd) { + results[i] = miopenConvolutionFwdAlgoWinograd; + } + else if(solutions[i].algorithm == miopenConvolutionAlgoImplicitGEMM) { + results[i] = miopenConvolutionFwdAlgoImplicitGEMM; + } + else{ + throw StringError("Unknown miopenConvolutionFwdAlgo: " + std::to_string(solutions[i].algorithm)); + } + } + (*convolutionAlgorithms)[batchSize].fwd_algo = results[0]; } } @@ -465,43 +425,42 @@ struct ConvLayer { int batchSize ) const { size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(), miopenConvolutionForwardGetWorkSpaceSize( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptors[batchSize], - convolutionDescriptor, - outputDescriptors[batchSize], - &workspaceBytes)); + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptors[batchSize], + convolutionDescriptor, + outputDescriptors[batchSize], + &workspaceBytes + )); return workspaceBytes; } void apply( CudaHandles* cudaHandles, - int batchSize, - bool accumulate, // if true, beta = 1 (unsupported by MIOpen fwd) - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes) const -{ - const float alpha = 1.0f; - const float beta = accumulate ? 1.0f : 0.0f; - - // New MIOpen API order: ... algo, beta, yDesc, y, workSpace, workSpaceSize - CUDNN_ERR(name.c_str(), miopenConvolutionForward( - cudaHandles->cudnn, - &alpha, - inputDescriptors[batchSize], - inputBuf, - filterDescriptor, - filterBuf, - convolutionDescriptor, - (*convolutionAlgorithms)[batchSize], - &beta, - outputDescriptors[batchSize], - outputBuf, - workspaceBuf, - workspaceBytes)); + int batchSize, + bool accumulate, + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + const float alpha = 1.0f; + const float beta = accumulate ? 1.0f : 0.0f; + CUDNN_ERR(name.c_str(), miopenConvolutionForward( + cudaHandles->cudnn, + &alpha, + inputDescriptors[batchSize], + inputBuf, + filterDescriptor, + filterBuf, + convolutionDescriptor, + (*convolutionAlgorithms)[batchSize].fwd_algo, + &beta, + outputDescriptors[batchSize], + outputBuf, + workspaceBuf, + workspaceBytes)); } }; @@ -674,34 +633,21 @@ struct MatMulLayer { )); } else { - // const half* alpha = (const half*)scratch->oneBuf; - // const half* beta = (const half*)scratch->zeroBuf; - // CUBLAS_ERR(name.c_str(),hipblasHgemm( - // cudaHandles->cublas, - // HIPBLAS_OP_N, - // HIPBLAS_OP_N, - // outChannels, - // batchSize, - // inChannels, - // alpha, - // (const half*)matBuf,outChannels, - // (const half*)inputBuf,inChannels, - // beta, - // (half*)outputBuf,outChannels - // )); - static const half alpha_h = half(1.0f); - static const half beta_h = half(0.0f); - CUBLAS_ERR(name.c_str(), hipblasGemmEx( + const hipblasHalf* alpha = (const hipblasHalf*)scratch->oneBuf; + const hipblasHalf* beta = (const hipblasHalf*)scratch->zeroBuf; + CUBLAS_ERR(name.c_str(),hipblasHgemm( cudaHandles->cublas, - HIPBLAS_OP_N, HIPBLAS_OP_N, - outChannels, batchSize, inChannels, - &alpha_h, - (const half*)matBuf, HIPBLAS_R_16F, outChannels, - (const half*)inputBuf, HIPBLAS_R_16F, inChannels, - &beta_h, - (half*)outputBuf, HIPBLAS_R_16F, outChannels, - HIPBLAS_R_16F, /* compute_type */ - HIPBLAS_GEMM_DEFAULT)); /* algo */ + CUBLAS_OP_N, + CUBLAS_OP_N, + outChannels, + batchSize, + inChannels, + alpha, + (const hipblasHalf*)matBuf,outChannels, + (const hipblasHalf*)inputBuf,inChannels, + beta, + (hipblasHalf*)outputBuf,outChannels + )); } } @@ -2406,36 +2352,8 @@ ComputeHandle* NeuralNet::createComputeHandle( bool useFP16 = false; bool useNHWC = false; - //Old GPUs - use FP32 and explicitly fail if FP16 enabled - if(prop.major < 5 || (prop.major == 5 && prop.minor < 3)) { - if(context->useFP16Mode == enabled_t::True) - throw StringError("ROCm device versions below 6.0 do not support useFP16=true"); - if(context->useNHWCMode == enabled_t::True) - useNHWC = true; - } - //In theory these GPUs support FP16, so allow if the user wants. - else if(prop.major < 6) { - if(context->useFP16Mode == enabled_t::True) - useFP16 = true; - if(context->useNHWCMode == enabled_t::True) - useNHWC = true; - } - //On Pascal architecture, default to using FP16 operations - //Actually, just use FP32 - there's a risk that on certain cards this might just be a lot worse. - //A user manually fine-tuning for performance can just enable it themselves if they know how. - else if(prop.major < 7) { - if(context->useFP16Mode == enabled_t::True) - useFP16 = true; - if(context->useNHWCMode == enabled_t::True) - useNHWC = true; - } - //On Volta and higher, use FP16 and NHWC together because we have tensor cores. - else { - if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) - useFP16 = true; - if(context->useNHWCMode == enabled_t::True || (context->useNHWCMode == enabled_t::Auto && useFP16)) - useNHWC = true; - } + if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) + useFP16 = true; if(logger != NULL) { logger->write( diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index 9c423771b0..01a742f60f 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -144,7 +144,7 @@ vector Setup::initializeNNEvaluators( requireExactNNLen = cfg.getBool("requireMaxBoardSize"); } - bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" ? false : true; + bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" || backendPrefix == "rocm" ? false : true; if(cfg.contains(backendPrefix+"InputsUseNHWC"+idxStr)) inputsUseNHWC = cfg.getBool(backendPrefix+"InputsUseNHWC"+idxStr); else if(cfg.contains("inputsUseNHWC"+idxStr)) From abb61240eec638b6b955eb31cf514cedb1039a8b Mon Sep 17 00:00:00 2001 From: Looong01 Date: Fri, 1 Aug 2025 18:03:45 +0200 Subject: [PATCH 05/37] Fix bugs --- cpp/neuralnet/rocmbackend.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index a6bc8862c4..08857d76d9 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -1,9 +1,4 @@ #ifdef USE_ROCM_BACKEND -#include "hip/hip_runtime.h" -#include -#include -#include -#include #include "../neuralnet/rocmerrorcheck.h" #include "../neuralnet/rocmincludes.h" @@ -344,8 +339,8 @@ struct ConvLayer { else { const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - int requestedAlgoCount = 8; - int returnedAlgoCount = -1; + size_t requestedAlgoCount = 8; + size_t returnedAlgoCount = -1; miopenConvFwdAlgorithm_t results[2 * requestedAlgoCount]; miopenConvSolution_t solutions[2 * requestedAlgoCount]; CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( @@ -460,7 +455,8 @@ struct ConvLayer { outputDescriptors[batchSize], outputBuf, workspaceBuf, - workspaceBytes)); + workspaceBytes + )); } }; @@ -637,8 +633,8 @@ struct MatMulLayer { const hipblasHalf* beta = (const hipblasHalf*)scratch->zeroBuf; CUBLAS_ERR(name.c_str(),hipblasHgemm( cudaHandles->cublas, - CUBLAS_OP_N, - CUBLAS_OP_N, + HIPBLAS_OP_N, + HIPBLAS_OP_N, outChannels, batchSize, inChannels, From bfb292e7f85397e32b9b0eed64ff4a2e182a595d Mon Sep 17 00:00:00 2001 From: Looong01 Date: Fri, 1 Aug 2025 19:20:31 +0200 Subject: [PATCH 06/37] All bug fixed --- cpp/neuralnet/rocmbackend.cpp | 62 ++++++++++++++--------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 08857d76d9..260c2c72e8 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -255,7 +255,7 @@ struct ConvLayer { ByBatchSizeView outputDescriptors; miopenTensorDescriptor_t filterDescriptor; miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size + ByBatchSize* convolutionAlgorithms; //array of one for each batch size void* filterBuf; ConvLayer() = delete; @@ -329,19 +329,18 @@ struct ConvLayer { CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); } - convolutionAlgorithms = new ByBatchSize(maxBatchSize); + convolutionAlgorithms = new ByBatchSize(maxBatchSize); for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - if(useFP16 && dilationX <= 1 && dilationY <= 1) { - (*convolutionAlgorithms)[batchSize].fwd_algo = miopenConvolutionFwdAlgoImplicitGEMM; - continue; - } - else { + // if(useFP16 && dilationX <= 1 && dilationY <= 1) { + // (*convolutionAlgorithms)[batchSize].solution_id = 0; + // continue; + // } + // else { const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; size_t requestedAlgoCount = 8; size_t returnedAlgoCount = -1; - miopenConvFwdAlgorithm_t results[2 * requestedAlgoCount]; miopenConvSolution_t solutions[2 * requestedAlgoCount]; CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( cudaHandles->cudnn, @@ -363,28 +362,16 @@ struct ConvLayer { )); if(returnedAlgoCount <= 0) throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); - for (size_t i = 0; i < returnedAlgoCount; i++) { - if(solutions[i].algorithm == miopenConvolutionAlgoGEMM) { - results[i] = miopenConvolutionFwdAlgoGEMM; - } - else if(solutions[i].algorithm == miopenConvolutionAlgoDirect) { - results[i] = miopenConvolutionFwdAlgoDirect; - } - else if(solutions[i].algorithm == miopenConvolutionAlgoFFT) { - results[i] = miopenConvolutionFwdAlgoFFT; - } - else if(solutions[i].algorithm == miopenConvolutionAlgoWinograd) { - results[i] = miopenConvolutionFwdAlgoWinograd; - } - else if(solutions[i].algorithm == miopenConvolutionAlgoImplicitGEMM) { - results[i] = miopenConvolutionFwdAlgoImplicitGEMM; - } - else{ - throw StringError("Unknown miopenConvolutionFwdAlgo: " + std::to_string(solutions[i].algorithm)); - } - } - (*convolutionAlgorithms)[batchSize].fwd_algo = results[0]; - } + (*convolutionAlgorithms)[batchSize] = solutions[0]; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + (*convolutionAlgorithms)[batchSize].solution_id + )); + // } } assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); @@ -420,12 +407,13 @@ struct ConvLayer { int batchSize ) const { size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( cudaHandles->cudnn, filterDescriptor, inputDescriptors[batchSize], convolutionDescriptor, outputDescriptors[batchSize], + (*convolutionAlgorithms)[batchSize].solution_id, &workspaceBytes )); return workspaceBytes; @@ -442,20 +430,18 @@ struct ConvLayer { ) const { const float alpha = 1.0f; const float beta = accumulate ? 1.0f : 0.0f; - CUDNN_ERR(name.c_str(), miopenConvolutionForward( + CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( cudaHandles->cudnn, - &alpha, - inputDescriptors[batchSize], - inputBuf, filterDescriptor, filterBuf, + inputDescriptors[batchSize], + inputBuf, convolutionDescriptor, - (*convolutionAlgorithms)[batchSize].fwd_algo, - &beta, outputDescriptors[batchSize], outputBuf, workspaceBuf, - workspaceBytes + workspaceBytes, + (*convolutionAlgorithms)[batchSize].solution_id )); } From 4606424fa97a1dd73e8ebed13d4804bf773a5187 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Fri, 1 Aug 2025 19:23:26 +0200 Subject: [PATCH 07/37] Update --- cpp/neuralnet/rocmhelpers.h | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/neuralnet/rocmhelpers.h b/cpp/neuralnet/rocmhelpers.h index 215b1e9fd4..489142cfd3 100644 --- a/cpp/neuralnet/rocmhelpers.h +++ b/cpp/neuralnet/rocmhelpers.h @@ -1,4 +1,3 @@ -#include "hip/hip_runtime.h" #ifndef NEURALNET_ROCMHELPERS_H_ #define NEURALNET_ROCMHELPERS_H_ From 1e8ea78876cc57eec4ddfeffee8db8268865629f Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 01:03:25 +0200 Subject: [PATCH 08/37] test new method --- cpp/neuralnet/rocmbackend_new.cpp | 3016 +++++++++++++++++++++++++++++ 1 file changed, 3016 insertions(+) create mode 100644 cpp/neuralnet/rocmbackend_new.cpp diff --git a/cpp/neuralnet/rocmbackend_new.cpp b/cpp/neuralnet/rocmbackend_new.cpp new file mode 100644 index 0000000000..af1164f197 --- /dev/null +++ b/cpp/neuralnet/rocmbackend_new.cpp @@ -0,0 +1,3016 @@ +#ifdef USE_ROCM_BACKEND + +#include "../neuralnet/rocmerrorcheck.h" +#include "../neuralnet/rocmincludes.h" + +#include "../neuralnet/rocmhelpers.h" +#include "../neuralnet/rocmutils.h" +#include "../neuralnet/modelversion.h" +#include "../neuralnet/nninterface.h" +#include "../neuralnet/nninputs.h" +#include "../neuralnet/sgfmetadata.h" +#include "../neuralnet/nneval.h" +#include "../neuralnet/desc.h" + +#include "../core/simpleallocator.h" +#include "../core/test.h" + +#include "../external/half-2.2.0/include/half.hpp" + +//------------------------ +#include "../core/using.h" +//------------------------ + +using half_t = half_float::half; + +//Define this to print out some of the intermediate values of the neural net +//#define DEBUG_INTERMEDIATE_VALUES + +void NeuralNet::globalInitialize() { + //Empty for cudnn backend +} + +void NeuralNet::globalCleanup() { + hipDeviceReset(); +} + +struct CudaHandles { + hipblasHandle_t cublas; + miopenHandle_t cudnn; + const int majorComputeCapability; + const int minorComputeCapability; + + CudaHandles(int major, int minor) + : majorComputeCapability(major), + minorComputeCapability(minor) + { + CUBLAS_ERR("CudaHandles",hipblasCreate(&cublas)); + CUDNN_ERR("CudaHandles",miopenCreate(&cudnn)); + } + + ~CudaHandles() { + hipblasDestroy(cublas); + miopenDestroy(cudnn); + } + + static CudaHandles* cudaHandlesTesting() { + const int gpuIdxForThisThread = 0; + hipDeviceProp_t prop; + hipGetDeviceProperties(&prop,gpuIdxForThisThread); + return new CudaHandles(prop.major, prop.minor); + } + + CudaHandles(const CudaHandles&) = delete; + CudaHandles& operator=(const CudaHandles&) = delete; +}; + +//--------------------------------------------------------------------------------- + +template +struct ByBatchSize { + const int maxBatchSize; + T* data; + miopenStatus_t (*destroyFunc)(T); + + ByBatchSize() + : maxBatchSize(0), data(nullptr), destroyFunc(nullptr) + {} + + ByBatchSize( + int maxBatchSize_ + ) : maxBatchSize(maxBatchSize_), data(nullptr), destroyFunc(nullptr) { + data = new T[maxBatchSize]; + } + + ByBatchSize(const ByBatchSize&) = delete; + ByBatchSize& operator=(const ByBatchSize&) = delete; + + ~ByBatchSize() { + if(destroyFunc != nullptr && data != nullptr) { + for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { + (*destroyFunc)(data[batchSize-1]); + } + } + if(data != nullptr) { + delete[] data; + data = nullptr; + } + } + T& operator[](int batchSize) { + return data[batchSize-1]; + } + const T& operator[](int batchSize) const { + return data[batchSize-1]; + } +}; + +template +struct ByBatchSizeView { + int maxBatchSize; + T* data; + + ByBatchSizeView() + : maxBatchSize(0), data(nullptr) + {} + + ByBatchSizeView(const ByBatchSize& toView) + : maxBatchSize(toView.maxBatchSize), data(toView.data) + {} + ByBatchSizeView& operator=(const ByBatchSize& toView) { + maxBatchSize = toView.maxBatchSize; + data = toView.data; + } + + ~ByBatchSizeView() { + } + T& operator[](int batchSize) { + return data[batchSize-1]; + } + const T& operator[](int batchSize) const { + return data[batchSize-1]; + } +}; + +//--------------------------------------------------------------------------------- + + +//channels, useFP16, useNHWC +typedef std::tuple CudnnTensorDesc4DKey; + +struct CudnnManager { + const string name; + const int maxBatchSize; + const int nnXLen; + const int nnYLen; + std::map*> tensorDesc4DByBatchSizeByKey; + + CudnnManager(string name_, int maxBatchSize_, int nnXLen_, int nnYLen_) + :name(name_), + maxBatchSize(maxBatchSize_), + nnXLen(nnXLen_), + nnYLen(nnYLen_), + tensorDesc4DByBatchSizeByKey() + { + } + + ~CudnnManager() { + for(auto& iter: tensorDesc4DByBatchSizeByKey) { + delete iter.second; + } + } + + ByBatchSizeView getTensorDesc4DByBatchSize( + int channels, bool useFP16, bool useNHWC + ) { + auto iter = tensorDesc4DByBatchSizeByKey.find({channels, useFP16, useNHWC}); + if(iter != tensorDesc4DByBatchSizeByKey.end()) { + return ByBatchSizeView(*(iter->second)); + } + ByBatchSize* descs = new ByBatchSize(maxBatchSize); + for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { + miopenTensorDescriptor_t& desc = (*descs)[batchSize]; + CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&desc)); + CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( + desc, + (useFP16 ? miopenHalf : miopenFloat), + batchSize, + channels, + nnYLen, + nnXLen + )); + } + descs->destroyFunc = miopenDestroyTensorDescriptor; + tensorDesc4DByBatchSizeByKey[{channels, useFP16, useNHWC}] = descs; + return ByBatchSizeView(*descs); + } +}; + +//--------------------------------------------------------------------------------- + +struct ScratchBuffers { + + const size_t batchXYFloatBytes; + const size_t batchFloatBytes; + const size_t batchXYBytes; + const size_t batchBytes; + + SimpleAllocator* allocator; + + // Not scratch, but convenient to have here + void* zeroBuf; + void* oneBuf; + + ScratchBuffers() = delete; + ScratchBuffers(const ScratchBuffers&) = delete; + ScratchBuffers& operator=(const ScratchBuffers&) = delete; + + ScratchBuffers(int maxBatchSize, int nnXLen, int nnYLen, bool useFP16) + : batchXYFloatBytes((size_t)maxBatchSize * nnXLen * nnYLen * sizeof(float)), + batchFloatBytes((size_t)maxBatchSize * sizeof(float)), + batchXYBytes((size_t)maxBatchSize * nnXLen * nnYLen * (useFP16 ? sizeof(half_t) : sizeof(float))), + batchBytes((size_t)maxBatchSize * (useFP16 ? sizeof(half_t) : sizeof(float))) + { + std::function allocateFunc = [](size_t size) { + void* buf; + CUDA_ERR("ScratchBuffers",hipMalloc(&buf, size)); + return buf; + }; + std::function releaseFunc = [](void* buf) { + hipFree(buf); + }; + + allocator = new SimpleAllocator(allocateFunc, releaseFunc); + + CudaUtils::hostMallocZeroOneBufs(zeroBuf, oneBuf, useFP16); + } + ~ScratchBuffers() { + delete allocator; + free(zeroBuf); + free(oneBuf); + } + + size_t getBufSizeXY(int channels) const { + return channels * batchXYBytes; + } + size_t getBufSizeXYFloat(int channels) const { + return channels * batchXYFloatBytes; + } + size_t getBufSizeFloat(int channels) const { + return channels * batchFloatBytes; + } + size_t getBufSize(int channels) const { + return channels * batchBytes; + } + +}; + + +//--------------------------------------------------------------------------------- + +struct ConvLayer { + const string name; + const int inChannels; + const int outChannels; + ByBatchSizeView inputDescriptors; + ByBatchSizeView outputDescriptors; + miopenTensorDescriptor_t filterDescriptor; + miopenConvolutionDescriptor_t convolutionDescriptor; + ByBatchSize* convolutionAlgorithms; //array of one for each batch size + void* filterBuf; + void* inputTmp; + void* outputTmp; + void* workspaceTmp; + + ConvLayer() = delete; + ConvLayer(const ConvLayer&) = delete; + ConvLayer& operator=(const ConvLayer&) = delete; + + ConvLayer( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ConvLayerDesc* desc, + bool useFP16, + bool useNHWC + ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) + {} + + ConvLayer( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ConvLayerDesc* desc, + bool useFP16, + bool useNHWCIn, + bool useNHWCOut + ) : + name(desc->name), + inChannels(desc->inChannels), + outChannels(desc->outChannels) + { + int convYSize = desc->convYSize; + int convXSize = desc->convXSize; + int dilationY = desc->dilationY; + int dilationX = desc->dilationX; + int paddingX = (convXSize / 2) * dilationX; + int paddingY = (convYSize / 2) * dilationY; + + assert(convXSize % 2 == 1); + assert(convYSize % 2 == 1); + + inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); + outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); + int maxBatchSize = manager->maxBatchSize; + int xLen = manager->nnXLen; + int yLen = manager->nnYLen; + + bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; + + CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); + CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( + filterDescriptor, + (useFP16 ? miopenHalf : miopenFloat), + outChannels, + inChannels, + convYSize, + convXSize + )); + + int yStride = 1; + int xStride = 1; + + + CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); + CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( + convolutionDescriptor, + miopenConvolution, + paddingY, + paddingX, + yStride, + xStride, + dilationY, + dilationX + )); + if(useFP16) { + int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs + CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); + } + + convolutionAlgorithms = new ByBatchSize(maxBatchSize); + + size_t inBytes = maxBatchSize * inChannels * xLen * yLen; + size_t outBytes = maxBatchSize * outChannels * xLen * yLen; + size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize); + + CudaUtils::mallocOnDevice(name, inBytes, inputTmp, useFP16); + CudaUtils::mallocOnDevice(name, outBytes, outputTmp, useFP16); + CudaUtils::mallocOnDevice(name, workspaceBytes, workspaceTmp, useFP16); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + + for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { + // if(useFP16 && dilationX <= 1 && dilationY <= 1) { + // (*convolutionAlgorithms)[batchSize].fwd_algo = miopenConvolutionFwdAlgoGEMM; + // } + // else { + const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; + const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; + const int requestedAlgoCount = 8; + int returnedAlgoCount = -1; + miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; + CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( + cudaHandles->cudnn, + inputDescriptor, + inputTmp, + filterDescriptor, + filterBuf, + convolutionDescriptor, + outputDescriptor, + outputTmp, + requestedAlgoCount, + &returnedAlgoCount, + results, + workspaceTmp, + workspaceBytes, + true + )); + if(returnedAlgoCount <= 0) + throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); + (*convolutionAlgorithms)[batchSize] = results[0]; + printf("%d / %d\n", batchSize, maxBatchSize); + // } + } + + assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); + + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + } + + ~ConvLayer() { + hipFree(filterBuf); + hipFree(inputTmp); + hipFree(outputTmp); + hipFree(workspaceTmp); + miopenDestroyTensorDescriptor(filterDescriptor); + miopenDestroyConvolutionDescriptor(convolutionDescriptor); + delete convolutionAlgorithms; + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t workspaceBytes = 0; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptors[batchSize], + convolutionDescriptor, + outputDescriptors[batchSize], + &workspaceBytes + )); + return workspaceBytes; + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + bool accumulate, + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + const float alpha = 1.0f; + const float beta = accumulate ? 1.0f : 0.0f; + CUDNN_ERR(name.c_str(), miopenConvolutionForward( + cudaHandles->cudnn, + &alpha, + inputDescriptors[batchSize], + inputBuf, + filterDescriptor, + filterBuf, + convolutionDescriptor, + (*convolutionAlgorithms)[batchSize].fwd_algo, + &beta, + outputDescriptors[batchSize], + outputBuf, + workspaceBuf, + workspaceBytes + )); + } + +}; + + +//--------------------------------------------------------------------------------- + +struct BatchNormLayer { + const string name; + const int numChannels; + const float epsilon; + const int activation; + const int nnXLen; + const int nnYLen; + + const bool usingFP16; + const bool usingNHWC; + + void* mergedScaleBuf; + void* mergedBiasBuf; + + BatchNormLayer() = delete; + BatchNormLayer(const BatchNormLayer&) = delete; + BatchNormLayer& operator=(const BatchNormLayer&) = delete; + + BatchNormLayer( + CudaHandles* cudaHandles, + const BatchNormLayerDesc* desc, + const ActivationLayerDesc* actDesc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + numChannels(desc->numChannels), + epsilon(desc->epsilon), + activation(actDesc->activation), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC) + { + (void)cudaHandles; + + assert(desc->mean.size() == numChannels); + assert(desc->variance.size() == numChannels); + assert(desc->scale.size() == numChannels); + assert(desc->bias.size() == numChannels); + assert(desc->mergedScale.size() == numChannels); + assert(desc->mergedBias.size() == numChannels); + CudaUtils::mallocAndCopyToDevice(name,desc->mergedScale,mergedScaleBuf,useFP16); + CudaUtils::mallocAndCopyToDevice(name,desc->mergedBias,mergedBiasBuf,useFP16); + } + ~BatchNormLayer() { + hipFree(mergedScaleBuf); + hipFree(mergedBiasBuf); + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + void* inputBuf, + const void* maskBuf, //ok to be null + void* outputBuf + ) const { + (void)cudaHandles; + if(!usingFP16) { + if(!usingNHWC) + customCudaApplyCScaleBiasNCHW((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, + (const float*)maskBuf, + batchSize,numChannels,nnXLen*nnYLen,activation); + else + customCudaApplyCScaleBiasNHWC((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, + (const float*)maskBuf, + batchSize,nnXLen*nnYLen,numChannels,activation); + } + else { + if(!usingNHWC) + customCudaApplyCScaleBiasNCHW((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, + (const half*)maskBuf, + batchSize,numChannels,nnXLen*nnYLen,activation); + else + customCudaApplyCScaleBiasNHWC((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, + (const half*)maskBuf, + batchSize,nnXLen*nnYLen,numChannels,activation); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + + } + +}; + + +//--------------------------------------------------------------------------------- + +struct MatMulLayer { + const string name; + const int inChannels; + const int outChannels; + const bool usingFP16; + void* matBuf; + + MatMulLayer() = delete; + MatMulLayer(const MatMulLayer&) = delete; + MatMulLayer& operator=(const MatMulLayer&) = delete; + + MatMulLayer( + CudaHandles* cudaHandles, + const MatMulLayerDesc* desc, + bool useFP16 + ) : + name(desc->name), + inChannels(desc->inChannels), + outChannels(desc->outChannels), + usingFP16(useFP16) + { + (void)cudaHandles; + + if(inChannels > 0 && outChannels > 0) { + assert(desc->weights.size() == inChannels * outChannels); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,matBuf,useFP16); + } + else { + matBuf = NULL; + } + } + + ~MatMulLayer() { + if(inChannels > 0 && outChannels > 0) + hipFree(matBuf); + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles + ) const { + (void)cudaHandles; + size_t workspaceBytes = 0; + return workspaceBytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + (void)workspaceBuf; + (void)workspaceBytes; + assert(inChannels > 0 && outChannels > 0); + + if(!usingFP16) { + const float alpha = 1.0f; + const float beta = 0.0f; + CUBLAS_ERR(name.c_str(),hipblasSgemm( + cudaHandles->cublas, + HIPBLAS_OP_N, + HIPBLAS_OP_N, + outChannels, + batchSize, + inChannels, + &alpha, + (const float*)matBuf,outChannels, + (const float*)inputBuf,inChannels, + &beta, + (float*)outputBuf,outChannels + )); + } + else { + const hipblasHalf* alpha = (const hipblasHalf*)scratch->oneBuf; + const hipblasHalf* beta = (const hipblasHalf*)scratch->zeroBuf; + CUBLAS_ERR(name.c_str(),hipblasHgemm( + cudaHandles->cublas, + HIPBLAS_OP_N, + HIPBLAS_OP_N, + outChannels, + batchSize, + inChannels, + alpha, + (const hipblasHalf*)matBuf,outChannels, + (const hipblasHalf*)inputBuf,inChannels, + beta, + (hipblasHalf*)outputBuf,outChannels + )); + } + + } + +}; + +//--------------------------------------------------------------------------------- + +struct MatBiasLayer { + const string name; + const int numChannels; + const bool usingFP16; + const int activation; + + void* biasBuf; + + MatBiasLayer() = delete; + MatBiasLayer(const MatBiasLayer&) = delete; + MatBiasLayer& operator=(const MatBiasLayer&) = delete; + + MatBiasLayer( + CudaHandles* cudaHandles, + const MatBiasLayerDesc* desc, + bool useFP16, + int activation_ + ) : + name(desc->name), + numChannels(desc->numChannels), + usingFP16(useFP16), + activation(activation_) + { + (void)cudaHandles; + if(numChannels > 0) { + assert(desc->weights.size() == numChannels); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,biasBuf,useFP16); + } + else + biasBuf = NULL; + } + + ~MatBiasLayer() { + if(numChannels > 0) + hipFree(biasBuf); + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + void* matBuf + ) const { + (void)cudaHandles; + assert(numChannels > 0); + if(!usingFP16) { + customCudaAddCBiasInplaceNC((float*)matBuf,(const float*)biasBuf,batchSize,numChannels,activation); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + else { + customCudaAddCBiasInplaceNC((half*)matBuf,(const half*)biasBuf,batchSize,numChannels,activation); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + } + +}; + +//--------------------------------------------------------------------------------- + +struct NormActConv { + const BatchNormLayer norm; + const ConvLayer conv; + + const int inChannels; + const int outChannels; + const int nnXLen; + const int nnYLen; + const bool usingFP16; + const bool usingNHWC; + + NormActConv() = delete; + NormActConv(const NormActConv&) = delete; + NormActConv& operator=(const NormActConv&) = delete; + + NormActConv( + CudaHandles* cudaHandles, + CudnnManager* manager, + const BatchNormLayerDesc* normDesc, + const ActivationLayerDesc* actDesc, + const ConvLayerDesc* convDesc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): norm(cudaHandles,normDesc,actDesc,nnX,nnY,useFP16,useNHWC), + conv(cudaHandles,manager,convDesc,useFP16,useNHWC), + inChannels(norm.numChannels), + outChannels(conv.outChannels), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC) + { + assert(norm.numChannels == conv.inChannels); + } + + ~NormActConv() + {} + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + int batchSize, + bool accumulate, + void* inBuf, + void* inScratchBuf, + void* outBuf, + void* maskBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + norm.apply(cudaHandles,batchSize,inBuf,maskBuf,inScratchBuf); +#ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("AFTER NORM "), inScratchBuf, batchSize, inChannels, nnXLen, nnYLen, usingNHWC, usingFP16); +#endif + conv.apply(cudaHandles,batchSize,accumulate,inScratchBuf,outBuf,workspaceBuf,workspaceBytes); + } + +}; + + +//--------------------------------------------------------------------------------- + +struct ResidualBlock { + const string name; + const NormActConv normActConv1; + const NormActConv normActConv2; + + ResidualBlock() = delete; + ResidualBlock(const ResidualBlock&) = delete; + ResidualBlock& operator=(const ResidualBlock&) = delete; + + ResidualBlock( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ResidualBlockDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): name(desc->name), + normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->regularConv,nnX,nnY,useFP16,useNHWC), + normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC) + { + } + + ~ResidualBlock() + {} + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* trunkBuf, + void* trunkScratchBuf, + void* maskBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf midIn(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,midIn.buf,maskBuf,workspaceBuf,workspaceBytes); + normActConv2.apply(cudaHandles,batchSize,true,midIn.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); + } + +}; + + +//---------------------------------------------------------------------------- + + +struct GlobalPoolingResidualBlock { + const string name; + const BatchNormLayer preBN; + const ConvLayer regularConv; + const ConvLayer gpoolConv; + const BatchNormLayer gpoolBN; + const MatMulLayer gpoolToBiasMul; + const NormActConv normActConv2; + + const int nnXLen; + const int nnYLen; + const int regularChannels; + const int gpoolChannels; + const bool usingFP16; + const bool usingNHWC; + + GlobalPoolingResidualBlock() = delete; + GlobalPoolingResidualBlock(const GlobalPoolingResidualBlock&) = delete; + GlobalPoolingResidualBlock& operator=(const GlobalPoolingResidualBlock&) = delete; + + GlobalPoolingResidualBlock( + CudaHandles* cudaHandles, + CudnnManager* manager, + const GlobalPoolingResidualBlockDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): name(desc->name), + preBN(cudaHandles,&desc->preBN,&desc->preActivation,nnX,nnY,useFP16,useNHWC), + regularConv(cudaHandles,manager,&desc->regularConv,useFP16,useNHWC), + gpoolConv(cudaHandles,manager,&desc->gpoolConv,useFP16,useNHWC), + gpoolBN(cudaHandles,&desc->gpoolBN,&desc->gpoolActivation,nnX,nnY,useFP16,useNHWC), + gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,useFP16), + normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC), + nnXLen(nnX), + nnYLen(nnY), + regularChannels(desc->regularConv.outChannels), + gpoolChannels(desc->gpoolConv.outChannels), + usingFP16(useFP16), + usingNHWC(useNHWC) + { + } + + ~GlobalPoolingResidualBlock() { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = regularConv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolConv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*gpoolChannels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* trunkBuf, + void* trunkScratchBuf, + void* maskBuf, + float* maskSumBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf regularOut(scratch->allocator, scratch->getBufSizeXY(regularChannels)); + SizedBuf regularScratch(scratch->allocator, scratch->getBufSizeXY(regularChannels)); + SizedBuf gpoolOut(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); + SizedBuf gpoolOut2(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); + SizedBuf gpoolConcat(scratch->allocator, scratch->getBufSize(gpoolChannels*3)); + SizedBuf gpoolBias(scratch->allocator, scratch->getBufSize(regularChannels)); + + preBN.apply(cudaHandles,batchSize,trunkBuf,maskBuf,trunkScratchBuf); + regularConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,regularOut.buf,workspaceBuf,workspaceBytes); + gpoolConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,gpoolOut.buf,workspaceBuf,workspaceBytes); + gpoolBN.apply(cudaHandles,batchSize,gpoolOut.buf,maskBuf,gpoolOut2.buf); + + if(!usingFP16) { + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const float*)maskBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const float*)maskBuf,maskSumBuf); + } + else { + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const half*)maskBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const half*)maskBuf,maskSumBuf); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,gpoolConcat.buf,gpoolBias.buf,workspaceBuf,workspaceBytes); + + if(!usingFP16) { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); + } + else { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + normActConv2.apply(cudaHandles,batchSize,true,regularOut.buf,regularScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); + } + +}; + +//------------------------------------------------------------------------------ + +struct BlockStack { + const int numBlocks; + const int trunkNumChannels; + const int nnXLen; + const int nnYLen; + const bool usingFP16; + const bool usingNHWC; + vector> blocks; + + BlockStack() = delete; + BlockStack(const BlockStack&) = delete; + BlockStack& operator=(const BlockStack&) = delete; + + BlockStack( + CudaHandles* cudaHandles, + CudnnManager* manager, + int nBlocks, + int trunkChannels, + const std::vector>& descBlocks, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ); + ~BlockStack(); + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const; + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + void* trunkScratchBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const; + +}; + +//------------------------------------------------------------------------------ + +struct NestedBottleneckResidualBlock { + const string name; + const NormActConv normActConv1; + const BlockStack blocks; + const NormActConv normActConv2; + + NestedBottleneckResidualBlock() = delete; + NestedBottleneckResidualBlock(const NestedBottleneckResidualBlock&) = delete; + NestedBottleneckResidualBlock& operator=(const NestedBottleneckResidualBlock&) = delete; + + NestedBottleneckResidualBlock( + CudaHandles* cudaHandles, + CudnnManager* manager, + const NestedBottleneckResidualBlockDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ): name(desc->name), + normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->preConv,nnX,nnY,useFP16,useNHWC), + blocks(cudaHandles,manager,desc->numBlocks,desc->preConv.outChannels,desc->blocks,nnX,nnY,useFP16,useNHWC), + normActConv2(cudaHandles,manager,&desc->postBN,&desc->postActivation,&desc->postConv,nnX,nnY,useFP16,useNHWC) + { + } + + ~NestedBottleneckResidualBlock() + {} + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* trunkBuf, + void* trunkScratchBuf, + void* maskBuf, + float* maskSumBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf mid(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); + assert(normActConv1.outChannels == normActConv2.inChannels); + normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,mid.buf,maskBuf,workspaceBuf,workspaceBytes); + blocks.apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskSumBuf, + mid.buf, + midScratch.buf, + workspaceBuf, + workspaceBytes + ); + normActConv2.apply(cudaHandles,batchSize,true,mid.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); + } + +}; + +//------------------------------------------------------------------------------ + +BlockStack::BlockStack( + CudaHandles* cudaHandles, + CudnnManager* manager, + int nBlocks, + int trunkChannels, + const std::vector>& descBlocks, + int nnX, + int nnY, + bool useFP16, + bool useNHWC +) : + numBlocks(nBlocks), + trunkNumChannels(trunkChannels), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC) +{ + assert(numBlocks == descBlocks.size()); + for(int i = 0; irequiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { + GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); + b = block->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { + NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); + b = block->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + else { + ASSERT_UNREACHABLE; + } + } + return bytes; +} + +void BlockStack::apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + void* trunkScratchBuf, + void* workspaceBuf, + size_t workspaceBytes +) const { + + for(int i = 0; iapply( + cudaHandles, + scratch, + batchSize, + trunkBuf, + trunkScratchBuf, + maskBuf, + workspaceBuf, + workspaceBytes + ); + } + else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { + GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); + block->apply( + cudaHandles, + scratch, + batchSize, + trunkBuf, + trunkScratchBuf, + maskBuf, + maskSumBuf, + workspaceBuf, + workspaceBytes + ); + } + else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { + NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); + block->apply( + cudaHandles, + scratch, + batchSize, + trunkBuf, + trunkScratchBuf, + maskBuf, + maskSumBuf, + workspaceBuf, + workspaceBytes + ); + } + else { + ASSERT_UNREACHABLE; + } + } +} +//------------------------------------------------------------------------------ + +struct SGFMetadataEncoder { + const string name; + + const bool usingFP16; + + const MatMulLayer mul1; + const MatBiasLayer bias1; + const MatMulLayer mul2; + const MatBiasLayer bias2; + const MatMulLayer mul3; + + SGFMetadataEncoder() = delete; + SGFMetadataEncoder(const SGFMetadataEncoder&) = delete; + SGFMetadataEncoder& operator=(const SGFMetadataEncoder&) = delete; + + SGFMetadataEncoder( + CudaHandles* cudaHandles, + const SGFMetadataEncoderDesc* desc, + bool useFP16 + ) : + name(desc->name), + usingFP16(useFP16), + mul1(cudaHandles,&desc->mul1,useFP16), + bias1(cudaHandles,&desc->bias1,useFP16,desc->act1.activation), + mul2(cudaHandles,&desc->mul2,useFP16), + bias2(cudaHandles,&desc->bias2,useFP16,desc->act2.activation), + mul3(cudaHandles,&desc->mul3,useFP16) + { + } + + ~SGFMetadataEncoder() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + (void)batchSize; + size_t bytes = 0; + size_t b; + + b = mul1.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = mul2.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = mul3.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* inputBuf, + void* outputBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf internalBuf1(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); + SizedBuf internalBuf2(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); + + mul1.apply(cudaHandles,scratch,batchSize,inputBuf,internalBuf1.buf,workspaceBuf,workspaceBytes); + bias1.apply(cudaHandles,batchSize,internalBuf1.buf); + mul2.apply(cudaHandles,scratch,batchSize,internalBuf1.buf,internalBuf2.buf,workspaceBuf,workspaceBytes); + bias2.apply(cudaHandles,batchSize,internalBuf2.buf); + mul3.apply(cudaHandles,scratch,batchSize,internalBuf2.buf,outputBuf,workspaceBuf,workspaceBytes); + } + +}; + + +//---------------------------------------------------------------------------- + +struct Trunk { + const string name; + const int modelVersion; + const int numBlocks; + const int trunkNumChannels; + + const int nnXLen; + const int nnYLen; + const bool usingFP16; + const bool usingNHWC; + + std::unique_ptr initialConv; + std::unique_ptr initialMatMul; + std::unique_ptr sgfMetadataEncoder; + const BlockStack blocks; + std::unique_ptr trunkTipBN; + + Trunk() = delete; + Trunk(const Trunk&) = delete; + Trunk& operator=(const Trunk&) = delete; + + Trunk( + CudaHandles* cudaHandles, + CudnnManager* manager, + const TrunkDesc* desc, + int nnX, + int nnY, + bool inputsUseNHWC, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + numBlocks(desc->numBlocks), + trunkNumChannels(desc->trunkNumChannels), + nnXLen(nnX), + nnYLen(nnY), + usingFP16(useFP16), + usingNHWC(useNHWC), + blocks(cudaHandles,manager,desc->numBlocks,desc->trunkNumChannels,desc->blocks,nnX,nnY,useFP16,useNHWC) + { + int midNumChannels = desc->midNumChannels; + int regularNumChannels = desc->regularNumChannels; + int gpoolNumChannels = desc->gpoolNumChannels; + + int maxBatchSize = manager->maxBatchSize; + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,trunkNumChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,midNumChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,regularNumChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,gpoolNumChannels); + + initialConv = std::make_unique(cudaHandles,manager,&desc->initialConv,useFP16,inputsUseNHWC,useNHWC); + initialMatMul = std::make_unique(cudaHandles,&desc->initialMatMul,useFP16); + if(desc->metaEncoderVersion > 0) { + sgfMetadataEncoder = std::make_unique(cudaHandles,&desc->sgfMetadataEncoder,useFP16); + testAssert(sgfMetadataEncoder->mul3.outChannels == initialMatMul->outChannels); + } + + trunkTipBN = std::make_unique(cudaHandles,&desc->trunkTipBN,&desc->trunkTipActivation,nnXLen,nnYLen,useFP16,useNHWC); + assert(desc->blocks.size() == numBlocks); + } + + ~Trunk() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = initialConv->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + + b = initialMatMul->requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + + if(sgfMetadataEncoder != nullptr) { + b = sgfMetadataEncoder->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + + b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* inputBuf, + void* inputGlobalBuf, + void* inputMetaBuf, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + + SizedBuf trunkScratch(scratch->allocator, scratch->getBufSizeXY(trunkNumChannels)); + + //Feed the conv into trunkScratch.buf, not trunkBuf + initialConv->apply(cudaHandles,batchSize,false,inputBuf,trunkScratch.buf,workspaceBuf,workspaceBytes); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("After initial conv"), trunkScratch.buf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); + #endif + + //Feed the matmul into trunkBuf + initialMatMul->apply(cudaHandles,scratch,batchSize,inputGlobalBuf,trunkBuf,workspaceBuf,workspaceBytes); + //Then accumulate it into trunkScratch.buf, broadcasting during the process + if(!usingFP16) { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + else { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + if(sgfMetadataEncoder != nullptr) { + testAssert(inputMetaBuf != NULL); + //Feed the result into trunkBuf + sgfMetadataEncoder->apply(cudaHandles,scratch,batchSize,inputMetaBuf,trunkBuf,workspaceBuf,workspaceBytes); + //Then accumulate it into trunkScratch.buf, broadcasting during the process + if(!usingFP16) { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + else { + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); + } + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + else { + testAssert(inputMetaBuf == NULL); + } + + //Flip trunkBuf and trunkScratch.buf so that the result gets accumulated in trunkScratch.buf + blocks.apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskSumBuf, + trunkScratch.buf, + trunkBuf, + workspaceBuf, + workspaceBytes + ); + + //And now with the final BN port it from trunkScratch.buf to trunkBuf. + trunkTipBN->apply(cudaHandles,batchSize,trunkScratch.buf,maskBuf,trunkBuf); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("Trunk tip"), trunkBuf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); + #endif + } + +}; + +//------------------------------------------------------------------------------ + +static void fillMaskFloatBufAndMaskSumBuf(void* maskBuf, float*& maskFloatBuf, float*& maskSumBuf, bool usingFP16, int batchSize, int nnXLen, int nnYLen) { + if(!usingFP16) { + maskFloatBuf = (float*)maskBuf; + customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); + CUDA_ERR("sumMask",hipPeekAtLastError()); + } + else { + customCudaCopyFromHalf((const half*)maskBuf,maskFloatBuf,batchSize*nnXLen*nnYLen); + CUDA_ERR("copyMaskFromHalf",hipPeekAtLastError()); + customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); + CUDA_ERR("sumMask",hipPeekAtLastError()); + } +} + + +//------------------------------------------------------------------------------ + +struct PolicyHead { + const string name; + const int modelVersion; + const int nnXLen; + const int nnYLen; + const int p1Channels; + const int g1Channels; + const int p2Channels; + const bool usingFP16; + const bool usingNHWC; + + const ConvLayer p1Conv; + const ConvLayer g1Conv; + const BatchNormLayer g1BN; + const MatMulLayer gpoolToBiasMul; + const BatchNormLayer p1BN; + const ConvLayer p2Conv; + const MatMulLayer gpoolToPassMul; + const MatBiasLayer gpoolToPassBias; + const MatMulLayer gpoolToPassMul2; + + PolicyHead() = delete; + PolicyHead(const PolicyHead&) = delete; + PolicyHead& operator=(const PolicyHead&) = delete; + + PolicyHead( + CudaHandles* cudaHandles, + CudnnManager* manager, + const PolicyHeadDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + nnXLen(nnX), + nnYLen(nnY), + p1Channels(desc->p1Conv.outChannels), + g1Channels(desc->g1Conv.outChannels), + p2Channels(desc->p2Conv.outChannels), + usingFP16(useFP16), + usingNHWC(useNHWC), + p1Conv(cudaHandles,manager,&desc->p1Conv,useFP16,useNHWC), + g1Conv(cudaHandles,manager,&desc->g1Conv,useFP16,useNHWC), + g1BN(cudaHandles,&desc->g1BN,&desc->g1Activation,nnX,nnY,useFP16,useNHWC), + gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,false), + p1BN(cudaHandles,&desc->p1BN,&desc->p1Activation,nnX,nnY,false,useNHWC), + p2Conv(cudaHandles,manager,&desc->p2Conv,false,useNHWC), + gpoolToPassMul(cudaHandles,&desc->gpoolToPassMul,false), + gpoolToPassBias(cudaHandles,&desc->gpoolToPassBias,false,desc->passActivation.activation), + gpoolToPassMul2(cudaHandles,&desc->gpoolToPassMul2,false) + { + } + + ~PolicyHead() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = p1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = g1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = p2Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = gpoolToPassMul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = gpoolToPassMul2.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*g1Channels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskFloatBuf, + float* maskSumBuf, + void* trunkBuf, + float* policyPassBuf, + float* policyBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + + SizedBuf p1Out(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs + SizedBuf p1Out2(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs + SizedBuf g1Out(scratch->allocator, scratch->getBufSizeXY(g1Channels)); + SizedBuf g1Out2(scratch->allocator, scratch->getBufSizeXY(g1Channels)); + SizedBuf g1Concat(scratch->allocator, scratch->getBufSizeFloat(g1Channels*3)); + SizedBuf g1Bias(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); + SizedBuf p1Pass(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); + + p1Conv.apply(cudaHandles,batchSize,false,trunkBuf,p1Out.buf,workspaceBuf,workspaceBytes); + g1Conv.apply(cudaHandles,batchSize,false,trunkBuf,g1Out.buf,workspaceBuf,workspaceBytes); + g1BN.apply(cudaHandles,batchSize,g1Out.buf,maskBuf,g1Out2.buf); + + if(!usingFP16) { + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + else { + customCudaCopyFromHalf((const half*)g1Out2.buf,(float*)workspaceBuf,batchSize*g1Channels*nnXLen*nnYLen); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + if(!usingNHWC) + customCudaPoolRowsGPoolNCHW((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); + else + customCudaPoolRowsGPoolNHWC((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + } + + gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,g1Bias.buf,workspaceBuf,workspaceBytes); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("p1 pre-gpool-sum"), p1Out.buf, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); + CudaUtils::debugPrint4D(string("g1 pre-gpool"), g1Out.buf, batchSize, g1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); + CudaUtils::debugPrint2D(string("g1 pooled"), g1Concat.buf, batchSize, g1Channels*3, false); + CudaUtils::debugPrint2D(string("g1 biases"), g1Bias.buf, batchSize, p1Channels, false); + #endif + + float* p1OutBufA; + float* p1OutBufB; + if(!usingFP16) { + p1OutBufA = (float*)p1Out.buf; + p1OutBufB = (float*)p1Out2.buf; + } + else { + customCudaCopyFromHalf((const half*)p1Out.buf,(float*)p1Out2.buf,batchSize*p1Channels*nnXLen*nnYLen); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + p1OutBufA = (float*)p1Out2.buf; + p1OutBufB = (float*)p1Out.buf; + } + + if(!usingNHWC) + customCudaAddNCBiasInplaceNCHW(p1OutBufA,(float*)g1Bias.buf,batchSize,p1Channels,nnXLen*nnYLen); + else + customCudaAddNCBiasInplaceNHWC(p1OutBufA,(float*)g1Bias.buf,batchSize,nnXLen*nnYLen,p1Channels); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + p1BN.apply(cudaHandles,batchSize,p1OutBufA,maskFloatBuf,p1OutBufB); + p2Conv.apply(cudaHandles,batchSize,false,p1OutBufB,(float*)policyBuf,workspaceBuf,workspaceBytes); + + if(modelVersion >= 15) { + gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,p1Pass.buf,workspaceBuf,workspaceBytes); + gpoolToPassBias.apply(cudaHandles,batchSize,p1Pass.buf); + gpoolToPassMul2.apply(cudaHandles,scratch,batchSize,p1Pass.buf,policyPassBuf,workspaceBuf,workspaceBytes); + } + else { + gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,policyPassBuf,workspaceBuf,workspaceBytes); + } + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("p1 after-gpool-sum"), p1OutBufA, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, false); + CudaUtils::debugPrint2D(string("policypass"), policyPassBuf, batchSize, 1, false); + CudaUtils::debugPrint4D(string("policy"), policyBuf, batchSize, p2Channels, nnXLen, nnYLen, usingNHWC, false); + #endif + + } + +}; + +//------------------------------------------------------------------------------ + +struct ValueHead { + const string name; + const int modelVersion; + const int nnXLen; + const int nnYLen; + const int v1Channels; + const int v2Channels; + const int valueChannels; + const int scoreValueChannels; + const int ownershipChannels; + const bool usingFP16; + const bool usingNHWC; + + const ConvLayer v1Conv; + const BatchNormLayer v1BN; + const MatMulLayer v2Mul; + const MatBiasLayer v2Bias; + const MatMulLayer v3Mul; + const MatBiasLayer v3Bias; + const MatMulLayer sv3Mul; + const MatBiasLayer sv3Bias; + const ConvLayer vOwnershipConv; + + ValueHead() = delete; + ValueHead(const ValueHead&) = delete; + ValueHead& operator=(const ValueHead&) = delete; + + ValueHead( + CudaHandles* cudaHandles, + CudnnManager* manager, + const ValueHeadDesc* desc, + int nnX, + int nnY, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + nnXLen(nnX), + nnYLen(nnY), + v1Channels(desc->v1Conv.outChannels), + v2Channels(desc->v2Mul.outChannels), + valueChannels(desc->v3Mul.outChannels), + scoreValueChannels(desc->sv3Mul.outChannels), + ownershipChannels(desc->vOwnershipConv.outChannels), + usingFP16(useFP16), + usingNHWC(useNHWC), + v1Conv(cudaHandles,manager,&desc->v1Conv,useFP16,useNHWC), + v1BN(cudaHandles,&desc->v1BN,&desc->v1Activation,nnX,nnY,useFP16,useNHWC), + v2Mul(cudaHandles,&desc->v2Mul,false), + v2Bias(cudaHandles,&desc->v2Bias,false,desc->v2Activation.activation), + v3Mul(cudaHandles,&desc->v3Mul,false), + v3Bias(cudaHandles,&desc->v3Bias,false,ACTIVATION_IDENTITY), + sv3Mul(cudaHandles,&desc->sv3Mul,false), + sv3Bias(cudaHandles,&desc->sv3Bias,false,ACTIVATION_IDENTITY), + vOwnershipConv(cudaHandles,manager,&desc->vOwnershipConv,useFP16,useNHWC) + { + } + + ~ValueHead() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = v1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = v2Mul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = v3Mul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*v1Channels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + + b = sv3Mul.requiredWorkspaceBytes(cudaHandles); + bytes = std::max(bytes,b); + b = vOwnershipConv.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = sizeof(float)*batchSize*ownershipChannels*nnXLen*nnYLen; + bytes = std::max(bytes,b); + + return bytes; + } + + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + void* maskBuf, + float* maskSumBuf, + void* trunkBuf, + float* valueBuf, + float* scoreValueBuf, + void* ownershipBuf, + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf v1Out(scratch->allocator, scratch->getBufSizeXY(v1Channels)); + SizedBuf v1Out2(scratch->allocator, scratch->getBufSizeXY(v1Channels)); + SizedBuf v1Mean(scratch->allocator, scratch->getBufSizeFloat(v1Channels*3)); + SizedBuf v2Out(scratch->allocator, scratch->getBufSizeFloat(v2Channels)); + SizedBuf ownershipScratch(scratch->allocator, scratch->getBufSizeXYFloat(ownershipChannels)); + + v1Conv.apply(cudaHandles,batchSize,false,trunkBuf,v1Out.buf,workspaceBuf,workspaceBytes); + v1BN.apply(cudaHandles,batchSize,v1Out.buf,maskBuf,v1Out2.buf); + + void* bufToBePooled = v1Out2.buf; + if(usingFP16) { + customCudaCopyFromHalf((const half*)v1Out2.buf,(float*)workspaceBuf,batchSize*v1Channels*nnXLen*nnYLen); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + bufToBePooled = workspaceBuf; + } + + if(!usingNHWC) + customCudaValueHeadPoolNCHW((float*)bufToBePooled,(float*)v1Mean.buf,batchSize,v1Channels,nnXLen*nnYLen,maskSumBuf); + else + customCudaValueHeadPoolNHWC((const float*)bufToBePooled,(float*)v1Mean.buf,batchSize,nnXLen*nnYLen,v1Channels,maskSumBuf); + CUDA_ERR(name.c_str(),hipPeekAtLastError()); + + v2Mul.apply(cudaHandles,scratch,batchSize,v1Mean.buf,v2Out.buf,workspaceBuf,workspaceBytes); + v2Bias.apply(cudaHandles,batchSize,v2Out.buf); + v3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,valueBuf,workspaceBuf,workspaceBytes); + v3Bias.apply(cudaHandles,batchSize,valueBuf); + + sv3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,scoreValueBuf,workspaceBuf,workspaceBytes); + sv3Bias.apply(cudaHandles,batchSize,scoreValueBuf); + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("v1"), v1Out.buf, batchSize, v1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); + CudaUtils::debugPrint2D(string("v1 pooled"), v1Mean.buf, batchSize, v1Channels, false); + CudaUtils::debugPrint2D(string("v2"), v2Out.buf, batchSize, v1Channels, false); + #endif + + if(!usingFP16) { + vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipBuf,workspaceBuf,workspaceBytes); + } + else { + vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipScratch.buf,workspaceBuf,workspaceBytes); + customCudaCopyFromHalf((const half*)ownershipScratch.buf,(float*)ownershipBuf,batchSize*ownershipChannels*nnXLen*nnYLen); + CUDA_ERR("vOwnership copy",hipPeekAtLastError()); + } + + } + +}; + +//------------------------------------------------------------------------------ + +struct Model { + const string name; + const int modelVersion; + const int maxBatchSize; + const int nnXLen; + const int nnYLen; + const int numInputChannels; + const int numInputGlobalChannels; + const int numInputMetaChannels; + const int numPolicyChannels; + const int numValueChannels; + const int numScoreValueChannels; + const int numOwnershipChannels; + const bool usingFP16; + const bool usingNHWC; + const bool inputsUsingNHWC; + + std::unique_ptr trunk; + std::unique_ptr policyHead; + std::unique_ptr valueHead; + std::unique_ptr manager; + + Model() = delete; + Model(const Model&) = delete; + Model& operator=(const Model&) = delete; + + Model( + CudaHandles* cudaHandles, + const ModelDesc* desc, + int maxBatchSz, + int nnX, + int nnY, + bool inputsUseNHWC, + bool useFP16, + bool useNHWC + ) : + name(desc->name), + modelVersion(desc->modelVersion), + maxBatchSize(maxBatchSz), + nnXLen(nnX), + nnYLen(nnY), + numInputChannels(desc->numInputChannels), + numInputGlobalChannels(desc->numInputGlobalChannels), + numInputMetaChannels(desc->numInputMetaChannels), + numPolicyChannels(desc->numPolicyChannels), + numValueChannels(desc->numValueChannels), + numScoreValueChannels(desc->numScoreValueChannels), + numOwnershipChannels(desc->numOwnershipChannels), + usingFP16(useFP16), + usingNHWC(useNHWC), + inputsUsingNHWC(inputsUseNHWC) + { + if(nnXLen > NNPos::MAX_BOARD_LEN) + throw StringError(Global::strprintf("nnXLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", + nnXLen, NNPos::MAX_BOARD_LEN + )); + if(nnYLen > NNPos::MAX_BOARD_LEN) + throw StringError(Global::strprintf("nnYLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", + nnYLen, NNPos::MAX_BOARD_LEN + )); + + int numFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); + if(numInputChannels != numFeatures) + throw StringError(Global::strprintf("Neural net numInputChannels (%d) was not the expected number based on version (%d)", + numInputChannels, numFeatures + )); + int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); + if(numInputGlobalChannels != numGlobalFeatures) + throw StringError(Global::strprintf("Neural net numInputGlobalChannels (%d) was not the expected number based on version (%d)", + numInputGlobalChannels, numGlobalFeatures + )); + if(numInputMetaChannels > 0) { + if(numInputMetaChannels != SGFMetadata::METADATA_INPUT_NUM_CHANNELS) + throw StringError(Global::strprintf("Neural net numInputMetaChannels (%d) was not the expected number (%d)", + numInputMetaChannels, SGFMetadata::METADATA_INPUT_NUM_CHANNELS + )); + } + + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputGlobalChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputMetaChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numPolicyChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numValueChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numScoreValueChannels); + CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numOwnershipChannels); + + manager = std::make_unique(name, maxBatchSize, nnXLen, nnYLen); + trunk = std::make_unique(cudaHandles,manager.get(),&desc->trunk,nnXLen,nnYLen,inputsUseNHWC,useFP16,useNHWC); + policyHead = std::make_unique(cudaHandles,manager.get(),&desc->policyHead,nnXLen,nnYLen,useFP16,useNHWC); + valueHead = std::make_unique(cudaHandles,manager.get(),&desc->valueHead,nnXLen,nnYLen,useFP16,useNHWC); + } + + ~Model() + { + } + + size_t requiredWorkspaceBytes( + CudaHandles* cudaHandles, + int batchSize + ) const { + size_t bytes = 0; + size_t b; + + b = trunk->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = policyHead->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + b = valueHead->requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + + return bytes; + } + + void apply( + CudaHandles* cudaHandles, + ScratchBuffers* scratch, + int batchSize, + bool requireExactNNLen, + + void* inputBuf, + void* inputGlobalBuf, + void* inputMetaBuf, + + float* policyPassBuf, + float* policyBuf, + + float* valueBuf, + float* scoreValueBuf, + void* ownershipBuf, + + void* workspaceBuf, + size_t workspaceBytes + ) const { + SizedBuf mask(scratch->allocator, scratch->getBufSizeXY(1)); + SizedBuf maskFloat(scratch->allocator, scratch->getBufSizeXYFloat(1)); + SizedBuf maskSum(scratch->allocator, scratch->getBufSizeFloat(1)); + + void* maskBuf = mask.buf; + float* maskFloatBuf = (float*)maskFloat.buf; + float* maskSumBuf = (float*)maskSum.buf; + + if(!usingFP16) { + if(inputsUsingNHWC) + customCudaChannel0ExtractNHWC((const float*)inputBuf, (float*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); + else + customCudaChannel0ExtractNCHW((const float*)inputBuf, (float*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); + CUDA_ERR("modelExtractMask",hipPeekAtLastError()); + } + else { + if(inputsUsingNHWC) + customCudaChannel0ExtractNHWC((const half*)inputBuf, (half*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); + else + customCudaChannel0ExtractNCHW((const half*)inputBuf, (half*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); + CUDA_ERR("modelExtractMask",hipPeekAtLastError()); + } + + fillMaskFloatBufAndMaskSumBuf(maskBuf,maskFloatBuf,maskSumBuf,usingFP16,batchSize,nnXLen,nnYLen); + + //Don't do any masking if we know the board is exactly the desired size + if(requireExactNNLen) { + //Set to NULL to signal downstream that this buf doesn't need to be used + maskBuf = NULL; + maskFloatBuf = NULL; + //The global pooling structures need this no matter what, for normalizing based on this and its sqrt. + //maskSumBuf = NULL; + } + + #ifdef DEBUG_INTERMEDIATE_VALUES + CudaUtils::debugPrint4D(string("Initial bin features"), inputBuf, batchSize, trunk->initialConv->inChannels, nnXLen, nnYLen, inputsUsingNHWC, usingFP16); + CudaUtils::debugPrint2D(string("Initial global features"), inputGlobalBuf, batchSize, trunk->initialMatMul->inChannels, usingFP16); + if(trunk->sgfMetadataEncoder != nullptr) { + assert(inputMetaBuf != NULL); + CudaUtils::debugPrint2D(string("Initial meta features"), inputMetaBuf, batchSize, trunk->sgfMetadataEncoder->mul1.inChannels, usingFP16); + } + #endif + + SizedBuf trunkBuf(scratch->allocator, scratch->getBufSizeXY(trunk->trunkNumChannels)); + + trunk->apply( + cudaHandles, + scratch, + batchSize, + inputBuf, + inputGlobalBuf, + inputMetaBuf, + maskBuf, + maskSumBuf, + trunkBuf.buf, + workspaceBuf, + workspaceBytes + ); + policyHead->apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskFloatBuf, + maskSumBuf, + trunkBuf.buf, + policyPassBuf, + policyBuf, + workspaceBuf, + workspaceBytes + ); + valueHead->apply( + cudaHandles, + scratch, + batchSize, + maskBuf, + maskSumBuf, + trunkBuf.buf, + valueBuf, + scoreValueBuf, + ownershipBuf, + workspaceBuf, + workspaceBytes + ); + } + +}; + + +//------------------------------------------------------------------------------ + +struct LoadedModel { + ModelDesc modelDesc; + + LoadedModel(const string& fileName, const string& expectedSha256) { + ModelDesc::loadFromFileMaybeGZipped(fileName,modelDesc,expectedSha256); + modelDesc.applyScale8ToReduceActivations(); + } + + LoadedModel() = delete; + LoadedModel(const LoadedModel&) = delete; + LoadedModel& operator=(const LoadedModel&) = delete; +}; + +LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { + LoadedModel* loadedModel = new LoadedModel(file,expectedSha256); + return loadedModel; +} + +void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { + delete loadedModel; +} + +const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { + return loadedModel->modelDesc; +} + +//------------------------------------------------------------------------------ + +struct Buffers { + //All of these are device pointers + + float* inputBufFloat; + void* inputBuf; + float* inputGlobalBufFloat; + void* inputGlobalBuf; + float* inputMetaBufFloat; + void* inputMetaBuf; + size_t inputBufBytesFloat; + size_t inputBufBytes; + size_t inputGlobalBufBytesFloat; + size_t inputGlobalBufBytes; + size_t inputMetaBufBytesFloat; + size_t inputMetaBufBytes; + + float* policyPassBuf; + size_t policyPassBufBytes; + float* policyBuf; + size_t policyBufBytes; + + float* valueBuf; + size_t valueBufBytes; + float* scoreValueBuf; + size_t scoreValueBufBytes; + void* ownershipBuf; + size_t ownershipBufBytes; + + void* workspaceBuf; + size_t workspaceBytes; + + Buffers() = delete; + Buffers(const Buffers&) = delete; + Buffers& operator=(const Buffers&) = delete; + + Buffers(CudaHandles* cudaHandles, const Model& m, const ScratchBuffers& scratch) { + size_t batchXYFloatBytes = (size_t)scratch.batchXYFloatBytes; + size_t batchFloatBytes = (size_t)scratch.batchFloatBytes; + size_t batchXYBytes = (size_t)scratch.batchXYBytes; + size_t batchBytes = (size_t)scratch.batchBytes; + + inputBufBytesFloat = m.numInputChannels * batchXYFloatBytes; + inputBufBytes = m.numInputChannels * batchXYBytes; + inputGlobalBufBytesFloat = m.numInputGlobalChannels * batchFloatBytes; + inputGlobalBufBytes = m.numInputGlobalChannels * batchBytes; + inputMetaBufBytesFloat = m.numInputMetaChannels * batchFloatBytes; + inputMetaBufBytes = m.numInputMetaChannels * batchBytes; + + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputBufFloat), inputBufBytesFloat)); + CUDA_ERR("Buffers",hipMalloc(&inputBuf, inputBufBytes)); + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputGlobalBufFloat), inputGlobalBufBytesFloat)); + CUDA_ERR("Buffers",hipMalloc(&inputGlobalBuf, inputGlobalBufBytes)); + if(m.numInputMetaChannels > 0) { + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputMetaBufFloat), inputMetaBufBytesFloat)); + CUDA_ERR("Buffers",hipMalloc(&inputMetaBuf, inputMetaBufBytes)); + } + else { + inputMetaBufFloat = NULL; + inputMetaBuf = NULL; + } + + if(m.modelVersion >= 16) + testAssert(m.policyHead->p2Channels == 4); + else if(m.modelVersion >= 12) + testAssert(m.policyHead->p2Channels == 2); + else + testAssert(m.policyHead->p2Channels == 1); + + policyPassBufBytes = m.policyHead->p2Channels * batchFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyPassBuf), policyPassBufBytes)); + policyBufBytes = m.policyHead->p2Channels * batchXYFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyBuf), policyBufBytes)); + + valueBufBytes = m.valueHead->valueChannels * batchFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&valueBuf), valueBufBytes)); + + scoreValueBufBytes = m.valueHead->scoreValueChannels * batchFloatBytes; + CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&scoreValueBuf), scoreValueBufBytes)); + + //This buf is used for both an intermdiate fp16 result in fp16 mode, and ALSO the final fp32 output, so always must be fp32-sized + ownershipBufBytes = m.valueHead->ownershipChannels * batchXYFloatBytes; + CUDA_ERR("Buffers",hipMalloc(&ownershipBuf, ownershipBufBytes)); + + //In theory the requiredWorkspaceBytes calls could give us values non-monotone in batch size + //such as if the convolution algorithm changes between batch size 1 and larger. + //So we call it for all the batch sizes. + size_t bytes = 0; + size_t b; + for(int batchSize = 1; batchSize <= m.maxBatchSize; batchSize++) { + b = m.requiredWorkspaceBytes(cudaHandles,batchSize); + bytes = std::max(bytes,b); + } + + CUDA_ERR("Buffers",hipMalloc(&workspaceBuf, bytes)); + workspaceBytes = bytes; + } + + ~Buffers() { + hipFree(inputBufFloat); + hipFree(inputBuf); + hipFree(inputGlobalBufFloat); + hipFree(inputGlobalBuf); + if(inputMetaBufFloat != NULL) + hipFree(inputMetaBufFloat); + if(inputMetaBuf != NULL) + hipFree(inputMetaBuf); + + hipFree(policyPassBuf); + hipFree(policyBuf); + + hipFree(valueBuf); + hipFree(scoreValueBuf); + hipFree(ownershipBuf); + + hipFree(workspaceBuf); + } + +}; + +//------------------------------------------------------------------------------ + +struct ComputeContext { + int nnXLen; + int nnYLen; + enabled_t useFP16Mode; + enabled_t useNHWCMode; +}; + +ComputeContext* NeuralNet::createComputeContext( + const std::vector& gpuIdxs, + Logger* logger, + int nnXLen, + int nnYLen, + const string& openCLTunerFile, + const string& homeDataDirOverride, + bool openCLReTunePerBoardSize, + enabled_t useFP16Mode, + enabled_t useNHWCMode, + const LoadedModel* loadedModel +) { + (void)gpuIdxs; + (void)logger; + (void)openCLTunerFile; + (void)homeDataDirOverride; + (void)openCLReTunePerBoardSize; + (void)loadedModel; + + ComputeContext* context = new ComputeContext(); + context->nnXLen = nnXLen; + context->nnYLen = nnYLen; + context->useFP16Mode = useFP16Mode; + context->useNHWCMode = useNHWCMode; + return context; +} + +void NeuralNet::freeComputeContext(ComputeContext* computeContext) { + delete computeContext; +} + +//------------------------------------------------------------------------------ + +struct ComputeHandle { + std::unique_ptr cudaHandles; + std::unique_ptr model; + std::unique_ptr scratch; + std::unique_ptr buffers; + const bool usingFP16; + const int nnXLen; + const int nnYLen; + const bool requireExactNNLen; + const bool inputsUseNHWC; + const bool usingNHWC; + + ComputeHandle( + const ComputeContext* context, + const LoadedModel* loadedModel, + int majorComputeCapability, + int minorComputeCapability, + int maxBatchSize, + bool requireExactNNLen_, + bool inputsUseNHWC_, + bool useFP16, + bool useNHWC + ) : + usingFP16(useFP16), + nnXLen(context->nnXLen), + nnYLen(context->nnYLen), + requireExactNNLen(requireExactNNLen_), + inputsUseNHWC(inputsUseNHWC_), + usingNHWC(useNHWC) + { + cudaHandles = std::make_unique(majorComputeCapability,minorComputeCapability); + model = std::make_unique( + cudaHandles.get(), &(loadedModel->modelDesc), maxBatchSize, + nnXLen, nnYLen, inputsUseNHWC, useFP16, useNHWC + ); + scratch = std::make_unique(maxBatchSize, nnXLen, nnYLen, useFP16); + buffers = std::make_unique(cudaHandles.get(), *model, *scratch); + + //Synchronize after creating buffers and copying all the weights, just in case + CUDA_ERR("ComputeHandle", hipDeviceSynchronize()); + } + ~ComputeHandle() { + } + + ComputeHandle() = delete; + ComputeHandle(const ComputeHandle&) = delete; + ComputeHandle& operator=(const ComputeHandle&) = delete; +}; + +ComputeHandle* NeuralNet::createComputeHandle( + ComputeContext* context, + const LoadedModel* loadedModel, + Logger* logger, + int maxBatchSize, + bool requireExactNNLen, + bool inputsUseNHWC, + int gpuIdxForThisThread, + int serverThreadIdx +) { + //Use whatever CUDA believes GPU 0 to be. + if(gpuIdxForThisThread == -1) + gpuIdxForThisThread = 0; + + CUDA_ERR("createComputeHandle",hipSetDevice(gpuIdxForThisThread)); + + hipDeviceProp_t prop; + hipGetDeviceProperties(&prop,gpuIdxForThisThread); + + bool useFP16 = false; + bool useNHWC = false; + if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) + useFP16 = true; + + if(logger != NULL) { + logger->write( + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) + + " memory " + Global::uint64ToString(prop.totalGlobalMem) + + " compute capability major " + Global::intToString(prop.major) + + " minor " + Global::intToString(prop.minor) + ); + logger->write( + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion) + + " useFP16 = " + Global::boolToString(useFP16) + + " useNHWC = " + Global::boolToString(useNHWC) + ); + logger->write( + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name + ); + logger->write( + "MIOpen finding convolution algorithms for GPU " + string(prop.name) + ". This may take a while, please wait............" + ); + } + + ComputeHandle* gpuHandle = new ComputeHandle( + context,loadedModel,prop.major,prop.minor,maxBatchSize,requireExactNNLen,inputsUseNHWC,useFP16,useNHWC + ); + return gpuHandle; +} + +void NeuralNet::freeComputeHandle(ComputeHandle* gpuHandle) { + delete gpuHandle; +} + +bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { + return handle->usingFP16; +} + +//------------------------------------------------------------------------------ + +void NeuralNet::printDevices() { + int numDevices = 0; + hipGetDeviceCount(&numDevices); + for(int i = 0; imodelDesc; + + maxBatchSize = maxBatchSz; + singleInputElts = (size_t)m.numInputChannels * nnXLen * nnYLen; + singleInputBytes = (size_t)m.numInputChannels * nnXLen * nnYLen * sizeof(float); + singleInputGlobalElts = (size_t)m.numInputGlobalChannels; + singleInputGlobalBytes = (size_t)m.numInputGlobalChannels * sizeof(float); + singleInputMetaElts = (size_t)m.numInputMetaChannels; + singleInputMetaBytes = (size_t)m.numInputMetaChannels * sizeof(float); + singlePolicyPassResultElts = (size_t)(m.numPolicyChannels); + singlePolicyPassResultBytes = (size_t)(m.numPolicyChannels) * sizeof(float); + singlePolicyResultElts = (size_t)(m.numPolicyChannels * nnXLen * nnYLen); + singlePolicyResultBytes = (size_t)(m.numPolicyChannels * nnXLen * nnYLen) * sizeof(float); + singleValueResultElts = (size_t)m.numValueChannels; + singleValueResultBytes = (size_t)m.numValueChannels * sizeof(float); + singleScoreValueResultElts = (size_t)m.numScoreValueChannels; + singleScoreValueResultBytes = (size_t)m.numScoreValueChannels * sizeof(float); + singleOwnershipResultElts = (size_t)m.numOwnershipChannels * nnXLen * nnYLen; + singleOwnershipResultBytes = (size_t)m.numOwnershipChannels * nnXLen * nnYLen * sizeof(float); + + assert(NNModelVersion::getNumSpatialFeatures(m.modelVersion) == m.numInputChannels); + assert(NNModelVersion::getNumGlobalFeatures(m.modelVersion) == m.numInputGlobalChannels); + if(m.numInputMetaChannels > 0) { + assert(SGFMetadata::METADATA_INPUT_NUM_CHANNELS == m.numInputMetaChannels); + } + + userInputBufferBytes = (size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen * sizeof(float); + userInputGlobalBufferBytes = (size_t)m.numInputGlobalChannels * maxBatchSize * sizeof(float); + userInputMetaBufferBytes = (size_t)m.numInputMetaChannels * maxBatchSize * sizeof(float); + policyPassResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * sizeof(float); + policyResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen * sizeof(float); + valueResultBufferBytes = (size_t)maxBatchSize * m.numValueChannels * sizeof(float); + scoreValueResultBufferBytes = (size_t)maxBatchSize * m.numScoreValueChannels * sizeof(float); + ownershipResultBufferBytes = (size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels * sizeof(float); + + userInputBuffer = new float[(size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen]; + userInputGlobalBuffer = new float[(size_t)m.numInputGlobalChannels * maxBatchSize]; + if(m.numInputMetaChannels > 0) + userInputMetaBuffer = new float[(size_t)m.numInputMetaChannels * maxBatchSize]; + else + userInputMetaBuffer = NULL; + + policyPassResults = new float[(size_t)maxBatchSize * m.numPolicyChannels]; + policyResults = new float[(size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen]; + valueResults = new float[(size_t)maxBatchSize * m.numValueChannels]; + + scoreValueResults = new float[(size_t)maxBatchSize * m.numScoreValueChannels]; + ownershipResults = new float[(size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels]; + } + + ~InputBuffers() { + delete[] userInputBuffer; + delete[] userInputGlobalBuffer; + if(userInputMetaBuffer != NULL) + delete[] userInputMetaBuffer; + delete[] policyPassResults; + delete[] policyResults; + delete[] valueResults; + delete[] scoreValueResults; + delete[] ownershipResults; + } + + InputBuffers() = delete; + InputBuffers(const InputBuffers&) = delete; + InputBuffers& operator=(const InputBuffers&) = delete; + +}; + +InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { + return new InputBuffers(loadedModel,maxBatchSize,nnXLen,nnYLen); +} +void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { + delete inputBuffers; +} + +//--------------------------------------------------------------------------------------- + + +void NeuralNet::getOutput( + ComputeHandle* gpuHandle, + InputBuffers* inputBuffers, + int numBatchEltsFilled, + NNResultBuf** inputBufs, + vector& outputs +) { + assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); + assert(numBatchEltsFilled > 0); + const int batchSize = numBatchEltsFilled; + const int nnXLen = gpuHandle->nnXLen; + const int nnYLen = gpuHandle->nnYLen; + const int modelVersion = gpuHandle->model->modelVersion; + + const int numSpatialFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); + const int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); + const int numMetaFeatures = inputBuffers->singleInputMetaElts; + assert(numSpatialFeatures == gpuHandle->model->numInputChannels); + assert(numSpatialFeatures * nnXLen * nnYLen == inputBuffers->singleInputElts); + assert(numGlobalFeatures == inputBuffers->singleInputGlobalElts); + const int numPolicyChannels = gpuHandle->model->numPolicyChannels; + + for(int nIdx = 0; nIdxuserInputBuffer + (inputBuffers->singleInputElts * nIdx); + float* rowGlobalInput = inputBuffers->userInputGlobalBuffer + (inputBuffers->singleInputGlobalElts * nIdx); + float* rowMetaInput = inputBuffers->userInputMetaBuffer + (inputBuffers->singleInputMetaElts * nIdx); + + const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); + const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); + const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); + bool hasRowMeta = inputBufs[nIdx]->hasRowMeta; + std::copy(rowGlobal,rowGlobal+numGlobalFeatures,rowGlobalInput); + if(numMetaFeatures > 0) { + testAssert(rowMeta != NULL); + testAssert(hasRowMeta); + std::copy(rowMeta,rowMeta+numMetaFeatures,rowMetaInput); + } + else { + testAssert(!hasRowMeta); + } + SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, gpuHandle->inputsUseNHWC, inputBufs[nIdx]->symmetry); + } + + Buffers* buffers = gpuHandle->buffers.get(); + ScratchBuffers* scratch = gpuHandle->scratch.get(); + + if(!gpuHandle->usingFP16) { + assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes); + assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes); + assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes); + assert(inputBuffers->policyPassResultBufferBytes == buffers->policyPassBufBytes); + assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); + assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); + assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); + assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); + assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); + assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); + assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); + assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); + assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); + assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); + assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); + assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); + assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); + + CUDA_ERR("getOutput",hipMemcpy(buffers->inputBuf, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); + CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBuf, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); + if(numMetaFeatures > 0) { + CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBuf, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); + } + } + else { + assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytesFloat); + assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytesFloat); + assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytesFloat); + assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); + assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); + assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes*2); + assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes*2); + assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes*2); + assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); + assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); + assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); + assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); + assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); + assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); + assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); + assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); + assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); + assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); + assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); + + CUDA_ERR("getOutput",hipMemcpy(buffers->inputBufFloat, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); + CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBufFloat, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); + if(numMetaFeatures > 0) { + CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBufFloat, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); + } + + customCudaCopyToHalf((const float*)buffers->inputBufFloat,(half*)buffers->inputBuf,inputBuffers->singleInputElts*batchSize); + CUDA_ERR("getOutput",hipPeekAtLastError()); + customCudaCopyToHalf((const float*)buffers->inputGlobalBufFloat,(half*)buffers->inputGlobalBuf,inputBuffers->singleInputGlobalElts*batchSize); + CUDA_ERR("getOutput",hipPeekAtLastError()); + if(numMetaFeatures > 0) { + customCudaCopyToHalf((const float*)buffers->inputMetaBufFloat,(half*)buffers->inputMetaBuf,inputBuffers->singleInputMetaElts*batchSize); + CUDA_ERR("getOutput",hipPeekAtLastError()); + } + } + + gpuHandle->model->apply( + gpuHandle->cudaHandles.get(), + scratch, + batchSize, + gpuHandle->requireExactNNLen, + + buffers->inputBuf, + buffers->inputGlobalBuf, + buffers->inputMetaBuf, + + buffers->policyPassBuf, + buffers->policyBuf, + + buffers->valueBuf, + buffers->scoreValueBuf, + buffers->ownershipBuf, + + buffers->workspaceBuf, + buffers->workspaceBytes + ); + + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyPassResults, buffers->policyPassBuf, inputBuffers->singlePolicyPassResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyResults, buffers->policyBuf, inputBuffers->singlePolicyResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->valueResults, buffers->valueBuf, inputBuffers->singleValueResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->scoreValueResults, buffers->scoreValueBuf, inputBuffers->singleScoreValueResultBytes*batchSize, hipMemcpyDeviceToHost)); + CUDA_ERR("getOutput",hipMemcpy(inputBuffers->ownershipResults, buffers->ownershipBuf, inputBuffers->singleOwnershipResultBytes*batchSize, hipMemcpyDeviceToHost)); + + assert(outputs.size() == batchSize); + + float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; + + for(int row = 0; row < batchSize; row++) { + NNOutput* output = outputs[row]; + assert(output->nnXLen == nnXLen); + assert(output->nnYLen == nnYLen); + float policyOptimism = (float)inputBufs[row]->policyOptimism; + + const float* policyPassSrcBuf = inputBuffers->policyPassResults + row * numPolicyChannels; + const float* policySrcBuf = inputBuffers->policyResults + row * numPolicyChannels * nnXLen * nnYLen; + float* policyProbs = output->policyProbs; + + // These are in logits, the client does the postprocessing to turn them into + // policy probabilities and white game outcome probabilities + // Also we don't fill in the nnHash here either + // Handle version >= 12 policy optimism + if(numPolicyChannels == 2 || (numPolicyChannels == 4 && modelVersion >= 16)) { + if(gpuHandle->usingNHWC) { + for(int i = 0; isymmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; + } + else { + for(int i = 0; isymmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; + } + } + else { + assert(numPolicyChannels == 1); + SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0]; + } + + int numValueChannels = gpuHandle->model->numValueChannels; + assert(numValueChannels == 3); + output->whiteWinProb = inputBuffers->valueResults[row * numValueChannels]; + output->whiteLossProb = inputBuffers->valueResults[row * numValueChannels + 1]; + output->whiteNoResultProb = inputBuffers->valueResults[row * numValueChannels + 2]; + + //As above, these are NOT actually from white's perspective, but rather the player to move. + //As usual the client does the postprocessing. + if(output->whiteOwnerMap != NULL) { + const float* ownershipSrcBuf = inputBuffers->ownershipResults + row * nnXLen * nnYLen; + assert(gpuHandle->model->numOwnershipChannels == 1); + SymmetryHelpers::copyOutputsWithSymmetry(ownershipSrcBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + } + + if(modelVersion >= 9) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 6); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; + output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; + output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 4]; + output->shorttermScoreError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 5]; + } + else if(modelVersion >= 8) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 4); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; + output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; + output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(modelVersion >= 4) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 2); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(modelVersion >= 3) { + int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; + assert(numScoreValueChannels == 1); + output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; + //Version 3 neural nets don't have any second moment output, implicitly already folding it in, so we just use the mean squared + output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else { + ASSERT_UNREACHABLE; + } + } + +} + +//TESTING ---------------------------------------------------------------------------------- + + +bool NeuralNet::testEvaluateConv( + const ConvLayerDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->inChannels; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->outChannels; + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateConv: unexpected input buffer size"); + + void* deviceInput; + void* deviceOutput; + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); + + int maxBatchSize = desiredBatchSize; + + CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); + ConvLayer* convLayer = new ConvLayer(cudaHandles,manager,desc,useFP16,useNHWC); + + size_t workspaceBytes = + convLayer->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); + void* deviceWorkspace; + CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); + + + bool accumulate = false; + convLayer->apply( + cudaHandles, + desiredBatchSize, + accumulate, + deviceInput, + deviceOutput, + deviceWorkspace, + workspaceBytes + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); + + hipFree(deviceWorkspace); + + delete convLayer; + delete manager; + hipFree(deviceInput); + hipFree(deviceOutput); + delete cudaHandles; + + return true; +} + + +bool NeuralNet::testEvaluateBatchNorm( + const BatchNormLayerDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + const vector& maskBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; + size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateBatchNorm: unexpected input buffer size"); + if(numMaskFloats != maskBuffer.size()) + throw StringError("testEvaluateBatchNorm: unexpected mask buffer size"); + + ActivationLayerDesc actDesc; + actDesc.activation = ACTIVATION_IDENTITY; + + void* deviceInput; + void* deviceMask; + void* deviceOutput; + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); + CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); + + BatchNormLayer* batchNormLayer = new BatchNormLayer(cudaHandles,desc,&actDesc,nnXLen,nnYLen,useFP16,useNHWC); + + batchNormLayer->apply( + cudaHandles, + desiredBatchSize, + deviceInput, + deviceMask, + deviceOutput + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); + + delete batchNormLayer; + + hipFree(deviceInput); + hipFree(deviceMask); + hipFree(deviceOutput); + delete cudaHandles; + + return true; +} + + +bool NeuralNet::testEvaluateResidualBlock( + const ResidualBlockDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + const vector& maskBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; + size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateResidualBlock: unexpected input buffer size"); + if(numMaskFloats != maskBuffer.size()) + throw StringError("testEvaluateResidualBlock: unexpected mask buffer size"); + + ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); + + void* deviceInput; + void* deviceMask; + void* deviceScratch; + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); + CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); + + int maxBatchSize = desiredBatchSize; + + CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); + ResidualBlock* residualBlock = new ResidualBlock(cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC); + + size_t workspaceBytes = + residualBlock->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); + void* deviceWorkspace; + CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); + + residualBlock->apply( + cudaHandles, + scratch, + desiredBatchSize, + deviceInput, + deviceScratch, + deviceMask, + deviceWorkspace, + workspaceBytes + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); + + hipFree(deviceWorkspace); + + delete residualBlock; + delete manager; + hipFree(deviceInput); + hipFree(deviceMask); + hipFree(deviceScratch); + delete scratch; + delete cudaHandles; + + return true; +} + +bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( + const GlobalPoolingResidualBlockDesc* desc, + int desiredBatchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const vector& inputBuffer, + const vector& maskBuffer, + vector& outputBuffer +) { + hipDeviceSynchronize(); + CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); + + size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; + size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; + size_t numMaskSumFloats = (size_t)desiredBatchSize; + size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; + + if(numInputFloats != inputBuffer.size()) + throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected input buffer size"); + if(numMaskFloats != maskBuffer.size()) + throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected mask buffer size"); + + ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); + + void* deviceInput; + void* deviceMask; + float* deviceMaskFloatOrig; + float* deviceMaskFloat; + float* deviceMaskSum; + void* deviceScratch; + + CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); + CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); + CUDA_ERR("deviceMaskFloat",hipMalloc(reinterpret_cast(&deviceMaskFloat), numMaskFloats * sizeof(float))); + CUDA_ERR("deviceMaskSum",hipMalloc(reinterpret_cast(&deviceMaskSum), numMaskSumFloats * sizeof(float))); + deviceMaskFloatOrig = deviceMaskFloat; + CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); + + fillMaskFloatBufAndMaskSumBuf(deviceMask, deviceMaskFloat, deviceMaskSum, useFP16, desiredBatchSize, nnXLen, nnYLen); + + int maxBatchSize = desiredBatchSize; + + CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); + GlobalPoolingResidualBlock* residualBlock = new GlobalPoolingResidualBlock( + cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC + ); + + size_t workspaceBytes = + residualBlock->requiredWorkspaceBytes( + cudaHandles,desiredBatchSize + ); + + void* deviceWorkspace; + CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); + + residualBlock->apply( + cudaHandles, + scratch, + desiredBatchSize, + deviceInput, + deviceScratch, + deviceMask, + deviceMaskSum, + deviceWorkspace, + workspaceBytes + ); + + outputBuffer.resize(numOutputFloats); + CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); + + hipFree(deviceWorkspace); + + delete residualBlock; + delete manager; + + hipFree(deviceInput); + hipFree(deviceMask); + hipFree(deviceMaskFloatOrig); + hipFree(deviceMaskSum); + hipFree(deviceScratch); + delete scratch; + delete cudaHandles; + + return true; +} + + +#endif // USE_ROCM_BACKEND From c1a09cf343054b1ad9ba5f93d56ac723bf4aadcc Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 02:44:33 +0200 Subject: [PATCH 09/37] Update --- cpp/neuralnet/rocmbackend_new.cpp | 55 ++++++++++++++----------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/cpp/neuralnet/rocmbackend_new.cpp b/cpp/neuralnet/rocmbackend_new.cpp index af1164f197..af6bee51e0 100644 --- a/cpp/neuralnet/rocmbackend_new.cpp +++ b/cpp/neuralnet/rocmbackend_new.cpp @@ -346,36 +346,30 @@ struct ConvLayer { CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - // if(useFP16 && dilationX <= 1 && dilationY <= 1) { - // (*convolutionAlgorithms)[batchSize].fwd_algo = miopenConvolutionFwdAlgoGEMM; - // } - // else { - const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; - const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - const int requestedAlgoCount = 8; - int returnedAlgoCount = -1; - miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; - CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( - cudaHandles->cudnn, - inputDescriptor, - inputTmp, - filterDescriptor, - filterBuf, - convolutionDescriptor, - outputDescriptor, - outputTmp, - requestedAlgoCount, - &returnedAlgoCount, - results, - workspaceTmp, - workspaceBytes, - true - )); - if(returnedAlgoCount <= 0) - throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); - (*convolutionAlgorithms)[batchSize] = results[0]; - printf("%d / %d\n", batchSize, maxBatchSize); - // } + const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; + const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; + const int requestedAlgoCount = 8; + int returnedAlgoCount = -1; + miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; + CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( + cudaHandles->cudnn, + inputDescriptor, + inputTmp, + filterDescriptor, + filterBuf, + convolutionDescriptor, + outputDescriptor, + outputTmp, + requestedAlgoCount, + &returnedAlgoCount, + results, + workspaceTmp, + workspaceBytes, + false + )); + if(returnedAlgoCount <= 0) + throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); + (*convolutionAlgorithms)[batchSize] = results[0]; } assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); @@ -418,6 +412,7 @@ struct ConvLayer { void* workspaceBuf, size_t workspaceBytes ) const { + accumulate = false; const float alpha = 1.0f; const float beta = accumulate ? 1.0f : 0.0f; CUDNN_ERR(name.c_str(), miopenConvolutionForward( From 0957b88b53515c33c9670a0ac00796557bbc3332 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 03:50:20 +0200 Subject: [PATCH 10/37] Test finished --- cpp/neuralnet/rocmbackend.cpp | 305 ++- cpp/neuralnet/rocmbackend_new.cpp | 3011 ----------------------------- 2 files changed, 245 insertions(+), 3071 deletions(-) delete mode 100644 cpp/neuralnet/rocmbackend_new.cpp diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 260c2c72e8..539f0b91af 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -255,8 +255,11 @@ struct ConvLayer { ByBatchSizeView outputDescriptors; miopenTensorDescriptor_t filterDescriptor; miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size + ByBatchSize* convolutionAlgorithms; //array of one for each batch size void* filterBuf; + void* inputTmp; + void* outputTmp; + void* workspaceTmp; ConvLayer() = delete; ConvLayer(const ConvLayer&) = delete; @@ -296,6 +299,8 @@ struct ConvLayer { inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); int maxBatchSize = manager->maxBatchSize; + int xLen = manager->nnXLen; + int yLen = manager->nnYLen; bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; @@ -329,74 +334,54 @@ struct ConvLayer { CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); } - convolutionAlgorithms = new ByBatchSize(maxBatchSize); + convolutionAlgorithms = new ByBatchSize(maxBatchSize); + + size_t inBytes = maxBatchSize * inChannels * xLen * yLen; + size_t outBytes = maxBatchSize * outChannels * xLen * yLen; + size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize) + 10305856; //1661440; + + CudaUtils::mallocOnDevice(name, inBytes, inputTmp, useFP16); + CudaUtils::mallocOnDevice(name, outBytes, outputTmp, useFP16); + CudaUtils::mallocOnDevice(name, workspaceBytes, workspaceTmp, useFP16); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - // if(useFP16 && dilationX <= 1 && dilationY <= 1) { - // (*convolutionAlgorithms)[batchSize].solution_id = 0; - // continue; - // } - // else { - const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; - const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - size_t requestedAlgoCount = 8; - size_t returnedAlgoCount = -1; - miopenConvSolution_t solutions[2 * requestedAlgoCount]; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( + const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; + const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; + const int requestedAlgoCount = 8; + int returnedAlgoCount = -1; + miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; + CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( cudaHandles->cudnn, - filterDescriptor, inputDescriptor, - convolutionDescriptor, - outputDescriptor, - &requestedAlgoCount - )); - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptor, - convolutionDescriptor, - outputDescriptor, - requestedAlgoCount, - &returnedAlgoCount, - solutions - )); - if(returnedAlgoCount <= 0) - throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); - (*convolutionAlgorithms)[batchSize] = solutions[0]; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( - cudaHandles->cudnn, + inputTmp, filterDescriptor, - inputDescriptor, + filterBuf, convolutionDescriptor, outputDescriptor, - (*convolutionAlgorithms)[batchSize].solution_id + outputTmp, + requestedAlgoCount, + &returnedAlgoCount, + results, + workspaceTmp, + workspaceBytes, + false )); - // } + if(returnedAlgoCount <= 0) + throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); + (*convolutionAlgorithms)[batchSize] = results[0]; } assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - if(filterNHWC) { - vector weightsTransposed(desc->weights.size()); - for(int y = 0; y < convYSize; y++) { - for(int x = 0; x < convXSize; x++) { - for(int ic = 0; ic < inChannels; ic++) { - for(int oc = 0; oc < outChannels; oc++) { - weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = - desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; - } - } - } - } - CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); - hipDeviceSynchronize(); - } - else - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); } ~ConvLayer() { hipFree(filterBuf); + hipFree(inputTmp); + hipFree(outputTmp); + hipFree(workspaceTmp); miopenDestroyTensorDescriptor(filterDescriptor); miopenDestroyConvolutionDescriptor(convolutionDescriptor); delete convolutionAlgorithms; @@ -407,13 +392,12 @@ struct ConvLayer { int batchSize ) const { size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( cudaHandles->cudnn, filterDescriptor, inputDescriptors[batchSize], convolutionDescriptor, outputDescriptors[batchSize], - (*convolutionAlgorithms)[batchSize].solution_id, &workspaceBytes )); return workspaceBytes; @@ -428,25 +412,223 @@ struct ConvLayer { void* workspaceBuf, size_t workspaceBytes ) const { + accumulate = false; const float alpha = 1.0f; const float beta = accumulate ? 1.0f : 0.0f; - CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( + CUDNN_ERR(name.c_str(), miopenConvolutionForward( cudaHandles->cudnn, - filterDescriptor, - filterBuf, + &alpha, inputDescriptors[batchSize], inputBuf, + filterDescriptor, + filterBuf, convolutionDescriptor, + (*convolutionAlgorithms)[batchSize].fwd_algo, + &beta, outputDescriptors[batchSize], outputBuf, workspaceBuf, - workspaceBytes, - (*convolutionAlgorithms)[batchSize].solution_id + workspaceBytes )); } }; +// New ConvLayer structure with MIOpen API + +// struct ConvLayer { +// const string name; +// const int inChannels; +// const int outChannels; +// ByBatchSizeView inputDescriptors; +// ByBatchSizeView outputDescriptors; +// miopenTensorDescriptor_t filterDescriptor; +// miopenConvolutionDescriptor_t convolutionDescriptor; +// ByBatchSize* convolutionAlgorithms; //array of one for each batch size +// void* filterBuf; + +// ConvLayer() = delete; +// ConvLayer(const ConvLayer&) = delete; +// ConvLayer& operator=(const ConvLayer&) = delete; + +// ConvLayer( +// CudaHandles* cudaHandles, +// CudnnManager* manager, +// const ConvLayerDesc* desc, +// bool useFP16, +// bool useNHWC +// ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) +// {} + +// ConvLayer( +// CudaHandles* cudaHandles, +// CudnnManager* manager, +// const ConvLayerDesc* desc, +// bool useFP16, +// bool useNHWCIn, +// bool useNHWCOut +// ) : +// name(desc->name), +// inChannels(desc->inChannels), +// outChannels(desc->outChannels) +// { +// int convYSize = desc->convYSize; +// int convXSize = desc->convXSize; +// int dilationY = desc->dilationY; +// int dilationX = desc->dilationX; +// int paddingX = (convXSize / 2) * dilationX; +// int paddingY = (convYSize / 2) * dilationY; + +// assert(convXSize % 2 == 1); +// assert(convYSize % 2 == 1); + +// inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); +// outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); +// int maxBatchSize = manager->maxBatchSize; + +// bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; + +// CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); +// CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( +// filterDescriptor, +// (useFP16 ? miopenHalf : miopenFloat), +// outChannels, +// inChannels, +// convYSize, +// convXSize +// )); + +// int yStride = 1; +// int xStride = 1; + + +// CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); +// CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( +// convolutionDescriptor, +// miopenConvolution, +// paddingY, +// paddingX, +// yStride, +// xStride, +// dilationY, +// dilationX +// )); +// if(useFP16) { +// int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs +// CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); +// } + +// convolutionAlgorithms = new ByBatchSize(maxBatchSize); + +// for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { +// const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; +// const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; +// size_t requestedAlgoCount = 8; +// size_t returnedAlgoCount = -1; +// miopenConvSolution_t solutions[2 * requestedAlgoCount]; +// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( +// cudaHandles->cudnn, +// filterDescriptor, +// inputDescriptor, +// convolutionDescriptor, +// outputDescriptor, +// &requestedAlgoCount +// )); +// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( +// cudaHandles->cudnn, +// filterDescriptor, +// inputDescriptor, +// convolutionDescriptor, +// outputDescriptor, +// requestedAlgoCount, +// &returnedAlgoCount, +// solutions +// )); +// if(returnedAlgoCount <= 0) +// throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); +// (*convolutionAlgorithms)[batchSize] = solutions[0]; +// CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( +// cudaHandles->cudnn, +// filterDescriptor, +// inputDescriptor, +// convolutionDescriptor, +// outputDescriptor, +// (*convolutionAlgorithms)[batchSize].solution_id +// )); +// } + +// assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); + +// if(filterNHWC) { +// vector weightsTransposed(desc->weights.size()); +// for(int y = 0; y < convYSize; y++) { +// for(int x = 0; x < convXSize; x++) { +// for(int ic = 0; ic < inChannels; ic++) { +// for(int oc = 0; oc < outChannels; oc++) { +// weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = +// desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; +// } +// } +// } +// } +// CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); +// hipDeviceSynchronize(); +// } +// else +// CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); +// } + +// ~ConvLayer() { +// hipFree(filterBuf); +// miopenDestroyTensorDescriptor(filterDescriptor); +// miopenDestroyConvolutionDescriptor(convolutionDescriptor); +// delete convolutionAlgorithms; +// } + +// size_t requiredWorkspaceBytes( +// CudaHandles* cudaHandles, +// int batchSize +// ) const { +// size_t workspaceBytes = 0; +// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( +// cudaHandles->cudnn, +// filterDescriptor, +// inputDescriptors[batchSize], +// convolutionDescriptor, +// outputDescriptors[batchSize], +// (*convolutionAlgorithms)[batchSize].solution_id, +// &workspaceBytes +// )); +// return workspaceBytes; +// } + +// void apply( +// CudaHandles* cudaHandles, +// int batchSize, +// bool accumulate, +// void* inputBuf, +// void* outputBuf, +// void* workspaceBuf, +// size_t workspaceBytes +// ) const { +// const float alpha = 1.0f; +// const float beta = accumulate ? 1.0f : 0.0f; +// CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( +// cudaHandles->cudnn, +// filterDescriptor, +// filterBuf, +// inputDescriptors[batchSize], +// inputBuf, +// convolutionDescriptor, +// outputDescriptors[batchSize], +// outputBuf, +// workspaceBuf, +// workspaceBytes, +// (*convolutionAlgorithms)[batchSize].solution_id +// )); +// } + +// }; //--------------------------------------------------------------------------------- @@ -2352,6 +2534,9 @@ ComputeHandle* NeuralNet::createComputeHandle( logger->write( "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name ); + logger->write( + "MIOpen finding convolution algorithms for GPU " + string(prop.name) + ". This may take a while, please wait......" + ); } ComputeHandle* gpuHandle = new ComputeHandle( diff --git a/cpp/neuralnet/rocmbackend_new.cpp b/cpp/neuralnet/rocmbackend_new.cpp deleted file mode 100644 index af6bee51e0..0000000000 --- a/cpp/neuralnet/rocmbackend_new.cpp +++ /dev/null @@ -1,3011 +0,0 @@ -#ifdef USE_ROCM_BACKEND - -#include "../neuralnet/rocmerrorcheck.h" -#include "../neuralnet/rocmincludes.h" - -#include "../neuralnet/rocmhelpers.h" -#include "../neuralnet/rocmutils.h" -#include "../neuralnet/modelversion.h" -#include "../neuralnet/nninterface.h" -#include "../neuralnet/nninputs.h" -#include "../neuralnet/sgfmetadata.h" -#include "../neuralnet/nneval.h" -#include "../neuralnet/desc.h" - -#include "../core/simpleallocator.h" -#include "../core/test.h" - -#include "../external/half-2.2.0/include/half.hpp" - -//------------------------ -#include "../core/using.h" -//------------------------ - -using half_t = half_float::half; - -//Define this to print out some of the intermediate values of the neural net -//#define DEBUG_INTERMEDIATE_VALUES - -void NeuralNet::globalInitialize() { - //Empty for cudnn backend -} - -void NeuralNet::globalCleanup() { - hipDeviceReset(); -} - -struct CudaHandles { - hipblasHandle_t cublas; - miopenHandle_t cudnn; - const int majorComputeCapability; - const int minorComputeCapability; - - CudaHandles(int major, int minor) - : majorComputeCapability(major), - minorComputeCapability(minor) - { - CUBLAS_ERR("CudaHandles",hipblasCreate(&cublas)); - CUDNN_ERR("CudaHandles",miopenCreate(&cudnn)); - } - - ~CudaHandles() { - hipblasDestroy(cublas); - miopenDestroy(cudnn); - } - - static CudaHandles* cudaHandlesTesting() { - const int gpuIdxForThisThread = 0; - hipDeviceProp_t prop; - hipGetDeviceProperties(&prop,gpuIdxForThisThread); - return new CudaHandles(prop.major, prop.minor); - } - - CudaHandles(const CudaHandles&) = delete; - CudaHandles& operator=(const CudaHandles&) = delete; -}; - -//--------------------------------------------------------------------------------- - -template -struct ByBatchSize { - const int maxBatchSize; - T* data; - miopenStatus_t (*destroyFunc)(T); - - ByBatchSize() - : maxBatchSize(0), data(nullptr), destroyFunc(nullptr) - {} - - ByBatchSize( - int maxBatchSize_ - ) : maxBatchSize(maxBatchSize_), data(nullptr), destroyFunc(nullptr) { - data = new T[maxBatchSize]; - } - - ByBatchSize(const ByBatchSize&) = delete; - ByBatchSize& operator=(const ByBatchSize&) = delete; - - ~ByBatchSize() { - if(destroyFunc != nullptr && data != nullptr) { - for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - (*destroyFunc)(data[batchSize-1]); - } - } - if(data != nullptr) { - delete[] data; - data = nullptr; - } - } - T& operator[](int batchSize) { - return data[batchSize-1]; - } - const T& operator[](int batchSize) const { - return data[batchSize-1]; - } -}; - -template -struct ByBatchSizeView { - int maxBatchSize; - T* data; - - ByBatchSizeView() - : maxBatchSize(0), data(nullptr) - {} - - ByBatchSizeView(const ByBatchSize& toView) - : maxBatchSize(toView.maxBatchSize), data(toView.data) - {} - ByBatchSizeView& operator=(const ByBatchSize& toView) { - maxBatchSize = toView.maxBatchSize; - data = toView.data; - } - - ~ByBatchSizeView() { - } - T& operator[](int batchSize) { - return data[batchSize-1]; - } - const T& operator[](int batchSize) const { - return data[batchSize-1]; - } -}; - -//--------------------------------------------------------------------------------- - - -//channels, useFP16, useNHWC -typedef std::tuple CudnnTensorDesc4DKey; - -struct CudnnManager { - const string name; - const int maxBatchSize; - const int nnXLen; - const int nnYLen; - std::map*> tensorDesc4DByBatchSizeByKey; - - CudnnManager(string name_, int maxBatchSize_, int nnXLen_, int nnYLen_) - :name(name_), - maxBatchSize(maxBatchSize_), - nnXLen(nnXLen_), - nnYLen(nnYLen_), - tensorDesc4DByBatchSizeByKey() - { - } - - ~CudnnManager() { - for(auto& iter: tensorDesc4DByBatchSizeByKey) { - delete iter.second; - } - } - - ByBatchSizeView getTensorDesc4DByBatchSize( - int channels, bool useFP16, bool useNHWC - ) { - auto iter = tensorDesc4DByBatchSizeByKey.find({channels, useFP16, useNHWC}); - if(iter != tensorDesc4DByBatchSizeByKey.end()) { - return ByBatchSizeView(*(iter->second)); - } - ByBatchSize* descs = new ByBatchSize(maxBatchSize); - for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - miopenTensorDescriptor_t& desc = (*descs)[batchSize]; - CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&desc)); - CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( - desc, - (useFP16 ? miopenHalf : miopenFloat), - batchSize, - channels, - nnYLen, - nnXLen - )); - } - descs->destroyFunc = miopenDestroyTensorDescriptor; - tensorDesc4DByBatchSizeByKey[{channels, useFP16, useNHWC}] = descs; - return ByBatchSizeView(*descs); - } -}; - -//--------------------------------------------------------------------------------- - -struct ScratchBuffers { - - const size_t batchXYFloatBytes; - const size_t batchFloatBytes; - const size_t batchXYBytes; - const size_t batchBytes; - - SimpleAllocator* allocator; - - // Not scratch, but convenient to have here - void* zeroBuf; - void* oneBuf; - - ScratchBuffers() = delete; - ScratchBuffers(const ScratchBuffers&) = delete; - ScratchBuffers& operator=(const ScratchBuffers&) = delete; - - ScratchBuffers(int maxBatchSize, int nnXLen, int nnYLen, bool useFP16) - : batchXYFloatBytes((size_t)maxBatchSize * nnXLen * nnYLen * sizeof(float)), - batchFloatBytes((size_t)maxBatchSize * sizeof(float)), - batchXYBytes((size_t)maxBatchSize * nnXLen * nnYLen * (useFP16 ? sizeof(half_t) : sizeof(float))), - batchBytes((size_t)maxBatchSize * (useFP16 ? sizeof(half_t) : sizeof(float))) - { - std::function allocateFunc = [](size_t size) { - void* buf; - CUDA_ERR("ScratchBuffers",hipMalloc(&buf, size)); - return buf; - }; - std::function releaseFunc = [](void* buf) { - hipFree(buf); - }; - - allocator = new SimpleAllocator(allocateFunc, releaseFunc); - - CudaUtils::hostMallocZeroOneBufs(zeroBuf, oneBuf, useFP16); - } - ~ScratchBuffers() { - delete allocator; - free(zeroBuf); - free(oneBuf); - } - - size_t getBufSizeXY(int channels) const { - return channels * batchXYBytes; - } - size_t getBufSizeXYFloat(int channels) const { - return channels * batchXYFloatBytes; - } - size_t getBufSizeFloat(int channels) const { - return channels * batchFloatBytes; - } - size_t getBufSize(int channels) const { - return channels * batchBytes; - } - -}; - - -//--------------------------------------------------------------------------------- - -struct ConvLayer { - const string name; - const int inChannels; - const int outChannels; - ByBatchSizeView inputDescriptors; - ByBatchSizeView outputDescriptors; - miopenTensorDescriptor_t filterDescriptor; - miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size - void* filterBuf; - void* inputTmp; - void* outputTmp; - void* workspaceTmp; - - ConvLayer() = delete; - ConvLayer(const ConvLayer&) = delete; - ConvLayer& operator=(const ConvLayer&) = delete; - - ConvLayer( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ConvLayerDesc* desc, - bool useFP16, - bool useNHWC - ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) - {} - - ConvLayer( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ConvLayerDesc* desc, - bool useFP16, - bool useNHWCIn, - bool useNHWCOut - ) : - name(desc->name), - inChannels(desc->inChannels), - outChannels(desc->outChannels) - { - int convYSize = desc->convYSize; - int convXSize = desc->convXSize; - int dilationY = desc->dilationY; - int dilationX = desc->dilationX; - int paddingX = (convXSize / 2) * dilationX; - int paddingY = (convYSize / 2) * dilationY; - - assert(convXSize % 2 == 1); - assert(convYSize % 2 == 1); - - inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); - outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); - int maxBatchSize = manager->maxBatchSize; - int xLen = manager->nnXLen; - int yLen = manager->nnYLen; - - bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; - - CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); - CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( - filterDescriptor, - (useFP16 ? miopenHalf : miopenFloat), - outChannels, - inChannels, - convYSize, - convXSize - )); - - int yStride = 1; - int xStride = 1; - - - CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); - CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( - convolutionDescriptor, - miopenConvolution, - paddingY, - paddingX, - yStride, - xStride, - dilationY, - dilationX - )); - if(useFP16) { - int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs - CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); - } - - convolutionAlgorithms = new ByBatchSize(maxBatchSize); - - size_t inBytes = maxBatchSize * inChannels * xLen * yLen; - size_t outBytes = maxBatchSize * outChannels * xLen * yLen; - size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize); - - CudaUtils::mallocOnDevice(name, inBytes, inputTmp, useFP16); - CudaUtils::mallocOnDevice(name, outBytes, outputTmp, useFP16); - CudaUtils::mallocOnDevice(name, workspaceBytes, workspaceTmp, useFP16); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); - - for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; - const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - const int requestedAlgoCount = 8; - int returnedAlgoCount = -1; - miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; - CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( - cudaHandles->cudnn, - inputDescriptor, - inputTmp, - filterDescriptor, - filterBuf, - convolutionDescriptor, - outputDescriptor, - outputTmp, - requestedAlgoCount, - &returnedAlgoCount, - results, - workspaceTmp, - workspaceBytes, - false - )); - if(returnedAlgoCount <= 0) - throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); - (*convolutionAlgorithms)[batchSize] = results[0]; - } - - assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); - } - - ~ConvLayer() { - hipFree(filterBuf); - hipFree(inputTmp); - hipFree(outputTmp); - hipFree(workspaceTmp); - miopenDestroyTensorDescriptor(filterDescriptor); - miopenDestroyConvolutionDescriptor(convolutionDescriptor); - delete convolutionAlgorithms; - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptors[batchSize], - convolutionDescriptor, - outputDescriptors[batchSize], - &workspaceBytes - )); - return workspaceBytes; - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - bool accumulate, - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - accumulate = false; - const float alpha = 1.0f; - const float beta = accumulate ? 1.0f : 0.0f; - CUDNN_ERR(name.c_str(), miopenConvolutionForward( - cudaHandles->cudnn, - &alpha, - inputDescriptors[batchSize], - inputBuf, - filterDescriptor, - filterBuf, - convolutionDescriptor, - (*convolutionAlgorithms)[batchSize].fwd_algo, - &beta, - outputDescriptors[batchSize], - outputBuf, - workspaceBuf, - workspaceBytes - )); - } - -}; - - -//--------------------------------------------------------------------------------- - -struct BatchNormLayer { - const string name; - const int numChannels; - const float epsilon; - const int activation; - const int nnXLen; - const int nnYLen; - - const bool usingFP16; - const bool usingNHWC; - - void* mergedScaleBuf; - void* mergedBiasBuf; - - BatchNormLayer() = delete; - BatchNormLayer(const BatchNormLayer&) = delete; - BatchNormLayer& operator=(const BatchNormLayer&) = delete; - - BatchNormLayer( - CudaHandles* cudaHandles, - const BatchNormLayerDesc* desc, - const ActivationLayerDesc* actDesc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - numChannels(desc->numChannels), - epsilon(desc->epsilon), - activation(actDesc->activation), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC) - { - (void)cudaHandles; - - assert(desc->mean.size() == numChannels); - assert(desc->variance.size() == numChannels); - assert(desc->scale.size() == numChannels); - assert(desc->bias.size() == numChannels); - assert(desc->mergedScale.size() == numChannels); - assert(desc->mergedBias.size() == numChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->mergedScale,mergedScaleBuf,useFP16); - CudaUtils::mallocAndCopyToDevice(name,desc->mergedBias,mergedBiasBuf,useFP16); - } - ~BatchNormLayer() { - hipFree(mergedScaleBuf); - hipFree(mergedBiasBuf); - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - void* inputBuf, - const void* maskBuf, //ok to be null - void* outputBuf - ) const { - (void)cudaHandles; - if(!usingFP16) { - if(!usingNHWC) - customCudaApplyCScaleBiasNCHW((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, - (const float*)maskBuf, - batchSize,numChannels,nnXLen*nnYLen,activation); - else - customCudaApplyCScaleBiasNHWC((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, - (const float*)maskBuf, - batchSize,nnXLen*nnYLen,numChannels,activation); - } - else { - if(!usingNHWC) - customCudaApplyCScaleBiasNCHW((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, - (const half*)maskBuf, - batchSize,numChannels,nnXLen*nnYLen,activation); - else - customCudaApplyCScaleBiasNHWC((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, - (const half*)maskBuf, - batchSize,nnXLen*nnYLen,numChannels,activation); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - - } - -}; - - -//--------------------------------------------------------------------------------- - -struct MatMulLayer { - const string name; - const int inChannels; - const int outChannels; - const bool usingFP16; - void* matBuf; - - MatMulLayer() = delete; - MatMulLayer(const MatMulLayer&) = delete; - MatMulLayer& operator=(const MatMulLayer&) = delete; - - MatMulLayer( - CudaHandles* cudaHandles, - const MatMulLayerDesc* desc, - bool useFP16 - ) : - name(desc->name), - inChannels(desc->inChannels), - outChannels(desc->outChannels), - usingFP16(useFP16) - { - (void)cudaHandles; - - if(inChannels > 0 && outChannels > 0) { - assert(desc->weights.size() == inChannels * outChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,matBuf,useFP16); - } - else { - matBuf = NULL; - } - } - - ~MatMulLayer() { - if(inChannels > 0 && outChannels > 0) - hipFree(matBuf); - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles - ) const { - (void)cudaHandles; - size_t workspaceBytes = 0; - return workspaceBytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - (void)workspaceBuf; - (void)workspaceBytes; - assert(inChannels > 0 && outChannels > 0); - - if(!usingFP16) { - const float alpha = 1.0f; - const float beta = 0.0f; - CUBLAS_ERR(name.c_str(),hipblasSgemm( - cudaHandles->cublas, - HIPBLAS_OP_N, - HIPBLAS_OP_N, - outChannels, - batchSize, - inChannels, - &alpha, - (const float*)matBuf,outChannels, - (const float*)inputBuf,inChannels, - &beta, - (float*)outputBuf,outChannels - )); - } - else { - const hipblasHalf* alpha = (const hipblasHalf*)scratch->oneBuf; - const hipblasHalf* beta = (const hipblasHalf*)scratch->zeroBuf; - CUBLAS_ERR(name.c_str(),hipblasHgemm( - cudaHandles->cublas, - HIPBLAS_OP_N, - HIPBLAS_OP_N, - outChannels, - batchSize, - inChannels, - alpha, - (const hipblasHalf*)matBuf,outChannels, - (const hipblasHalf*)inputBuf,inChannels, - beta, - (hipblasHalf*)outputBuf,outChannels - )); - } - - } - -}; - -//--------------------------------------------------------------------------------- - -struct MatBiasLayer { - const string name; - const int numChannels; - const bool usingFP16; - const int activation; - - void* biasBuf; - - MatBiasLayer() = delete; - MatBiasLayer(const MatBiasLayer&) = delete; - MatBiasLayer& operator=(const MatBiasLayer&) = delete; - - MatBiasLayer( - CudaHandles* cudaHandles, - const MatBiasLayerDesc* desc, - bool useFP16, - int activation_ - ) : - name(desc->name), - numChannels(desc->numChannels), - usingFP16(useFP16), - activation(activation_) - { - (void)cudaHandles; - if(numChannels > 0) { - assert(desc->weights.size() == numChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,biasBuf,useFP16); - } - else - biasBuf = NULL; - } - - ~MatBiasLayer() { - if(numChannels > 0) - hipFree(biasBuf); - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - void* matBuf - ) const { - (void)cudaHandles; - assert(numChannels > 0); - if(!usingFP16) { - customCudaAddCBiasInplaceNC((float*)matBuf,(const float*)biasBuf,batchSize,numChannels,activation); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - else { - customCudaAddCBiasInplaceNC((half*)matBuf,(const half*)biasBuf,batchSize,numChannels,activation); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - } - -}; - -//--------------------------------------------------------------------------------- - -struct NormActConv { - const BatchNormLayer norm; - const ConvLayer conv; - - const int inChannels; - const int outChannels; - const int nnXLen; - const int nnYLen; - const bool usingFP16; - const bool usingNHWC; - - NormActConv() = delete; - NormActConv(const NormActConv&) = delete; - NormActConv& operator=(const NormActConv&) = delete; - - NormActConv( - CudaHandles* cudaHandles, - CudnnManager* manager, - const BatchNormLayerDesc* normDesc, - const ActivationLayerDesc* actDesc, - const ConvLayerDesc* convDesc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): norm(cudaHandles,normDesc,actDesc,nnX,nnY,useFP16,useNHWC), - conv(cudaHandles,manager,convDesc,useFP16,useNHWC), - inChannels(norm.numChannels), - outChannels(conv.outChannels), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC) - { - assert(norm.numChannels == conv.inChannels); - } - - ~NormActConv() - {} - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - bool accumulate, - void* inBuf, - void* inScratchBuf, - void* outBuf, - void* maskBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - norm.apply(cudaHandles,batchSize,inBuf,maskBuf,inScratchBuf); -#ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("AFTER NORM "), inScratchBuf, batchSize, inChannels, nnXLen, nnYLen, usingNHWC, usingFP16); -#endif - conv.apply(cudaHandles,batchSize,accumulate,inScratchBuf,outBuf,workspaceBuf,workspaceBytes); - } - -}; - - -//--------------------------------------------------------------------------------- - -struct ResidualBlock { - const string name; - const NormActConv normActConv1; - const NormActConv normActConv2; - - ResidualBlock() = delete; - ResidualBlock(const ResidualBlock&) = delete; - ResidualBlock& operator=(const ResidualBlock&) = delete; - - ResidualBlock( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ResidualBlockDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): name(desc->name), - normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->regularConv,nnX,nnY,useFP16,useNHWC), - normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC) - { - } - - ~ResidualBlock() - {} - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* trunkBuf, - void* trunkScratchBuf, - void* maskBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf midIn(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,midIn.buf,maskBuf,workspaceBuf,workspaceBytes); - normActConv2.apply(cudaHandles,batchSize,true,midIn.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); - } - -}; - - -//---------------------------------------------------------------------------- - - -struct GlobalPoolingResidualBlock { - const string name; - const BatchNormLayer preBN; - const ConvLayer regularConv; - const ConvLayer gpoolConv; - const BatchNormLayer gpoolBN; - const MatMulLayer gpoolToBiasMul; - const NormActConv normActConv2; - - const int nnXLen; - const int nnYLen; - const int regularChannels; - const int gpoolChannels; - const bool usingFP16; - const bool usingNHWC; - - GlobalPoolingResidualBlock() = delete; - GlobalPoolingResidualBlock(const GlobalPoolingResidualBlock&) = delete; - GlobalPoolingResidualBlock& operator=(const GlobalPoolingResidualBlock&) = delete; - - GlobalPoolingResidualBlock( - CudaHandles* cudaHandles, - CudnnManager* manager, - const GlobalPoolingResidualBlockDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): name(desc->name), - preBN(cudaHandles,&desc->preBN,&desc->preActivation,nnX,nnY,useFP16,useNHWC), - regularConv(cudaHandles,manager,&desc->regularConv,useFP16,useNHWC), - gpoolConv(cudaHandles,manager,&desc->gpoolConv,useFP16,useNHWC), - gpoolBN(cudaHandles,&desc->gpoolBN,&desc->gpoolActivation,nnX,nnY,useFP16,useNHWC), - gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,useFP16), - normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC), - nnXLen(nnX), - nnYLen(nnY), - regularChannels(desc->regularConv.outChannels), - gpoolChannels(desc->gpoolConv.outChannels), - usingFP16(useFP16), - usingNHWC(useNHWC) - { - } - - ~GlobalPoolingResidualBlock() { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = regularConv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolConv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*gpoolChannels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* trunkBuf, - void* trunkScratchBuf, - void* maskBuf, - float* maskSumBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf regularOut(scratch->allocator, scratch->getBufSizeXY(regularChannels)); - SizedBuf regularScratch(scratch->allocator, scratch->getBufSizeXY(regularChannels)); - SizedBuf gpoolOut(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); - SizedBuf gpoolOut2(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); - SizedBuf gpoolConcat(scratch->allocator, scratch->getBufSize(gpoolChannels*3)); - SizedBuf gpoolBias(scratch->allocator, scratch->getBufSize(regularChannels)); - - preBN.apply(cudaHandles,batchSize,trunkBuf,maskBuf,trunkScratchBuf); - regularConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,regularOut.buf,workspaceBuf,workspaceBytes); - gpoolConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,gpoolOut.buf,workspaceBuf,workspaceBytes); - gpoolBN.apply(cudaHandles,batchSize,gpoolOut.buf,maskBuf,gpoolOut2.buf); - - if(!usingFP16) { - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const float*)maskBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const float*)maskBuf,maskSumBuf); - } - else { - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const half*)maskBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const half*)maskBuf,maskSumBuf); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,gpoolConcat.buf,gpoolBias.buf,workspaceBuf,workspaceBytes); - - if(!usingFP16) { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); - } - else { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - normActConv2.apply(cudaHandles,batchSize,true,regularOut.buf,regularScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); - } - -}; - -//------------------------------------------------------------------------------ - -struct BlockStack { - const int numBlocks; - const int trunkNumChannels; - const int nnXLen; - const int nnYLen; - const bool usingFP16; - const bool usingNHWC; - vector> blocks; - - BlockStack() = delete; - BlockStack(const BlockStack&) = delete; - BlockStack& operator=(const BlockStack&) = delete; - - BlockStack( - CudaHandles* cudaHandles, - CudnnManager* manager, - int nBlocks, - int trunkChannels, - const std::vector>& descBlocks, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ); - ~BlockStack(); - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const; - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - void* trunkScratchBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const; - -}; - -//------------------------------------------------------------------------------ - -struct NestedBottleneckResidualBlock { - const string name; - const NormActConv normActConv1; - const BlockStack blocks; - const NormActConv normActConv2; - - NestedBottleneckResidualBlock() = delete; - NestedBottleneckResidualBlock(const NestedBottleneckResidualBlock&) = delete; - NestedBottleneckResidualBlock& operator=(const NestedBottleneckResidualBlock&) = delete; - - NestedBottleneckResidualBlock( - CudaHandles* cudaHandles, - CudnnManager* manager, - const NestedBottleneckResidualBlockDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): name(desc->name), - normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->preConv,nnX,nnY,useFP16,useNHWC), - blocks(cudaHandles,manager,desc->numBlocks,desc->preConv.outChannels,desc->blocks,nnX,nnY,useFP16,useNHWC), - normActConv2(cudaHandles,manager,&desc->postBN,&desc->postActivation,&desc->postConv,nnX,nnY,useFP16,useNHWC) - { - } - - ~NestedBottleneckResidualBlock() - {} - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* trunkBuf, - void* trunkScratchBuf, - void* maskBuf, - float* maskSumBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf mid(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - assert(normActConv1.outChannels == normActConv2.inChannels); - normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,mid.buf,maskBuf,workspaceBuf,workspaceBytes); - blocks.apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskSumBuf, - mid.buf, - midScratch.buf, - workspaceBuf, - workspaceBytes - ); - normActConv2.apply(cudaHandles,batchSize,true,mid.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); - } - -}; - -//------------------------------------------------------------------------------ - -BlockStack::BlockStack( - CudaHandles* cudaHandles, - CudnnManager* manager, - int nBlocks, - int trunkChannels, - const std::vector>& descBlocks, - int nnX, - int nnY, - bool useFP16, - bool useNHWC -) : - numBlocks(nBlocks), - trunkNumChannels(trunkChannels), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC) -{ - assert(numBlocks == descBlocks.size()); - for(int i = 0; irequiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { - GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); - b = block->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { - NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); - b = block->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - else { - ASSERT_UNREACHABLE; - } - } - return bytes; -} - -void BlockStack::apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - void* trunkScratchBuf, - void* workspaceBuf, - size_t workspaceBytes -) const { - - for(int i = 0; iapply( - cudaHandles, - scratch, - batchSize, - trunkBuf, - trunkScratchBuf, - maskBuf, - workspaceBuf, - workspaceBytes - ); - } - else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { - GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); - block->apply( - cudaHandles, - scratch, - batchSize, - trunkBuf, - trunkScratchBuf, - maskBuf, - maskSumBuf, - workspaceBuf, - workspaceBytes - ); - } - else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { - NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); - block->apply( - cudaHandles, - scratch, - batchSize, - trunkBuf, - trunkScratchBuf, - maskBuf, - maskSumBuf, - workspaceBuf, - workspaceBytes - ); - } - else { - ASSERT_UNREACHABLE; - } - } -} -//------------------------------------------------------------------------------ - -struct SGFMetadataEncoder { - const string name; - - const bool usingFP16; - - const MatMulLayer mul1; - const MatBiasLayer bias1; - const MatMulLayer mul2; - const MatBiasLayer bias2; - const MatMulLayer mul3; - - SGFMetadataEncoder() = delete; - SGFMetadataEncoder(const SGFMetadataEncoder&) = delete; - SGFMetadataEncoder& operator=(const SGFMetadataEncoder&) = delete; - - SGFMetadataEncoder( - CudaHandles* cudaHandles, - const SGFMetadataEncoderDesc* desc, - bool useFP16 - ) : - name(desc->name), - usingFP16(useFP16), - mul1(cudaHandles,&desc->mul1,useFP16), - bias1(cudaHandles,&desc->bias1,useFP16,desc->act1.activation), - mul2(cudaHandles,&desc->mul2,useFP16), - bias2(cudaHandles,&desc->bias2,useFP16,desc->act2.activation), - mul3(cudaHandles,&desc->mul3,useFP16) - { - } - - ~SGFMetadataEncoder() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - (void)batchSize; - size_t bytes = 0; - size_t b; - - b = mul1.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = mul2.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = mul3.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf internalBuf1(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); - SizedBuf internalBuf2(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); - - mul1.apply(cudaHandles,scratch,batchSize,inputBuf,internalBuf1.buf,workspaceBuf,workspaceBytes); - bias1.apply(cudaHandles,batchSize,internalBuf1.buf); - mul2.apply(cudaHandles,scratch,batchSize,internalBuf1.buf,internalBuf2.buf,workspaceBuf,workspaceBytes); - bias2.apply(cudaHandles,batchSize,internalBuf2.buf); - mul3.apply(cudaHandles,scratch,batchSize,internalBuf2.buf,outputBuf,workspaceBuf,workspaceBytes); - } - -}; - - -//---------------------------------------------------------------------------- - -struct Trunk { - const string name; - const int modelVersion; - const int numBlocks; - const int trunkNumChannels; - - const int nnXLen; - const int nnYLen; - const bool usingFP16; - const bool usingNHWC; - - std::unique_ptr initialConv; - std::unique_ptr initialMatMul; - std::unique_ptr sgfMetadataEncoder; - const BlockStack blocks; - std::unique_ptr trunkTipBN; - - Trunk() = delete; - Trunk(const Trunk&) = delete; - Trunk& operator=(const Trunk&) = delete; - - Trunk( - CudaHandles* cudaHandles, - CudnnManager* manager, - const TrunkDesc* desc, - int nnX, - int nnY, - bool inputsUseNHWC, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - numBlocks(desc->numBlocks), - trunkNumChannels(desc->trunkNumChannels), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC), - blocks(cudaHandles,manager,desc->numBlocks,desc->trunkNumChannels,desc->blocks,nnX,nnY,useFP16,useNHWC) - { - int midNumChannels = desc->midNumChannels; - int regularNumChannels = desc->regularNumChannels; - int gpoolNumChannels = desc->gpoolNumChannels; - - int maxBatchSize = manager->maxBatchSize; - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,trunkNumChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,midNumChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,regularNumChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,gpoolNumChannels); - - initialConv = std::make_unique(cudaHandles,manager,&desc->initialConv,useFP16,inputsUseNHWC,useNHWC); - initialMatMul = std::make_unique(cudaHandles,&desc->initialMatMul,useFP16); - if(desc->metaEncoderVersion > 0) { - sgfMetadataEncoder = std::make_unique(cudaHandles,&desc->sgfMetadataEncoder,useFP16); - testAssert(sgfMetadataEncoder->mul3.outChannels == initialMatMul->outChannels); - } - - trunkTipBN = std::make_unique(cudaHandles,&desc->trunkTipBN,&desc->trunkTipActivation,nnXLen,nnYLen,useFP16,useNHWC); - assert(desc->blocks.size() == numBlocks); - } - - ~Trunk() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = initialConv->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - - b = initialMatMul->requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - - if(sgfMetadataEncoder != nullptr) { - b = sgfMetadataEncoder->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - - b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* inputBuf, - void* inputGlobalBuf, - void* inputMetaBuf, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - - SizedBuf trunkScratch(scratch->allocator, scratch->getBufSizeXY(trunkNumChannels)); - - //Feed the conv into trunkScratch.buf, not trunkBuf - initialConv->apply(cudaHandles,batchSize,false,inputBuf,trunkScratch.buf,workspaceBuf,workspaceBytes); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("After initial conv"), trunkScratch.buf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); - #endif - - //Feed the matmul into trunkBuf - initialMatMul->apply(cudaHandles,scratch,batchSize,inputGlobalBuf,trunkBuf,workspaceBuf,workspaceBytes); - //Then accumulate it into trunkScratch.buf, broadcasting during the process - if(!usingFP16) { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - else { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - if(sgfMetadataEncoder != nullptr) { - testAssert(inputMetaBuf != NULL); - //Feed the result into trunkBuf - sgfMetadataEncoder->apply(cudaHandles,scratch,batchSize,inputMetaBuf,trunkBuf,workspaceBuf,workspaceBytes); - //Then accumulate it into trunkScratch.buf, broadcasting during the process - if(!usingFP16) { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - else { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - else { - testAssert(inputMetaBuf == NULL); - } - - //Flip trunkBuf and trunkScratch.buf so that the result gets accumulated in trunkScratch.buf - blocks.apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskSumBuf, - trunkScratch.buf, - trunkBuf, - workspaceBuf, - workspaceBytes - ); - - //And now with the final BN port it from trunkScratch.buf to trunkBuf. - trunkTipBN->apply(cudaHandles,batchSize,trunkScratch.buf,maskBuf,trunkBuf); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("Trunk tip"), trunkBuf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); - #endif - } - -}; - -//------------------------------------------------------------------------------ - -static void fillMaskFloatBufAndMaskSumBuf(void* maskBuf, float*& maskFloatBuf, float*& maskSumBuf, bool usingFP16, int batchSize, int nnXLen, int nnYLen) { - if(!usingFP16) { - maskFloatBuf = (float*)maskBuf; - customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); - CUDA_ERR("sumMask",hipPeekAtLastError()); - } - else { - customCudaCopyFromHalf((const half*)maskBuf,maskFloatBuf,batchSize*nnXLen*nnYLen); - CUDA_ERR("copyMaskFromHalf",hipPeekAtLastError()); - customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); - CUDA_ERR("sumMask",hipPeekAtLastError()); - } -} - - -//------------------------------------------------------------------------------ - -struct PolicyHead { - const string name; - const int modelVersion; - const int nnXLen; - const int nnYLen; - const int p1Channels; - const int g1Channels; - const int p2Channels; - const bool usingFP16; - const bool usingNHWC; - - const ConvLayer p1Conv; - const ConvLayer g1Conv; - const BatchNormLayer g1BN; - const MatMulLayer gpoolToBiasMul; - const BatchNormLayer p1BN; - const ConvLayer p2Conv; - const MatMulLayer gpoolToPassMul; - const MatBiasLayer gpoolToPassBias; - const MatMulLayer gpoolToPassMul2; - - PolicyHead() = delete; - PolicyHead(const PolicyHead&) = delete; - PolicyHead& operator=(const PolicyHead&) = delete; - - PolicyHead( - CudaHandles* cudaHandles, - CudnnManager* manager, - const PolicyHeadDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - nnXLen(nnX), - nnYLen(nnY), - p1Channels(desc->p1Conv.outChannels), - g1Channels(desc->g1Conv.outChannels), - p2Channels(desc->p2Conv.outChannels), - usingFP16(useFP16), - usingNHWC(useNHWC), - p1Conv(cudaHandles,manager,&desc->p1Conv,useFP16,useNHWC), - g1Conv(cudaHandles,manager,&desc->g1Conv,useFP16,useNHWC), - g1BN(cudaHandles,&desc->g1BN,&desc->g1Activation,nnX,nnY,useFP16,useNHWC), - gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,false), - p1BN(cudaHandles,&desc->p1BN,&desc->p1Activation,nnX,nnY,false,useNHWC), - p2Conv(cudaHandles,manager,&desc->p2Conv,false,useNHWC), - gpoolToPassMul(cudaHandles,&desc->gpoolToPassMul,false), - gpoolToPassBias(cudaHandles,&desc->gpoolToPassBias,false,desc->passActivation.activation), - gpoolToPassMul2(cudaHandles,&desc->gpoolToPassMul2,false) - { - } - - ~PolicyHead() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = p1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = g1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = p2Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolToPassMul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = gpoolToPassMul2.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*g1Channels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskFloatBuf, - float* maskSumBuf, - void* trunkBuf, - float* policyPassBuf, - float* policyBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - - SizedBuf p1Out(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs - SizedBuf p1Out2(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs - SizedBuf g1Out(scratch->allocator, scratch->getBufSizeXY(g1Channels)); - SizedBuf g1Out2(scratch->allocator, scratch->getBufSizeXY(g1Channels)); - SizedBuf g1Concat(scratch->allocator, scratch->getBufSizeFloat(g1Channels*3)); - SizedBuf g1Bias(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); - SizedBuf p1Pass(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); - - p1Conv.apply(cudaHandles,batchSize,false,trunkBuf,p1Out.buf,workspaceBuf,workspaceBytes); - g1Conv.apply(cudaHandles,batchSize,false,trunkBuf,g1Out.buf,workspaceBuf,workspaceBytes); - g1BN.apply(cudaHandles,batchSize,g1Out.buf,maskBuf,g1Out2.buf); - - if(!usingFP16) { - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - else { - customCudaCopyFromHalf((const half*)g1Out2.buf,(float*)workspaceBuf,batchSize*g1Channels*nnXLen*nnYLen); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - - gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,g1Bias.buf,workspaceBuf,workspaceBytes); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("p1 pre-gpool-sum"), p1Out.buf, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); - CudaUtils::debugPrint4D(string("g1 pre-gpool"), g1Out.buf, batchSize, g1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); - CudaUtils::debugPrint2D(string("g1 pooled"), g1Concat.buf, batchSize, g1Channels*3, false); - CudaUtils::debugPrint2D(string("g1 biases"), g1Bias.buf, batchSize, p1Channels, false); - #endif - - float* p1OutBufA; - float* p1OutBufB; - if(!usingFP16) { - p1OutBufA = (float*)p1Out.buf; - p1OutBufB = (float*)p1Out2.buf; - } - else { - customCudaCopyFromHalf((const half*)p1Out.buf,(float*)p1Out2.buf,batchSize*p1Channels*nnXLen*nnYLen); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - p1OutBufA = (float*)p1Out2.buf; - p1OutBufB = (float*)p1Out.buf; - } - - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW(p1OutBufA,(float*)g1Bias.buf,batchSize,p1Channels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC(p1OutBufA,(float*)g1Bias.buf,batchSize,nnXLen*nnYLen,p1Channels); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - p1BN.apply(cudaHandles,batchSize,p1OutBufA,maskFloatBuf,p1OutBufB); - p2Conv.apply(cudaHandles,batchSize,false,p1OutBufB,(float*)policyBuf,workspaceBuf,workspaceBytes); - - if(modelVersion >= 15) { - gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,p1Pass.buf,workspaceBuf,workspaceBytes); - gpoolToPassBias.apply(cudaHandles,batchSize,p1Pass.buf); - gpoolToPassMul2.apply(cudaHandles,scratch,batchSize,p1Pass.buf,policyPassBuf,workspaceBuf,workspaceBytes); - } - else { - gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,policyPassBuf,workspaceBuf,workspaceBytes); - } - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("p1 after-gpool-sum"), p1OutBufA, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, false); - CudaUtils::debugPrint2D(string("policypass"), policyPassBuf, batchSize, 1, false); - CudaUtils::debugPrint4D(string("policy"), policyBuf, batchSize, p2Channels, nnXLen, nnYLen, usingNHWC, false); - #endif - - } - -}; - -//------------------------------------------------------------------------------ - -struct ValueHead { - const string name; - const int modelVersion; - const int nnXLen; - const int nnYLen; - const int v1Channels; - const int v2Channels; - const int valueChannels; - const int scoreValueChannels; - const int ownershipChannels; - const bool usingFP16; - const bool usingNHWC; - - const ConvLayer v1Conv; - const BatchNormLayer v1BN; - const MatMulLayer v2Mul; - const MatBiasLayer v2Bias; - const MatMulLayer v3Mul; - const MatBiasLayer v3Bias; - const MatMulLayer sv3Mul; - const MatBiasLayer sv3Bias; - const ConvLayer vOwnershipConv; - - ValueHead() = delete; - ValueHead(const ValueHead&) = delete; - ValueHead& operator=(const ValueHead&) = delete; - - ValueHead( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ValueHeadDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - nnXLen(nnX), - nnYLen(nnY), - v1Channels(desc->v1Conv.outChannels), - v2Channels(desc->v2Mul.outChannels), - valueChannels(desc->v3Mul.outChannels), - scoreValueChannels(desc->sv3Mul.outChannels), - ownershipChannels(desc->vOwnershipConv.outChannels), - usingFP16(useFP16), - usingNHWC(useNHWC), - v1Conv(cudaHandles,manager,&desc->v1Conv,useFP16,useNHWC), - v1BN(cudaHandles,&desc->v1BN,&desc->v1Activation,nnX,nnY,useFP16,useNHWC), - v2Mul(cudaHandles,&desc->v2Mul,false), - v2Bias(cudaHandles,&desc->v2Bias,false,desc->v2Activation.activation), - v3Mul(cudaHandles,&desc->v3Mul,false), - v3Bias(cudaHandles,&desc->v3Bias,false,ACTIVATION_IDENTITY), - sv3Mul(cudaHandles,&desc->sv3Mul,false), - sv3Bias(cudaHandles,&desc->sv3Bias,false,ACTIVATION_IDENTITY), - vOwnershipConv(cudaHandles,manager,&desc->vOwnershipConv,useFP16,useNHWC) - { - } - - ~ValueHead() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = v1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = v2Mul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = v3Mul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*v1Channels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - - b = sv3Mul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = vOwnershipConv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*ownershipChannels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - - return bytes; - } - - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - float* valueBuf, - float* scoreValueBuf, - void* ownershipBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf v1Out(scratch->allocator, scratch->getBufSizeXY(v1Channels)); - SizedBuf v1Out2(scratch->allocator, scratch->getBufSizeXY(v1Channels)); - SizedBuf v1Mean(scratch->allocator, scratch->getBufSizeFloat(v1Channels*3)); - SizedBuf v2Out(scratch->allocator, scratch->getBufSizeFloat(v2Channels)); - SizedBuf ownershipScratch(scratch->allocator, scratch->getBufSizeXYFloat(ownershipChannels)); - - v1Conv.apply(cudaHandles,batchSize,false,trunkBuf,v1Out.buf,workspaceBuf,workspaceBytes); - v1BN.apply(cudaHandles,batchSize,v1Out.buf,maskBuf,v1Out2.buf); - - void* bufToBePooled = v1Out2.buf; - if(usingFP16) { - customCudaCopyFromHalf((const half*)v1Out2.buf,(float*)workspaceBuf,batchSize*v1Channels*nnXLen*nnYLen); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - bufToBePooled = workspaceBuf; - } - - if(!usingNHWC) - customCudaValueHeadPoolNCHW((float*)bufToBePooled,(float*)v1Mean.buf,batchSize,v1Channels,nnXLen*nnYLen,maskSumBuf); - else - customCudaValueHeadPoolNHWC((const float*)bufToBePooled,(float*)v1Mean.buf,batchSize,nnXLen*nnYLen,v1Channels,maskSumBuf); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - v2Mul.apply(cudaHandles,scratch,batchSize,v1Mean.buf,v2Out.buf,workspaceBuf,workspaceBytes); - v2Bias.apply(cudaHandles,batchSize,v2Out.buf); - v3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,valueBuf,workspaceBuf,workspaceBytes); - v3Bias.apply(cudaHandles,batchSize,valueBuf); - - sv3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,scoreValueBuf,workspaceBuf,workspaceBytes); - sv3Bias.apply(cudaHandles,batchSize,scoreValueBuf); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("v1"), v1Out.buf, batchSize, v1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); - CudaUtils::debugPrint2D(string("v1 pooled"), v1Mean.buf, batchSize, v1Channels, false); - CudaUtils::debugPrint2D(string("v2"), v2Out.buf, batchSize, v1Channels, false); - #endif - - if(!usingFP16) { - vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipBuf,workspaceBuf,workspaceBytes); - } - else { - vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipScratch.buf,workspaceBuf,workspaceBytes); - customCudaCopyFromHalf((const half*)ownershipScratch.buf,(float*)ownershipBuf,batchSize*ownershipChannels*nnXLen*nnYLen); - CUDA_ERR("vOwnership copy",hipPeekAtLastError()); - } - - } - -}; - -//------------------------------------------------------------------------------ - -struct Model { - const string name; - const int modelVersion; - const int maxBatchSize; - const int nnXLen; - const int nnYLen; - const int numInputChannels; - const int numInputGlobalChannels; - const int numInputMetaChannels; - const int numPolicyChannels; - const int numValueChannels; - const int numScoreValueChannels; - const int numOwnershipChannels; - const bool usingFP16; - const bool usingNHWC; - const bool inputsUsingNHWC; - - std::unique_ptr trunk; - std::unique_ptr policyHead; - std::unique_ptr valueHead; - std::unique_ptr manager; - - Model() = delete; - Model(const Model&) = delete; - Model& operator=(const Model&) = delete; - - Model( - CudaHandles* cudaHandles, - const ModelDesc* desc, - int maxBatchSz, - int nnX, - int nnY, - bool inputsUseNHWC, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - maxBatchSize(maxBatchSz), - nnXLen(nnX), - nnYLen(nnY), - numInputChannels(desc->numInputChannels), - numInputGlobalChannels(desc->numInputGlobalChannels), - numInputMetaChannels(desc->numInputMetaChannels), - numPolicyChannels(desc->numPolicyChannels), - numValueChannels(desc->numValueChannels), - numScoreValueChannels(desc->numScoreValueChannels), - numOwnershipChannels(desc->numOwnershipChannels), - usingFP16(useFP16), - usingNHWC(useNHWC), - inputsUsingNHWC(inputsUseNHWC) - { - if(nnXLen > NNPos::MAX_BOARD_LEN) - throw StringError(Global::strprintf("nnXLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", - nnXLen, NNPos::MAX_BOARD_LEN - )); - if(nnYLen > NNPos::MAX_BOARD_LEN) - throw StringError(Global::strprintf("nnYLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", - nnYLen, NNPos::MAX_BOARD_LEN - )); - - int numFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); - if(numInputChannels != numFeatures) - throw StringError(Global::strprintf("Neural net numInputChannels (%d) was not the expected number based on version (%d)", - numInputChannels, numFeatures - )); - int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); - if(numInputGlobalChannels != numGlobalFeatures) - throw StringError(Global::strprintf("Neural net numInputGlobalChannels (%d) was not the expected number based on version (%d)", - numInputGlobalChannels, numGlobalFeatures - )); - if(numInputMetaChannels > 0) { - if(numInputMetaChannels != SGFMetadata::METADATA_INPUT_NUM_CHANNELS) - throw StringError(Global::strprintf("Neural net numInputMetaChannels (%d) was not the expected number (%d)", - numInputMetaChannels, SGFMetadata::METADATA_INPUT_NUM_CHANNELS - )); - } - - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputGlobalChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputMetaChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numPolicyChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numValueChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numScoreValueChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numOwnershipChannels); - - manager = std::make_unique(name, maxBatchSize, nnXLen, nnYLen); - trunk = std::make_unique(cudaHandles,manager.get(),&desc->trunk,nnXLen,nnYLen,inputsUseNHWC,useFP16,useNHWC); - policyHead = std::make_unique(cudaHandles,manager.get(),&desc->policyHead,nnXLen,nnYLen,useFP16,useNHWC); - valueHead = std::make_unique(cudaHandles,manager.get(),&desc->valueHead,nnXLen,nnYLen,useFP16,useNHWC); - } - - ~Model() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = trunk->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = policyHead->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = valueHead->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - bool requireExactNNLen, - - void* inputBuf, - void* inputGlobalBuf, - void* inputMetaBuf, - - float* policyPassBuf, - float* policyBuf, - - float* valueBuf, - float* scoreValueBuf, - void* ownershipBuf, - - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf mask(scratch->allocator, scratch->getBufSizeXY(1)); - SizedBuf maskFloat(scratch->allocator, scratch->getBufSizeXYFloat(1)); - SizedBuf maskSum(scratch->allocator, scratch->getBufSizeFloat(1)); - - void* maskBuf = mask.buf; - float* maskFloatBuf = (float*)maskFloat.buf; - float* maskSumBuf = (float*)maskSum.buf; - - if(!usingFP16) { - if(inputsUsingNHWC) - customCudaChannel0ExtractNHWC((const float*)inputBuf, (float*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); - else - customCudaChannel0ExtractNCHW((const float*)inputBuf, (float*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); - CUDA_ERR("modelExtractMask",hipPeekAtLastError()); - } - else { - if(inputsUsingNHWC) - customCudaChannel0ExtractNHWC((const half*)inputBuf, (half*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); - else - customCudaChannel0ExtractNCHW((const half*)inputBuf, (half*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); - CUDA_ERR("modelExtractMask",hipPeekAtLastError()); - } - - fillMaskFloatBufAndMaskSumBuf(maskBuf,maskFloatBuf,maskSumBuf,usingFP16,batchSize,nnXLen,nnYLen); - - //Don't do any masking if we know the board is exactly the desired size - if(requireExactNNLen) { - //Set to NULL to signal downstream that this buf doesn't need to be used - maskBuf = NULL; - maskFloatBuf = NULL; - //The global pooling structures need this no matter what, for normalizing based on this and its sqrt. - //maskSumBuf = NULL; - } - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("Initial bin features"), inputBuf, batchSize, trunk->initialConv->inChannels, nnXLen, nnYLen, inputsUsingNHWC, usingFP16); - CudaUtils::debugPrint2D(string("Initial global features"), inputGlobalBuf, batchSize, trunk->initialMatMul->inChannels, usingFP16); - if(trunk->sgfMetadataEncoder != nullptr) { - assert(inputMetaBuf != NULL); - CudaUtils::debugPrint2D(string("Initial meta features"), inputMetaBuf, batchSize, trunk->sgfMetadataEncoder->mul1.inChannels, usingFP16); - } - #endif - - SizedBuf trunkBuf(scratch->allocator, scratch->getBufSizeXY(trunk->trunkNumChannels)); - - trunk->apply( - cudaHandles, - scratch, - batchSize, - inputBuf, - inputGlobalBuf, - inputMetaBuf, - maskBuf, - maskSumBuf, - trunkBuf.buf, - workspaceBuf, - workspaceBytes - ); - policyHead->apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskFloatBuf, - maskSumBuf, - trunkBuf.buf, - policyPassBuf, - policyBuf, - workspaceBuf, - workspaceBytes - ); - valueHead->apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskSumBuf, - trunkBuf.buf, - valueBuf, - scoreValueBuf, - ownershipBuf, - workspaceBuf, - workspaceBytes - ); - } - -}; - - -//------------------------------------------------------------------------------ - -struct LoadedModel { - ModelDesc modelDesc; - - LoadedModel(const string& fileName, const string& expectedSha256) { - ModelDesc::loadFromFileMaybeGZipped(fileName,modelDesc,expectedSha256); - modelDesc.applyScale8ToReduceActivations(); - } - - LoadedModel() = delete; - LoadedModel(const LoadedModel&) = delete; - LoadedModel& operator=(const LoadedModel&) = delete; -}; - -LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { - LoadedModel* loadedModel = new LoadedModel(file,expectedSha256); - return loadedModel; -} - -void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { - delete loadedModel; -} - -const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { - return loadedModel->modelDesc; -} - -//------------------------------------------------------------------------------ - -struct Buffers { - //All of these are device pointers - - float* inputBufFloat; - void* inputBuf; - float* inputGlobalBufFloat; - void* inputGlobalBuf; - float* inputMetaBufFloat; - void* inputMetaBuf; - size_t inputBufBytesFloat; - size_t inputBufBytes; - size_t inputGlobalBufBytesFloat; - size_t inputGlobalBufBytes; - size_t inputMetaBufBytesFloat; - size_t inputMetaBufBytes; - - float* policyPassBuf; - size_t policyPassBufBytes; - float* policyBuf; - size_t policyBufBytes; - - float* valueBuf; - size_t valueBufBytes; - float* scoreValueBuf; - size_t scoreValueBufBytes; - void* ownershipBuf; - size_t ownershipBufBytes; - - void* workspaceBuf; - size_t workspaceBytes; - - Buffers() = delete; - Buffers(const Buffers&) = delete; - Buffers& operator=(const Buffers&) = delete; - - Buffers(CudaHandles* cudaHandles, const Model& m, const ScratchBuffers& scratch) { - size_t batchXYFloatBytes = (size_t)scratch.batchXYFloatBytes; - size_t batchFloatBytes = (size_t)scratch.batchFloatBytes; - size_t batchXYBytes = (size_t)scratch.batchXYBytes; - size_t batchBytes = (size_t)scratch.batchBytes; - - inputBufBytesFloat = m.numInputChannels * batchXYFloatBytes; - inputBufBytes = m.numInputChannels * batchXYBytes; - inputGlobalBufBytesFloat = m.numInputGlobalChannels * batchFloatBytes; - inputGlobalBufBytes = m.numInputGlobalChannels * batchBytes; - inputMetaBufBytesFloat = m.numInputMetaChannels * batchFloatBytes; - inputMetaBufBytes = m.numInputMetaChannels * batchBytes; - - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputBufFloat), inputBufBytesFloat)); - CUDA_ERR("Buffers",hipMalloc(&inputBuf, inputBufBytes)); - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputGlobalBufFloat), inputGlobalBufBytesFloat)); - CUDA_ERR("Buffers",hipMalloc(&inputGlobalBuf, inputGlobalBufBytes)); - if(m.numInputMetaChannels > 0) { - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputMetaBufFloat), inputMetaBufBytesFloat)); - CUDA_ERR("Buffers",hipMalloc(&inputMetaBuf, inputMetaBufBytes)); - } - else { - inputMetaBufFloat = NULL; - inputMetaBuf = NULL; - } - - if(m.modelVersion >= 16) - testAssert(m.policyHead->p2Channels == 4); - else if(m.modelVersion >= 12) - testAssert(m.policyHead->p2Channels == 2); - else - testAssert(m.policyHead->p2Channels == 1); - - policyPassBufBytes = m.policyHead->p2Channels * batchFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyPassBuf), policyPassBufBytes)); - policyBufBytes = m.policyHead->p2Channels * batchXYFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyBuf), policyBufBytes)); - - valueBufBytes = m.valueHead->valueChannels * batchFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&valueBuf), valueBufBytes)); - - scoreValueBufBytes = m.valueHead->scoreValueChannels * batchFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&scoreValueBuf), scoreValueBufBytes)); - - //This buf is used for both an intermdiate fp16 result in fp16 mode, and ALSO the final fp32 output, so always must be fp32-sized - ownershipBufBytes = m.valueHead->ownershipChannels * batchXYFloatBytes; - CUDA_ERR("Buffers",hipMalloc(&ownershipBuf, ownershipBufBytes)); - - //In theory the requiredWorkspaceBytes calls could give us values non-monotone in batch size - //such as if the convolution algorithm changes between batch size 1 and larger. - //So we call it for all the batch sizes. - size_t bytes = 0; - size_t b; - for(int batchSize = 1; batchSize <= m.maxBatchSize; batchSize++) { - b = m.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - - CUDA_ERR("Buffers",hipMalloc(&workspaceBuf, bytes)); - workspaceBytes = bytes; - } - - ~Buffers() { - hipFree(inputBufFloat); - hipFree(inputBuf); - hipFree(inputGlobalBufFloat); - hipFree(inputGlobalBuf); - if(inputMetaBufFloat != NULL) - hipFree(inputMetaBufFloat); - if(inputMetaBuf != NULL) - hipFree(inputMetaBuf); - - hipFree(policyPassBuf); - hipFree(policyBuf); - - hipFree(valueBuf); - hipFree(scoreValueBuf); - hipFree(ownershipBuf); - - hipFree(workspaceBuf); - } - -}; - -//------------------------------------------------------------------------------ - -struct ComputeContext { - int nnXLen; - int nnYLen; - enabled_t useFP16Mode; - enabled_t useNHWCMode; -}; - -ComputeContext* NeuralNet::createComputeContext( - const std::vector& gpuIdxs, - Logger* logger, - int nnXLen, - int nnYLen, - const string& openCLTunerFile, - const string& homeDataDirOverride, - bool openCLReTunePerBoardSize, - enabled_t useFP16Mode, - enabled_t useNHWCMode, - const LoadedModel* loadedModel -) { - (void)gpuIdxs; - (void)logger; - (void)openCLTunerFile; - (void)homeDataDirOverride; - (void)openCLReTunePerBoardSize; - (void)loadedModel; - - ComputeContext* context = new ComputeContext(); - context->nnXLen = nnXLen; - context->nnYLen = nnYLen; - context->useFP16Mode = useFP16Mode; - context->useNHWCMode = useNHWCMode; - return context; -} - -void NeuralNet::freeComputeContext(ComputeContext* computeContext) { - delete computeContext; -} - -//------------------------------------------------------------------------------ - -struct ComputeHandle { - std::unique_ptr cudaHandles; - std::unique_ptr model; - std::unique_ptr scratch; - std::unique_ptr buffers; - const bool usingFP16; - const int nnXLen; - const int nnYLen; - const bool requireExactNNLen; - const bool inputsUseNHWC; - const bool usingNHWC; - - ComputeHandle( - const ComputeContext* context, - const LoadedModel* loadedModel, - int majorComputeCapability, - int minorComputeCapability, - int maxBatchSize, - bool requireExactNNLen_, - bool inputsUseNHWC_, - bool useFP16, - bool useNHWC - ) : - usingFP16(useFP16), - nnXLen(context->nnXLen), - nnYLen(context->nnYLen), - requireExactNNLen(requireExactNNLen_), - inputsUseNHWC(inputsUseNHWC_), - usingNHWC(useNHWC) - { - cudaHandles = std::make_unique(majorComputeCapability,minorComputeCapability); - model = std::make_unique( - cudaHandles.get(), &(loadedModel->modelDesc), maxBatchSize, - nnXLen, nnYLen, inputsUseNHWC, useFP16, useNHWC - ); - scratch = std::make_unique(maxBatchSize, nnXLen, nnYLen, useFP16); - buffers = std::make_unique(cudaHandles.get(), *model, *scratch); - - //Synchronize after creating buffers and copying all the weights, just in case - CUDA_ERR("ComputeHandle", hipDeviceSynchronize()); - } - ~ComputeHandle() { - } - - ComputeHandle() = delete; - ComputeHandle(const ComputeHandle&) = delete; - ComputeHandle& operator=(const ComputeHandle&) = delete; -}; - -ComputeHandle* NeuralNet::createComputeHandle( - ComputeContext* context, - const LoadedModel* loadedModel, - Logger* logger, - int maxBatchSize, - bool requireExactNNLen, - bool inputsUseNHWC, - int gpuIdxForThisThread, - int serverThreadIdx -) { - //Use whatever CUDA believes GPU 0 to be. - if(gpuIdxForThisThread == -1) - gpuIdxForThisThread = 0; - - CUDA_ERR("createComputeHandle",hipSetDevice(gpuIdxForThisThread)); - - hipDeviceProp_t prop; - hipGetDeviceProperties(&prop,gpuIdxForThisThread); - - bool useFP16 = false; - bool useNHWC = false; - if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) - useFP16 = true; - - if(logger != NULL) { - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) - + " memory " + Global::uint64ToString(prop.totalGlobalMem) - + " compute capability major " + Global::intToString(prop.major) - + " minor " + Global::intToString(prop.minor) - ); - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion) + - " useFP16 = " + Global::boolToString(useFP16) + - " useNHWC = " + Global::boolToString(useNHWC) - ); - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name - ); - logger->write( - "MIOpen finding convolution algorithms for GPU " + string(prop.name) + ". This may take a while, please wait............" - ); - } - - ComputeHandle* gpuHandle = new ComputeHandle( - context,loadedModel,prop.major,prop.minor,maxBatchSize,requireExactNNLen,inputsUseNHWC,useFP16,useNHWC - ); - return gpuHandle; -} - -void NeuralNet::freeComputeHandle(ComputeHandle* gpuHandle) { - delete gpuHandle; -} - -bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { - return handle->usingFP16; -} - -//------------------------------------------------------------------------------ - -void NeuralNet::printDevices() { - int numDevices = 0; - hipGetDeviceCount(&numDevices); - for(int i = 0; imodelDesc; - - maxBatchSize = maxBatchSz; - singleInputElts = (size_t)m.numInputChannels * nnXLen * nnYLen; - singleInputBytes = (size_t)m.numInputChannels * nnXLen * nnYLen * sizeof(float); - singleInputGlobalElts = (size_t)m.numInputGlobalChannels; - singleInputGlobalBytes = (size_t)m.numInputGlobalChannels * sizeof(float); - singleInputMetaElts = (size_t)m.numInputMetaChannels; - singleInputMetaBytes = (size_t)m.numInputMetaChannels * sizeof(float); - singlePolicyPassResultElts = (size_t)(m.numPolicyChannels); - singlePolicyPassResultBytes = (size_t)(m.numPolicyChannels) * sizeof(float); - singlePolicyResultElts = (size_t)(m.numPolicyChannels * nnXLen * nnYLen); - singlePolicyResultBytes = (size_t)(m.numPolicyChannels * nnXLen * nnYLen) * sizeof(float); - singleValueResultElts = (size_t)m.numValueChannels; - singleValueResultBytes = (size_t)m.numValueChannels * sizeof(float); - singleScoreValueResultElts = (size_t)m.numScoreValueChannels; - singleScoreValueResultBytes = (size_t)m.numScoreValueChannels * sizeof(float); - singleOwnershipResultElts = (size_t)m.numOwnershipChannels * nnXLen * nnYLen; - singleOwnershipResultBytes = (size_t)m.numOwnershipChannels * nnXLen * nnYLen * sizeof(float); - - assert(NNModelVersion::getNumSpatialFeatures(m.modelVersion) == m.numInputChannels); - assert(NNModelVersion::getNumGlobalFeatures(m.modelVersion) == m.numInputGlobalChannels); - if(m.numInputMetaChannels > 0) { - assert(SGFMetadata::METADATA_INPUT_NUM_CHANNELS == m.numInputMetaChannels); - } - - userInputBufferBytes = (size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen * sizeof(float); - userInputGlobalBufferBytes = (size_t)m.numInputGlobalChannels * maxBatchSize * sizeof(float); - userInputMetaBufferBytes = (size_t)m.numInputMetaChannels * maxBatchSize * sizeof(float); - policyPassResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * sizeof(float); - policyResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen * sizeof(float); - valueResultBufferBytes = (size_t)maxBatchSize * m.numValueChannels * sizeof(float); - scoreValueResultBufferBytes = (size_t)maxBatchSize * m.numScoreValueChannels * sizeof(float); - ownershipResultBufferBytes = (size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels * sizeof(float); - - userInputBuffer = new float[(size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen]; - userInputGlobalBuffer = new float[(size_t)m.numInputGlobalChannels * maxBatchSize]; - if(m.numInputMetaChannels > 0) - userInputMetaBuffer = new float[(size_t)m.numInputMetaChannels * maxBatchSize]; - else - userInputMetaBuffer = NULL; - - policyPassResults = new float[(size_t)maxBatchSize * m.numPolicyChannels]; - policyResults = new float[(size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen]; - valueResults = new float[(size_t)maxBatchSize * m.numValueChannels]; - - scoreValueResults = new float[(size_t)maxBatchSize * m.numScoreValueChannels]; - ownershipResults = new float[(size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels]; - } - - ~InputBuffers() { - delete[] userInputBuffer; - delete[] userInputGlobalBuffer; - if(userInputMetaBuffer != NULL) - delete[] userInputMetaBuffer; - delete[] policyPassResults; - delete[] policyResults; - delete[] valueResults; - delete[] scoreValueResults; - delete[] ownershipResults; - } - - InputBuffers() = delete; - InputBuffers(const InputBuffers&) = delete; - InputBuffers& operator=(const InputBuffers&) = delete; - -}; - -InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { - return new InputBuffers(loadedModel,maxBatchSize,nnXLen,nnYLen); -} -void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { - delete inputBuffers; -} - -//--------------------------------------------------------------------------------------- - - -void NeuralNet::getOutput( - ComputeHandle* gpuHandle, - InputBuffers* inputBuffers, - int numBatchEltsFilled, - NNResultBuf** inputBufs, - vector& outputs -) { - assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); - assert(numBatchEltsFilled > 0); - const int batchSize = numBatchEltsFilled; - const int nnXLen = gpuHandle->nnXLen; - const int nnYLen = gpuHandle->nnYLen; - const int modelVersion = gpuHandle->model->modelVersion; - - const int numSpatialFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); - const int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); - const int numMetaFeatures = inputBuffers->singleInputMetaElts; - assert(numSpatialFeatures == gpuHandle->model->numInputChannels); - assert(numSpatialFeatures * nnXLen * nnYLen == inputBuffers->singleInputElts); - assert(numGlobalFeatures == inputBuffers->singleInputGlobalElts); - const int numPolicyChannels = gpuHandle->model->numPolicyChannels; - - for(int nIdx = 0; nIdxuserInputBuffer + (inputBuffers->singleInputElts * nIdx); - float* rowGlobalInput = inputBuffers->userInputGlobalBuffer + (inputBuffers->singleInputGlobalElts * nIdx); - float* rowMetaInput = inputBuffers->userInputMetaBuffer + (inputBuffers->singleInputMetaElts * nIdx); - - const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); - const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); - const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); - bool hasRowMeta = inputBufs[nIdx]->hasRowMeta; - std::copy(rowGlobal,rowGlobal+numGlobalFeatures,rowGlobalInput); - if(numMetaFeatures > 0) { - testAssert(rowMeta != NULL); - testAssert(hasRowMeta); - std::copy(rowMeta,rowMeta+numMetaFeatures,rowMetaInput); - } - else { - testAssert(!hasRowMeta); - } - SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, gpuHandle->inputsUseNHWC, inputBufs[nIdx]->symmetry); - } - - Buffers* buffers = gpuHandle->buffers.get(); - ScratchBuffers* scratch = gpuHandle->scratch.get(); - - if(!gpuHandle->usingFP16) { - assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes); - assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes); - assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes); - assert(inputBuffers->policyPassResultBufferBytes == buffers->policyPassBufBytes); - assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); - assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); - assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); - assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); - assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); - assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); - assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); - assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); - assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); - assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); - assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); - assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); - assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); - - CUDA_ERR("getOutput",hipMemcpy(buffers->inputBuf, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); - CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBuf, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); - if(numMetaFeatures > 0) { - CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBuf, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); - } - } - else { - assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytesFloat); - assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytesFloat); - assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytesFloat); - assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); - assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); - assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes*2); - assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes*2); - assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes*2); - assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); - assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); - assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); - assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); - assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); - assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); - assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); - assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); - assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); - assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); - assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); - - CUDA_ERR("getOutput",hipMemcpy(buffers->inputBufFloat, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); - CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBufFloat, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); - if(numMetaFeatures > 0) { - CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBufFloat, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); - } - - customCudaCopyToHalf((const float*)buffers->inputBufFloat,(half*)buffers->inputBuf,inputBuffers->singleInputElts*batchSize); - CUDA_ERR("getOutput",hipPeekAtLastError()); - customCudaCopyToHalf((const float*)buffers->inputGlobalBufFloat,(half*)buffers->inputGlobalBuf,inputBuffers->singleInputGlobalElts*batchSize); - CUDA_ERR("getOutput",hipPeekAtLastError()); - if(numMetaFeatures > 0) { - customCudaCopyToHalf((const float*)buffers->inputMetaBufFloat,(half*)buffers->inputMetaBuf,inputBuffers->singleInputMetaElts*batchSize); - CUDA_ERR("getOutput",hipPeekAtLastError()); - } - } - - gpuHandle->model->apply( - gpuHandle->cudaHandles.get(), - scratch, - batchSize, - gpuHandle->requireExactNNLen, - - buffers->inputBuf, - buffers->inputGlobalBuf, - buffers->inputMetaBuf, - - buffers->policyPassBuf, - buffers->policyBuf, - - buffers->valueBuf, - buffers->scoreValueBuf, - buffers->ownershipBuf, - - buffers->workspaceBuf, - buffers->workspaceBytes - ); - - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyPassResults, buffers->policyPassBuf, inputBuffers->singlePolicyPassResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyResults, buffers->policyBuf, inputBuffers->singlePolicyResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->valueResults, buffers->valueBuf, inputBuffers->singleValueResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->scoreValueResults, buffers->scoreValueBuf, inputBuffers->singleScoreValueResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->ownershipResults, buffers->ownershipBuf, inputBuffers->singleOwnershipResultBytes*batchSize, hipMemcpyDeviceToHost)); - - assert(outputs.size() == batchSize); - - float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; - - for(int row = 0; row < batchSize; row++) { - NNOutput* output = outputs[row]; - assert(output->nnXLen == nnXLen); - assert(output->nnYLen == nnYLen); - float policyOptimism = (float)inputBufs[row]->policyOptimism; - - const float* policyPassSrcBuf = inputBuffers->policyPassResults + row * numPolicyChannels; - const float* policySrcBuf = inputBuffers->policyResults + row * numPolicyChannels * nnXLen * nnYLen; - float* policyProbs = output->policyProbs; - - // These are in logits, the client does the postprocessing to turn them into - // policy probabilities and white game outcome probabilities - // Also we don't fill in the nnHash here either - // Handle version >= 12 policy optimism - if(numPolicyChannels == 2 || (numPolicyChannels == 4 && modelVersion >= 16)) { - if(gpuHandle->usingNHWC) { - for(int i = 0; isymmetry); - policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; - } - else { - for(int i = 0; isymmetry); - policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; - } - } - else { - assert(numPolicyChannels == 1); - SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0]; - } - - int numValueChannels = gpuHandle->model->numValueChannels; - assert(numValueChannels == 3); - output->whiteWinProb = inputBuffers->valueResults[row * numValueChannels]; - output->whiteLossProb = inputBuffers->valueResults[row * numValueChannels + 1]; - output->whiteNoResultProb = inputBuffers->valueResults[row * numValueChannels + 2]; - - //As above, these are NOT actually from white's perspective, but rather the player to move. - //As usual the client does the postprocessing. - if(output->whiteOwnerMap != NULL) { - const float* ownershipSrcBuf = inputBuffers->ownershipResults + row * nnXLen * nnYLen; - assert(gpuHandle->model->numOwnershipChannels == 1); - SymmetryHelpers::copyOutputsWithSymmetry(ownershipSrcBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - } - - if(modelVersion >= 9) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 6); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; - output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; - output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 4]; - output->shorttermScoreError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 5]; - } - else if(modelVersion >= 8) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 4); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; - output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; - output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(modelVersion >= 4) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 2); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(modelVersion >= 3) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 1); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - //Version 3 neural nets don't have any second moment output, implicitly already folding it in, so we just use the mean squared - output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else { - ASSERT_UNREACHABLE; - } - } - -} - -//TESTING ---------------------------------------------------------------------------------- - - -bool NeuralNet::testEvaluateConv( - const ConvLayerDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->inChannels; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->outChannels; - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateConv: unexpected input buffer size"); - - void* deviceInput; - void* deviceOutput; - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); - - int maxBatchSize = desiredBatchSize; - - CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); - ConvLayer* convLayer = new ConvLayer(cudaHandles,manager,desc,useFP16,useNHWC); - - size_t workspaceBytes = - convLayer->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); - void* deviceWorkspace; - CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); - - - bool accumulate = false; - convLayer->apply( - cudaHandles, - desiredBatchSize, - accumulate, - deviceInput, - deviceOutput, - deviceWorkspace, - workspaceBytes - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); - - hipFree(deviceWorkspace); - - delete convLayer; - delete manager; - hipFree(deviceInput); - hipFree(deviceOutput); - delete cudaHandles; - - return true; -} - - -bool NeuralNet::testEvaluateBatchNorm( - const BatchNormLayerDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - const vector& maskBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; - size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateBatchNorm: unexpected input buffer size"); - if(numMaskFloats != maskBuffer.size()) - throw StringError("testEvaluateBatchNorm: unexpected mask buffer size"); - - ActivationLayerDesc actDesc; - actDesc.activation = ACTIVATION_IDENTITY; - - void* deviceInput; - void* deviceMask; - void* deviceOutput; - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); - CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); - - BatchNormLayer* batchNormLayer = new BatchNormLayer(cudaHandles,desc,&actDesc,nnXLen,nnYLen,useFP16,useNHWC); - - batchNormLayer->apply( - cudaHandles, - desiredBatchSize, - deviceInput, - deviceMask, - deviceOutput - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); - - delete batchNormLayer; - - hipFree(deviceInput); - hipFree(deviceMask); - hipFree(deviceOutput); - delete cudaHandles; - - return true; -} - - -bool NeuralNet::testEvaluateResidualBlock( - const ResidualBlockDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - const vector& maskBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; - size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateResidualBlock: unexpected input buffer size"); - if(numMaskFloats != maskBuffer.size()) - throw StringError("testEvaluateResidualBlock: unexpected mask buffer size"); - - ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); - - void* deviceInput; - void* deviceMask; - void* deviceScratch; - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); - CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); - - int maxBatchSize = desiredBatchSize; - - CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); - ResidualBlock* residualBlock = new ResidualBlock(cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC); - - size_t workspaceBytes = - residualBlock->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); - void* deviceWorkspace; - CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); - - residualBlock->apply( - cudaHandles, - scratch, - desiredBatchSize, - deviceInput, - deviceScratch, - deviceMask, - deviceWorkspace, - workspaceBytes - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); - - hipFree(deviceWorkspace); - - delete residualBlock; - delete manager; - hipFree(deviceInput); - hipFree(deviceMask); - hipFree(deviceScratch); - delete scratch; - delete cudaHandles; - - return true; -} - -bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( - const GlobalPoolingResidualBlockDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - const vector& maskBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; - size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; - size_t numMaskSumFloats = (size_t)desiredBatchSize; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; - - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected input buffer size"); - if(numMaskFloats != maskBuffer.size()) - throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected mask buffer size"); - - ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); - - void* deviceInput; - void* deviceMask; - float* deviceMaskFloatOrig; - float* deviceMaskFloat; - float* deviceMaskSum; - void* deviceScratch; - - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); - CUDA_ERR("deviceMaskFloat",hipMalloc(reinterpret_cast(&deviceMaskFloat), numMaskFloats * sizeof(float))); - CUDA_ERR("deviceMaskSum",hipMalloc(reinterpret_cast(&deviceMaskSum), numMaskSumFloats * sizeof(float))); - deviceMaskFloatOrig = deviceMaskFloat; - CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); - - fillMaskFloatBufAndMaskSumBuf(deviceMask, deviceMaskFloat, deviceMaskSum, useFP16, desiredBatchSize, nnXLen, nnYLen); - - int maxBatchSize = desiredBatchSize; - - CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); - GlobalPoolingResidualBlock* residualBlock = new GlobalPoolingResidualBlock( - cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC - ); - - size_t workspaceBytes = - residualBlock->requiredWorkspaceBytes( - cudaHandles,desiredBatchSize - ); - - void* deviceWorkspace; - CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); - - residualBlock->apply( - cudaHandles, - scratch, - desiredBatchSize, - deviceInput, - deviceScratch, - deviceMask, - deviceMaskSum, - deviceWorkspace, - workspaceBytes - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); - - hipFree(deviceWorkspace); - - delete residualBlock; - delete manager; - - hipFree(deviceInput); - hipFree(deviceMask); - hipFree(deviceMaskFloatOrig); - hipFree(deviceMaskSum); - hipFree(deviceScratch); - delete scratch; - delete cudaHandles; - - return true; -} - - -#endif // USE_ROCM_BACKEND From c70d841a92f97d364ba6132b4957eb6014310cbb Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 04:27:09 +0200 Subject: [PATCH 11/37] Update docks --- .gitignore | 2 +- Compiling.md | 3 +- README.md | 55 +++++++++++++++++------------- cpp/README.md | 2 +- cpp/configs/analysis_example.cfg | 29 ++++++++++++++-- cpp/configs/contribute_example.cfg | 30 ++++++++++++++-- cpp/configs/gtp_example.cfg | 32 +++++++++++++++-- cpp/configs/match_example.cfg | 30 ++++++++++++++-- 8 files changed, 144 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 2e933d553b..83492a14f0 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ cpp/main cpp/maincuda cpp/mainopencl cpp/katago -cpp/configs +# cpp/configs cpp/evalsgf cpp/run*.sh cpp/tests/scratch diff --git a/Compiling.md b/Compiling.md index 648fea548e..9d810a5039 100644 --- a/Compiling.md +++ b/Compiling.md @@ -33,6 +33,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the OpenCL backend, a modern GPU that supports OpenCL 1.2 or greater, or else something like [this](https://software.intel.com/en-us/opencl-sdk) for CPU. But if using CPU, Eigen should be better. * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. + * If using the ROCm backend, ROCm 6.4 or later and a GPU capable of supporting them. More information about installation(https://rocm.docs.amd.com/projects/install-on-linux/en/latest/) and please install all possiable ROCm developer packages, instead of just ROCm runtime packages. * If using the Eigen backend, Eigen3. With Debian packages, (i.e. apt or apt-get), this should be `libeigen3-dev`. * zlib, libzip. With Debian packages (i.e. apt or apt-get), these should be `zlib1g-dev`, `libzip-dev`. * If you want to do self-play training and research, probably Google perftools `libgoogle-perftools-dev` for TCMalloc or some other better malloc implementation. For unknown reasons, the allocation pattern in self-play with large numbers of threads and parallel games causes a lot of memory fragmentation under glibc malloc that will eventually run your machine out of memory, but better mallocs handle it fine. @@ -41,7 +42,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * `git clone https://github.com/lightvector/KataGo.git` * Compile using CMake and make in the cpp directory: * `cd KataGo/cpp` - * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` depending on which backend you want. + * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` or `cmake . -DUSE_BACKEND=ROCM`depending on which backend you want. * Specify also `-DUSE_TCMALLOC=1` if using TCMalloc. * Compiling will also call git commands to embed the git hash into the compiled executable, specify also `-DNO_GIT_REVISION=1` to disable it if this is causing issues for you. * Specify `-DUSE_AVX2=1` to also compile Eigen with AVX2 and FMA support, which will make it incompatible with old CPUs but much faster. (If you want to go further, you can also add `-DCMAKE_CXX_FLAGS='-march=native'` which will specialize to precisely your machine's CPU, but the exe might not run on other machines at all). diff --git a/README.md b/README.md index ce7e87b97d..768e408384 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,30 @@ # KataGo -* [Overview](#overview) -* [Training History and Research](#training-history-and-research) -* [Where To Download Stuff](#where-to-download-stuff) -* [Setting Up and Running KataGo](#setting-up-and-running-katago) - * [GUIs](#guis) - * [Windows and Linux](#windows-and-linux) - * [MacOS](#macos) - * [OpenCL vs CUDA vs TensorRT vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-eigen) - * [How To Use](#how-to-use) - * [Tuning for Performance](#tuning-for-performance) - * [Common Questions and Issues](#common-questions-and-issues) - * [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers) - * [Common Problems](#common-problems) - * [Other Questions](#other-questions) -* [Features for Developers](#features-for-developers) - * [GTP Extensions](#gtp-extensions) - * [Analysis Engine](#analysis-engine) -* [Compiling KataGo](#compiling-katago) -* [Source Code Overview](#source-code-overview) -* [Selfplay Training](#selfplay-training) -* [Contributors](#contributors) -* [License](#license) +- [KataGo](#katago) + - [Overview](#overview) + - [Training History and Research and Docs](#training-history-and-research-and-docs) + - [Where To Download Stuff](#where-to-download-stuff) + - [Setting Up and Running KataGo](#setting-up-and-running-katago) + - [GUIs](#guis) + - [Windows and Linux](#windows-and-linux) + - [MacOS](#macos) + - [OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-rocm-vs-eigen) + - [How To Use](#how-to-use) + - [Human-style Play and Analysis](#human-style-play-and-analysis) + - [Other Commands:](#other-commands) + - [Tuning for Performance](#tuning-for-performance) + - [Common Questions and Issues](#common-questions-and-issues) + - [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers) + - [Common Problems](#common-problems) + - [Other Questions](#other-questions) + - [Features for Developers](#features-for-developers) + - [GTP Extensions:](#gtp-extensions) + - [Analysis Engine:](#analysis-engine) + - [Compiling KataGo](#compiling-katago) + - [Source Code Overview:](#source-code-overview) + - [Selfplay Training:](#selfplay-training) + - [Contributors](#contributors) + - [License](#license) ## Overview @@ -84,8 +87,8 @@ The community also provides KataGo packages for [Homebrew](https://brew.sh) on M Use `brew install katago`. The latest config files and networks are installed in KataGo's `share` directory. Find them via `brew list --verbose katago`. A basic way to run katago will be `katago gtp -config $(brew list --verbose katago | grep 'gtp.*\.cfg') -model $(brew list --verbose katago | grep .gz | head -1)`. You should choose the Network according to the release notes here and customize the provided example config as with every other way of installing KataGo. -### OpenCL vs CUDA vs TensorRT vs Eigen -KataGo has four backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), and Eigen (CPU). +### OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen +KataGo has five backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), ROCm (GPU) and Eigen (CPU). The quick summary is: * **To easily get something working, try OpenCL if you have any good or decent GPU.** @@ -93,11 +96,13 @@ The quick summary is: * Use Eigen with AVX2 if you don't have a GPU or if your GPU is too old/weak to work with OpenCL, and you just want a plain CPU KataGo. * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. * The CUDA backend can work for NVIDIA GPUs with CUDA+CUDNN installed but is likely worse than TensorRT. + * The ROCm backend can work for AMD GPUs with ROCm+MIOpen installed. More in detail: * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. On most GPUs, the OpenCL implementation will actually beat NVIDIA's own CUDA/CUDNN at performance. The exception is for top-end NVIDIA GPUs that support FP16 and tensor cores, in which case sometimes one is better and sometimes the other is better. * TensorRT is similar to CUDA, but only uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs, it should work whenever CUDA does and will usually be faster than CUDA or any other backend. + * ROCm is a GPU backend specific to AMD GPUs (it will not work with NVIDIA or Intel or any other GPUs) and requires installing [ROCm](https://rocm.docs.amd.com) and [MIOpen](https://rocm.docs.amd.com/projects/MIOpen) and a modern AMD GPU. On most GPUs, the OpenCL implementation will actually beat AMD's own ROCm/MIOpen at performance. The exception is for top-end AMD GPUs that support FP16 and stream processors, in which case sometimes one is better and sometimes the other is better. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. For **any** implementation, it's recommended that you also tune the number of threads used if you care about optimal performance, as it can make a factor of 2-3 difference in the speed. See "Tuning for Performance" below. However, if you mostly just want to get it working, then the default untuned settings should also be still reasonable. @@ -175,6 +180,8 @@ This section summarizes a number of common questions and issues when running Kat #### Issues with specific GPUs or GPU drivers If you are observing any crashes in KataGo while attempting to run the benchmark or the program itself, and you have one of the below GPUs, then this is likely the reason. +* **AMD GPUs** - If you choose to use ROCm backend, uou need a GPU supported with official [System requirements lists](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html) (at least AMD Radeon RX 7700 XT). And ROCm backend only supports Linux now, because MIOpen and CMake HIP Language doesn't support Windows at this moment. We suggest installing the lastest version of ROCm developer stack. + * **AMD Radeon RX 5700** - AMD's drivers for OpenCL for this GPU have been buggy ever since this GPU was released, and as of May 2020 AMD has still never released a fix. If you are using this GPU, you will just not be able to run KataGo (Leela Zero and other Go engines will probably fail too) and will probably also obtain incorrect calculations or crash if doing anything else scientific or mathematical that uses OpenCL. See for example these reddit threads: [[1]](https://www.reddit.com/r/Amd/comments/ebso1x/its_not_just_setihome_any_mathematic_or/) or [[2]](https://www.reddit.com/r/BOINC/comments/ebiz18/psa_please_remove_your_amd_rx5700xt_from_setihome/) or this [L19 thread](https://lifein19x19.com/viewtopic.php?f=18&t=17093). * **OpenCL Mesa** - These drivers for OpenCL are buggy. Particularly if on startup before crashing you see KataGo printing something like `Found OpenCL Platform 0: ... (Mesa) (OpenCL 1.1 Mesa ...) ...` diff --git a/cpp/README.md b/cpp/README.md index 1f5d8d21fc..7376c6b7d3 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -15,7 +15,7 @@ Summary of source folders, in approximate dependency order, from lowest level to * `nninputs.{cpp,h}` - Implements the input features for the neural net. * `sgfmetadata.{cpp,h}` - Implements the input features for the [HumanSL neural net](https://github.com/lightvector/KataGo/blob/master/docs/Analysis_Engine.md#human-sl-analysis-guide), for conditioning on various SGF metadata about human players from training data. * `nninterface.h` - Common interface that is implemented by every low-level neural net backend. - * `{cuda,opencl,eigen,trt,dummy}backend.cpp` - Various backends. + * `{cuda,opencl,eigen,trt,rocm,metal,dummy}backend.cpp` - Various backends. * `nneval.{cpp,h}` - Top-level handle to the neural net used by the rest of the engine, implements thread-safe batching of queries. * `search` - The main search engine. * `timecontrols.cpp` - Basic handling of a few possible time controls. diff --git a/cpp/configs/analysis_example.cfg b/cpp/configs/analysis_example.cfg index 090bdd2425..d5b7e3990c 100644 --- a/cpp/configs/analysis_example.cfg +++ b/cpp/configs/analysis_example.cfg @@ -207,9 +207,7 @@ nnRandomize = true # cudaUseNHWC = auto -# ------------------------------ -# Metal GPU settings -# ------------------------------ +# Metal GPU settings-------------------------------------- # These only apply when using the METAL version of KataGo. # For one Metal instance: KataGo will automatically use the default device. @@ -223,6 +221,31 @@ nnRandomize = true # The pattern continues for additional Metal instances. +# ROCm GPU settings-------------------------------------- +# These only apply when using the ROCm version of KataGo. + +# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 +# rocmDeviceToUse = 0 + +# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 + +# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 +# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 + +# You can probably guess the pattern if you have four, five, etc. GPUs. + +# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you +# want to try to force a particular behavior though you can uncomment these lines and change them +# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using +# FP16 but you think it should. +# rocmUseFP16 = auto +# ROCm does not support NHWC, so this is always false. + + # OpenCL-specific GPU settings-------------------------------------- # These only apply when using the OpenCL version of KataGo. diff --git a/cpp/configs/contribute_example.cfg b/cpp/configs/contribute_example.cfg index 6ca039f112..fb6f0d81d7 100644 --- a/cpp/configs/contribute_example.cfg +++ b/cpp/configs/contribute_example.cfg @@ -83,9 +83,8 @@ watchOngoingGameInFileName = watchgame.txt # cudaUseNHWC = auto -# ------------------------------ -# Metal GPU settings -# ------------------------------ +# Metal GPU settings-------------------------------------- + # These only apply when using the METAL version of KataGo. # For one Metal instance: KataGo will automatically use the default device. @@ -99,6 +98,31 @@ watchOngoingGameInFileName = watchgame.txt # The pattern continues for additional Metal instances. +# ROCm GPU settings-------------------------------------- +# These only apply when using the ROCm version of KataGo. + +# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 +# rocmDeviceToUse = 0 + +# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 + +# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 +# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 + +# You can probably guess the pattern if you have four, five, etc. GPUs. + +# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you +# want to try to force a particular behavior though you can uncomment these lines and change them +# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using +# FP16 but you think it should. +# rocmUseFP16 = auto +# ROCm does not support NHWC, so this is always false. + + # OpenCL GPU settings-------------------------------------- # These only apply when using the OpenCL version of KataGo. diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index 58098db425..f8289140d3 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -443,9 +443,9 @@ searchFactorWhenWinningThreshold = 0.95 # cudaUseFP16 = auto # cudaUseNHWC = auto -# ------------------------------ -# Metal GPU settings -# ------------------------------ + +# Metal GPU settings-------------------------------------- + # These only apply when using the METAL version of KataGo. # For one Metal instance: KataGo will automatically use the default device. @@ -458,6 +458,32 @@ searchFactorWhenWinningThreshold = 0.95 # The pattern continues for additional Metal instances. + +# ROCm GPU settings-------------------------------------- +# These only apply when using the ROCm version of KataGo. + +# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 +# rocmDeviceToUse = 0 + +# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 + +# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 +# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 + +# You can probably guess the pattern if you have four, five, etc. GPUs. + +# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you +# want to try to force a particular behavior though you can uncomment these lines and change them +# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using +# FP16 but you think it should. +# rocmUseFP16 = auto +# ROCm does not support NHWC, so this is always false. + + # ------------------------------ # OpenCL GPU settings # ------------------------------ diff --git a/cpp/configs/match_example.cfg b/cpp/configs/match_example.cfg index 7e5b4fc09f..08859f557f 100644 --- a/cpp/configs/match_example.cfg +++ b/cpp/configs/match_example.cfg @@ -156,9 +156,8 @@ numNNServerThreadsPerModel = 1 # cudaUseNHWC = auto -# ------------------------------ -# Metal GPU settings -# ------------------------------ +# Metal GPU settings-------------------------------------- + # These only apply when using the METAL version of KataGo. # For one Metal instance: KataGo will automatically use the default device. @@ -172,6 +171,31 @@ numNNServerThreadsPerModel = 1 # The pattern continues for additional Metal instances. +# ROCm GPU settings-------------------------------------- +# These only apply when using the ROCm version of KataGo. + +# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 +# rocmDeviceToUse = 0 + +# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 + +# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): +# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 +# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 +# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 + +# You can probably guess the pattern if you have four, five, etc. GPUs. + +# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you +# want to try to force a particular behavior though you can uncomment these lines and change them +# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using +# FP16 but you think it should. +# rocmUseFP16 = auto +# ROCm does not support NHWC, so this is always false. + + # OpenCL GPU settings-------------------------------------- # These only apply when using OpenCL as the backend for inference. # (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg) From 1d05ca8d640a1aa55a7f7a835b0f84db7e85d36d Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 04:28:24 +0200 Subject: [PATCH 12/37] Update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 83492a14f0..2e933d553b 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ cpp/main cpp/maincuda cpp/mainopencl cpp/katago -# cpp/configs +cpp/configs cpp/evalsgf cpp/run*.sh cpp/tests/scratch From 9d4662b7d8cacaec0f9b566aa8741813fa2bc870 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 14:01:55 +0200 Subject: [PATCH 13/37] Update new method --- cpp/neuralnet/rocmbackend.cpp | 289 ++++++---------------------------- 1 file changed, 50 insertions(+), 239 deletions(-) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 0fd5aa03fe..9e7f4cf0be 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -255,11 +255,8 @@ struct ConvLayer { ByBatchSizeView outputDescriptors; miopenTensorDescriptor_t filterDescriptor; miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size + ByBatchSize* convolutionAlgorithms; //array of one for each batch size void* filterBuf; - void* inputTmp; - void* outputTmp; - void* workspaceTmp; ConvLayer() = delete; ConvLayer(const ConvLayer&) = delete; @@ -299,8 +296,6 @@ struct ConvLayer { inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); int maxBatchSize = manager->maxBatchSize; - int xLen = manager->nnXLen; - int yLen = manager->nnYLen; bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; @@ -334,54 +329,68 @@ struct ConvLayer { CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); } - convolutionAlgorithms = new ByBatchSize(maxBatchSize); - - size_t inBytes = maxBatchSize * inChannels * xLen * yLen + 3324928; - size_t outBytes = maxBatchSize * outChannels * xLen * yLen + 3324928; - size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize) + 3324928; - - CudaUtils::mallocOnDevice(name, inBytes, inputTmp, useFP16); - CudaUtils::mallocOnDevice(name, outBytes, outputTmp, useFP16); - CudaUtils::mallocOnDevice(name, workspaceBytes, workspaceTmp, useFP16); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + convolutionAlgorithms = new ByBatchSize(maxBatchSize); for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - const int requestedAlgoCount = 8; - int returnedAlgoCount = -1; - miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; - CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( + size_t requestedAlgoCount = 8; + size_t returnedAlgoCount = -1; + miopenConvSolution_t solutions[2 * requestedAlgoCount]; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + &requestedAlgoCount + )); + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( cudaHandles->cudnn, - inputDescriptor, - inputTmp, filterDescriptor, - filterBuf, + inputDescriptor, convolutionDescriptor, outputDescriptor, - outputTmp, requestedAlgoCount, &returnedAlgoCount, - results, - workspaceTmp, - workspaceBytes, - false + solutions )); if(returnedAlgoCount <= 0) - throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); - (*convolutionAlgorithms)[batchSize] = results[0]; + throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); + (*convolutionAlgorithms)[batchSize] = solutions[0]; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + (*convolutionAlgorithms)[batchSize].solution_id + )); } assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + if(filterNHWC) { + vector weightsTransposed(desc->weights.size()); + for(int y = 0; y < convYSize; y++) { + for(int x = 0; x < convXSize; x++) { + for(int ic = 0; ic < inChannels; ic++) { + for(int oc = 0; oc < outChannels; oc++) { + weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = + desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; + } + } + } + } + CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); + hipDeviceSynchronize(); + } + else + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); } ~ConvLayer() { hipFree(filterBuf); - hipFree(inputTmp); - hipFree(outputTmp); - hipFree(workspaceTmp); miopenDestroyTensorDescriptor(filterDescriptor); miopenDestroyConvolutionDescriptor(convolutionDescriptor); delete convolutionAlgorithms; @@ -392,12 +401,13 @@ struct ConvLayer { int batchSize ) const { size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( cudaHandles->cudnn, filterDescriptor, inputDescriptors[batchSize], convolutionDescriptor, outputDescriptors[batchSize], + (*convolutionAlgorithms)[batchSize].solution_id, &workspaceBytes )); return workspaceBytes; @@ -412,224 +422,25 @@ struct ConvLayer { void* workspaceBuf, size_t workspaceBytes ) const { - accumulate = false; const float alpha = 1.0f; const float beta = accumulate ? 1.0f : 0.0f; - CUDNN_ERR(name.c_str(), miopenConvolutionForward( + CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( cudaHandles->cudnn, - &alpha, - inputDescriptors[batchSize], - inputBuf, filterDescriptor, filterBuf, + inputDescriptors[batchSize], + inputBuf, convolutionDescriptor, - (*convolutionAlgorithms)[batchSize].fwd_algo, - &beta, outputDescriptors[batchSize], outputBuf, workspaceBuf, - workspaceBytes + workspaceBytes, + (*convolutionAlgorithms)[batchSize].solution_id )); } }; -// New ConvLayer structure with MIOpen API - -// struct ConvLayer { -// const string name; -// const int inChannels; -// const int outChannels; -// ByBatchSizeView inputDescriptors; -// ByBatchSizeView outputDescriptors; -// miopenTensorDescriptor_t filterDescriptor; -// miopenConvolutionDescriptor_t convolutionDescriptor; -// ByBatchSize* convolutionAlgorithms; //array of one for each batch size -// void* filterBuf; - -// ConvLayer() = delete; -// ConvLayer(const ConvLayer&) = delete; -// ConvLayer& operator=(const ConvLayer&) = delete; - -// ConvLayer( -// CudaHandles* cudaHandles, -// CudnnManager* manager, -// const ConvLayerDesc* desc, -// bool useFP16, -// bool useNHWC -// ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) -// {} - -// ConvLayer( -// CudaHandles* cudaHandles, -// CudnnManager* manager, -// const ConvLayerDesc* desc, -// bool useFP16, -// bool useNHWCIn, -// bool useNHWCOut -// ) : -// name(desc->name), -// inChannels(desc->inChannels), -// outChannels(desc->outChannels) -// { -// int convYSize = desc->convYSize; -// int convXSize = desc->convXSize; -// int dilationY = desc->dilationY; -// int dilationX = desc->dilationX; -// int paddingX = (convXSize / 2) * dilationX; -// int paddingY = (convYSize / 2) * dilationY; - -// assert(convXSize % 2 == 1); -// assert(convYSize % 2 == 1); - -// inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); -// outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); -// int maxBatchSize = manager->maxBatchSize; - -// bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; - -// CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); -// CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( -// filterDescriptor, -// (useFP16 ? miopenHalf : miopenFloat), -// outChannels, -// inChannels, -// convYSize, -// convXSize -// )); - -// int yStride = 1; -// int xStride = 1; - - -// CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); -// CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( -// convolutionDescriptor, -// miopenConvolution, -// paddingY, -// paddingX, -// yStride, -// xStride, -// dilationY, -// dilationX -// )); -// if(useFP16) { -// int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs -// CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); -// } - -// convolutionAlgorithms = new ByBatchSize(maxBatchSize); - -// for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { -// const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; -// const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; -// size_t requestedAlgoCount = 8; -// size_t returnedAlgoCount = -1; -// miopenConvSolution_t solutions[2 * requestedAlgoCount]; -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptor, -// convolutionDescriptor, -// outputDescriptor, -// &requestedAlgoCount -// )); -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptor, -// convolutionDescriptor, -// outputDescriptor, -// requestedAlgoCount, -// &returnedAlgoCount, -// solutions -// )); -// if(returnedAlgoCount <= 0) -// throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); -// (*convolutionAlgorithms)[batchSize] = solutions[0]; -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptor, -// convolutionDescriptor, -// outputDescriptor, -// (*convolutionAlgorithms)[batchSize].solution_id -// )); -// } - -// assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - -// if(filterNHWC) { -// vector weightsTransposed(desc->weights.size()); -// for(int y = 0; y < convYSize; y++) { -// for(int x = 0; x < convXSize; x++) { -// for(int ic = 0; ic < inChannels; ic++) { -// for(int oc = 0; oc < outChannels; oc++) { -// weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = -// desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; -// } -// } -// } -// } -// CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); -// hipDeviceSynchronize(); -// } -// else -// CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); -// } - -// ~ConvLayer() { -// hipFree(filterBuf); -// miopenDestroyTensorDescriptor(filterDescriptor); -// miopenDestroyConvolutionDescriptor(convolutionDescriptor); -// delete convolutionAlgorithms; -// } - -// size_t requiredWorkspaceBytes( -// CudaHandles* cudaHandles, -// int batchSize -// ) const { -// size_t workspaceBytes = 0; -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptors[batchSize], -// convolutionDescriptor, -// outputDescriptors[batchSize], -// (*convolutionAlgorithms)[batchSize].solution_id, -// &workspaceBytes -// )); -// return workspaceBytes; -// } - -// void apply( -// CudaHandles* cudaHandles, -// int batchSize, -// bool accumulate, -// void* inputBuf, -// void* outputBuf, -// void* workspaceBuf, -// size_t workspaceBytes -// ) const { -// const float alpha = 1.0f; -// const float beta = accumulate ? 1.0f : 0.0f; -// CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( -// cudaHandles->cudnn, -// filterDescriptor, -// filterBuf, -// inputDescriptors[batchSize], -// inputBuf, -// convolutionDescriptor, -// outputDescriptors[batchSize], -// outputBuf, -// workspaceBuf, -// workspaceBytes, -// (*convolutionAlgorithms)[batchSize].solution_id -// )); -// } - -// }; - //--------------------------------------------------------------------------------- struct BatchNormLayer { From d40bd509355f882a1efcd9bdc9ae1ef2713f90cd Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 2 Aug 2025 14:20:05 +0200 Subject: [PATCH 14/37] Optimize performance --- cpp/neuralnet/rocmbackend.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 539f0b91af..0fd5aa03fe 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -336,9 +336,9 @@ struct ConvLayer { convolutionAlgorithms = new ByBatchSize(maxBatchSize); - size_t inBytes = maxBatchSize * inChannels * xLen * yLen; - size_t outBytes = maxBatchSize * outChannels * xLen * yLen; - size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize) + 10305856; //1661440; + size_t inBytes = maxBatchSize * inChannels * xLen * yLen + 3324928; + size_t outBytes = maxBatchSize * outChannels * xLen * yLen + 3324928; + size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize) + 3324928; CudaUtils::mallocOnDevice(name, inBytes, inputTmp, useFP16); CudaUtils::mallocOnDevice(name, outBytes, outputTmp, useFP16); From 158d24dff21eedc12e58d202d52a4a766ac1f2fc Mon Sep 17 00:00:00 2001 From: Looong01 Date: Wed, 13 Aug 2025 04:05:50 +0200 Subject: [PATCH 15/37] Update new Convlayer method --- cpp/neuralnet/rocmbackend.cpp | 289 ++++++---------------------------- 1 file changed, 50 insertions(+), 239 deletions(-) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 0fd5aa03fe..9e7f4cf0be 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -255,11 +255,8 @@ struct ConvLayer { ByBatchSizeView outputDescriptors; miopenTensorDescriptor_t filterDescriptor; miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size + ByBatchSize* convolutionAlgorithms; //array of one for each batch size void* filterBuf; - void* inputTmp; - void* outputTmp; - void* workspaceTmp; ConvLayer() = delete; ConvLayer(const ConvLayer&) = delete; @@ -299,8 +296,6 @@ struct ConvLayer { inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); int maxBatchSize = manager->maxBatchSize; - int xLen = manager->nnXLen; - int yLen = manager->nnYLen; bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; @@ -334,54 +329,68 @@ struct ConvLayer { CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); } - convolutionAlgorithms = new ByBatchSize(maxBatchSize); - - size_t inBytes = maxBatchSize * inChannels * xLen * yLen + 3324928; - size_t outBytes = maxBatchSize * outChannels * xLen * yLen + 3324928; - size_t workspaceBytes = requiredWorkspaceBytes(cudaHandles, maxBatchSize) + 3324928; - - CudaUtils::mallocOnDevice(name, inBytes, inputTmp, useFP16); - CudaUtils::mallocOnDevice(name, outBytes, outputTmp, useFP16); - CudaUtils::mallocOnDevice(name, workspaceBytes, workspaceTmp, useFP16); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + convolutionAlgorithms = new ByBatchSize(maxBatchSize); for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - const int requestedAlgoCount = 8; - int returnedAlgoCount = -1; - miopenConvAlgoPerf_t results[2 * requestedAlgoCount]; - CUDNN_ERR(name.c_str(),miopenFindConvolutionForwardAlgorithm( + size_t requestedAlgoCount = 8; + size_t returnedAlgoCount = -1; + miopenConvSolution_t solutions[2 * requestedAlgoCount]; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + &requestedAlgoCount + )); + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( cudaHandles->cudnn, - inputDescriptor, - inputTmp, filterDescriptor, - filterBuf, + inputDescriptor, convolutionDescriptor, outputDescriptor, - outputTmp, requestedAlgoCount, &returnedAlgoCount, - results, - workspaceTmp, - workspaceBytes, - false + solutions )); if(returnedAlgoCount <= 0) - throw StringError("miopenFindConvolutionForwardAlgorithm returned no algorithms?"); - (*convolutionAlgorithms)[batchSize] = results[0]; + throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); + (*convolutionAlgorithms)[batchSize] = solutions[0]; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( + cudaHandles->cudnn, + filterDescriptor, + inputDescriptor, + convolutionDescriptor, + outputDescriptor, + (*convolutionAlgorithms)[batchSize].solution_id + )); } assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); + if(filterNHWC) { + vector weightsTransposed(desc->weights.size()); + for(int y = 0; y < convYSize; y++) { + for(int x = 0; x < convXSize; x++) { + for(int ic = 0; ic < inChannels; ic++) { + for(int oc = 0; oc < outChannels; oc++) { + weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = + desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; + } + } + } + } + CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); + hipDeviceSynchronize(); + } + else + CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); } ~ConvLayer() { hipFree(filterBuf); - hipFree(inputTmp); - hipFree(outputTmp); - hipFree(workspaceTmp); miopenDestroyTensorDescriptor(filterDescriptor); miopenDestroyConvolutionDescriptor(convolutionDescriptor); delete convolutionAlgorithms; @@ -392,12 +401,13 @@ struct ConvLayer { int batchSize ) const { size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetWorkSpaceSize( + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( cudaHandles->cudnn, filterDescriptor, inputDescriptors[batchSize], convolutionDescriptor, outputDescriptors[batchSize], + (*convolutionAlgorithms)[batchSize].solution_id, &workspaceBytes )); return workspaceBytes; @@ -412,224 +422,25 @@ struct ConvLayer { void* workspaceBuf, size_t workspaceBytes ) const { - accumulate = false; const float alpha = 1.0f; const float beta = accumulate ? 1.0f : 0.0f; - CUDNN_ERR(name.c_str(), miopenConvolutionForward( + CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( cudaHandles->cudnn, - &alpha, - inputDescriptors[batchSize], - inputBuf, filterDescriptor, filterBuf, + inputDescriptors[batchSize], + inputBuf, convolutionDescriptor, - (*convolutionAlgorithms)[batchSize].fwd_algo, - &beta, outputDescriptors[batchSize], outputBuf, workspaceBuf, - workspaceBytes + workspaceBytes, + (*convolutionAlgorithms)[batchSize].solution_id )); } }; -// New ConvLayer structure with MIOpen API - -// struct ConvLayer { -// const string name; -// const int inChannels; -// const int outChannels; -// ByBatchSizeView inputDescriptors; -// ByBatchSizeView outputDescriptors; -// miopenTensorDescriptor_t filterDescriptor; -// miopenConvolutionDescriptor_t convolutionDescriptor; -// ByBatchSize* convolutionAlgorithms; //array of one for each batch size -// void* filterBuf; - -// ConvLayer() = delete; -// ConvLayer(const ConvLayer&) = delete; -// ConvLayer& operator=(const ConvLayer&) = delete; - -// ConvLayer( -// CudaHandles* cudaHandles, -// CudnnManager* manager, -// const ConvLayerDesc* desc, -// bool useFP16, -// bool useNHWC -// ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) -// {} - -// ConvLayer( -// CudaHandles* cudaHandles, -// CudnnManager* manager, -// const ConvLayerDesc* desc, -// bool useFP16, -// bool useNHWCIn, -// bool useNHWCOut -// ) : -// name(desc->name), -// inChannels(desc->inChannels), -// outChannels(desc->outChannels) -// { -// int convYSize = desc->convYSize; -// int convXSize = desc->convXSize; -// int dilationY = desc->dilationY; -// int dilationX = desc->dilationX; -// int paddingX = (convXSize / 2) * dilationX; -// int paddingY = (convYSize / 2) * dilationY; - -// assert(convXSize % 2 == 1); -// assert(convYSize % 2 == 1); - -// inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); -// outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); -// int maxBatchSize = manager->maxBatchSize; - -// bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; - -// CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); -// CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( -// filterDescriptor, -// (useFP16 ? miopenHalf : miopenFloat), -// outChannels, -// inChannels, -// convYSize, -// convXSize -// )); - -// int yStride = 1; -// int xStride = 1; - - -// CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); -// CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( -// convolutionDescriptor, -// miopenConvolution, -// paddingY, -// paddingX, -// yStride, -// xStride, -// dilationY, -// dilationX -// )); -// if(useFP16) { -// int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs -// CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); -// } - -// convolutionAlgorithms = new ByBatchSize(maxBatchSize); - -// for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { -// const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; -// const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; -// size_t requestedAlgoCount = 8; -// size_t returnedAlgoCount = -1; -// miopenConvSolution_t solutions[2 * requestedAlgoCount]; -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptor, -// convolutionDescriptor, -// outputDescriptor, -// &requestedAlgoCount -// )); -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptor, -// convolutionDescriptor, -// outputDescriptor, -// requestedAlgoCount, -// &returnedAlgoCount, -// solutions -// )); -// if(returnedAlgoCount <= 0) -// throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); -// (*convolutionAlgorithms)[batchSize] = solutions[0]; -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptor, -// convolutionDescriptor, -// outputDescriptor, -// (*convolutionAlgorithms)[batchSize].solution_id -// )); -// } - -// assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - -// if(filterNHWC) { -// vector weightsTransposed(desc->weights.size()); -// for(int y = 0; y < convYSize; y++) { -// for(int x = 0; x < convXSize; x++) { -// for(int ic = 0; ic < inChannels; ic++) { -// for(int oc = 0; oc < outChannels; oc++) { -// weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = -// desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; -// } -// } -// } -// } -// CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); -// hipDeviceSynchronize(); -// } -// else -// CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); -// } - -// ~ConvLayer() { -// hipFree(filterBuf); -// miopenDestroyTensorDescriptor(filterDescriptor); -// miopenDestroyConvolutionDescriptor(convolutionDescriptor); -// delete convolutionAlgorithms; -// } - -// size_t requiredWorkspaceBytes( -// CudaHandles* cudaHandles, -// int batchSize -// ) const { -// size_t workspaceBytes = 0; -// CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( -// cudaHandles->cudnn, -// filterDescriptor, -// inputDescriptors[batchSize], -// convolutionDescriptor, -// outputDescriptors[batchSize], -// (*convolutionAlgorithms)[batchSize].solution_id, -// &workspaceBytes -// )); -// return workspaceBytes; -// } - -// void apply( -// CudaHandles* cudaHandles, -// int batchSize, -// bool accumulate, -// void* inputBuf, -// void* outputBuf, -// void* workspaceBuf, -// size_t workspaceBytes -// ) const { -// const float alpha = 1.0f; -// const float beta = accumulate ? 1.0f : 0.0f; -// CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( -// cudaHandles->cudnn, -// filterDescriptor, -// filterBuf, -// inputDescriptors[batchSize], -// inputBuf, -// convolutionDescriptor, -// outputDescriptors[batchSize], -// outputBuf, -// workspaceBuf, -// workspaceBytes, -// (*convolutionAlgorithms)[batchSize].solution_id -// )); -// } - -// }; - //--------------------------------------------------------------------------------- struct BatchNormLayer { From 0bfe0a144279a54e50e5a0555d82633d19360f07 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 4 Oct 2025 15:43:24 +0200 Subject: [PATCH 16/37] Add new compile target --- cpp/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 471a67a5f5..69ecf22b47 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -165,7 +165,8 @@ elseif(USE_BACKEND STREQUAL "ROCM") # Users can -DCMAKE_HIP_ARCHITECTURES=gfx90a;gfx942 manually specify GFX architectures if(NOT DEFINED CMAKE_HIP_ARCHITECTURES) # Default compile MI200 / RDNA3 cards, can be simplified as needed - set(CMAKE_HIP_ARCHITECTURES 90a 942 908 1100 1101 1200 1201 CACHE STRING "AMD GPU targets") + # set(CMAKE_HIP_ARCHITECTURES gfx950 gfx942 gfx90a gfx908 gfx1100 gfx1101 gfx1151 gfx1201 gfx1030 CACHE STRING "AMD GPU targets") + add_compile_definitions(-DGPU_TARGETS=gfx950,gfx942,gfx90a,gfx908,gfx1100,gfx1101,gfx1151,gfx1201,gfx1030) endif() # 2) Specify backend source code. rocmhelpers.hip contains GPU kernels, don't forget it @@ -464,7 +465,7 @@ elseif(USE_BACKEND STREQUAL "ROCM") target_compile_definitions(katago PRIVATE HIP_TARGET_VERSION=${CMAKE_HIP_COMPILER_VERSION}) string(TOLOWER "${CMAKE_HIP_ARCHITECTURES}" _gfxlist) # e.g. "90a;942" - if(_gfxlist MATCHES "803|900|90a|94[0-9]|110[0-9]|120[0-9]") + if(_gfxlist MATCHES "803|900|90a|94[0-9]|110[0-9]|120[0-9]|115[0-9]|1030") target_compile_definitions(katago PRIVATE HIP_SUPPORTS_FP16) message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") endif() From 26d8c5bd257a8508bae7673ade8b60a5d5506188 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 8 Nov 2025 13:04:03 +0100 Subject: [PATCH 17/37] Add ROCm for Windows support --- cpp/CMakeLists.txt | 119 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 26 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index de93a05404..830b529f86 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -2,8 +2,20 @@ cmake_minimum_required(VERSION 3.18.2) if(USE_BACKEND STREQUAL "METAL") project(katago LANGUAGES CXX Swift) elseif(USE_BACKEND STREQUAL "ROCM") - set(CMAKE_C_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) - set(CMAKE_CXX_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) + if(WIN32) + # Windows: Use clang++ from HIP SDK (hipcc doesn't work well on Windows) + # User can override with -DCMAKE_CXX_COMPILER if needed + if(NOT DEFINED CMAKE_CXX_COMPILER) + if(DEFINED ENV{HIP_PATH}) + set(CMAKE_CXX_COMPILER "$ENV{HIP_PATH}/bin/clang++.exe" CACHE FILEPATH "" FORCE) + set(CMAKE_C_COMPILER "$ENV{HIP_PATH}/bin/clang.exe" CACHE FILEPATH "" FORCE) + endif() + endif() + else() + # Linux: Use hipcc + set(CMAKE_C_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) + set(CMAKE_CXX_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) + endif() project(katago LANGUAGES C CXX HIP) else() project(katago) @@ -151,14 +163,23 @@ elseif(USE_BACKEND STREQUAL "ROCM") set(CMAKE_HIP_STANDARD 17) if(CMAKE_PREFIX_PATH STREQUAL "" OR NOT DEFINED CMAKE_PREFIX_PATH) - if(DEFINED ENV{HIP_PATH}) - # Windows HIP‑SDK - list(APPEND CMAKE_PREFIX_PATH $ENV{HIP_PATH}) - message(STATUS "Auto‑detected HIP_PATH=$ENV{HIP_PATH} → CMAKE_PREFIX_PATH") - elseif(EXISTS "/opt/rocm") - # Linux - list(APPEND CMAKE_PREFIX_PATH "/opt/rocm") - message(STATUS "CMAKE_PREFIX_PATH not given; defaulting to /opt/rocm") + if(WIN32) + # Windows: HIP SDK installed via installer or manually + if(DEFINED ENV{HIP_PATH}) + list(APPEND CMAKE_PREFIX_PATH "$ENV{HIP_PATH}") + message(STATUS "Auto-detected HIP_PATH=$ENV{HIP_PATH} → CMAKE_PREFIX_PATH") + elseif(DEFINED ENV{ROCM_PATH}) + list(APPEND CMAKE_PREFIX_PATH "$ENV{ROCM_PATH}") + message(STATUS "Auto-detected ROCM_PATH=$ENV{ROCM_PATH} → CMAKE_PREFIX_PATH") + else() + message(WARNING "HIP_PATH or ROCM_PATH environment variable not set. Please install HIP SDK for Windows.") + endif() + else() + # Linux: Standard ROCm installation path + if(EXISTS "/opt/rocm") + list(APPEND CMAKE_PREFIX_PATH "/opt/rocm") + message(STATUS "CMAKE_PREFIX_PATH not given; defaulting to /opt/rocm") + endif() endif() endif() @@ -473,20 +494,38 @@ elseif(USE_BACKEND STREQUAL "ROCM") message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") endif() - # 3) Find ROCm runtime & libraries. Since ROCm 6.x, CMake config-mode packages are included. If not found, add -DCMAKE_PREFIX_PATH=/opt/rocm + # 3) Find ROCm runtime & libraries. Since ROCm 6.x, CMake config-mode packages are included. If not found, add -DCMAKE_PREFIX_PATH=/opt/rocm (Linux) or HIP SDK path (Windows) find_package(hip QUIET CONFIG) # Export hip::device / hip::host find_package(hipblas QUIET CONFIG) # Export roc::hipblas - find_package(miopen QUIET CONFIG) # Export roc::miopen + find_package(miopen QUIET CONFIG) # Export roc::miopen or MIOpen + # ---------- fallback:HIP Runtime ---------- if(NOT hip_FOUND) - find_path(HIP_INCLUDE_DIR hip/hip_runtime.h - HINTS ${CMAKE_PREFIX_PATH} /opt/rocm - PATH_SUFFIXES include) - find_library(HIP_RUNTIME_LIB amdhip64 - HINTS ${CMAKE_PREFIX_PATH} /opt/rocm - PATH_SUFFIXES lib lib64) + if(WIN32) + # Windows: Search in HIP SDK installation + find_path(HIP_INCLUDE_DIR hip/hip_runtime.h + HINTS ${CMAKE_PREFIX_PATH} ENV HIP_PATH ENV ROCM_PATH + PATH_SUFFIXES include) + find_library(HIP_RUNTIME_LIB + NAMES amdhip64 amdhip64_6 + HINTS ${CMAKE_PREFIX_PATH} ENV HIP_PATH ENV ROCM_PATH + PATH_SUFFIXES lib bin) + else() + # Linux: Search in /opt/rocm + find_path(HIP_INCLUDE_DIR hip/hip_runtime.h + HINTS ${CMAKE_PREFIX_PATH} /opt/rocm + PATH_SUFFIXES include) + find_library(HIP_RUNTIME_LIB amdhip64 + HINTS ${CMAKE_PREFIX_PATH} /opt/rocm + PATH_SUFFIXES lib lib64) + endif() + if(NOT HIP_INCLUDE_DIR OR NOT HIP_RUNTIME_LIB) - message(FATAL_ERROR "HIP headers or runtime NOT found; install ROCm or set CMAKE_PREFIX_PATH.") + if(WIN32) + message(FATAL_ERROR "HIP headers or runtime NOT found; install HIP SDK for Windows or set CMAKE_PREFIX_PATH to HIP SDK installation path.") + else() + message(FATAL_ERROR "HIP headers or runtime NOT found; install ROCm or set CMAKE_PREFIX_PATH.") + endif() endif() add_library(hip::device UNKNOWN IMPORTED) set_target_properties(hip::device PROPERTIES @@ -498,26 +537,54 @@ elseif(USE_BACKEND STREQUAL "ROCM") # ---------- fallback:hipBLAS / MIOpen ---------- foreach(_pkg hipblas miopen) if(NOT ${_pkg}_FOUND) - find_library(${_pkg}_LIB ${_pkg} - HINTS ${CMAKE_PREFIX_PATH} /opt/rocm - PATH_SUFFIXES lib lib64) + if(WIN32) + # Windows naming conventions + if(_pkg STREQUAL "hipblas") + set(_lib_names hipblas) + else() + set(_lib_names MIOpen) + endif() + find_library(${_pkg}_LIB + NAMES ${_lib_names} + HINTS ${CMAKE_PREFIX_PATH} ENV HIP_PATH ENV ROCM_PATH + PATH_SUFFIXES lib bin) + else() + # Linux naming + find_library(${_pkg}_LIB ${_pkg} + HINTS ${CMAKE_PREFIX_PATH} /opt/rocm + PATH_SUFFIXES lib lib64) + endif() + if(${_pkg}_LIB) add_library(roc::${_pkg} UNKNOWN IMPORTED) set_target_properties(roc::${_pkg} PROPERTIES IMPORTED_LOCATION "${${_pkg}_LIB}") target_include_directories(katago SYSTEM PRIVATE ${HIP_INCLUDE_DIR}) + message(STATUS "Found ${_pkg} at ${${_pkg}_LIB}") else() - message(FATAL_ERROR "Required ROCm component ${_pkg} not found – install it or set CMAKE_PREFIX_PATH.") + if(WIN32) + message(FATAL_ERROR "Required ROCm component ${_pkg} not found – install HIP SDK for Windows or set CMAKE_PREFIX_PATH.") + else() + message(FATAL_ERROR "Required ROCm component ${_pkg} not found – install it or set CMAKE_PREFIX_PATH.") + endif() endif() endif() endforeach() - # 4) Header file paths are resolved by config-mode targets, no need to hard-code + # 4) Link libraries + # Note: On Windows, MIOpen might need to be linked as "MIOpen" directly if the target doesn't exist + if(TARGET MIOpen) + set(_miopen_target MIOpen) + elseif(TARGET roc::miopen) + set(_miopen_target roc::miopen) + else() + set(_miopen_target roc::miopen) + endif() + target_link_libraries(katago hip::device # HIP runtime & kernel offload roc::hipblas # BLAS - MIOpen - # roc::miopen # DNN primitives + ${_miopen_target} # DNN primitives ) elseif(USE_BACKEND STREQUAL "EIGEN") target_compile_definitions(katago PRIVATE USE_EIGEN_BACKEND) From ed396b72aa93e30e9ffcb728e879093151b92033 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sat, 28 Feb 2026 05:28:48 +0800 Subject: [PATCH 18/37] Fix bugs --- cpp/CMakeLists.txt | 11 +++++++++-- cpp/neuralnet/rocmbackend.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 577dfd2c3a..ddf9f11b14 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -495,10 +495,17 @@ elseif(USE_BACKEND STREQUAL "ROCM") target_compile_definitions(katago PRIVATE USE_ROCM_BACKEND) target_compile_definitions(katago PRIVATE HIP_TARGET_VERSION=${CMAKE_HIP_COMPILER_VERSION}) + # Option to disable FP16 support + set(ROCM_DISABLE_FP16 OFF CACHE BOOL "Disable FP16 support for ROCm backend") + string(TOLOWER "${CMAKE_HIP_ARCHITECTURES}" _gfxlist) # e.g. "90a;942" if(_gfxlist MATCHES "803|900|90a|94[0-9]|110[0-9]|120[0-9]|115[0-9]|1030") - target_compile_definitions(katago PRIVATE HIP_SUPPORTS_FP16) - message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") + if(ROCM_DISABLE_FP16) + message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}), but ROCM_DISABLE_FP16 is set, NOT defining HIP_SUPPORTS_FP16") + else() + target_compile_definitions(katago PRIVATE HIP_SUPPORTS_FP16) + message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") + endif() endif() # 3) Find ROCm runtime & libraries. Since ROCm 6.x, CMake config-mode packages are included. If not found, add -DCMAKE_PREFIX_PATH=/opt/rocm (Linux) or HIP SDK path (Windows) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp index 9e7f4cf0be..53e2c8d5ac 100644 --- a/cpp/neuralnet/rocmbackend.cpp +++ b/cpp/neuralnet/rocmbackend.cpp @@ -2330,6 +2330,15 @@ ComputeHandle* NeuralNet::createComputeHandle( if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) useFP16 = true; + // ROCm backend currently only supports NCHW format + if(inputsUseNHWC) { + if(logger != NULL) { + logger->write( + "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": WARNING - NHWC format requested but not supported by ROCm backend, falling back to NCHW" + ); + } + } + if(logger != NULL) { logger->write( "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) From ce2c9fc53a115a4aa7ae8d0240c56aacd4da0c20 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 16 Mar 2026 18:38:00 +0800 Subject: [PATCH 19/37] Add Intel NPU support --- .gitignore | 2 +- Compiling.md | 68 ++- README.md | 32 +- cpp/CMakeLists.txt | 199 ++++++- cpp/README.md | 5 +- cpp/command/benchmark.cpp | 97 +++- cpp/command/misc.cpp | 57 ++ cpp/configs/analysis_example.cfg | 28 + cpp/configs/contribute_example.cfg | 28 + cpp/configs/gtp_example.cfg | 37 ++ cpp/configs/match_example.cfg | 30 + cpp/dataio/loadmodel.cpp | 19 +- cpp/main.cpp | 7 + cpp/main.h | 1 + cpp/neuralnet/onnxbackend.cpp | 867 +++++++++++++++++++++++++++++ cpp/neuralnet/onnxmodelbuilder.cpp | 774 +++++++++++++++++++++++++ cpp/neuralnet/onnxmodelbuilder.h | 14 + cpp/program/gtpconfig.cpp | 31 +- cpp/program/gtpconfig.h | 3 +- cpp/program/setup.cpp | 55 +- cpp/runonnxtests.sh | 43 ++ 21 files changed, 2350 insertions(+), 47 deletions(-) create mode 100644 cpp/neuralnet/onnxbackend.cpp create mode 100644 cpp/neuralnet/onnxmodelbuilder.cpp create mode 100644 cpp/neuralnet/onnxmodelbuilder.h create mode 100644 cpp/runonnxtests.sh diff --git a/.gitignore b/.gitignore index 2e933d553b..94076bdce8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ cpp/mainopencl cpp/katago cpp/configs cpp/evalsgf -cpp/run*.sh +# cpp/run*.sh cpp/tests/scratch cpp/program/gitinfo.h diff --git a/Compiling.md b/Compiling.md index 60a0b8276c..8fcea46f85 100644 --- a/Compiling.md +++ b/Compiling.md @@ -35,6 +35,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. * If using the ROCm backend, ROCm 6.4 or later and a GPU capable of supporting them. More information about installation(https://rocm.docs.amd.com/projects/install-on-linux/en/latest/) and please install all possiable ROCm developer packages, instead of just ROCm runtime packages. * If using the Eigen backend, Eigen3. With Debian packages, (i.e. apt or apt-get), this should be `libeigen3-dev`. + * If using the ONNX backend, ONNX Runtime headers/libs and ONNX protobuf dependencies (`onnx/onnx-ml.pb.h`, `onnx_proto`, `protobuf-lite`) for `.bin.gz` model conversion support. * zlib, libzip. With Debian packages (i.e. apt or apt-get), these should be `zlib1g-dev`, `libzip-dev`. * If you want to do self-play training and research, probably Google perftools `libgoogle-perftools-dev` for TCMalloc or some other better malloc implementation. For unknown reasons, the allocation pattern in self-play with large numbers of threads and parallel games causes a lot of memory fragmentation under glibc malloc that will eventually run your machine out of memory, but better mallocs handle it fine. * If compiling to contribute to public distributed training runs, OpenSSL is required (`libssl-dev`). @@ -42,7 +43,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * `git clone https://github.com/lightvector/KataGo.git` * Compile using CMake and make in the cpp directory: * `cd KataGo/cpp` - * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` or `cmake . -DUSE_BACKEND=ROCM`depending on which backend you want. + * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` or `cmake . -DUSE_BACKEND=ROCM` or `cmake . -DUSE_BACKEND=ONNX` depending on which backend you want. * Specify also `-DUSE_TCMALLOC=1` if using TCMalloc. * Compiling will also call git commands to embed the git hash into the compiled executable, specify also `-DNO_GIT_REVISION=1` to disable it if this is causing issues for you. * Specify `-DUSE_AVX2=1` to also compile Eigen with AVX2 and FMA support, which will make it incompatible with old CPUs but much faster. (If you want to go further, you can also add `-DCMAKE_CXX_FLAGS='-march=native'` which will specialize to precisely your machine's CPU, but the exe might not run on other machines at all). @@ -55,6 +56,60 @@ As also mentioned in the instructions below but repeated here for visibility, if * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device when you run it (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). +## ONNX Runtime Backend +The ONNX backend uses ONNX Runtime for inference, and supports both: +* `.onnx` models loaded directly. +* `.bin.gz` KataGo models via internal conversion to ONNX graph (requires ONNX protobuf dependencies in CMake). + +### Windows Intel NPU (OpenVINO EP) Setup +1. Install Visual Studio Community or Visual Studio 2026 Build Tools: + * https://visualstudio.microsoft.com/zh-hans/downloads/ + * In installer workloads, select **Desktop development with C++**. +2. Install Intel NPU driver: + * https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html +3. Install OpenVINO 2026 archive package on Windows: + * https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html + * Typical install root looks like: `C:\Program Files (x86)\Intel\openvino_2026.0` +4. Build ONNX Runtime with OpenVINO EP for NPU (follow official docs): + * https://onnxruntime.ai/docs/build/eps.html#openvino + * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). + +### Prepare `ONNXRUNTIME_ROOT` in KataGo +Create: +* `cpp/external/onnxruntime-win-x64-openvino/include` +* `cpp/external/onnxruntime-win-x64-openvino/lib` + +Copy from your ONNX Runtime build/package output (``) to KataGo: +* `/include/*` -> `cpp/external/onnxruntime-win-x64-openvino/include/` +* `/lib/onnxruntime.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.lib` +* `/lib/onnxruntime.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.dll` +* `/lib/onnxruntime_providers_shared.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.dll` +* `/lib/onnxruntime_providers_openvino.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.dll` + +Optional if present in your ORT output: +* `/lib/onnxruntime_providers_shared.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` +* `/lib/onnxruntime_providers_openvino.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` + +### Minimal KataGo Build Commands (Windows, ONNX backend) +On Windows, `KATAGO_AUTO_FETCH_DEPS=ON` by default, so missing `zlib`, `onnx`, and `protobuf` dependencies are auto-fetched via vcpkg into `cpp/build/deps/vcpkg`. + +``` +cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-win-x64-openvino +cmake --build cpp/build --config Release +``` + +If you want to disable auto-fetch and provide dependencies manually: +* `-DKATAGO_AUTO_FETCH_DEPS=OFF` +* plus `-DONNX_INCLUDE_DIR=... -DONNX_PROTO_LIB=... -DPROTOBUF_INCLUDE_DIR=... -DPROTOBUF_LIB=... -DZLIB_INCLUDE_DIR=... -DZLIB_LIBRARY=...` + +Typical run config for Intel NPU: +* `onnxProvider = openvino` +* `onnxOpenVINODeviceType = NPU` +* `onnxOpenVINOEnableNPUFastCompile = true` (optional; may be ignored on ORT builds that do not support this key) + +Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). +For `onnxProvider=openvino` on Intel NPU, a single device is typically used. + ## Windows * TLDR: * Building from source on Windows is actually a bit tricky, depending on what version you're building, there's not necessarily a super-fast way. @@ -65,13 +120,8 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. I'm unsure how version compatibility works with CUDA, there's a good chance that later versions than these work just as well, but they have not been tested. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. * If using the Eigen backend, Eigen3, version 3.3.x. (http://eigen.tuxfamily.org/index.php?title=Main_Page#Download). - * zlib. Easy way to build zlib on Windows is to use vcpkg. Run in Powershell: - * git clone https://github.com/microsoft/vcpkg.git - * cd .\vcpkg\ - * .\bootstrap-vcpkg.bat - * .\vcpkg.exe install zlib:x64-windows - * Set CMake ZLIB_LIBRARY to vcpkg\installed\x64-windows\lib\zlib.lib and ZLIB_INCLUDE_DIRECTORY to vcpkg\installed\x64-windows\include. - * Copy zlib1.dll from vcpkg\installed\x64-windows\bin to Katago folder after you've built Katago executable. + * If using the ONNX backend, ONNX Runtime package (headers + import libs + runtime DLLs). + * On Windows, missing `zlib` and ONNX model-conversion dependencies (`onnx`, `protobuf`) can be auto-fetched by CMake into `cpp/build/deps/vcpkg` (default `KATAGO_AUTO_FETCH_DEPS=ON`). * libzip (optional, needed only for self-play training) - for example https://github.com/kiyolee/libzip-win-build * For MinGW it's recommended to use [MSYS2](https://www.msys2.org/) building platform to get necessary zlib and libzip dependencies: * Install MSYS2 according to the instruction on the official site @@ -98,7 +148,7 @@ As also mentioned in the instructions below but repeated here for visibility, if -DLIBZIP_INCLUDE_DIR_ZIPCONF:PATH="C:/msys64/mingw64/include" -DLIBZIP_LIBRARY:FILEPATH="C:/msys64/mingw64/lib/libzip.dll.a" ``` - * Also set `USE_BACKEND` to `OPENCL`, or `CUDA`, or `TENSORRT`, or `EIGEN` depending on what backend you want to use. + * Also set `USE_BACKEND` to `OPENCL`, or `CUDA`, or `TENSORRT`, or `EIGEN`, or `ROCM`, or `ONNX` depending on what backend you want to use. * Set any other options you want and re-run "Configure" again as needed after setting them. Such as: * `NO_GIT_REVISION` if you don't have Git or if cmake is not finding it. * `NO_LIBZIP` if you don't care about running self-play training and you don't have libzip. diff --git a/README.md b/README.md index 768e408384..04560bb7a4 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,9 @@ - [GUIs](#guis) - [Windows and Linux](#windows-and-linux) - [MacOS](#macos) - - [OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-rocm-vs-eigen) + - [OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen vs ONNX](#opencl-vs-cuda-vs-tensorrt-vs-rocm-vs-eigen-vs-onnx) - [How To Use](#how-to-use) + - [ONNX/OpenVINO Intel NPU Quick Start (Windows)](#onnxopenvino-intel-npu-quick-start-windows) - [Human-style Play and Analysis](#human-style-play-and-analysis) - [Other Commands:](#other-commands) - [Tuning for Performance](#tuning-for-performance) @@ -87,8 +88,8 @@ The community also provides KataGo packages for [Homebrew](https://brew.sh) on M Use `brew install katago`. The latest config files and networks are installed in KataGo's `share` directory. Find them via `brew list --verbose katago`. A basic way to run katago will be `katago gtp -config $(brew list --verbose katago | grep 'gtp.*\.cfg') -model $(brew list --verbose katago | grep .gz | head -1)`. You should choose the Network according to the release notes here and customize the provided example config as with every other way of installing KataGo. -### OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen -KataGo has five backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), ROCm (GPU) and Eigen (CPU). +### OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen vs ONNX +KataGo has six backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), ROCm (GPU), Eigen (CPU), and ONNX (CPU/GPU/NPU via providers). The quick summary is: * **To easily get something working, try OpenCL if you have any good or decent GPU.** @@ -97,6 +98,7 @@ The quick summary is: * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. * The CUDA backend can work for NVIDIA GPUs with CUDA+CUDNN installed but is likely worse than TensorRT. * The ROCm backend can work for AMD GPUs with ROCm+MIOpen installed. + * ONNX backend uses ONNX Runtime execution providers (CPU/OpenVINO/CUDA/TensorRT/MIGraphX/CoreML). It is useful for Intel NPU (OpenVINO) and raw `.onnx` models. More in detail: * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). @@ -104,6 +106,7 @@ More in detail: * TensorRT is similar to CUDA, but only uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs, it should work whenever CUDA does and will usually be faster than CUDA or any other backend. * ROCm is a GPU backend specific to AMD GPUs (it will not work with NVIDIA or Intel or any other GPUs) and requires installing [ROCm](https://rocm.docs.amd.com) and [MIOpen](https://rocm.docs.amd.com/projects/MIOpen) and a modern AMD GPU. On most GPUs, the OpenCL implementation will actually beat AMD's own ROCm/MIOpen at performance. The exception is for top-end AMD GPUs that support FP16 and stream processors, in which case sometimes one is better and sometimes the other is better. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. + * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, OpenVINO for Intel hardware (including NPU on supported systems), CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers, while OpenVINO NPU setups are typically single-device. For **any** implementation, it's recommended that you also tune the number of threads used if you care about optimal performance, as it can make a factor of 2-3 difference in the speed. See "Tuning for Performance" below. However, if you mostly just want to get it working, then the default untuned settings should also be still reasonable. @@ -137,6 +140,29 @@ path/to/katago.exe gtp -model path/to/.bin.gz path/to/katago.exe gtp -model path/to/.bin.gz -config path/to/gtp_custom.cfg ``` +#### ONNX/OpenVINO Intel NPU Quick Start (Windows) + +If you want to use ONNX Runtime + OpenVINO on Intel NPU: +* Install Intel NPU driver: https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html +* Install OpenVINO archive package (Windows): https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html +* Build ONNX Runtime with OpenVINO EP for NPU (`use_openvino=NPU`): https://onnxruntime.ai/docs/build/eps.html#openvino +* See [Compiling.md](Compiling.md) for the full build/copy steps for `cpp/external/onnxruntime-win-x64-openvino`. + +Minimal commands: +``` +# 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) +./katago.exe exportonnx -model .bin.gz -output .19x19.onnx + +# 2) Benchmark on Intel NPU (OpenVINO provider) +./katago.exe benchmark -config cpp/configs/gtp_example.cfg -model .19x19.onnx -visits 32 -threads 1 -n 2 -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU,numSearchThreads=1,numNNServerThreadsPerModel=1 + +# 3) Run GTP for GUI tools (Sabaki/Lizzie/q5Go/etc) +./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .19x19.onnx + +If you don't prepare config file, then use -override-config args, like: +./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .19x19.onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU +``` + #### Human-style Play and Analysis You can also have KataGo imitate human play if you download the human SL model b18c384nbt-humanv0.bin.gz from https://github.com/lightvector/KataGo/releases/tag/v1.15.0, and run a command like the following, providing both the normal model and the human SL model: diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index ddf9f11b14..b30bb964a8 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -48,7 +48,7 @@ endif() set(BUILD_DISTRIBUTED 0 CACHE BOOL "Build with http support for contributing to distributed training") set(USE_BACKEND CACHE STRING "Neural net backend") string(TOUPPER "${USE_BACKEND}" USE_BACKEND) -set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN ROCM) +set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN ROCM ONNX) set(USE_TCMALLOC 0 CACHE BOOL "Use TCMalloc") set(NO_GIT_REVISION 0 CACHE BOOL "Disable embedding the git revision into the compiled exe") @@ -58,6 +58,77 @@ set(USE_BIGGER_BOARDS_EXPENSIVE 0 CACHE BOOL "Allow boards up to size 50. Compil set(USE_CACHE_TENSORRT_PLAN 0 CACHE BOOL "Use TENSORRT plan cache. May use a lot of disk space. Only applies when USE_BACKEND is TENSORRT.") mark_as_advanced(USE_CACHE_TENSORRT_PLAN) +if(WIN32) + set(_katago_auto_fetch_default ON) +else() + set(_katago_auto_fetch_default OFF) +endif() +option(KATAGO_AUTO_FETCH_DEPS "Automatically fetch missing dependencies into build/deps (Windows uses vcpkg)." ${_katago_auto_fetch_default}) +set(KATAGO_DEPS_DIR "${CMAKE_SOURCE_DIR}/build/deps" CACHE PATH "Directory for auto-fetched third-party dependencies") +set(KATAGO_VCPKG_TRIPLET "x64-windows" CACHE STRING "vcpkg triplet used by KATAGO_AUTO_FETCH_DEPS on Windows") +set(KATAGO_VCPKG_ROOT "${KATAGO_DEPS_DIR}/vcpkg" CACHE PATH "Path to local vcpkg clone used by KATAGO_AUTO_FETCH_DEPS") +mark_as_advanced(KATAGO_VCPKG_TRIPLET KATAGO_VCPKG_ROOT) + +function(katago_vcpkg_bootstrap_if_needed) + if(NOT WIN32) + message(FATAL_ERROR "katago_vcpkg_bootstrap_if_needed is only supported on Windows") + endif() + + if(NOT KATAGO_AUTO_FETCH_DEPS) + message(FATAL_ERROR "KATAGO_AUTO_FETCH_DEPS is OFF, cannot auto-fetch missing dependency") + endif() + + file(MAKE_DIRECTORY "${KATAGO_DEPS_DIR}") + + if(NOT EXISTS "${KATAGO_VCPKG_ROOT}/vcpkg.exe") + if(NOT EXISTS "${KATAGO_VCPKG_ROOT}/.git") + find_package(Git QUIET) + if(NOT GIT_FOUND) + message(FATAL_ERROR "KATAGO_AUTO_FETCH_DEPS requires git to clone vcpkg") + endif() + message(STATUS "Auto-fetch deps: cloning vcpkg into ${KATAGO_VCPKG_ROOT}") + execute_process( + COMMAND "${GIT_EXECUTABLE}" clone --depth=1 https://github.com/microsoft/vcpkg.git "${KATAGO_VCPKG_ROOT}" + RESULT_VARIABLE _clone_result + OUTPUT_VARIABLE _clone_out + ERROR_VARIABLE _clone_err + ) + if(NOT _clone_result EQUAL 0) + message(FATAL_ERROR "Failed to clone vcpkg.\n${_clone_out}\n${_clone_err}") + endif() + endif() + + message(STATUS "Auto-fetch deps: bootstrapping vcpkg") + execute_process( + COMMAND "${KATAGO_VCPKG_ROOT}/bootstrap-vcpkg.bat" -disableMetrics + WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" + RESULT_VARIABLE _bootstrap_result + ) + if(NOT _bootstrap_result EQUAL 0) + message(FATAL_ERROR "Failed to bootstrap vcpkg") + endif() + endif() +endfunction() + +function(katago_vcpkg_install_if_needed package_name) + if(NOT WIN32) + message(FATAL_ERROR "katago_vcpkg_install_if_needed is only supported on Windows") + endif() + + katago_vcpkg_bootstrap_if_needed() + + set(_spec "${package_name}:${KATAGO_VCPKG_TRIPLET}") + message(STATUS "Auto-fetch deps: ensuring ${_spec} via vcpkg") + execute_process( + COMMAND "${KATAGO_VCPKG_ROOT}/vcpkg.exe" install "${_spec}" --disable-metrics + WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" + RESULT_VARIABLE _install_result + ) + if(NOT _install_result EQUAL 0) + message(FATAL_ERROR "Failed to install ${_spec} via vcpkg") + endif() +endfunction() + #--------------------------- NEURAL NET BACKEND ------------------------------------------------------------------------ message(STATUS "Building 'katago' executable for GTP engine and other tools.") @@ -161,6 +232,12 @@ elseif(USE_BACKEND STREQUAL "EIGEN") set(NEURALNET_BACKEND_SOURCES neuralnet/eigenbackend.cpp ) +elseif(USE_BACKEND STREQUAL "ONNX") + message(STATUS "-DUSE_BACKEND=ONNX, using ONNX Runtime backend.") + set(NEURALNET_BACKEND_SOURCES + neuralnet/onnxbackend.cpp + neuralnet/onnxmodelbuilder.cpp + ) # --------------------------- ROCM backend(AMD GPU / HIP MIOpen) --------------------------- elseif(USE_BACKEND STREQUAL "ROCM") message(STATUS "-DUSE_BACKEND=ROCM, using AMD ROCm backend.") @@ -207,7 +284,7 @@ elseif(USE_BACKEND STREQUAL "ROCM") # add_compile_definitions(HIP_SUPPORTS_FP16) elseif(USE_BACKEND STREQUAL "") - message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN to compile with the respective backend.${ColorReset}") + message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN or -DUSE_BACKEND=ONNX to compile with the respective backend.${ColorReset}") set(NEURALNET_BACKEND_SOURCES neuralnet/dummybackend.cpp) else() message(FATAL_ERROR "Unrecognized backend: " ${USE_BACKEND}) @@ -600,6 +677,107 @@ elseif(USE_BACKEND STREQUAL "ROCM") roc::hipblas # BLAS ${_miopen_target} # DNN primitives ) +elseif(USE_BACKEND STREQUAL "ONNX") + target_compile_definitions(katago PRIVATE USE_ONNX_BACKEND) + + if(WIN32) + set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-win-x64-openvino") + else() + set(_onnx_default_root "") + endif() + set(ONNXRUNTIME_ROOT "${_onnx_default_root}" CACHE PATH "Path to ONNX Runtime package root") + + if(NOT IS_DIRECTORY "${ONNXRUNTIME_ROOT}") + message(FATAL_ERROR "ONNXRUNTIME_ROOT does not exist: ${ONNXRUNTIME_ROOT}") + endif() + + set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include") + if(NOT IS_DIRECTORY "${ONNXRUNTIME_INCLUDE_DIR}") + message(FATAL_ERROR "ONNX Runtime include directory not found: ${ONNXRUNTIME_INCLUDE_DIR}") + endif() + target_include_directories(katago SYSTEM PRIVATE "${ONNXRUNTIME_INCLUDE_DIR}") + + if(WIN32) + set(ONNXRUNTIME_LIB "${ONNXRUNTIME_ROOT}/lib/onnxruntime.lib") + file(GLOB ONNXRUNTIME_DLLS "${ONNXRUNTIME_ROOT}/lib/*.dll") + else() + find_library(ONNXRUNTIME_LIB onnxruntime HINTS "${ONNXRUNTIME_ROOT}/lib" "${ONNXRUNTIME_ROOT}") + endif() + if(NOT EXISTS "${ONNXRUNTIME_LIB}" AND NOT ONNXRUNTIME_LIB) + message(FATAL_ERROR "Could not find onnxruntime library under ${ONNXRUNTIME_ROOT}") + endif() + target_link_libraries(katago ${ONNXRUNTIME_LIB}) + + # Required by onnxmodelbuilder.cpp for building ONNX graphs from .bin.gz. + # These are intentionally configurable because package layouts vary. + set(ONNX_INCLUDE_DIR "" CACHE PATH "Directory containing onnx/onnx-ml.pb.h (required for .bin.gz -> ONNX conversion)") + set(ONNX_PROTO_LIB "" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)") + set(PROTOBUF_INCLUDE_DIR "" CACHE PATH "Directory containing google/protobuf/message.h (required for .bin.gz -> ONNX conversion)") + set(PROTOBUF_LIB "" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)") + mark_as_advanced(CLEAR ONNX_INCLUDE_DIR ONNX_PROTO_LIB PROTOBUF_INCLUDE_DIR PROTOBUF_LIB) + + # Backward compatibility with older cache variable name. + if(NOT PROTOBUF_LIB AND PROTOBUF_LITE_LIB) + set(PROTOBUF_LIB "${PROTOBUF_LITE_LIB}") + endif() + + if(WIN32 AND KATAGO_AUTO_FETCH_DEPS) + set(_need_onnx_proto_deps FALSE) + if(NOT ONNX_INCLUDE_DIR OR NOT ONNX_PROTO_LIB OR NOT PROTOBUF_INCLUDE_DIR OR NOT PROTOBUF_LIB) + set(_need_onnx_proto_deps TRUE) + endif() + if(_need_onnx_proto_deps) + katago_vcpkg_install_if_needed("onnx") + katago_vcpkg_install_if_needed("protobuf") + set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") + if(EXISTS "${_katago_vcpkg_installed_root}/include/onnx/onnx-ml.pb.h") + set(ONNX_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Directory containing onnx/onnx-ml.pb.h (required for .bin.gz -> ONNX conversion)" FORCE) + endif() + if(EXISTS "${_katago_vcpkg_installed_root}/lib/onnx_proto.lib") + set(ONNX_PROTO_LIB "${_katago_vcpkg_installed_root}/lib/onnx_proto.lib" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)" FORCE) + endif() + if(EXISTS "${_katago_vcpkg_installed_root}/include/google/protobuf/message.h") + set(PROTOBUF_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Directory containing google/protobuf/message.h (required for .bin.gz -> ONNX conversion)" FORCE) + endif() + if(EXISTS "${_katago_vcpkg_installed_root}/lib/libprotobuf-lite.lib") + set(PROTOBUF_LIB "${_katago_vcpkg_installed_root}/lib/libprotobuf-lite.lib" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)" FORCE) + elseif(EXISTS "${_katago_vcpkg_installed_root}/lib/libprotobuf.lib") + set(PROTOBUF_LIB "${_katago_vcpkg_installed_root}/lib/libprotobuf.lib" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)" FORCE) + endif() + endif() + endif() + + if(NOT ONNX_INCLUDE_DIR) + find_path(ONNX_INCLUDE_DIR onnx/onnx-ml.pb.h) + endif() + if(NOT ONNX_PROTO_LIB) + find_library(ONNX_PROTO_LIB onnx_proto) + endif() + if(NOT PROTOBUF_INCLUDE_DIR) + find_path(PROTOBUF_INCLUDE_DIR google/protobuf/message.h) + endif() + if(NOT PROTOBUF_LIB) + find_library(PROTOBUF_LIB protobuf-lite protobuf-lite32 libprotobuf protobuf) + endif() + + if(NOT ONNX_INCLUDE_DIR OR NOT ONNX_PROTO_LIB OR NOT PROTOBUF_INCLUDE_DIR OR NOT PROTOBUF_LIB) + message(FATAL_ERROR + "ONNX backend requires ONNX protobuf dependencies for .bin.gz model conversion. " + "Set ONNX_INCLUDE_DIR (contains onnx/onnx-ml.pb.h), ONNX_PROTO_LIB, PROTOBUF_INCLUDE_DIR, and PROTOBUF_LIB.") + endif() + target_include_directories(katago SYSTEM PRIVATE "${ONNX_INCLUDE_DIR}") + target_include_directories(katago SYSTEM PRIVATE "${PROTOBUF_INCLUDE_DIR}") + target_link_libraries(katago ${ONNX_PROTO_LIB} ${PROTOBUF_LIB}) + + if(WIN32 AND ONNXRUNTIME_DLLS) + foreach(_onnxruntime_dll IN LISTS ONNXRUNTIME_DLLS) + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${_onnxruntime_dll}" + $ + ) + endforeach() + endif() elseif(USE_BACKEND STREQUAL "EIGEN") target_compile_definitions(katago PRIVATE USE_EIGEN_BACKEND) if(NOT (MSVC)) @@ -631,6 +809,23 @@ if(NO_GIT_REVISION AND (NOT BUILD_DISTRIBUTED)) target_compile_definitions(katago PRIVATE NO_GIT_REVISION) endif() +if(WIN32 AND KATAGO_AUTO_FETCH_DEPS) + set(_need_zlib_deps FALSE) + if(NOT ZLIB_INCLUDE_DIR OR NOT ZLIB_LIBRARY) + set(_need_zlib_deps TRUE) + endif() + if(_need_zlib_deps) + katago_vcpkg_install_if_needed("zlib") + set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") + if(EXISTS "${_katago_vcpkg_installed_root}/include/zlib.h") + set(ZLIB_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zlib.h and other header files" FORCE) + endif() + if(EXISTS "${_katago_vcpkg_installed_root}/lib/zlib.lib") + set(ZLIB_LIBRARY "${_katago_vcpkg_installed_root}/lib/zlib.lib" CACHE FILEPATH "Path to 'libz.so' on Linux or 'libz.lib' on Windows" FORCE) + endif() + endif() +endif() + find_package(ZLIB) if(ZLIB_FOUND) include_directories(${ZLIB_INCLUDE_DIRS}) diff --git a/cpp/README.md b/cpp/README.md index 7376c6b7d3..6f5f95ad78 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -9,13 +9,14 @@ Summary of source folders, in approximate dependency order, from lowest level to * `board.{cpp,h}` - Raw board implementation, without move history. Helper functions for Benson's algorithm and ladder search. * `boardhistory.{cpp,h}` - Datastructure that does include move history - handles superko, passing, game end, final scoring, komi, handicap detection, etc. * `graphhash.{cpp,h}` - History-sensitive hash used for [monte-carlo graph search](https://github.com/lightvector/KataGo/blob/master/docs/GraphSearch.md). -* `neuralnet` - Neural net GPU implementation and interface. Contains OpenCL, CUDA, Eigen, TensorRT backends along with common interfaces and model data structures. +* `neuralnet` - Neural net GPU implementation and interface. Contains OpenCL, CUDA, TensorRT, ROCm, Metal, Eigen, and ONNX backends along with common interfaces and model data structures. * `desc.{cpp,h}` - Data structure holding neural net structure and weights. * `modelversion.{cpp,h}` - Enumerates the various versions of neural net features and models. * `nninputs.{cpp,h}` - Implements the input features for the neural net. * `sgfmetadata.{cpp,h}` - Implements the input features for the [HumanSL neural net](https://github.com/lightvector/KataGo/blob/master/docs/Analysis_Engine.md#human-sl-analysis-guide), for conditioning on various SGF metadata about human players from training data. * `nninterface.h` - Common interface that is implemented by every low-level neural net backend. - * `{cuda,opencl,eigen,trt,rocm,metal,dummy}backend.cpp` - Various backends. + * `{cuda,opencl,eigen,trt,rocm,metal,onnx,dummy}backend.cpp` - Various backends. + * `onnxmodelbuilder.{cpp,h}` - Builds ONNX graphs from KataGo model weights for ONNX Runtime. * `nneval.{cpp,h}` - Top-level handle to the neural net used by the rest of the engine, implements thread-safe batching of queries. * `search` - The main search engine. * `timecontrols.cpp` - Basic handling of a few possible time controls. diff --git a/cpp/command/benchmark.cpp b/cpp/command/benchmark.cpp index 92f44aae91..63ad26e578 100644 --- a/cpp/command/benchmark.cpp +++ b/cpp/command/benchmark.cpp @@ -272,6 +272,21 @@ int MainCmds::benchmark(const vector& args) { #endif #ifdef USE_EIGEN_BACKEND cout << "You are currently using the Eigen (CPU) version of KataGo. Due to having no GPU, it may be slow." << endl; +#endif +#ifdef USE_ONNX_BACKEND + string onnxProvider = cfg.contains("onnxProvider") ? cfg.getString("onnxProvider") : "cpu"; + string onnxProviderLower = Global::toLower(onnxProvider); + cout << "You are currently using the ONNX Runtime version of KataGo." << endl; + cout << "Your GTP config is currently set to onnxProvider = " << onnxProvider << endl; + if(onnxProviderLower == "openvino") { + string deviceType = cfg.contains("onnxOpenVINODeviceType") ? cfg.getString("onnxOpenVINODeviceType") : "CPU"; + cout << "OpenVINO device type = " << deviceType << endl; + cout << "For Intel NPU, typically set onnxOpenVINODeviceType = NPU." << endl; + cout << "OpenVINO/NPU usually uses a single device; onnxDeviceToUseThread* is typically for cuda/trt/migraphx providers." << endl; + } + else if(onnxProviderLower == "cuda" || onnxProviderLower == "tensorrt" || onnxProviderLower == "migraphx") { + cout << "For ONNX Runtime multi-GPU, use numNNServerThreadsPerModel + onnxDeviceToUseThreadX." << endl; + } #endif cout << endl; cout << "Your GTP config is currently set to use numSearchThreads = " << params.numThreads << endl; @@ -638,6 +653,9 @@ int MainCmds::genconfig(const vector& args, const string& firstCommand) int configNNCacheSizePowerOfTwo = 20; int configNNMutexPoolSizePowerOfTwo = 16; int configNumSearchThreads = 6; +#ifdef USE_ONNX_BACKEND + string configOnnxProvider = "openvino"; +#endif cout << endl; cout << "=========================================================================" << endl; @@ -763,30 +781,72 @@ int MainCmds::genconfig(const vector& args, const string& firstCommand) }); } +#ifdef USE_ONNX_BACKEND + { + cout << endl; + string prompt = + "Select ONNX Runtime execution provider in the generated config\n" + "(cpu, openvino, cuda, tensorrt, migraphx, coreml), default openvino:\n"; + promptAndParseInput(prompt, [&](const string& line) { + string provider = Global::toLower(Global::trim(line)); + if(provider == "") + provider = "openvino"; + if( + provider != "cpu" && + provider != "openvino" && + provider != "cuda" && + provider != "tensorrt" && + provider != "migraphx" && + provider != "coreml" + ) + throw StringError("Must be one of: cpu, openvino, cuda, tensorrt, migraphx, coreml"); + configOnnxProvider = provider; + }); + } +#endif + cout << endl; cout << "=========================================================================" << endl; cout << "GPUS AND RAM" << endl; #ifndef USE_EIGEN_BACKEND { - cout << endl; - cout << "Finding available GPU-like devices..." << endl; - NeuralNet::printDevices(); - cout << endl; + bool askForDeviceIdxs = true; +#ifdef USE_ONNX_BACKEND + bool onnxProviderSupportsThreadDeviceMap = + configOnnxProvider == "cuda" || + configOnnxProvider == "tensorrt" || + configOnnxProvider == "migraphx"; + askForDeviceIdxs = onnxProviderSupportsThreadDeviceMap; +#endif + if(askForDeviceIdxs) { + cout << endl; + cout << "Finding available GPU-like devices..." << endl; + NeuralNet::printDevices(); + cout << endl; - string prompt = - "Specify devices/GPUs to use (for example \"0,1,2\" to use devices 0, 1, and 2). Leave blank for a default SINGLE-GPU config:\n"; - promptAndParseInput(prompt, [&](const string& line) { - vector pieces = Global::split(line,','); - configDeviceIdxs.clear(); - for(size_t i = 0; i 10000) - throw StringError("Invalid device idx: " + Global::intToString(idx)); - configDeviceIdxs.push_back(idx); - } - }); + string prompt = + "Specify devices/GPUs to use (for example \"0,1,2\" to use devices 0, 1, and 2). Leave blank for a default SINGLE-GPU config:\n"; + promptAndParseInput(prompt, [&](const string& line) { + vector pieces = Global::split(line,','); + configDeviceIdxs.clear(); + for(size_t i = 0; i 10000) + throw StringError("Invalid device idx: " + Global::intToString(idx)); + configDeviceIdxs.push_back(idx); + } + }); + } +#ifdef USE_ONNX_BACKEND + else { + cout << endl; + cout << "onnxProvider = " << configOnnxProvider << " selected." << endl; + cout << "Skipping per-thread multi-device mapping (mainly used by cuda/tensorrt/migraphx providers)." << endl; + configDeviceIdxs.clear(); + } +#endif } #endif @@ -863,6 +923,9 @@ int MainCmds::genconfig(const vector& args, const string& firstCommand) configNNCacheSizePowerOfTwo, configNNMutexPoolSizePowerOfTwo, configNumSearchThreads +#ifdef USE_ONNX_BACKEND + ,configOnnxProvider +#endif ); }; updateConfigContents(); diff --git a/cpp/command/misc.cpp b/cpp/command/misc.cpp index 001bc5b3bd..31ca899fca 100644 --- a/cpp/command/misc.cpp +++ b/cpp/command/misc.cpp @@ -13,6 +13,10 @@ #include "../program/setup.h" #include "../program/playutils.h" #include "../program/play.h" +#include "../neuralnet/nninterface.h" +#ifdef USE_ONNX_BACKEND +#include "../neuralnet/onnxmodelbuilder.h" +#endif #include "../command/commandline.h" #include "../tests/tests.h" #include "../main.h" @@ -20,6 +24,7 @@ #include #include #include +#include using namespace std; @@ -35,6 +40,58 @@ int MainCmds::printclockinfo(const vector& args) { return 0; } +int MainCmds::exportonnx(const vector& args) { +#ifndef USE_ONNX_BACKEND + (void)args; + cerr << "exportonnx is only available in ONNX backend builds (USE_BACKEND=ONNX)." << endl; + return 1; +#else + string modelFile; + string outputFile; + int nnXLen; + int nnYLen; + try { + KataGoCommandLine cmd("Export KataGo .bin/.bin.gz model to ONNX file."); + cmd.addModelFileArg(); + TCLAP::ValueArg outputArg("o","output","Output ONNX file path",true,string(),"FILE"); + TCLAP::ValueArg xLenArg("x","xlen","Board x size baked into exported model",false,19,"N"); + TCLAP::ValueArg yLenArg("y","ylen","Board y size baked into exported model",false,19,"N"); + cmd.add(outputArg); + cmd.add(xLenArg); + cmd.add(yLenArg); + cmd.parseArgs(args); + + modelFile = cmd.getModelFile(); + outputFile = outputArg.getValue(); + nnXLen = xLenArg.getValue(); + nnYLen = yLenArg.getValue(); + } + catch(TCLAP::ArgException& e) { + cerr << "Error: " << e.error() << " for argument " << e.argId() << endl; + return 1; + } + + if(nnXLen < 2 || nnXLen > NNPos::MAX_BOARD_LEN || nnYLen < 2 || nnYLen > NNPos::MAX_BOARD_LEN) + throw StringError("Invalid board size for exportonnx"); + + const string expectedSha256 = ""; + std::unique_ptr loadedModel( + NeuralNet::loadModelFile(modelFile, expectedSha256), + NeuralNet::freeLoadedModel + ); + const ModelDesc& modelDesc = NeuralNet::getModelDesc(loadedModel.get()); + string onnxBytes = OnnxModelBuilder::buildOnnxModel(modelDesc, nnXLen, nnYLen); + + ofstream out; + FileUtils::open(out, outputFile, std::ios::binary | std::ios::out); + out.write(onnxBytes.data(), onnxBytes.size()); + out.close(); + + cout << "Exported ONNX model to " << outputFile << " (" << onnxBytes.size() << " bytes)" << endl; + return 0; +#endif +} + int MainCmds::sampleinitializations(const vector& args) { Board::initHash(); ScoreValue::initTables(); diff --git a/cpp/configs/analysis_example.cfg b/cpp/configs/analysis_example.cfg index c6ba9825ac..a877134826 100644 --- a/cpp/configs/analysis_example.cfg +++ b/cpp/configs/analysis_example.cfg @@ -292,6 +292,34 @@ nnRandomize = true # openclUseFP16 = auto +# ONNX Runtime settings-------------------------------------- +# These only apply when using the ONNX version of KataGo. + +# Execution provider: cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only) +# onnxProvider = openvino + +# Multi-device assignment is mainly for onnxProvider = cuda / tensorrt / migraphx: +# onnxDeviceToUse = 0 +# onnxDeviceToUseThread0 = 0 +# onnxDeviceToUseThread1 = 1 + +# OpenVINO EP options for Intel NPU (typically single device): +# onnxOpenVINODeviceType = NPU +# onnxOpenVINODeviceId = 0 +# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build +# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache + +# Optional overrides for raw .onnx I/O tensor names and model version: +# onnxInputSpatial = input_spatial +# onnxInputGlobal = input_global +# onnxInputMeta = input_meta +# onnxOutputPolicy = out_policy +# onnxOutputValue = out_value +# onnxOutputMiscvalue = out_miscvalue +# onnxOutputOwnership = out_ownership +# onnxModelVersion = 15 + + # Eigen-specific settings-------------------------------------- # These only apply when using the Eigen (pure CPU) version of KataGo. diff --git a/cpp/configs/contribute_example.cfg b/cpp/configs/contribute_example.cfg index fb6f0d81d7..ecaac3057e 100644 --- a/cpp/configs/contribute_example.cfg +++ b/cpp/configs/contribute_example.cfg @@ -157,6 +157,34 @@ watchOngoingGameInFileName = watchgame.txt # openclUseFP16 = auto +# ONNX Runtime settings-------------------------------------- +# These only apply when using the ONNX version of KataGo. + +# Execution provider: cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only) +# onnxProvider = openvino + +# Multi-device assignment (for onnxProvider = cuda / tensorrt / migraphx): +# onnxDeviceToUse = 0 +# onnxDeviceToUseThread0 = 0 +# onnxDeviceToUseThread1 = 1 + +# OpenVINO EP options for Intel NPU (typically single device): +# onnxOpenVINODeviceType = NPU +# onnxOpenVINODeviceId = 0 +# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build +# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache + +# Optional overrides for raw .onnx I/O tensor names and model version: +# onnxInputSpatial = input_spatial +# onnxInputGlobal = input_global +# onnxInputMeta = input_meta +# onnxOutputPolicy = out_policy +# onnxOutputValue = out_value +# onnxOutputMiscvalue = out_miscvalue +# onnxOutputOwnership = out_ownership +# onnxModelVersion = 15 + + # Eigen-specific settings-------------------------------------- # These only apply when using the Eigen (pure CPU) version of KataGo. diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index a860d6dfca..9787e11e8d 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -543,6 +543,43 @@ searchFactorWhenWinningThreshold = 0.95 # Default: numSearchThreads # numEigenThreadsPerModel = X +# ------------------------------ +# ONNX backend settings +# ------------------------------ +# These only apply when using the ONNX version of KataGo. + +# Execution provider: +# cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only). +# onnxProvider = cpu + +# Provider-specific device selection for multi-server-thread setups. +# Primarily for onnxProvider = cuda / tensorrt / migraphx. +# onnxDeviceToUse = 0 +# onnxDeviceToUseThread0 = 0 +# onnxDeviceToUseThread1 = 1 + +# OpenVINO EP options (useful for Intel NPU on Windows): +# NPU, CPU, GPU, AUTO:NPU,CPU, MULTI:NPU.0,NPU.1, etc. +# onnxOpenVINODeviceType = NPU +# Optional explicit OpenVINO device id (usually unnecessary for single NPU setups) +# onnxOpenVINODeviceId = 0 +# Optional fast compile mode for NPU +# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build +# Optional cache directory for compiled OpenVINO blobs +# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache + +# Override input/output tensor names for raw .onnx models: +# onnxInputSpatial = input_spatial +# onnxInputGlobal = input_global +# onnxInputMeta = input_meta +# onnxOutputPolicy = out_policy +# onnxOutputValue = out_value +# onnxOutputMiscvalue = out_miscvalue +# onnxOutputOwnership = out_ownership + +# Override auto-detected model version for raw .onnx model files. +# onnxModelVersion = 15 + # =========================================================================== # Root move selection and biases # =========================================================================== diff --git a/cpp/configs/match_example.cfg b/cpp/configs/match_example.cfg index 08859f557f..11b271ef08 100644 --- a/cpp/configs/match_example.cfg +++ b/cpp/configs/match_example.cfg @@ -214,6 +214,36 @@ numNNServerThreadsPerModel = 1 # openclUseFP16 = auto +# ONNX Runtime settings-------------------------------------- +# These only apply when using the ONNX version of KataGo. + +# Execution provider: cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only) +# onnxProvider = openvino + +# Multi-device assignment is mainly for onnxProvider = cuda / tensorrt / migraphx: +# onnxDeviceToUse = 0 +# onnxDeviceToUseModel0 = 0 +# onnxDeviceToUseModel1 = 1 +# onnxDeviceToUseModel0Thread0 = 0 +# onnxDeviceToUseModel0Thread1 = 1 + +# OpenVINO EP options for Intel NPU (typically single device): +# onnxOpenVINODeviceType = NPU +# onnxOpenVINODeviceId = 0 +# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build +# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache + +# Optional overrides for raw .onnx I/O tensor names and model version: +# onnxInputSpatial = input_spatial +# onnxInputGlobal = input_global +# onnxInputMeta = input_meta +# onnxOutputPolicy = out_policy +# onnxOutputValue = out_value +# onnxOutputMiscvalue = out_miscvalue +# onnxOutputOwnership = out_ownership +# onnxModelVersion = 15 + + # Eigen-specific settings-------------------------------------- # These only apply when using the Eigen (pure CPU) version of KataGo. diff --git a/cpp/dataio/loadmodel.cpp b/cpp/dataio/loadmodel.cpp index 81483b1704..71d3addf3e 100644 --- a/cpp/dataio/loadmodel.cpp +++ b/cpp/dataio/loadmodel.cpp @@ -20,30 +20,34 @@ std::time_t to_time_t(TP tp) static const vector ACCEPTABLE_MODEL_SUFFIXES { ".bin.gz", ".bin", + ".onnx", "model.txt.gz", "model.txt" }; static const vector GENERIC_MODEL_NAMES { "model.bin.gz", "model.bin", + "model.onnx", "model.txt.gz", - "model.txt" + "model.txt", "Model.bin.gz", "Model.bin", + "Model.onnx", "Model.txt.gz", - "Model.txt" + "Model.txt", "MODEL.bin.gz", "MODEL.bin", + "MODEL.onnx", "MODEL.txt.gz", - "MODEL.txt" + "MODEL.txt", "model.ckpt", - "Model.ckpt" + "Model.ckpt", "MODEL.ckpt", "model.checkpoint", - "Model.checkpoint" + "Model.checkpoint", "MODEL.checkpoint", "model", - "Model" + "Model", "MODEL", }; @@ -115,7 +119,8 @@ void LoadModel::deleteModelsOlderThan(const string& modelsDir, Logger& logger, c if(Global::isSuffix(filePathStr,".bin.gz") || Global::isSuffix(filePathStr,".txt.gz") || Global::isSuffix(filePathStr,".bin") || - Global::isSuffix(filePathStr,".txt")) { + Global::isSuffix(filePathStr,".txt") || + Global::isSuffix(filePathStr,".onnx")) { time_t thisTime = to_time_t(gfs::last_write_time(filePath)); if(thisTime < time) { pathsToRemove.push_back(filePath); diff --git a/cpp/main.cpp b/cpp/main.cpp index 734b0f8487..0d756bfc29 100644 --- a/cpp/main.cpp +++ b/cpp/main.cpp @@ -29,6 +29,7 @@ static void printHelp(const vector& args) { gtp : Runs GTP engine that can be plugged into any standard Go GUI for play/analysis. benchmark : Test speed with different numbers of search threads. genconfig : User-friendly interface to generate a config with rules and automatic performance tuning. +exportonnx : Export KataGo .bin/.bin.gz model to a fixed-size .onnx model. contribute : Connect to online distributed KataGo training and run perpetually contributing selfplay games. @@ -169,6 +170,8 @@ static int handleSubcommand(const string& subcommand, const vector& args return MainCmds::runsleeptest(subArgs); else if(subcommand == "printclockinfo") return MainCmds::printclockinfo(subArgs); + else if(subcommand == "exportonnx") + return MainCmds::exportonnx(subArgs); else if(subcommand == "sandbox") return MainCmds::sandbox(); else if(subcommand == "version") { @@ -255,6 +258,8 @@ string Version::getKataGoVersionFullInfo() { #endif #elif defined(USE_EIGEN_BACKEND) out << "Using Eigen(CPU) backend" << endl; +#elif defined(USE_ONNX_BACKEND) + out << "Using ONNX backend" << endl; #else out << "Using dummy backend" << endl; #endif @@ -293,6 +298,8 @@ string Version::getGitRevisionWithBackend() { s += "-opencl"; #elif defined(USE_EIGEN_BACKEND) s += "-eigen"; +#elif defined(USE_ONNX_BACKEND) + s += "-onnx"; #else s += "-dummy"; #endif diff --git a/cpp/main.h b/cpp/main.h index 3f8ad78d40..4f03f418ef 100644 --- a/cpp/main.h +++ b/cpp/main.h @@ -53,6 +53,7 @@ namespace MainCmds { int demoplay(const std::vector& args); int printclockinfo(const std::vector& args); + int exportonnx(const std::vector& args); int sampleinitializations(const std::vector& args); int evalrandominits(const std::vector& args); int searchentropyanalysis(const std::vector& args); diff --git a/cpp/neuralnet/onnxbackend.cpp b/cpp/neuralnet/onnxbackend.cpp new file mode 100644 index 0000000000..551fc5d4ba --- /dev/null +++ b/cpp/neuralnet/onnxbackend.cpp @@ -0,0 +1,867 @@ +// ONNX Runtime backend for KataGo. +// Loads standard .bin.gz model files (builds ONNX graph from ModelDesc) or +// raw .onnx model files directly, and runs inference via ONNX Runtime with a +// configurable execution provider (CPU, OpenVINO, CUDA, TensorRT, MIGraphX, CoreML) +// selected at +// runtime via the onnxProvider config key. + +#include "../neuralnet/nninterface.h" +#include "../neuralnet/nneval.h" +#include "../neuralnet/nninputs.h" +#include "../neuralnet/modelversion.h" +#include "../neuralnet/onnxmodelbuilder.h" + +#include +#ifdef __APPLE__ +#include +#endif + +#include +#include + +using namespace std; + +//-------------------------------------------------------------- + +// Auto-detect modelVersion from introspected channel counts. +// +// Detection is based on channel-count heuristics for raw .onnx files where the +// model version is not encoded in the file. The mapping assumes V7 inputs +// (22 spatial + 19 global channels) and distinguishes versions by the number of +// score-value and policy output channels: +// - 4 score-value channels -> version 8 +// - 6 score-value channels, 1 policy channel -> version 10 +// - 6 score-value channels, 2 policy channels -> version 15 +// +// If the heuristic picks the wrong version, set the `onnxModelVersion` config +// key to the correct value (>= 0) to override auto-detection. +static int detectModelVersion( + int numInputChannels, int numInputGlobalChannels, + int numPolicyChannels, int numScoreValueChannels, + int configModelVersion +) { + if(configModelVersion >= 0) + return configModelVersion; + + // inputsVersion 7 -> models 8-16: 22 spatial + 19 global + if(numInputChannels == NNInputs::NUM_FEATURES_SPATIAL_V7 && + numInputGlobalChannels == NNInputs::NUM_FEATURES_GLOBAL_V7) { + if(numScoreValueChannels == 6 && numPolicyChannels == 2) + return 15; + if(numScoreValueChannels == 6 && numPolicyChannels == 1) + return 10; + if(numScoreValueChannels == 4) + return 8; + // Default for V7 inputs + return 15; + } + // Older input versions -- fall back to a reasonable default + return NNModelVersion::defaultModelVersion; +} + +struct LoadedModel { + ModelDesc modelDesc; + bool isRawOnnx; + string rawOnnxBytes; + + // Constructor for .bin.gz files + LoadedModel(const string& fileName, const string& expectedSha256, bool rawOnnx) + : isRawOnnx(rawOnnx) + { + if(!rawOnnx) { + ModelDesc::loadFromFileMaybeGZipped(fileName, modelDesc, expectedSha256); + return; + } + + // Read raw .onnx file bytes + { + std::ifstream in(fileName, std::ios::binary | std::ios::ate); + if(!in.good()) + throw StringError("ONNX backend: could not open raw ONNX file: " + fileName); + std::streamsize size = in.tellg(); + if(size < 0) + throw StringError("ONNX backend: could not determine size of ONNX file: " + fileName); + in.seekg(0, std::ios::beg); + rawOnnxBytes.resize(size); + if(!in.read(rawOnnxBytes.data(), size)) + throw StringError("ONNX backend: failed to read raw ONNX file: " + fileName); + } + + // Create a temporary CPU session to introspect shapes + Ort::Env tmpEnv(ORT_LOGGING_LEVEL_WARNING, "KataGoOnnxIntrospect"); + Ort::SessionOptions tmpOpts; + tmpOpts.SetIntraOpNumThreads(1); + Ort::Session tmpSession(tmpEnv, rawOnnxBytes.data(), rawOnnxBytes.size(), tmpOpts); + + Ort::AllocatorWithDefaultOptions allocator; + + // Introspect inputs by name first, falling back to shape-based heuristic + int numInputChannels = 0; + int numInputGlobalChannels = 0; + int numInputMetaChannels = 0; + size_t numInputs = tmpSession.GetInputCount(); + for(size_t i = 0; i < numInputs; i++) { + Ort::AllocatedStringPtr namePtr = tmpSession.GetInputNameAllocated(i, allocator); + string name = namePtr.get(); + auto typeInfo = tmpSession.GetInputTypeInfo(i); + auto tensorInfo = typeInfo.GetTensorTypeAndShapeInfo(); + auto shape = tensorInfo.GetShape(); + if(name.find("spatial") != string::npos) { + if(shape.size() >= 2) + numInputChannels = (int)shape[1]; + } else if(name.find("global") != string::npos) { + if(shape.size() >= 2) + numInputGlobalChannels = (int)shape[1]; + } else if(name.find("meta") != string::npos) { + if(shape.size() >= 2) + numInputMetaChannels = (int)shape[1]; + } else if(shape.size() == 4) { + // Shape-based fallback: [N, C, H, W] -- spatial input + numInputChannels = (int)shape[1]; + } else if(shape.size() == 2) { + // Shape-based fallback: [N, C] -- first 2D is global, second is meta + if(numInputGlobalChannels == 0) + numInputGlobalChannels = (int)shape[1]; + else + numInputMetaChannels = (int)shape[1]; + } else { + cerr << "ONNX backend warning: unrecognized input tensor '" << name + << "' with " << shape.size() << "D shape, ignoring" << "\n"; + } + } + + // Introspect outputs + int numPolicyChannels = 0; + int numValueChannels = 0; + int numScoreValueChannels = 0; + int numOwnershipChannels = 0; + size_t numOutputs = tmpSession.GetOutputCount(); + for(size_t i = 0; i < numOutputs; i++) { + Ort::AllocatedStringPtr namePtr = tmpSession.GetOutputNameAllocated(i, allocator); + string name = namePtr.get(); + auto typeInfo = tmpSession.GetOutputTypeInfo(i); + auto tensorInfo = typeInfo.GetTensorTypeAndShapeInfo(); + auto shape = tensorInfo.GetShape(); + + if(name.find("policy") != string::npos) { + // Policy: [N, C, H*W+1] -> dim 1 is policy channels + if(shape.size() >= 2) + numPolicyChannels = (int)shape[1]; + } else if(name.find("miscvalue") != string::npos) { + // MiscValue: [N, numScoreValueChannels] -- check before "value" since "miscvalue" contains "value" + if(shape.size() >= 2) + numScoreValueChannels = (int)shape[1]; + } else if(name.find("value") != string::npos) { + // Value: [N, 3] + if(shape.size() >= 2) + numValueChannels = (int)shape[1]; + } else if(name.find("ownership") != string::npos) { + // Ownership: [N, 1, H, W] + if(shape.size() >= 2) + numOwnershipChannels = (int)shape[1]; + } + } + + // Populate ModelDesc metadata (weights are in the ONNX graph, not in modelDesc) + modelDesc.numInputChannels = numInputChannels; + modelDesc.numInputGlobalChannels = numInputGlobalChannels; + modelDesc.numInputMetaChannels = numInputMetaChannels; + modelDesc.numPolicyChannels = numPolicyChannels; + modelDesc.numValueChannels = numValueChannels; + modelDesc.numScoreValueChannels = numScoreValueChannels; + modelDesc.numOwnershipChannels = numOwnershipChannels; + + // Extract filename stem as model name + { + size_t lastSlash = fileName.find_last_of("/\\"); + string basename = (lastSlash != string::npos) ? fileName.substr(lastSlash + 1) : fileName; + size_t dotPos = basename.find('.'); + modelDesc.name = (dotPos != string::npos) ? basename.substr(0, dotPos) : basename; + } + + // Model version: auto-detect with possible config override (applied later) + modelDesc.modelVersion = detectModelVersion( + numInputChannels, numInputGlobalChannels, + numPolicyChannels, numScoreValueChannels, + -1 // No config override at load time; applied in createComputeHandle if needed + ); + + // postProcessParams gets default values from its constructor (already set) + } + + LoadedModel() = delete; + LoadedModel(const LoadedModel&) = delete; + LoadedModel& operator=(const LoadedModel&) = delete; +}; + +LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { + bool isRawOnnx = Global::isSuffix(file, ".onnx"); + return new LoadedModel(file, expectedSha256, isRawOnnx); +} + +void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { + delete loadedModel; +} + +const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { + return loadedModel->modelDesc; +} + +//-------------------------------------------------------------- + +struct ComputeContext { + Ort::Env env; + int nnXLen; + int nnYLen; + string providerName; + string openvinoDeviceType; + string openvinoDeviceId; + bool openvinoEnableNPUFastCompile; + string openvinoCacheDir; + + // Configurable input/output node names + string inputSpatialName; + string inputGlobalName; + string inputMetaName; + string outputPolicyName; + string outputValueName; + string outputMiscvalueName; + string outputOwnershipName; + + // Config override for model version (-1 means auto-detect) + int configModelVersion; + + ComputeContext(int xLen, int yLen, const string& provider) + : env(ORT_LOGGING_LEVEL_WARNING, "KataGoOnnx"), + nnXLen(xLen), + nnYLen(yLen), + providerName(provider), + openvinoDeviceType("CPU"), + openvinoDeviceId(""), + openvinoEnableNPUFastCompile(false), + openvinoCacheDir(""), + inputSpatialName("input_spatial"), + inputGlobalName("input_global"), + inputMetaName("input_meta"), + outputPolicyName("out_policy"), + outputValueName("out_value"), + outputMiscvalueName("out_miscvalue"), + outputOwnershipName("out_ownership"), + configModelVersion(-1) + {} +}; + +//-------------------------------------------------------------- + +struct ComputeHandle { + ComputeContext* context; + std::unique_ptr session; + int modelVersion; + int numInputChannels; + int numInputGlobalChannels; + int numPolicyChannels; + int numValueChannels; + int numScoreValueChannels; + int numOwnershipChannels; + int numInputMetaChannels; + int policyResultLen; // H*W+1 + + // Input/output names (stored for session->Run) + vector inputNames; + vector outputNames; + vector inputNamePtrs; + vector outputNamePtrs; + + ComputeHandle(ComputeContext* ctx, const LoadedModel& loadedModel, Logger* logger, int deviceIdxForThread) + : context(ctx), + modelVersion(loadedModel.modelDesc.modelVersion), + numInputChannels(loadedModel.modelDesc.numInputChannels), + numInputGlobalChannels(loadedModel.modelDesc.numInputGlobalChannels), + numPolicyChannels(loadedModel.modelDesc.numPolicyChannels), + numValueChannels(loadedModel.modelDesc.numValueChannels), + numScoreValueChannels(loadedModel.modelDesc.numScoreValueChannels), + numOwnershipChannels(loadedModel.modelDesc.numOwnershipChannels), + numInputMetaChannels(loadedModel.modelDesc.numInputMetaChannels), + policyResultLen(ctx->nnXLen * ctx->nnYLen + 1) + { + // Apply config model version override if set + if(ctx->configModelVersion >= 0) + modelVersion = ctx->configModelVersion; + + const char* onnxData; + size_t onnxSize; + string builtOnnxBytes; + if(loadedModel.isRawOnnx) { + if(logger != NULL) + logger->write("ONNX backend: using raw ONNX model (" + + Global::uint64ToString(loadedModel.rawOnnxBytes.size()) + " bytes)"); + onnxData = loadedModel.rawOnnxBytes.data(); + onnxSize = loadedModel.rawOnnxBytes.size(); + } else { + if(logger != NULL) + logger->write("ONNX backend: building ONNX graph from model weights..."); + builtOnnxBytes = OnnxModelBuilder::buildOnnxModel(loadedModel.modelDesc, ctx->nnXLen, ctx->nnYLen); + if(logger != NULL) + logger->write("ONNX backend: ONNX graph built (" + Global::uint64ToString(builtOnnxBytes.size()) + " bytes)"); + onnxData = builtOnnxBytes.data(); + onnxSize = builtOnnxBytes.size(); + } + + if(logger != NULL) + logger->write("ONNX backend: creating session..."); + + Ort::SessionOptions sessionOpts; + sessionOpts.SetIntraOpNumThreads(1); + + // Select execution provider based on providerName + const string& provider = ctx->providerName; + if(provider == "coreml") { +#ifdef __APPLE__ + uint32_t coremlFlags = COREML_FLAG_CREATE_MLPROGRAM; + Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CoreML(sessionOpts, coremlFlags)); + if(logger != NULL) + logger->write("ONNX backend: CoreML execution provider enabled (MLProgram mode)"); +#else + throw StringError("ONNX backend: CoreML is only available on Apple platforms"); +#endif + } else if(provider == "cuda") { + OrtCUDAProviderOptions cudaOpts{}; + cudaOpts.device_id = deviceIdxForThread >= 0 ? deviceIdxForThread : 0; + sessionOpts.AppendExecutionProvider_CUDA(cudaOpts); + if(logger != NULL) + logger->write("ONNX backend: CUDA execution provider enabled, device_id=" + Global::intToString(cudaOpts.device_id)); + } else if(provider == "tensorrt") { + OrtTensorRTProviderOptions trtOpts{}; + trtOpts.device_id = deviceIdxForThread >= 0 ? deviceIdxForThread : 0; + sessionOpts.AppendExecutionProvider_TensorRT(trtOpts); + if(logger != NULL) + logger->write("ONNX backend: TensorRT execution provider enabled, device_id=" + Global::intToString(trtOpts.device_id)); + } else if(provider == "migraphx") { + OrtMIGraphXProviderOptions migraphxOpts{}; + migraphxOpts.device_id = deviceIdxForThread >= 0 ? deviceIdxForThread : 0; + sessionOpts.AppendExecutionProvider_MIGraphX(migraphxOpts); + if(logger != NULL) + logger->write("ONNX backend: MIGraphX execution provider enabled, device_id=" + Global::intToString(migraphxOpts.device_id)); + } else if(provider == "openvino") { + std::unordered_map openvinoOpts; + openvinoOpts["device_type"] = ctx->openvinoDeviceType; + if(!ctx->openvinoDeviceId.empty()) + openvinoOpts["device_id"] = ctx->openvinoDeviceId; + if(!ctx->openvinoCacheDir.empty()) + openvinoOpts["cache_dir"] = ctx->openvinoCacheDir; + + if(ctx->openvinoEnableNPUFastCompile && logger != NULL) { + logger->write( + "ONNX backend: onnxOpenVINOEnableNPUFastCompile requested, but this ORT build may not " + "accept 'enable_npu_fast_compile'; currently ignoring this option for compatibility." + ); + } + + // Some ORT OpenVINO builds may not accept optional keys like cache_dir. + // Retry with only core device keys if optional keys are rejected. + try { + sessionOpts.AppendExecutionProvider_OpenVINO_V2(openvinoOpts); + } + catch(const Ort::Exception& e) { + bool hadOptionalKeys = openvinoOpts.count("cache_dir") > 0; + if(!hadOptionalKeys) + throw; + + if(logger != NULL) { + logger->write( + string("ONNX backend: OpenVINO optional provider options rejected, retrying without optional keys. Error: ") + + e.what() + ); + } + openvinoOpts.erase("cache_dir"); + sessionOpts.AppendExecutionProvider_OpenVINO_V2(openvinoOpts); + } + + if(logger != NULL) { + string deviceId = openvinoOpts.count("device_id") > 0 ? openvinoOpts["device_id"] : ""; + logger->write( + "ONNX backend: OpenVINO execution provider enabled, device_type=" + ctx->openvinoDeviceType + + (deviceId.empty() ? "" : (", device_id=" + deviceId)) + ); + } + } else if(provider == "cpu" || provider.empty()) { + if(logger != NULL) + logger->write("ONNX backend: using CPU execution provider"); + } else { + throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', or 'openvino'"); + } + + // Create session from in-memory bytes + session = std::make_unique(ctx->env, onnxData, onnxSize, sessionOpts); + + // Query and store input names + Ort::AllocatorWithDefaultOptions allocator; + size_t numInputs = session->GetInputCount(); + for(size_t i = 0; i < numInputs; i++) { + Ort::AllocatedStringPtr name = session->GetInputNameAllocated(i, allocator); + inputNames.push_back(name.get()); + } + for(auto& n : inputNames) + inputNamePtrs.push_back(n.c_str()); + + // Query and store output names + size_t numOutputs = session->GetOutputCount(); + for(size_t i = 0; i < numOutputs; i++) { + Ort::AllocatedStringPtr name = session->GetOutputNameAllocated(i, allocator); + outputNames.push_back(name.get()); + } + for(auto& n : outputNames) + outputNamePtrs.push_back(n.c_str()); + + if(logger != NULL) + logger->write("ONNX backend: session created, inputs=" + Global::uint64ToString(numInputs) + + " outputs=" + Global::uint64ToString(numOutputs)); + } + + ComputeHandle() = delete; + ComputeHandle(const ComputeHandle&) = delete; + ComputeHandle& operator=(const ComputeHandle&) = delete; +}; + +//-------------------------------------------------------------- + +struct InputBuffers { + int maxBatchSize; + + size_t singleInputElts; + size_t singleInputGlobalElts; + size_t singleInputMetaElts; + + vector spatialInput; + vector globalInput; + vector metaInput; + + InputBuffers(const LoadedModel* loadedModel, int maxBatchSz, int nnXLen, int nnYLen) { + const ModelDesc& m = loadedModel->modelDesc; + maxBatchSize = maxBatchSz; + singleInputElts = (size_t)m.numInputChannels * nnXLen * nnYLen; + singleInputGlobalElts = (size_t)m.numInputGlobalChannels; + singleInputMetaElts = (size_t)m.numInputMetaChannels; + spatialInput.resize(singleInputElts * maxBatchSize, 0.0f); + globalInput.resize(singleInputGlobalElts * maxBatchSize, 0.0f); + if(m.numInputMetaChannels > 0) + metaInput.resize(singleInputMetaElts * maxBatchSize, 0.0f); + } + + ~InputBuffers() {} + + InputBuffers() = delete; + InputBuffers(const InputBuffers&) = delete; + InputBuffers& operator=(const InputBuffers&) = delete; +}; + +InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { + return new InputBuffers(loadedModel, maxBatchSize, nnXLen, nnYLen); +} +void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { + delete inputBuffers; +} + +//-------------------------------------------------------------- + +void NeuralNet::globalInitialize() { +} + +void NeuralNet::globalCleanup() { +} + +//-------------------------------------------------------------- + +ComputeContext* NeuralNet::createComputeContext( + const std::vector& gpuIdxs, + Logger* logger, + int nnXLen, + int nnYLen, + const string& backendExtraParam, + const string& homeDataDirOverride, + bool openCLReTunePerBoardSize, + enabled_t useFP16Mode, + enabled_t useNHWCMode, + const LoadedModel* loadedModel +) { + (void)gpuIdxs; + (void)homeDataDirOverride; + (void)openCLReTunePerBoardSize; + (void)useFP16Mode; + (void)useNHWCMode; + (void)loadedModel; + + // Parse backendExtraParam as "key=value;key=value;..." + string providerName = "cpu"; + map params; + if(!backendExtraParam.empty()) { + vector parts = Global::split(backendExtraParam, ';'); + for(const string& part : parts) { + size_t eq = part.find('='); + if(eq != string::npos) { + string key = Global::trim(part.substr(0, eq)); + string val = Global::trim(part.substr(eq + 1)); + params[key] = val; + } else { + // Legacy: bare string is provider name + string trimmed = Global::trim(part); + if(!trimmed.empty()) + providerName = trimmed; + } + } + if(params.count("provider")) + providerName = params["provider"]; + } + providerName = Global::toLower(providerName); + + if(logger != NULL) + logger->write("ONNX backend: creating compute context for " + + Global::intToString(nnXLen) + "x" + Global::intToString(nnYLen) + + " with provider '" + providerName + "'"); + + ComputeContext* ctx = new ComputeContext(nnXLen, nnYLen, providerName); + + // Apply configured node names + if(params.count("inputSpatial")) ctx->inputSpatialName = params["inputSpatial"]; + if(params.count("inputGlobal")) ctx->inputGlobalName = params["inputGlobal"]; + if(params.count("inputMeta")) ctx->inputMetaName = params["inputMeta"]; + if(params.count("outputPolicy")) ctx->outputPolicyName = params["outputPolicy"]; + if(params.count("outputValue")) ctx->outputValueName = params["outputValue"]; + if(params.count("outputMiscvalue")) ctx->outputMiscvalueName = params["outputMiscvalue"]; + if(params.count("outputOwnership")) ctx->outputOwnershipName = params["outputOwnership"]; + if(params.count("openvinoDeviceType")) ctx->openvinoDeviceType = params["openvinoDeviceType"]; + if(params.count("openvinoDeviceId")) ctx->openvinoDeviceId = params["openvinoDeviceId"]; + if(params.count("openvinoEnableNPUFastCompile")) { + string v = Global::toLower(params["openvinoEnableNPUFastCompile"]); + ctx->openvinoEnableNPUFastCompile = (v == "1" || v == "true" || v == "yes" || v == "on"); + } + if(params.count("openvinoCacheDir")) ctx->openvinoCacheDir = params["openvinoCacheDir"]; + if(params.count("modelVersion")) { + int v = Global::stringToInt(params["modelVersion"]); + if(v >= 0) + ctx->configModelVersion = v; + } + + return ctx; +} + +void NeuralNet::freeComputeContext(ComputeContext* computeContext) { + delete computeContext; +} + +//-------------------------------------------------------------- + +ComputeHandle* NeuralNet::createComputeHandle( + ComputeContext* context, + const LoadedModel* loadedModel, + Logger* logger, + int maxBatchSize, + bool requireExactNNLen, + bool inputsUseNHWC, + int gpuIdxForThisThread, + int serverThreadIdx +) { + (void)maxBatchSize; + (void)requireExactNNLen; + if(inputsUseNHWC) + throw StringError("ONNX backend: inputsUseNHWC = true not supported, must use NCHW"); + + if(logger != NULL) { + logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion)); + logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + + ": Model name: " + loadedModel->modelDesc.name); + string deviceInfo = + context->providerName == "openvino" + ? "n/a (use onnxOpenVINODeviceType/onnxOpenVINODeviceId)" + : Global::intToString(gpuIdxForThisThread); + logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + + ": provider=" + context->providerName + + " deviceIdx=" + deviceInfo); + } + + return new ComputeHandle(context, *loadedModel, logger, gpuIdxForThisThread); +} + +void NeuralNet::freeComputeHandle(ComputeHandle* computeHandle) { + delete computeHandle; +} + +bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { + (void)handle; + return false; +} + +//-------------------------------------------------------------- + +// Helper to find the index of a name in a vector, checking multiple alternatives. +static int findNameIndex(const vector& names, const vector& targets) { + for(size_t i = 0; i < names.size(); i++) { + for(const auto& t : targets) { + if(names[i] == t) + return (int)i; + } + } + return -1; +} + +void NeuralNet::getOutput( + ComputeHandle* computeHandle, + InputBuffers* inputBuffers, + int numBatchEltsFilled, + NNResultBuf** inputBufs, + vector& outputs +) { + assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); + assert(numBatchEltsFilled > 0); + const int batchSize = numBatchEltsFilled; + const int nnXLen = computeHandle->context->nnXLen; + const int nnYLen = computeHandle->context->nnYLen; + const int numSpatialFeatures = computeHandle->numInputChannels; + const int numGlobalFeatures = computeHandle->numInputGlobalChannels; + const int numPolicyChannels = computeHandle->numPolicyChannels; + + // Fill input buffers + for(int nIdx = 0; nIdx < batchSize; nIdx++) { + float* rowSpatialInput = inputBuffers->spatialInput.data() + (inputBuffers->singleInputElts * nIdx); + float* rowGlobalInput = inputBuffers->globalInput.data() + (inputBuffers->singleInputGlobalElts * nIdx); + + const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); + const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); + std::copy(rowGlobal, rowGlobal + numGlobalFeatures, rowGlobalInput); + SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, false, inputBufs[nIdx]->symmetry); + + if(computeHandle->numInputMetaChannels > 0) { + float* rowMetaInput = inputBuffers->metaInput.data() + (inputBuffers->singleInputMetaElts * nIdx); + const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); + std::copy(rowMeta, rowMeta + computeHandle->numInputMetaChannels, rowMetaInput); + } + } + + // Create ONNX tensors + Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); + + std::array spatialShape = {batchSize, numSpatialFeatures, nnYLen, nnXLen}; + Ort::Value spatialTensor = Ort::Value::CreateTensor( + memInfo, inputBuffers->spatialInput.data(), inputBuffers->singleInputElts * batchSize, + spatialShape.data(), spatialShape.size() + ); + + std::array globalShape = {batchSize, numGlobalFeatures}; + Ort::Value globalTensor = Ort::Value::CreateTensor( + memInfo, inputBuffers->globalInput.data(), inputBuffers->singleInputGlobalElts * batchSize, + globalShape.data(), globalShape.size() + ); + + // Match input ordering using configured node names + const ComputeContext* ctx = computeHandle->context; + int spatialIdx = findNameIndex(computeHandle->inputNames, {ctx->inputSpatialName}); + int globalIdx = findNameIndex(computeHandle->inputNames, {ctx->inputGlobalName}); + if(spatialIdx < 0 || globalIdx < 0) + throw StringError("ONNX backend: could not find expected input names"); + + int metaIdx = -1; + Ort::Value metaTensor(nullptr); + if(computeHandle->numInputMetaChannels > 0) { + metaIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMetaName}); + if(metaIdx < 0) + throw StringError("ONNX backend: model has metadata channels but could not find input_meta"); + std::array metaShape = {batchSize, computeHandle->numInputMetaChannels}; + metaTensor = Ort::Value::CreateTensor( + memInfo, inputBuffers->metaInput.data(), inputBuffers->singleInputMetaElts * batchSize, + metaShape.data(), metaShape.size() + ); + } + + vector inputTensors; + inputTensors.reserve(computeHandle->inputNames.size()); + for(size_t i = 0; i < computeHandle->inputNames.size(); i++) { + if((int)i == spatialIdx) + inputTensors.push_back(std::move(spatialTensor)); + else if((int)i == globalIdx) + inputTensors.push_back(std::move(globalTensor)); + else if((int)i == metaIdx) + inputTensors.push_back(std::move(metaTensor)); + else { + throw StringError("ONNX backend: unexpected input node '" + computeHandle->inputNames[i] + + "' -- only spatial, global, and meta inputs are supported"); + } + } + + // Run inference + auto outputTensors = computeHandle->session->Run( + Ort::RunOptions{nullptr}, + computeHandle->inputNamePtrs.data(), + inputTensors.data(), + inputTensors.size(), + computeHandle->outputNamePtrs.data(), + computeHandle->outputNamePtrs.size() + ); + + // Find output indices using configured node names + int policyOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyName}); + int valueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputValueName}); + int miscvalueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputMiscvalueName}); + int ownershipOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputOwnershipName}); + + if(policyOutputIdx < 0) + throw StringError("ONNX backend: could not find policy output node '" + ctx->outputPolicyName + "'"); + if(valueOutputIdx < 0) + throw StringError("ONNX backend: could not find value output node '" + ctx->outputValueName + "'"); + if(miscvalueOutputIdx < 0) + throw StringError("ONNX backend: could not find miscvalue output node '" + ctx->outputMiscvalueName + "'"); + if(ownershipOutputIdx < 0) + throw StringError("ONNX backend: could not find ownership output node '" + ctx->outputOwnershipName + "'"); + + const float* policyData = outputTensors[policyOutputIdx].GetTensorData(); + const float* valueData = outputTensors[valueOutputIdx].GetTensorData(); + const float* miscvalueData = outputTensors[miscvalueOutputIdx].GetTensorData(); + const float* ownershipData = outputTensors[ownershipOutputIdx].GetTensorData(); + + assert(policyData != nullptr); + assert(valueData != nullptr); + assert(miscvalueData != nullptr); + assert(ownershipData != nullptr); + assert((int)outputs.size() == batchSize); + + const int policyResultLen = computeHandle->policyResultLen; + const int spatialPolicyLen = nnXLen * nnYLen; + float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; + + for(int row = 0; row < batchSize; row++) { + NNOutput* output = outputs[row]; + assert(output->nnXLen == nnXLen); + assert(output->nnYLen == nnYLen); + float policyOptimism = (float)inputBufs[row]->policyOptimism; + + // Policy: [N, C, H*W+1] + { + const float* policyRowBase = policyData + row * numPolicyChannels * policyResultLen; + float* policyProbs = output->policyProbs; + + if(numPolicyChannels >= 2) { + const float* ch0 = policyRowBase; + const float* ch1 = policyRowBase + policyResultLen; + for(int i = 0; i < spatialPolicyLen; i++) { + float p = ch0[i]; + float pOpt = ch1[i]; + policyProbsTmp[i] = p + (pOpt - p) * policyOptimism; + } + SymmetryHelpers::copyOutputsWithSymmetry(policyProbsTmp, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[spatialPolicyLen] = ch0[spatialPolicyLen] + (ch1[spatialPolicyLen] - ch0[spatialPolicyLen]) * policyOptimism; + } else { + assert(numPolicyChannels == 1); + const float* ch0 = policyRowBase; + SymmetryHelpers::copyOutputsWithSymmetry(ch0, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[spatialPolicyLen] = ch0[spatialPolicyLen]; + } + } + + // Value: [N, 3] + { + int numVC = computeHandle->numValueChannels; + assert(numVC == 3); + output->whiteWinProb = valueData[row * numVC]; + output->whiteLossProb = valueData[row * numVC + 1]; + output->whiteNoResultProb = valueData[row * numVC + 2]; + } + + // MiscValue: [N, numScoreValueChannels] -- version-dependent interpretation + { + int numScoreValueChannels = computeHandle->numScoreValueChannels; + if(computeHandle->modelVersion >= 9) { + assert(numScoreValueChannels >= 6); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; + output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; + output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = miscvalueData[row * numScoreValueChannels + 4]; + output->shorttermScoreError = miscvalueData[row * numScoreValueChannels + 5]; + } + else if(computeHandle->modelVersion >= 8) { + assert(numScoreValueChannels >= 4); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; + output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; + output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(computeHandle->modelVersion >= 4) { + assert(numScoreValueChannels >= 2); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(computeHandle->modelVersion >= 3) { + assert(numScoreValueChannels >= 1); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else { + ASSERT_UNREACHABLE; + } + } + + // Ownership: [N, 1, H, W] + if(output->whiteOwnerMap != NULL) { + assert(computeHandle->numOwnershipChannels == 1); + const float* ownershipRowBuf = ownershipData + row * nnXLen * nnYLen; + SymmetryHelpers::copyOutputsWithSymmetry(ownershipRowBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + } + } +} + +void NeuralNet::printDevices() { + cout << "ONNX backend: device enumeration is provider-specific." << endl; + cout << "Use onnxProvider plus provider-specific settings in config." << endl; +} + +//-------------------------------------------------------------- +// FOR TESTING -- all return false (not implemented for this backend) + +bool NeuralNet::testEvaluateConv( + const ConvLayerDesc* desc, int batchSize, int nnXLen, int nnYLen, + bool useFP16, bool useNHWC, const std::vector& inputBuffer, std::vector& outputBuffer +) { + (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; + (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)outputBuffer; + return false; +} + +bool NeuralNet::testEvaluateBatchNorm( + const BatchNormLayerDesc* desc, int batchSize, int nnXLen, int nnYLen, + bool useFP16, bool useNHWC, const std::vector& inputBuffer, + const std::vector& maskBuffer, std::vector& outputBuffer +) { + (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; + (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)maskBuffer; (void)outputBuffer; + return false; +} + +bool NeuralNet::testEvaluateResidualBlock( + const ResidualBlockDesc* desc, int batchSize, int nnXLen, int nnYLen, + bool useFP16, bool useNHWC, const std::vector& inputBuffer, + const std::vector& maskBuffer, std::vector& outputBuffer +) { + (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; + (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)maskBuffer; (void)outputBuffer; + return false; +} + +bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( + const GlobalPoolingResidualBlockDesc* desc, int batchSize, int nnXLen, int nnYLen, + bool useFP16, bool useNHWC, const std::vector& inputBuffer, + const std::vector& maskBuffer, std::vector& outputBuffer +) { + (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; + (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)maskBuffer; (void)outputBuffer; + return false; +} diff --git a/cpp/neuralnet/onnxmodelbuilder.cpp b/cpp/neuralnet/onnxmodelbuilder.cpp new file mode 100644 index 0000000000..a301b7dc0d --- /dev/null +++ b/cpp/neuralnet/onnxmodelbuilder.cpp @@ -0,0 +1,774 @@ +// Builds an ONNX computational graph from a KataGo ModelDesc. +// Uses the ONNX protobuf API (onnx-ml.pb.h) to construct a ModelProto +// that can be loaded directly by ONNX Runtime. + +#include "../neuralnet/onnxmodelbuilder.h" +#include "../neuralnet/activations.h" +#include "../core/global.h" + +#include + +#include +#include + +using namespace std; + +static string uniqueName(int& nameCounter, const string& prefix) { + return prefix + "_" + to_string(nameCounter++); +} + +// ===================================================================== +// Helper: Add a float tensor initializer to the graph +// ===================================================================== +static string addInitializer( + onnx::GraphProto* graph, + const string& name, + const vector& shape, + const float* data, + size_t numElements +) { + onnx::TensorProto* tensor = graph->add_initializer(); + tensor->set_name(name); + tensor->set_data_type(onnx::TensorProto_DataType_FLOAT); + for(int64_t d : shape) + tensor->add_dims(d); + tensor->set_raw_data(data, numElements * sizeof(float)); + return name; +} + +static string addInitializer( + onnx::GraphProto* graph, + const string& name, + const vector& shape, + const vector& data +) { + return addInitializer(graph, name, shape, data.data(), data.size()); +} + +// Add a scalar float constant +static string addScalarInitializer(onnx::GraphProto* graph, const string& name, float value) { + return addInitializer(graph, name, {}, &value, 1); +} + +// Add a 1D int64 constant tensor +static string addInt64Initializer( + onnx::GraphProto* graph, + const string& name, + const vector& data +) { + onnx::TensorProto* tensor = graph->add_initializer(); + tensor->set_name(name); + tensor->set_data_type(onnx::TensorProto_DataType_INT64); + tensor->add_dims((int64_t)data.size()); + tensor->set_raw_data(data.data(), data.size() * sizeof(int64_t)); + return name; +} + +// ===================================================================== +// Helper: Add ONNX graph node +// ===================================================================== + +// Generic node with n inputs, 1 output +static onnx::NodeProto* addNode( + onnx::GraphProto* graph, + const string& opType, + const vector& inputs, + const string& outputName +) { + onnx::NodeProto* node = graph->add_node(); + node->set_op_type(opType); + for(const auto& inp : inputs) + node->add_input(inp); + node->add_output(outputName); + return node; +} + +// Add an attribute (int) to a node +static void setAttrInt(onnx::NodeProto* node, const string& attrName, int64_t value) { + onnx::AttributeProto* attr = node->add_attribute(); + attr->set_name(attrName); + attr->set_type(onnx::AttributeProto_AttributeType_INT); + attr->set_i(value); +} + +// Add an attribute (ints) to a node +static void setAttrInts(onnx::NodeProto* node, const string& attrName, const vector& values) { + onnx::AttributeProto* attr = node->add_attribute(); + attr->set_name(attrName); + attr->set_type(onnx::AttributeProto_AttributeType_INTS); + for(int64_t v : values) + attr->add_ints(v); +} + +// ===================================================================== +// Convolution: Conv with zero-padding +// ===================================================================== +static string addConvNode( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const ConvLayerDesc& desc, + const string& prefix +) { + string weightsName = addInitializer( + graph, prefix + "/w", + {desc.outChannels, desc.inChannels, desc.convYSize, desc.convXSize}, + desc.weights + ); + + int padY = desc.convYSize / 2; + int padX = desc.convXSize / 2; + string output = uniqueName(nameCounter, prefix + "/out"); + + onnx::NodeProto* convNode = addNode(graph, "Conv", {input, weightsName}, output); + setAttrInts(convNode, "kernel_shape", {desc.convYSize, desc.convXSize}); + setAttrInts(convNode, "pads", {padY, padX, padY, padX}); + setAttrInts(convNode, "dilations", {desc.dilationY, desc.dilationX}); + setAttrInts(convNode, "strides", {1, 1}); + + return output; +} + +// ===================================================================== +// Merged Batch Norm: output = input * mergedScale + mergedBias +// Applied channel-wise, broadcasting over [N, C, H, W] +// ===================================================================== +static string addMergedBNNode( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const BatchNormLayerDesc& desc, + const string& prefix +) { + int C = desc.numChannels; + string scaleName = addInitializer(graph, prefix + "/scale", {C, 1, 1}, desc.mergedScale); + string biasName = addInitializer(graph, prefix + "/bias", {C, 1, 1}, desc.mergedBias); + + string scaled = uniqueName(nameCounter, prefix + "/scaled"); + addNode(graph, "Mul", {input, scaleName}, scaled); + + string output = uniqueName(nameCounter, prefix + "/bn_out"); + addNode(graph, "Add", {scaled, biasName}, output); + + return output; +} + +// ===================================================================== +// Activation: ReLU, Mish (softplus->tanh->mul), or Identity +// ===================================================================== +static string addActivationNode( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + int activationType, + const string& prefix +) { + if(activationType == ACTIVATION_RELU) { + string output = uniqueName(nameCounter, prefix + "/relu"); + addNode(graph, "Relu", {input}, output); + return output; + } else if(activationType == ACTIVATION_MISH) { + // Mish = x * tanh(softplus(x)) = x * tanh(ln(1 + exp(x))) + string sp = uniqueName(nameCounter, prefix + "/softplus"); + addNode(graph, "Softplus", {input}, sp); + + string th = uniqueName(nameCounter, prefix + "/tanh"); + addNode(graph, "Tanh", {sp}, th); + + string output = uniqueName(nameCounter, prefix + "/mish"); + addNode(graph, "Mul", {input, th}, output); + return output; + } else { + // ACTIVATION_IDENTITY -- pass through + return input; + } +} + +// ===================================================================== +// BN + Activation + Mask multiply +// output = activation(input * scale + bias) * mask +// ===================================================================== +static string addBNActivationMask( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const BatchNormLayerDesc& bnDesc, + const ActivationLayerDesc& actDesc, + const string& mask, + const string& prefix +) { + string bn = addMergedBNNode(graph, nameCounter, input, bnDesc, prefix + "/bn"); + string act = addActivationNode(graph, nameCounter, bn, actDesc.activation, prefix + "/act"); + string output = uniqueName(nameCounter, prefix + "/masked"); + addNode(graph, "Mul", {act, mask}, output); + return output; +} + +// ===================================================================== +// MatMul: output = input @ W +// W is [inC, outC] +// ===================================================================== +static string addMatMulNode( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const MatMulLayerDesc& desc, + const string& prefix +) { + string weightsName = addInitializer(graph, prefix + "/w", {desc.inChannels, desc.outChannels}, desc.weights); + string output = uniqueName(nameCounter, prefix + "/matmul"); + addNode(graph, "MatMul", {input, weightsName}, output); + return output; +} + +// ===================================================================== +// Bias addition: output = input + bias +// bias is [C], broadcast over [N, C] or [N, C, H, W] +// ===================================================================== +static string addBiasNode( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const MatBiasLayerDesc& desc, + const string& prefix +) { + string biasName = addInitializer(graph, prefix + "/b", {desc.numChannels}, desc.weights); + string output = uniqueName(nameCounter, prefix + "/biased"); + addNode(graph, "Add", {input, biasName}, output); + return output; +} + +// ===================================================================== +// KataGPool: Global pooling producing 3 values per channel +// Pool 1: mean = ReduceSum(x * mask, [2,3]) / maskSum +// Pool 2: mean * (sqrt(maskSum) - 14.0) * 0.1 +// Pool 3: ReduceMax(x + (mask - 1.0), [2,3]) +// Output: [N, 3*C] +// ===================================================================== +static string addGlobalPool( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const string& mask, + const string& maskSumHW, + const string& prefix +) { + // x_masked = input * mask (already masked, but let's be safe) + string xMasked = uniqueName(nameCounter, prefix + "/gpool_xm"); + addNode(graph, "Mul", {input, mask}, xMasked); + + // sum = ReduceSum(xMasked, axes=[2,3]) + string axesName = addInt64Initializer(graph, uniqueName(nameCounter, prefix + "/axes23"), {2, 3}); + string sumOut = uniqueName(nameCounter, prefix + "/gpool_sum"); + onnx::NodeProto* sumNode = addNode(graph, "ReduceSum", {xMasked, axesName}, sumOut); + setAttrInt(sumNode, "keepdims", 0); + + // mean = sum / maskSumFlat + // maskSumHW is [N,1,1,1], we need [N,1] for division + string maskSumFlat = uniqueName(nameCounter, prefix + "/gpool_msf"); + string reshapeShape = addInt64Initializer(graph, uniqueName(nameCounter, prefix + "/shape_n1"), {0, 1}); + addNode(graph, "Reshape", {maskSumHW, reshapeShape}, maskSumFlat); + + string mean = uniqueName(nameCounter, prefix + "/gpool_mean"); + addNode(graph, "Div", {sumOut, maskSumFlat}, mean); + + // sqrtMaskSum = sqrt(maskSumFlat) + string sqrtMs = uniqueName(nameCounter, prefix + "/gpool_sqrt"); + addNode(graph, "Sqrt", {maskSumFlat}, sqrtMs); + + // sqrtMs - 14.0 + string const14 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/c14"), 14.0f); + string sqrtMsSub = uniqueName(nameCounter, prefix + "/gpool_sqrtsub"); + addNode(graph, "Sub", {sqrtMs, const14}, sqrtMsSub); + + // * 0.1 + string const01 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/c01"), 0.1f); + string scaledSqrt = uniqueName(nameCounter, prefix + "/gpool_ssm"); + addNode(graph, "Mul", {sqrtMsSub, const01}, scaledSqrt); + + // pool2 = mean * scaledSqrt + string pool2 = uniqueName(nameCounter, prefix + "/gpool_p2"); + addNode(graph, "Mul", {mean, scaledSqrt}, pool2); + + // Pool3: max over (x + mask - 1) + string constNeg1 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/cn1"), -1.0f); + string maskBias = uniqueName(nameCounter, prefix + "/gpool_mb"); + addNode(graph, "Add", {mask, constNeg1}, maskBias); + + string xShifted = uniqueName(nameCounter, prefix + "/gpool_xs"); + addNode(graph, "Add", {input, maskBias}, xShifted); + + // ReduceMax over [2,3] + string axesName2 = addInt64Initializer(graph, uniqueName(nameCounter, prefix + "/axes23b"), {2, 3}); + string pool3 = uniqueName(nameCounter, prefix + "/gpool_max"); + onnx::NodeProto* maxNode = addNode(graph, "ReduceMax", {xShifted, axesName2}, pool3); + setAttrInt(maxNode, "keepdims", 0); + + // Concat [mean, pool2, pool3] along axis=1 + string output = uniqueName(nameCounter, prefix + "/gpool_out"); + onnx::NodeProto* concatNode = addNode(graph, "Concat", {mean, pool2, pool3}, output); + setAttrInt(concatNode, "axis", 1); + + return output; +} + +// ===================================================================== +// KataValueHeadGPool: Different third pool from KataGPool +// Pool 3: mean * ((sqrt(maskSum) - 14.0)^2 * 0.01 - 0.1) +// ===================================================================== +static string addValueHeadGPool( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const string& mask, + const string& maskSumHW, + const string& prefix +) { + // x for value head already has activation applied + // sum = ReduceSum(input * mask, [2,3]) + string xMasked = uniqueName(nameCounter, prefix + "/vgpool_xm"); + addNode(graph, "Mul", {input, mask}, xMasked); + + string axesName = addInt64Initializer(graph, uniqueName(nameCounter, prefix + "/axes23"), {2, 3}); + string sumOut = uniqueName(nameCounter, prefix + "/vgpool_sum"); + onnx::NodeProto* sumNode = addNode(graph, "ReduceSum", {xMasked, axesName}, sumOut); + setAttrInt(sumNode, "keepdims", 0); + + // mean + string maskSumFlat = uniqueName(nameCounter, prefix + "/vgpool_msf"); + string reshapeShape = addInt64Initializer(graph, uniqueName(nameCounter, prefix + "/shape_n1"), {0, 1}); + addNode(graph, "Reshape", {maskSumHW, reshapeShape}, maskSumFlat); + + string mean = uniqueName(nameCounter, prefix + "/vgpool_mean"); + addNode(graph, "Div", {sumOut, maskSumFlat}, mean); + + // sqrt(maskSum) + string sqrtMs = uniqueName(nameCounter, prefix + "/vgpool_sqrt"); + addNode(graph, "Sqrt", {maskSumFlat}, sqrtMs); + + // (sqrt(maskSum) - 14.0) + string const14 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/c14"), 14.0f); + string sqrtMsSub = uniqueName(nameCounter, prefix + "/vgpool_ss"); + addNode(graph, "Sub", {sqrtMs, const14}, sqrtMsSub); + + // pool2 = mean * (sqrtMsSub) * 0.1 + string const01 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/c01"), 0.1f); + string scaledSqrt = uniqueName(nameCounter, prefix + "/vgpool_ssm"); + addNode(graph, "Mul", {sqrtMsSub, const01}, scaledSqrt); + string pool2 = uniqueName(nameCounter, prefix + "/vgpool_p2"); + addNode(graph, "Mul", {mean, scaledSqrt}, pool2); + + // pool3 = mean * ((sqrtMsSub)^2 * 0.01 - 0.1) + string sqrtMsSubSq = uniqueName(nameCounter, prefix + "/vgpool_sq"); + addNode(graph, "Mul", {sqrtMsSub, sqrtMsSub}, sqrtMsSubSq); + + string constP01 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/cp01"), 0.01f); + string sqScaled = uniqueName(nameCounter, prefix + "/vgpool_sqs"); + addNode(graph, "Mul", {sqrtMsSubSq, constP01}, sqScaled); + + string constN01 = addScalarInitializer(graph, uniqueName(nameCounter, prefix + "/cn01"), -0.1f); + string sqShifted = uniqueName(nameCounter, prefix + "/vgpool_sqsh"); + addNode(graph, "Add", {sqScaled, constN01}, sqShifted); + + string pool3 = uniqueName(nameCounter, prefix + "/vgpool_p3"); + addNode(graph, "Mul", {mean, sqShifted}, pool3); + + // Concat [mean, pool2, pool3] along axis=1 + string output = uniqueName(nameCounter, prefix + "/vgpool_out"); + onnx::NodeProto* concatNode = addNode(graph, "Concat", {mean, pool2, pool3}, output); + setAttrInt(concatNode, "axis", 1); + + return output; +} + +// ===================================================================== +// Residual Block: BN->Act->Conv->BN->Act->Conv + skip +// ===================================================================== +static string addResidualBlock( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const string& mask, + const ResidualBlockDesc& desc, + const string& prefix +) { + string pre = addBNActivationMask(graph, nameCounter, input, desc.preBN, desc.preActivation, mask, prefix + "/pre"); + string mid = addConvNode(graph, nameCounter, pre, desc.regularConv, prefix + "/conv1"); + string midAct = addBNActivationMask(graph, nameCounter, mid, desc.midBN, desc.midActivation, mask, prefix + "/mid"); + string final_ = addConvNode(graph, nameCounter, midAct, desc.finalConv, prefix + "/conv2"); + + // Residual add + string output = uniqueName(nameCounter, prefix + "/resadd"); + addNode(graph, "Add", {input, final_}, output); + return output; +} + +// ===================================================================== +// Global Pooling Residual Block +// ===================================================================== +static string addGPoolResidualBlock( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const string& mask, + const string& maskSumHW, + const GlobalPoolingResidualBlockDesc& desc, + const string& prefix +) { + string pre = addBNActivationMask(graph, nameCounter, input, desc.preBN, desc.preActivation, mask, prefix + "/pre"); + + // Regular path + string regOut = addConvNode(graph, nameCounter, pre, desc.regularConv, prefix + "/reg"); + + // Global pooling path + string gpoolConvOut = addConvNode(graph, nameCounter, pre, desc.gpoolConv, prefix + "/gconv"); + string gpoolBNAct = addBNActivationMask(graph, nameCounter, gpoolConvOut, desc.gpoolBN, desc.gpoolActivation, mask, prefix + "/gbn"); + string gpoolResult = addGlobalPool(graph, nameCounter, gpoolBNAct, mask, maskSumHW, prefix + "/gpool"); + + // gpoolToBiasMul: [N, 3*gpoolC] -> [N, regC] + string gpoolBias = addMatMulNode(graph, nameCounter, gpoolResult, desc.gpoolToBiasMul, prefix + "/g2b"); + + // Reshape bias to [N, C, 1, 1] for broadcasting + string biasShape = addInt64Initializer(graph, uniqueName(nameCounter, prefix + "/shape_nc11"), {0, -1, 1, 1}); + string gpoolBiasReshaped = uniqueName(nameCounter, prefix + "/gbr"); + addNode(graph, "Reshape", {gpoolBias, biasShape}, gpoolBiasReshaped); + + // Add bias to regular conv output + string regPlusBias = uniqueName(nameCounter, prefix + "/rpb"); + addNode(graph, "Add", {regOut, gpoolBiasReshaped}, regPlusBias); + + // Second half: BN->Act->Conv + string midAct = addBNActivationMask(graph, nameCounter, regPlusBias, desc.midBN, desc.midActivation, mask, prefix + "/mid"); + string final_ = addConvNode(graph, nameCounter, midAct, desc.finalConv, prefix + "/conv2"); + + // Residual add + string output = uniqueName(nameCounter, prefix + "/resadd"); + addNode(graph, "Add", {input, final_}, output); + return output; +} + +// ===================================================================== +// Nested Bottleneck Residual Block +// Pre: BN->Act->Mask->1x1Conv (c_main->c_mid) +// Inner: sequence of ordinary/gpool/nested_bottleneck sub-blocks at c_mid +// Post: BN->Act->Mask->1x1Conv (c_mid->c_main) + residual add +// ===================================================================== +static string addNestedBottleneckResidualBlock( + onnx::GraphProto* graph, + int& nameCounter, + const string& input, + const string& mask, + const string& maskSumHW, + const NestedBottleneckResidualBlockDesc& desc, + const string& prefix +) { + // Pre: BN -> Act -> Mask -> 1x1 Conv (c_main -> c_mid) + string pre = addBNActivationMask(graph, nameCounter, input, desc.preBN, desc.preActivation, mask, prefix + "/pre"); + string midOut = addConvNode(graph, nameCounter, pre, desc.preConv, prefix + "/preconv"); + + // Inner sub-blocks at c_mid channels + for(int i = 0; i < desc.numBlocks; i++) { + int kind = desc.blocks[i].first; + string sub = prefix + "/sub" + to_string(i); + if(kind == ORDINARY_BLOCK_KIND) { + midOut = addResidualBlock(graph, nameCounter, midOut, mask, + *((const ResidualBlockDesc*)desc.blocks[i].second.get()), sub); + } else if(kind == GLOBAL_POOLING_BLOCK_KIND) { + midOut = addGPoolResidualBlock(graph, nameCounter, midOut, mask, maskSumHW, + *((const GlobalPoolingResidualBlockDesc*)desc.blocks[i].second.get()), sub); + } else if(kind == NESTED_BOTTLENECK_BLOCK_KIND) { + midOut = addNestedBottleneckResidualBlock(graph, nameCounter, midOut, mask, maskSumHW, + *((const NestedBottleneckResidualBlockDesc*)desc.blocks[i].second.get()), sub); + } else { + throw StringError("ONNX backend: unknown sub-block kind " + to_string(kind)); + } + } + + // Post: BN -> Act -> Mask -> 1x1 Conv (c_mid -> c_main) + string post = addBNActivationMask(graph, nameCounter, midOut, desc.postBN, desc.postActivation, mask, prefix + "/post"); + string postOut = addConvNode(graph, nameCounter, post, desc.postConv, prefix + "/postconv"); + + // Residual add: input + postOut + string output = uniqueName(nameCounter, prefix + "/resadd"); + addNode(graph, "Add", {input, postOut}, output); + return output; +} + +// ===================================================================== +// Add ValueInfo for graph input/output +// ===================================================================== +static void addGraphInput( + onnx::GraphProto* graph, + const string& name, + const vector& shape +) { + onnx::ValueInfoProto* input = graph->add_input(); + input->set_name(name); + onnx::TypeProto* type = input->mutable_type(); + onnx::TypeProto_Tensor* tensorType = type->mutable_tensor_type(); + tensorType->set_elem_type(onnx::TensorProto_DataType_FLOAT); + onnx::TensorShapeProto* shapeProto = tensorType->mutable_shape(); + for(int64_t d : shape) { + auto* dim = shapeProto->add_dim(); + if(d < 0) + dim->set_dim_param("N"); + else + dim->set_dim_value(d); + } +} + +static void addGraphOutput( + onnx::GraphProto* graph, + const string& name, + const vector& shape +) { + onnx::ValueInfoProto* output = graph->add_output(); + output->set_name(name); + onnx::TypeProto* type = output->mutable_type(); + onnx::TypeProto_Tensor* tensorType = type->mutable_tensor_type(); + tensorType->set_elem_type(onnx::TensorProto_DataType_FLOAT); + onnx::TensorShapeProto* shapeProto = tensorType->mutable_shape(); + for(int64_t d : shape) { + auto* dim = shapeProto->add_dim(); + if(d < 0) + dim->set_dim_param("N"); + else + dim->set_dim_value(d); + } +} + +// ===================================================================== +// Main: Build the full ONNX model from ModelDesc +// ===================================================================== +string OnnxModelBuilder::buildOnnxModel(const ModelDesc& modelDesc, int nnXLen, int nnYLen) { + int nameCounter = 0; + + const int modelVersion = modelDesc.modelVersion; + const int numInputChannels = modelDesc.numInputChannels; + const int numInputGlobalChannels = modelDesc.numInputGlobalChannels; + const int numPolicyChannels = modelDesc.numPolicyChannels; + const int numValueChannels = modelDesc.numValueChannels; + const int numScoreValueChannels = modelDesc.numScoreValueChannels; + const int numOwnershipChannels = modelDesc.numOwnershipChannels; + + const TrunkDesc& trunk = modelDesc.trunk; + const PolicyHeadDesc& policyHead = modelDesc.policyHead; + const ValueHeadDesc& valueHead = modelDesc.valueHead; + + onnx::ModelProto model; + model.set_ir_version(8); + model.set_producer_name("KataGo"); + model.set_domain("ai.katago"); + + auto* opset = model.add_opset_import(); + opset->set_domain(""); + opset->set_version(18); + + onnx::GraphProto* graph = model.mutable_graph(); + graph->set_name("katago"); + + // ------------------------------------------------------------------ + // Graph Inputs + // ------------------------------------------------------------------ + addGraphInput(graph, "input_spatial", {-1, numInputChannels, nnYLen, nnXLen}); + addGraphInput(graph, "input_global", {-1, numInputGlobalChannels}); + if(modelDesc.numInputMetaChannels > 0) { + addGraphInput(graph, "input_meta", {-1, modelDesc.numInputMetaChannels}); + } + + // ------------------------------------------------------------------ + // Derive mask and maskSumHW from input_spatial. + // Channel 0 of the spatial input is the "on board" indicator: 1.0 for + // positions on the board, 0.0 for off-board padding. This is Feature 0 + // set by fillRowV3/V4/V5/V6/V7 in nninputs.cpp and holds across all + // supported input versions (V3-V7). + // + // mask = input_spatial[:, 0:1, :, :] -> [N, 1, H, W] + // maskSumHW = ReduceSum(mask, [2, 3], keepdims=true) -> [N, 1, 1, 1] + // ------------------------------------------------------------------ + + // Slice channel 0 to get mask + string sliceStarts = addInt64Initializer(graph, "mask_starts", {0}); + string sliceEnds = addInt64Initializer(graph, "mask_ends", {1}); + string sliceAxes = addInt64Initializer(graph, "mask_axes", {1}); + string mask = uniqueName(nameCounter, "mask"); + addNode(graph, "Slice", {"input_spatial", sliceStarts, sliceEnds, sliceAxes}, mask); + + // maskSumHW + string sumAxes = addInt64Initializer(graph, "mask_sum_axes", {2, 3}); + string maskSumHW = uniqueName(nameCounter, "maskSumHW"); + onnx::NodeProto* maskSumNode = addNode(graph, "ReduceSum", {mask, sumAxes}, maskSumHW); + setAttrInt(maskSumNode, "keepdims", 1); + + // ------------------------------------------------------------------ + // Trunk: Initial conv + matmul bias + // ------------------------------------------------------------------ + string trunkOut = addConvNode(graph, nameCounter, "input_spatial", trunk.initialConv, "trunk/init_conv"); + + // initialMatMul: global features -> [N, trunkNumChannels] + string globalBias = addMatMulNode(graph, nameCounter, "input_global", trunk.initialMatMul, "trunk/init_matmul"); + + // Reshape to [N, C, 1, 1] for broadcasting + string biasShape = addInt64Initializer(graph, "trunk_bias_shape", {0, -1, 1, 1}); + string globalBiasReshaped = uniqueName(nameCounter, "trunk/gbr"); + addNode(graph, "Reshape", {globalBias, biasShape}, globalBiasReshaped); + + // Add global bias to conv output + string trunkCombined = uniqueName(nameCounter, "trunk/combined"); + addNode(graph, "Add", {trunkOut, globalBiasReshaped}, trunkCombined); + trunkOut = trunkCombined; + + // ------------------------------------------------------------------ + // Trunk: Metadata encoder (SGF metadata -> trunk bias) + // ------------------------------------------------------------------ + if(trunk.metaEncoderVersion > 0) { + const SGFMetadataEncoderDesc& enc = trunk.sgfMetadataEncoder; + string metaOut = addMatMulNode(graph, nameCounter, "input_meta", enc.mul1, "trunk/meta_mul1"); + metaOut = addBiasNode(graph, nameCounter, metaOut, enc.bias1, "trunk/meta_b1"); + metaOut = addActivationNode(graph, nameCounter, metaOut, enc.act1.activation, "trunk/meta_a1"); + metaOut = addMatMulNode(graph, nameCounter, metaOut, enc.mul2, "trunk/meta_mul2"); + metaOut = addBiasNode(graph, nameCounter, metaOut, enc.bias2, "trunk/meta_b2"); + metaOut = addActivationNode(graph, nameCounter, metaOut, enc.act2.activation, "trunk/meta_a2"); + metaOut = addMatMulNode(graph, nameCounter, metaOut, enc.mul3, "trunk/meta_mul3"); + + // Reshape to [N, C, 1, 1] for spatial broadcasting + string metaBiasShape = addInt64Initializer(graph, "trunk_meta_bias_shape", {0, -1, 1, 1}); + string metaBiasReshaped = uniqueName(nameCounter, "trunk/mbr"); + addNode(graph, "Reshape", {metaOut, metaBiasShape}, metaBiasReshaped); + + // Add to trunk + string trunkWithMeta = uniqueName(nameCounter, "trunk/with_meta"); + addNode(graph, "Add", {trunkOut, metaBiasReshaped}, trunkWithMeta); + trunkOut = trunkWithMeta; + } + + // ------------------------------------------------------------------ + // Trunk: Residual blocks + // ------------------------------------------------------------------ + for(int i = 0; i < trunk.numBlocks; i++) { + int blockKind = trunk.blocks[i].first; + string blockPrefix = "trunk/block" + to_string(i); + + if(blockKind == ORDINARY_BLOCK_KIND) { + const ResidualBlockDesc& blockDesc = *((const ResidualBlockDesc*)trunk.blocks[i].second.get()); + trunkOut = addResidualBlock(graph, nameCounter, trunkOut, mask, blockDesc, blockPrefix); + } else if(blockKind == GLOBAL_POOLING_BLOCK_KIND) { + const GlobalPoolingResidualBlockDesc& blockDesc = *((const GlobalPoolingResidualBlockDesc*)trunk.blocks[i].second.get()); + trunkOut = addGPoolResidualBlock(graph, nameCounter, trunkOut, mask, maskSumHW, blockDesc, blockPrefix); + } else if(blockKind == NESTED_BOTTLENECK_BLOCK_KIND) { + const NestedBottleneckResidualBlockDesc& blockDesc = *((const NestedBottleneckResidualBlockDesc*)trunk.blocks[i].second.get()); + trunkOut = addNestedBottleneckResidualBlock(graph, nameCounter, trunkOut, mask, maskSumHW, blockDesc, blockPrefix); + } else { + throw StringError("ONNX backend: unknown block kind " + to_string(blockKind)); + } + } + + // Trunk tip: BN + activation + mask + trunkOut = addBNActivationMask(graph, nameCounter, trunkOut, trunk.trunkTipBN, trunk.trunkTipActivation, mask, "trunk/tip"); + + // ------------------------------------------------------------------ + // Policy Head + // ------------------------------------------------------------------ + + // p1Conv: spatial path + string p1Out = addConvNode(graph, nameCounter, trunkOut, policyHead.p1Conv, "policy/p1conv"); + + // g1Conv: global pooling path + string g1Out = addConvNode(graph, nameCounter, trunkOut, policyHead.g1Conv, "policy/g1conv"); + string g1BNAct = addBNActivationMask(graph, nameCounter, g1Out, policyHead.g1BN, policyHead.g1Activation, mask, "policy/g1bn"); + string g1Pool = addGlobalPool(graph, nameCounter, g1BNAct, mask, maskSumHW, "policy/g1pool"); + + // gpoolToBiasMul: [N, 3*g1C] -> [N, p1C] + string policyBias = addMatMulNode(graph, nameCounter, g1Pool, policyHead.gpoolToBiasMul, "policy/g2b"); + + // Reshape to [N, C, 1, 1] + string pBiasShape = addInt64Initializer(graph, uniqueName(nameCounter, "policy/bias_shape"), {0, -1, 1, 1}); + string policyBiasReshaped = uniqueName(nameCounter, "policy/pbr"); + addNode(graph, "Reshape", {policyBias, pBiasShape}, policyBiasReshaped); + + // Add bias to p1 + string p1PlusBias = uniqueName(nameCounter, "policy/p1pb"); + addNode(graph, "Add", {p1Out, policyBiasReshaped}, p1PlusBias); + + // p1BN + activation + mask + string p1BNAct = addBNActivationMask(graph, nameCounter, p1PlusBias, policyHead.p1BN, policyHead.p1Activation, mask, "policy/p1bn"); + + // p2Conv: [N, p1C, H, W] -> [N, policyChannels, H, W] + string p2Out = addConvNode(graph, nameCounter, p1BNAct, policyHead.p2Conv, "policy/p2conv"); + + // Reshape to [N, policyChannels, H*W] + string pSpatialShape = addInt64Initializer(graph, uniqueName(nameCounter, "policy/spat_shape"), {0, numPolicyChannels, -1}); + string policySpatial = uniqueName(nameCounter, "policy/spatial"); + addNode(graph, "Reshape", {p2Out, pSpatialShape}, policySpatial); + + // Pass move: gpoolToPassMul + string passOut; + if(modelVersion >= 15) { + // gpoolToPassMul -> bias -> activation -> gpoolToPassMul2 + string passMul1 = addMatMulNode(graph, nameCounter, g1Pool, policyHead.gpoolToPassMul, "policy/pass_mul1"); + string passBiased = addBiasNode(graph, nameCounter, passMul1, policyHead.gpoolToPassBias, "policy/pass_bias"); + string passAct = addActivationNode(graph, nameCounter, passBiased, policyHead.passActivation.activation, "policy/pass_act"); + passOut = addMatMulNode(graph, nameCounter, passAct, policyHead.gpoolToPassMul2, "policy/pass_mul2"); + } else { + passOut = addMatMulNode(graph, nameCounter, g1Pool, policyHead.gpoolToPassMul, "policy/pass_mul"); + } + + // Reshape pass to [N, policyChannels, 1] + string passShape = addInt64Initializer(graph, uniqueName(nameCounter, "policy/pass_shape"), {0, numPolicyChannels, 1}); + string passReshaped = uniqueName(nameCounter, "policy/pass_r"); + addNode(graph, "Reshape", {passOut, passShape}, passReshaped); + + // Concat spatial + pass -> out_policy [N, policyChannels, H*W+1] + onnx::NodeProto* policyConcatNode = addNode(graph, "Concat", {policySpatial, passReshaped}, "out_policy"); + setAttrInt(policyConcatNode, "axis", 2); + + // ------------------------------------------------------------------ + // Value Head + // ------------------------------------------------------------------ + + // v1Conv + string v1Out = addConvNode(graph, nameCounter, trunkOut, valueHead.v1Conv, "value/v1conv"); + + // v1BN + activation + mask + string v1BNAct = addBNActivationMask(graph, nameCounter, v1Out, valueHead.v1BN, valueHead.v1Activation, mask, "value/v1bn"); + + // Value head global pooling + string v1Pool = addValueHeadGPool(graph, nameCounter, v1BNAct, mask, maskSumHW, "value/vpool"); + + // v2Mul + v2Bias + v2Activation + string v2Out = addMatMulNode(graph, nameCounter, v1Pool, valueHead.v2Mul, "value/v2mul"); + string v2Biased = addBiasNode(graph, nameCounter, v2Out, valueHead.v2Bias, "value/v2bias"); + string v2Act = addActivationNode(graph, nameCounter, v2Biased, valueHead.v2Activation.activation, "value/v2act"); + + // v3Mul + v3Bias -> out_value [N, 3] + string v3Out = addMatMulNode(graph, nameCounter, v2Act, valueHead.v3Mul, "value/v3mul"); + string v3Biased = addBiasNode(graph, nameCounter, v3Out, valueHead.v3Bias, "value/v3bias"); + addNode(graph, "Identity", {v3Biased}, "out_value"); + + // sv3Mul + sv3Bias -> out_miscvalue [N, numScoreValueChannels] + string sv3Out = addMatMulNode(graph, nameCounter, v2Act, valueHead.sv3Mul, "value/sv3mul"); + string sv3Biased = addBiasNode(graph, nameCounter, sv3Out, valueHead.sv3Bias, "value/sv3bias"); + addNode(graph, "Identity", {sv3Biased}, "out_miscvalue"); + + // vOwnershipConv -> out_ownership [N, 1, H, W] + string ownOut = addConvNode(graph, nameCounter, v1BNAct, valueHead.vOwnershipConv, "value/own_conv"); + addNode(graph, "Identity", {ownOut}, "out_ownership"); + + // ------------------------------------------------------------------ + // Graph Outputs + // ------------------------------------------------------------------ + int policyResultLen = nnXLen * nnYLen + 1; + addGraphOutput(graph, "out_policy", {-1, numPolicyChannels, policyResultLen}); + addGraphOutput(graph, "out_value", {-1, numValueChannels}); + addGraphOutput(graph, "out_miscvalue", {-1, numScoreValueChannels}); + addGraphOutput(graph, "out_ownership", {-1, numOwnershipChannels, nnYLen, nnXLen}); + + // ------------------------------------------------------------------ + // Serialize to string + // ------------------------------------------------------------------ + string serialized; + if(!model.SerializeToString(&serialized)) + throw StringError("ONNX backend: failed to serialize ONNX model to protobuf"); + + return serialized; +} diff --git a/cpp/neuralnet/onnxmodelbuilder.h b/cpp/neuralnet/onnxmodelbuilder.h new file mode 100644 index 0000000000..96bc8e07af --- /dev/null +++ b/cpp/neuralnet/onnxmodelbuilder.h @@ -0,0 +1,14 @@ +#ifndef NEURALNET_ONNXMODELBUILDER_H_ +#define NEURALNET_ONNXMODELBUILDER_H_ + +#include +#include "../neuralnet/desc.h" + +namespace OnnxModelBuilder { + // Builds a serialized ONNX ModelProto from a KataGo ModelDesc. + // The model is constructed for a fixed spatial size of nnXLen x nnYLen. + // Returns the protobuf-serialized bytes, ready for Ort::Session creation. + std::string buildOnnxModel(const ModelDesc& modelDesc, int nnXLen, int nnYLen); +} + +#endif // NEURALNET_ONNXMODELBUILDER_H_ diff --git a/cpp/program/gtpconfig.cpp b/cpp/program/gtpconfig.cpp index d8f1decf3b..aa0e8393e2 100644 --- a/cpp/program/gtpconfig.cpp +++ b/cpp/program/gtpconfig.cpp @@ -280,6 +280,8 @@ nnCacheSizePowerOfTwo = $$NN_CACHE_SIZE_POWER_OF_TWO # Size of mutex pool for nnCache is (2 ** this). nnMutexPoolSizePowerOfTwo = $$NN_MUTEX_POOL_SIZE_POWER_OF_TWO +$$ONNX_PROVIDER + $$MULTIPLE_GPUS # =========================================================================== @@ -466,7 +468,8 @@ string GTPConfig::makeConfig( std::vector deviceIdxs, int nnCacheSizePowerOfTwo, int nnMutexPoolSizePowerOfTwo, - int numSearchThreads + int numSearchThreads, + const string& onnxProvider ) { string config = gtpBasePart1 + gtpBasePart2; auto replace = [&](const string& key, const string& replacement) { @@ -519,12 +522,27 @@ string GTPConfig::makeConfig( replace("$$NN_CACHE_SIZE_POWER_OF_TWO", Global::intToString(nnCacheSizePowerOfTwo)); replace("$$NN_MUTEX_POOL_SIZE_POWER_OF_TWO", Global::intToString(nnMutexPoolSizePowerOfTwo)); +#ifdef USE_ONNX_BACKEND + string onnxProviderLower = Global::toLower(Global::trim(onnxProvider)); + string onnxProviderConfigValue = onnxProviderLower.empty() ? "cpu" : onnxProviderLower; + replace("$$ONNX_PROVIDER", "onnxProvider = " + onnxProviderConfigValue); +#else + (void)onnxProvider; + replace("$$ONNX_PROVIDER", ""); +#endif + if(deviceIdxs.size() <= 0) { replace("$$MULTIPLE_GPUS", ""); } else { string replacement = ""; replacement += "numNNServerThreadsPerModel = " + Global::uint64ToString(deviceIdxs.size()) + "\n"; +#ifdef USE_ONNX_BACKEND + bool onnxProviderSupportsThreadDeviceMap = + onnxProviderConfigValue == "cuda" || + onnxProviderConfigValue == "tensorrt" || + onnxProviderConfigValue == "migraphx"; +#endif for(int i = 0; i deviceIdxs, int nnCacheSizePowerOfTwo, int nnMutexPoolSizePowerOfTwo, - int numSearchThreads + int numSearchThreads, + const std::string& onnxProvider = "cpu" ); } diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index fe4e5d7c15..2c7ec0847a 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -21,6 +21,7 @@ std::vector Setup::getBackendPrefixes() { prefixes.push_back("opencl"); prefixes.push_back("rocm"); prefixes.push_back("eigen"); + prefixes.push_back("onnx"); prefixes.push_back("dummybackend"); return prefixes; } @@ -89,12 +90,29 @@ vector Setup::initializeNNEvaluators( string backendPrefix = "opencl"; #elif defined(USE_ROCM_BACKEND) string backendPrefix = "rocm"; + #elif defined(USE_ONNX_BACKEND) + string backendPrefix = "onnx"; #elif defined(USE_EIGEN_BACKEND) string backendPrefix = "eigen"; #else string backendPrefix = "dummybackend"; #endif +#if !defined(USE_ONNX_BACKEND) + // In non-ONNX builds, fail fast on any ONNX-specific config instead of silently ignoring it. + { + const vector allKeys = cfg.unusedKeys(); + for(const string& key : allKeys) { + if(Global::isPrefix(Global::toLower(key),"onnx")) { + throw StringError( + "Config key '" + key + "' requires ONNX backend, but this executable is not built with USE_BACKEND=ONNX. " + "Remove onnx* settings or rebuild with -DUSE_BACKEND=ONNX." + ); + } + } + } +#endif + //Automatically flag keys that are for other backends as used so that we don't warn about unused keys //for those options for(const string& prefix: getBackendPrefixes()) { @@ -144,7 +162,7 @@ vector Setup::initializeNNEvaluators( requireExactNNLen = cfg.getBool("requireMaxBoardSize"); } - bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" || backendPrefix == "rocm" ? false : true; + bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" || backendPrefix == "rocm" || backendPrefix == "onnx" ? false : true; if(cfg.contains(backendPrefix+"InputsUseNHWC"+idxStr)) inputsUseNHWC = cfg.getBool(backendPrefix+"InputsUseNHWC"+idxStr); else if(cfg.contains("inputsUseNHWC"+idxStr)) @@ -223,9 +241,38 @@ vector Setup::initializeNNEvaluators( string homeDataDirOverride = loadHomeDataDirOverride(cfg); - string openCLTunerFile; + string backendExtraParam; +#if defined(USE_ONNX_BACKEND) + string onnxProvider = cfg.contains("onnxProvider") ? cfg.getString("onnxProvider") : "cpu"; + backendExtraParam = "provider=" + onnxProvider; + if(cfg.contains("onnxInputSpatial")) + backendExtraParam += ";inputSpatial=" + cfg.getString("onnxInputSpatial"); + if(cfg.contains("onnxInputGlobal")) + backendExtraParam += ";inputGlobal=" + cfg.getString("onnxInputGlobal"); + if(cfg.contains("onnxInputMeta")) + backendExtraParam += ";inputMeta=" + cfg.getString("onnxInputMeta"); + if(cfg.contains("onnxOutputPolicy")) + backendExtraParam += ";outputPolicy=" + cfg.getString("onnxOutputPolicy"); + if(cfg.contains("onnxOutputValue")) + backendExtraParam += ";outputValue=" + cfg.getString("onnxOutputValue"); + if(cfg.contains("onnxOutputMiscvalue")) + backendExtraParam += ";outputMiscvalue=" + cfg.getString("onnxOutputMiscvalue"); + if(cfg.contains("onnxOutputOwnership")) + backendExtraParam += ";outputOwnership=" + cfg.getString("onnxOutputOwnership"); + if(cfg.contains("onnxModelVersion")) + backendExtraParam += ";modelVersion=" + cfg.getString("onnxModelVersion"); + if(cfg.contains("onnxOpenVINODeviceType")) + backendExtraParam += ";openvinoDeviceType=" + cfg.getString("onnxOpenVINODeviceType"); + if(cfg.contains("onnxOpenVINODeviceId")) + backendExtraParam += ";openvinoDeviceId=" + cfg.getString("onnxOpenVINODeviceId"); + if(cfg.contains("onnxOpenVINOEnableNPUFastCompile")) + backendExtraParam += ";openvinoEnableNPUFastCompile=" + cfg.getString("onnxOpenVINOEnableNPUFastCompile"); + if(cfg.contains("onnxOpenVINOCacheDir")) + backendExtraParam += ";openvinoCacheDir=" + cfg.getString("onnxOpenVINOCacheDir"); +#else if(cfg.contains("openclTunerFile")) - openCLTunerFile = cfg.getString("openclTunerFile"); + backendExtraParam = cfg.getString("openclTunerFile"); +#endif bool openCLReTunePerBoardSize = false; if(cfg.contains("openclReTunePerBoardSize")) openCLReTunePerBoardSize = cfg.getBool("openclReTunePerBoardSize"); @@ -318,7 +365,7 @@ vector Setup::initializeNNEvaluators( nnCacheSizePowerOfTwo, nnMutexPoolSizePowerOfTwo, debugSkipNeuralNet, - openCLTunerFile, + backendExtraParam, homeDataDirOverride, openCLReTunePerBoardSize, useFP16Mode, diff --git a/cpp/runonnxtests.sh b/cpp/runonnxtests.sh new file mode 100644 index 0000000000..2aff647334 --- /dev/null +++ b/cpp/runonnxtests.sh @@ -0,0 +1,43 @@ +#!/bin/bash -eux +set -o pipefail +{ +# --------------------------------------------------------------- +# ONNX backend integration tests +# +# Exercises three levels of the inference pipeline: +# 1. runtinynntests — tiny model, full pipeline (no external model) +# 2. testgpuerror -quick — FP32 unbatched vs batched comparison +# 3. runnnevalcanarytests — sanity checks on real game positions +# --------------------------------------------------------------- + +mkdir -p tests/scratch + +# 1. Tiny NN tests — self-contained, no external model needed +echo "=== runtinynntests ===" +./katago runtinynntests tests/scratch 1.0 \ + | grep -v ': nnRandSeed0 = ' \ + | grep -v 'finishing, processed' + +# 2. GPU error test (quick) — compares unbatched vs batched inference +# For CPU ONNX provider both paths are FP32, so errors should be near zero. +# Any ownership indexing bug would surface as large ownership error. +echo "=== testgpuerror -quick ===" +./katago testgpuerror \ + -config configs/gtp_example.cfg \ + -model tests/models/g170-b6c96-s175395328-d26788732.bin.gz \ + -quick \ + -override-config "nnRandSeed=forTesting,forDeterministicTesting=true" + +# 3. NN eval canary tests — sanity checks on 5 real game positions +# Uses symmetries 0, 3, 6 (same as runsearchtests.sh) +echo "=== runnnevalcanarytests ===" +./katago runnnevalcanarytests configs/gtp_example.cfg tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz 0 \ + | grep -v ': nnRandSeed0 = ' +./katago runnnevalcanarytests configs/gtp_example.cfg tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz 3 \ + | grep -v ': nnRandSeed0 = ' +./katago runnnevalcanarytests configs/gtp_example.cfg tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz 6 \ + | grep -v ': nnRandSeed0 = ' + +echo "=== All ONNX tests passed ===" +exit 0 +} From d828f21fba094107d9987f96d849355778a73489 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 16 Mar 2026 18:39:44 +0800 Subject: [PATCH 20/37] Resume gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 94076bdce8..2e933d553b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ cpp/mainopencl cpp/katago cpp/configs cpp/evalsgf -# cpp/run*.sh +cpp/run*.sh cpp/tests/scratch cpp/program/gitinfo.h From 358dd84b7ef2efcc4e1225bbb7ac90cd5cbc0565 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 16 Mar 2026 20:59:28 +0800 Subject: [PATCH 21/37] Edit README.md and Compiling.md --- Compiling.md | 110 ++++++++++++++++++---------------- README.md | 4 +- cpp/neuralnet/onnxbackend.cpp | 2 +- 3 files changed, 60 insertions(+), 56 deletions(-) diff --git a/Compiling.md b/Compiling.md index 8fcea46f85..eda612daed 100644 --- a/Compiling.md +++ b/Compiling.md @@ -56,59 +56,6 @@ As also mentioned in the instructions below but repeated here for visibility, if * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device when you run it (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). -## ONNX Runtime Backend -The ONNX backend uses ONNX Runtime for inference, and supports both: -* `.onnx` models loaded directly. -* `.bin.gz` KataGo models via internal conversion to ONNX graph (requires ONNX protobuf dependencies in CMake). - -### Windows Intel NPU (OpenVINO EP) Setup -1. Install Visual Studio Community or Visual Studio 2026 Build Tools: - * https://visualstudio.microsoft.com/zh-hans/downloads/ - * In installer workloads, select **Desktop development with C++**. -2. Install Intel NPU driver: - * https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html -3. Install OpenVINO 2026 archive package on Windows: - * https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html - * Typical install root looks like: `C:\Program Files (x86)\Intel\openvino_2026.0` -4. Build ONNX Runtime with OpenVINO EP for NPU (follow official docs): - * https://onnxruntime.ai/docs/build/eps.html#openvino - * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). - -### Prepare `ONNXRUNTIME_ROOT` in KataGo -Create: -* `cpp/external/onnxruntime-win-x64-openvino/include` -* `cpp/external/onnxruntime-win-x64-openvino/lib` - -Copy from your ONNX Runtime build/package output (``) to KataGo: -* `/include/*` -> `cpp/external/onnxruntime-win-x64-openvino/include/` -* `/lib/onnxruntime.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.lib` -* `/lib/onnxruntime.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.dll` -* `/lib/onnxruntime_providers_shared.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.dll` -* `/lib/onnxruntime_providers_openvino.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.dll` - -Optional if present in your ORT output: -* `/lib/onnxruntime_providers_shared.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` -* `/lib/onnxruntime_providers_openvino.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` - -### Minimal KataGo Build Commands (Windows, ONNX backend) -On Windows, `KATAGO_AUTO_FETCH_DEPS=ON` by default, so missing `zlib`, `onnx`, and `protobuf` dependencies are auto-fetched via vcpkg into `cpp/build/deps/vcpkg`. - -``` -cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-win-x64-openvino -cmake --build cpp/build --config Release -``` - -If you want to disable auto-fetch and provide dependencies manually: -* `-DKATAGO_AUTO_FETCH_DEPS=OFF` -* plus `-DONNX_INCLUDE_DIR=... -DONNX_PROTO_LIB=... -DPROTOBUF_INCLUDE_DIR=... -DPROTOBUF_LIB=... -DZLIB_INCLUDE_DIR=... -DZLIB_LIBRARY=...` - -Typical run config for Intel NPU: -* `onnxProvider = openvino` -* `onnxOpenVINODeviceType = NPU` -* `onnxOpenVINOEnableNPUFastCompile = true` (optional; may be ignored on ORT builds that do not support this key) - -Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). -For `onnxProvider=openvino` on Intel NPU, a single device is typically used. ## Windows * TLDR: @@ -168,6 +115,63 @@ For `onnxProvider=openvino` on Intel NPU, a single device is typically used. * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). +##### ONNX Runtime Backend +The ONNX backend uses ONNX Runtime for inference, and supports both: +* `.onnx` models loaded directly. +* `.bin.gz` KataGo models via internal conversion to ONNX graph (requires ONNX protobuf dependencies in CMake). + +##### Windows Intel NPU (OpenVINO EP) Setup +1. Install Visual Studio 2026 Community or Visual Studio 2026 Build Tools: + * https://visualstudio.microsoft.com/zh-hans/downloads/ + * In installer workloads, select **Desktop development with C++**. +2. Install Intel NPU driver: + * https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html +3. Install OpenVINO 2026 archive package on Windows: + * https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html + * Typical install root looks like: `C:\Program Files (x86)\Intel\openvino_2026.0` +4. Add these to System PATH: + * `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\bin\intel64\Release` + * `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\3rdparty\tbb\bin` +5. Build ONNX Runtime with OpenVINO EP for NPU (follow official docs): + * https://onnxruntime.ai/docs/build/eps.html#openvino + * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). + +##### Prepare `ONNXRUNTIME_ROOT` in KataGo +Create: +* `cpp/external/onnxruntime-win-x64-openvino/include` +* `cpp/external/onnxruntime-win-x64-openvino/lib` + +Copy from your ONNX Runtime build/package output (``) to KataGo: +* `/include/*` -> `cpp/external/onnxruntime-win-x64-openvino/include/` +* `/lib/onnxruntime.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.lib` +* `/lib/onnxruntime.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.dll` +* `/lib/onnxruntime_providers_shared.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.dll` +* `/lib/onnxruntime_providers_openvino.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.dll` + +Optional if present in your ORT output: +* `/lib/onnxruntime_providers_shared.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` +* `/lib/onnxruntime_providers_openvino.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` + +##### Minimal KataGo Build Commands (Windows, ONNX backend) +On Windows, `KATAGO_AUTO_FETCH_DEPS=ON` by default, so missing `zlib`, `onnx`, and `protobuf` dependencies are auto-fetched via vcpkg into `cpp/build/deps/vcpkg`. + +``` +cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-win-x64-openvino +cmake --build cpp/build --config Release +``` + +If you want to disable auto-fetch and provide dependencies manually: +* `-DKATAGO_AUTO_FETCH_DEPS=OFF` +* plus `-DONNX_INCLUDE_DIR=... -DONNX_PROTO_LIB=... -DPROTOBUF_INCLUDE_DIR=... -DPROTOBUF_LIB=... -DZLIB_INCLUDE_DIR=... -DZLIB_LIBRARY=...` + +Typical run config for Intel NPU: +* `onnxProvider = openvino` +* `onnxOpenVINODeviceType = NPU` +* `onnxOpenVINOEnableNPUFastCompile = true` (optional; may be ignored on ORT builds that do not support this key) + +Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). +For `onnxProvider=openvino` on Intel NPU, a single device is typically used. + ## MacOS * TLDR: ``` diff --git a/README.md b/README.md index 04560bb7a4..068ab22e51 100644 --- a/README.md +++ b/README.md @@ -145,8 +145,8 @@ path/to/katago.exe gtp -model path/to/.bin.gz -config path/to/gtp_cus If you want to use ONNX Runtime + OpenVINO on Intel NPU: * Install Intel NPU driver: https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html * Install OpenVINO archive package (Windows): https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html -* Build ONNX Runtime with OpenVINO EP for NPU (`use_openvino=NPU`): https://onnxruntime.ai/docs/build/eps.html#openvino -* See [Compiling.md](Compiling.md) for the full build/copy steps for `cpp/external/onnxruntime-win-x64-openvino`. +* Typical install root looks like: `C:\Program Files (x86)\Intel\openvino_2026.0` +* Add `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\bin\intel64\Release` and `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\3rdparty\tbb\bin` to System PATH Minimal commands: ``` diff --git a/cpp/neuralnet/onnxbackend.cpp b/cpp/neuralnet/onnxbackend.cpp index 551fc5d4ba..4a537a977e 100644 --- a/cpp/neuralnet/onnxbackend.cpp +++ b/cpp/neuralnet/onnxbackend.cpp @@ -236,7 +236,7 @@ struct ComputeContext { nnXLen(xLen), nnYLen(yLen), providerName(provider), - openvinoDeviceType("CPU"), + openvinoDeviceType("NPU"), openvinoDeviceId(""), openvinoEnableNPUFastCompile(false), openvinoCacheDir(""), From 496bb964460e7b659bb38da6fb30d1159f3883ca Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 17 Mar 2026 07:29:50 +0800 Subject: [PATCH 22/37] Add Linux Intel NPU support --- Compiling.md | 130 ++++++++++++++++++++++++++++++++++++++----- README.md | 30 ++++++++-- cpp/CMakeLists.txt | 136 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 246 insertions(+), 50 deletions(-) diff --git a/Compiling.md b/Compiling.md index eda612daed..3908e8350c 100644 --- a/Compiling.md +++ b/Compiling.md @@ -56,6 +56,79 @@ As also mentioned in the instructions below but repeated here for visibility, if * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device when you run it (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). +##### ONNX Runtime Backend (Linux) +The ONNX backend uses ONNX Runtime for inference, and supports both: +* `.onnx` models loaded directly. +* `.bin.gz` KataGo models via internal conversion to ONNX graph (requires ONNX protobuf dependencies in CMake). + +##### Linux Intel NPU (OpenVINO EP) Setup +1. Install Intel NPU driver on Linux: + * https://github.com/intel/linux-npu-driver +2. Install OpenVINO via system package manager (APT example): + * https://docs.openvino.ai/2025/get-started/install-openvino/install-openvino-apt.html +3. Build ONNX Runtime with OpenVINO EP for NPU (same ORT flow as Windows): + * https://onnxruntime.ai/docs/build/eps.html#openvino + * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). + +##### Prepare `ONNXRUNTIME_ROOT` in KataGo (Linux) +Use package root: +* `cpp/external/onnxruntime-linux-x64-openvino` + +Linux one-to-one mapping (`` -> KataGo): + +Include files: + +| Source (``) | Destination (KataGo) | +| --- | --- | +| `include/core/*` | `cpp/external/onnxruntime-linux-x64-openvino/include/core/` | +| `include/cpu_provider_factory.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/cpu_provider_factory.h` | +| `include/provider_options.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/provider_options.h` | +| `include/onnxruntime_c_api.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_c_api.h` | +| `include/onnxruntime_cxx_api.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_cxx_api.h` | +| `include/onnxruntime_cxx_inline.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_cxx_inline.h` | +| `include/onnxruntime_env_config_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_env_config_keys.h` | +| `include/onnxruntime_ep_c_api.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_ep_c_api.h` | +| `include/onnxruntime_ep_device_ep_metadata_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_ep_device_ep_metadata_keys.h` | +| `include/onnxruntime_float16.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_float16.h` | +| `include/onnxruntime_lite_custom_op.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_lite_custom_op.h` | +| `include/onnxruntime_run_options_config_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_run_options_config_keys.h` | +| `include/onnxruntime_session_options_config_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_session_options_config_keys.h` | + +Library/config/pkgconfig files: + +| Source (``) | Destination (KataGo) | +| --- | --- | +| `lib/libonnxruntime_providers_openvino.so` | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime_providers_openvino.so` | +| `lib/libonnxruntime_providers_shared.so` | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime_providers_shared.so` | +| `lib/libonnxruntime.so.1.24.3` | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime.so.1.24.3` | +| `lib/libonnxruntime.so.1` (symlink to `.1.24.3`) | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime.so.1` | +| `lib/libonnxruntime.so` (symlink to `.1`) | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime.so` | +| `lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | +| `lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | +| `lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | +| `lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | +| `lib/pkgconfig/libonnxruntime.pc` | `cpp/external/onnxruntime-linux-x64-openvino/lib/pkgconfig/libonnxruntime.pc` | + +##### Minimal KataGo Build Commands (Linux, ONNX backend) +On Linux, `KATAGO_AUTO_FETCH_DEPS=ON` can auto-fetch missing `zlib`, `onnx`, and `protobuf` dependencies via vcpkg into `cpp/build/deps/vcpkg`. + +```bash +cmake -S cpp -B cpp/build -G Ninja -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-linux-x64-openvino +cmake --build cpp/build -j +``` + +If you want to disable auto-fetch and provide dependencies manually: +* `-DKATAGO_AUTO_FETCH_DEPS=OFF` +* plus `-DONNX_INCLUDE_DIR=... -DONNX_PROTO_LIB=... -DPROTOBUF_INCLUDE_DIR=... -DPROTOBUF_LIB=... -DZLIB_INCLUDE_DIR=... -DZLIB_LIBRARY=...` + +Typical run config for Intel NPU: +* `onnxProvider = openvino` +* `onnxOpenVINODeviceType = NPU` +* `onnxOpenVINOEnableNPUFastCompile = true` (optional; may be ignored on ORT builds that do not support this key) + +Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). +For `onnxProvider=openvino` on Intel NPU, a single device is typically used. + ## Windows * TLDR: @@ -136,21 +209,48 @@ The ONNX backend uses ONNX Runtime for inference, and supports both: * https://onnxruntime.ai/docs/build/eps.html#openvino * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). -##### Prepare `ONNXRUNTIME_ROOT` in KataGo -Create: -* `cpp/external/onnxruntime-win-x64-openvino/include` -* `cpp/external/onnxruntime-win-x64-openvino/lib` - -Copy from your ONNX Runtime build/package output (``) to KataGo: -* `/include/*` -> `cpp/external/onnxruntime-win-x64-openvino/include/` -* `/lib/onnxruntime.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.lib` -* `/lib/onnxruntime.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.dll` -* `/lib/onnxruntime_providers_shared.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.dll` -* `/lib/onnxruntime_providers_openvino.dll` -> `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.dll` - -Optional if present in your ORT output: -* `/lib/onnxruntime_providers_shared.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` -* `/lib/onnxruntime_providers_openvino.lib` -> `cpp/external/onnxruntime-win-x64-openvino/lib/` +##### Prepare `ONNXRUNTIME_ROOT` in KataGo (Windows) +Use package root: +* `cpp/external/onnxruntime-win-x64-openvino` + +Windows one-to-one mapping (`` -> KataGo): + +Windows and Linux generally share the same ORT include/config layout. +The main differences are binary file names/extensions (`.dll/.lib` vs `.so`). + +Include files: + +| Source (``) | Destination (KataGo) | +| --- | --- | +| `include/core/*` | `cpp/external/onnxruntime-win-x64-openvino/include/core/` | +| `include/cpu_provider_factory.h` | `cpp/external/onnxruntime-win-x64-openvino/include/cpu_provider_factory.h` | +| `include/provider_options.h` | `cpp/external/onnxruntime-win-x64-openvino/include/provider_options.h` | +| `include/onnxruntime_c_api.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_c_api.h` | +| `include/onnxruntime_cxx_api.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_cxx_api.h` | +| `include/onnxruntime_cxx_inline.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_cxx_inline.h` | +| `include/onnxruntime_env_config_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_env_config_keys.h` | +| `include/onnxruntime_ep_c_api.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_ep_c_api.h` | +| `include/onnxruntime_ep_device_ep_metadata_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_ep_device_ep_metadata_keys.h` | +| `include/onnxruntime_float16.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_float16.h` | +| `include/onnxruntime_lite_custom_op.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_lite_custom_op.h` | +| `include/onnxruntime_run_options_config_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_run_options_config_keys.h` | +| `include/onnxruntime_session_options_config_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_session_options_config_keys.h` | + +Library/config/pkgconfig files: + +| Source (``) | Destination (KataGo) | +| --- | --- | +| `lib/onnxruntime.lib` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.lib` | +| `lib/onnxruntime.dll` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.dll` | +| `lib/onnxruntime_providers_shared.dll` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.dll` | +| `lib/onnxruntime_providers_openvino.dll` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.dll` | +| `lib/onnxruntime_providers_shared.lib` (optional import lib) | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.lib` | +| `lib/onnxruntime_providers_openvino.lib` (optional import lib) | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.lib` | +| `lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | +| `lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | +| `lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | +| `lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | +| `lib/pkgconfig/libonnxruntime.pc` (optional) | `cpp/external/onnxruntime-win-x64-openvino/lib/pkgconfig/libonnxruntime.pc` | ##### Minimal KataGo Build Commands (Windows, ONNX backend) On Windows, `KATAGO_AUTO_FETCH_DEPS=ON` by default, so missing `zlib`, `onnx`, and `protobuf` dependencies are auto-fetched via vcpkg into `cpp/build/deps/vcpkg`. diff --git a/README.md b/README.md index 068ab22e51..bd9d86b426 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ - [OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen vs ONNX](#opencl-vs-cuda-vs-tensorrt-vs-rocm-vs-eigen-vs-onnx) - [How To Use](#how-to-use) - [ONNX/OpenVINO Intel NPU Quick Start (Windows)](#onnxopenvino-intel-npu-quick-start-windows) + - [ONNX/OpenVINO Intel NPU Quick Start (Linux)](#onnxopenvino-intel-npu-quick-start-linux) - [Human-style Play and Analysis](#human-style-play-and-analysis) - [Other Commands:](#other-commands) - [Tuning for Performance](#tuning-for-performance) @@ -151,16 +152,37 @@ If you want to use ONNX Runtime + OpenVINO on Intel NPU: Minimal commands: ``` # 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) -./katago.exe exportonnx -model .bin.gz -output .19x19.onnx +./katago.exe exportonnx -model .bin.gz -output .onnx # 2) Benchmark on Intel NPU (OpenVINO provider) -./katago.exe benchmark -config cpp/configs/gtp_example.cfg -model .19x19.onnx -visits 32 -threads 1 -n 2 -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU,numSearchThreads=1,numNNServerThreadsPerModel=1 +./katago.exe benchmark -config cpp/configs/gtp_example.cfg -model .onnx # 3) Run GTP for GUI tools (Sabaki/Lizzie/q5Go/etc) -./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .19x19.onnx +./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .onnx If you don't prepare config file, then use -override-config args, like: -./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .19x19.onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU +./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU +``` + +#### ONNX/OpenVINO Intel NPU Quick Start (Linux) + +If you want to use ONNX Runtime + OpenVINO on Intel NPU: +* Install Intel NPU driver (Linux): https://github.com/intel/linux-npu-driver +* Install OpenVINO via system package manager (APT example): https://docs.openvino.ai/2025/get-started/install-openvino/install-openvino-apt.html + +Minimal commands: +```bash +# 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) +./katago exportonnx -model .bin.gz -output .onnx + +# 2) Benchmark on Intel NPU (OpenVINO provider) +./katago benchmark -config cpp/configs/gtp_example.cfg -model .onnx + +# 3) Run GTP for GUI tools (Sabaki/Lizzie/q5Go/etc) +./katago gtp -config cpp/configs/gtp_example.cfg -model .onnx + +# If you don't prepare config file, use -override-config: +./katago gtp -config cpp/configs/gtp_example.cfg -model .onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU ``` #### Human-style Play and Analysis diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index b30bb964a8..1dd8ba5f74 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -58,20 +58,31 @@ set(USE_BIGGER_BOARDS_EXPENSIVE 0 CACHE BOOL "Allow boards up to size 50. Compil set(USE_CACHE_TENSORRT_PLAN 0 CACHE BOOL "Use TENSORRT plan cache. May use a lot of disk space. Only applies when USE_BACKEND is TENSORRT.") mark_as_advanced(USE_CACHE_TENSORRT_PLAN) -if(WIN32) +if(WIN32 OR (UNIX AND NOT APPLE)) set(_katago_auto_fetch_default ON) else() set(_katago_auto_fetch_default OFF) endif() -option(KATAGO_AUTO_FETCH_DEPS "Automatically fetch missing dependencies into build/deps (Windows uses vcpkg)." ${_katago_auto_fetch_default}) +option(KATAGO_AUTO_FETCH_DEPS "Automatically fetch missing dependencies into build/deps (Windows/Linux use vcpkg)." ${_katago_auto_fetch_default}) set(KATAGO_DEPS_DIR "${CMAKE_SOURCE_DIR}/build/deps" CACHE PATH "Directory for auto-fetched third-party dependencies") -set(KATAGO_VCPKG_TRIPLET "x64-windows" CACHE STRING "vcpkg triplet used by KATAGO_AUTO_FETCH_DEPS on Windows") +if(WIN32) + set(_katago_vcpkg_triplet_default "x64-windows") +elseif(UNIX AND NOT APPLE) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$") + set(_katago_vcpkg_triplet_default "arm64-linux") + else() + set(_katago_vcpkg_triplet_default "x64-linux") + endif() +else() + set(_katago_vcpkg_triplet_default "x64-windows") +endif() +set(KATAGO_VCPKG_TRIPLET "${_katago_vcpkg_triplet_default}" CACHE STRING "vcpkg triplet used by KATAGO_AUTO_FETCH_DEPS") set(KATAGO_VCPKG_ROOT "${KATAGO_DEPS_DIR}/vcpkg" CACHE PATH "Path to local vcpkg clone used by KATAGO_AUTO_FETCH_DEPS") mark_as_advanced(KATAGO_VCPKG_TRIPLET KATAGO_VCPKG_ROOT) function(katago_vcpkg_bootstrap_if_needed) - if(NOT WIN32) - message(FATAL_ERROR "katago_vcpkg_bootstrap_if_needed is only supported on Windows") + if(NOT WIN32 AND NOT (UNIX AND NOT APPLE)) + message(FATAL_ERROR "katago_vcpkg_bootstrap_if_needed is only supported on Windows and Linux") endif() if(NOT KATAGO_AUTO_FETCH_DEPS) @@ -80,7 +91,13 @@ function(katago_vcpkg_bootstrap_if_needed) file(MAKE_DIRECTORY "${KATAGO_DEPS_DIR}") - if(NOT EXISTS "${KATAGO_VCPKG_ROOT}/vcpkg.exe") + if(WIN32) + set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg.exe") + else() + set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg") + endif() + + if(NOT EXISTS "${_katago_vcpkg_exe}") if(NOT EXISTS "${KATAGO_VCPKG_ROOT}/.git") find_package(Git QUIET) if(NOT GIT_FOUND) @@ -99,11 +116,19 @@ function(katago_vcpkg_bootstrap_if_needed) endif() message(STATUS "Auto-fetch deps: bootstrapping vcpkg") - execute_process( - COMMAND "${KATAGO_VCPKG_ROOT}/bootstrap-vcpkg.bat" -disableMetrics - WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" - RESULT_VARIABLE _bootstrap_result - ) + if(WIN32) + execute_process( + COMMAND "${KATAGO_VCPKG_ROOT}/bootstrap-vcpkg.bat" -disableMetrics + WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" + RESULT_VARIABLE _bootstrap_result + ) + else() + execute_process( + COMMAND sh "${KATAGO_VCPKG_ROOT}/bootstrap-vcpkg.sh" -disableMetrics + WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" + RESULT_VARIABLE _bootstrap_result + ) + endif() if(NOT _bootstrap_result EQUAL 0) message(FATAL_ERROR "Failed to bootstrap vcpkg") endif() @@ -111,16 +136,21 @@ function(katago_vcpkg_bootstrap_if_needed) endfunction() function(katago_vcpkg_install_if_needed package_name) - if(NOT WIN32) - message(FATAL_ERROR "katago_vcpkg_install_if_needed is only supported on Windows") - endif() - katago_vcpkg_bootstrap_if_needed() + if(WIN32) + set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg.exe") + else() + set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg") + endif() + if(NOT EXISTS "${_katago_vcpkg_exe}") + message(FATAL_ERROR "vcpkg executable not found after bootstrap: ${_katago_vcpkg_exe}") + endif() + set(_spec "${package_name}:${KATAGO_VCPKG_TRIPLET}") message(STATUS "Auto-fetch deps: ensuring ${_spec} via vcpkg") execute_process( - COMMAND "${KATAGO_VCPKG_ROOT}/vcpkg.exe" install "${_spec}" --disable-metrics + COMMAND "${_katago_vcpkg_exe}" install "${_spec}" --disable-metrics WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" RESULT_VARIABLE _install_result ) @@ -682,6 +712,8 @@ elseif(USE_BACKEND STREQUAL "ONNX") if(WIN32) set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-win-x64-openvino") + elseif(UNIX AND NOT APPLE) + set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-linux-x64-openvino") else() set(_onnx_default_root "") endif() @@ -714,6 +746,8 @@ elseif(USE_BACKEND STREQUAL "ONNX") set(ONNX_PROTO_LIB "" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)") set(PROTOBUF_INCLUDE_DIR "" CACHE PATH "Directory containing google/protobuf/message.h (required for .bin.gz -> ONNX conversion)") set(PROTOBUF_LIB "" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)") + set(ONNX_PROTO_TARGET "" CACHE STRING "Imported CMake target for onnx_proto (optional, preferred over ONNX_PROTO_LIB)") + set(PROTOBUF_TARGET "" CACHE STRING "Imported CMake target for protobuf (optional, preferred over PROTOBUF_LIB)") mark_as_advanced(CLEAR ONNX_INCLUDE_DIR ONNX_PROTO_LIB PROTOBUF_INCLUDE_DIR PROTOBUF_LIB) # Backward compatibility with older cache variable name. @@ -721,7 +755,11 @@ elseif(USE_BACKEND STREQUAL "ONNX") set(PROTOBUF_LIB "${PROTOBUF_LITE_LIB}") endif() - if(WIN32 AND KATAGO_AUTO_FETCH_DEPS) + if(KATAGO_AUTO_FETCH_DEPS) + set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") + endif() + + if(KATAGO_AUTO_FETCH_DEPS) set(_need_onnx_proto_deps FALSE) if(NOT ONNX_INCLUDE_DIR OR NOT ONNX_PROTO_LIB OR NOT PROTOBUF_INCLUDE_DIR OR NOT PROTOBUF_LIB) set(_need_onnx_proto_deps TRUE) @@ -733,41 +771,76 @@ elseif(USE_BACKEND STREQUAL "ONNX") if(EXISTS "${_katago_vcpkg_installed_root}/include/onnx/onnx-ml.pb.h") set(ONNX_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Directory containing onnx/onnx-ml.pb.h (required for .bin.gz -> ONNX conversion)" FORCE) endif() - if(EXISTS "${_katago_vcpkg_installed_root}/lib/onnx_proto.lib") - set(ONNX_PROTO_LIB "${_katago_vcpkg_installed_root}/lib/onnx_proto.lib" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)" FORCE) + find_library(_katago_onnx_proto_lib NAMES onnx_proto HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) + if(_katago_onnx_proto_lib) + set(ONNX_PROTO_LIB "${_katago_onnx_proto_lib}" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)" FORCE) endif() if(EXISTS "${_katago_vcpkg_installed_root}/include/google/protobuf/message.h") set(PROTOBUF_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Directory containing google/protobuf/message.h (required for .bin.gz -> ONNX conversion)" FORCE) endif() - if(EXISTS "${_katago_vcpkg_installed_root}/lib/libprotobuf-lite.lib") - set(PROTOBUF_LIB "${_katago_vcpkg_installed_root}/lib/libprotobuf-lite.lib" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)" FORCE) - elseif(EXISTS "${_katago_vcpkg_installed_root}/lib/libprotobuf.lib") - set(PROTOBUF_LIB "${_katago_vcpkg_installed_root}/lib/libprotobuf.lib" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)" FORCE) + find_library(_katago_protobuf_lib NAMES protobuf-lite libprotobuf-lite protobuf libprotobuf HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) + if(_katago_protobuf_lib) + set(PROTOBUF_LIB "${_katago_protobuf_lib}" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)" FORCE) endif() endif() endif() + # Prefer config-mode packages (vcpkg provides these) so transitive dependencies + # like absl/utf8_range are linked automatically. + if(_katago_vcpkg_installed_root) + list(APPEND CMAKE_PREFIX_PATH "${_katago_vcpkg_installed_root}") + endif() + if(NOT ONNX_PROTO_TARGET) + find_package(ONNX CONFIG QUIET) + if(TARGET ONNX::onnx_proto) + set(ONNX_PROTO_TARGET "ONNX::onnx_proto") + endif() + endif() + if(NOT PROTOBUF_TARGET) + if(_katago_vcpkg_installed_root AND EXISTS "${_katago_vcpkg_installed_root}/share/protobuf/protobuf-config.cmake") + set(protobuf_DIR "${_katago_vcpkg_installed_root}/share/protobuf") + endif() + find_package(protobuf CONFIG QUIET) + if(NOT TARGET protobuf::libprotobuf AND NOT TARGET protobuf::libprotobuf-lite) + find_package(Protobuf CONFIG QUIET) + endif() + if(TARGET protobuf::libprotobuf) + set(PROTOBUF_TARGET "protobuf::libprotobuf") + elseif(TARGET protobuf::libprotobuf-lite) + set(PROTOBUF_TARGET "protobuf::libprotobuf-lite") + endif() + endif() + if(NOT ONNX_INCLUDE_DIR) find_path(ONNX_INCLUDE_DIR onnx/onnx-ml.pb.h) endif() - if(NOT ONNX_PROTO_LIB) + if(NOT ONNX_PROTO_LIB AND NOT ONNX_PROTO_TARGET) find_library(ONNX_PROTO_LIB onnx_proto) endif() if(NOT PROTOBUF_INCLUDE_DIR) find_path(PROTOBUF_INCLUDE_DIR google/protobuf/message.h) endif() - if(NOT PROTOBUF_LIB) - find_library(PROTOBUF_LIB protobuf-lite protobuf-lite32 libprotobuf protobuf) + if(NOT PROTOBUF_LIB AND NOT PROTOBUF_TARGET) + find_library(PROTOBUF_LIB libprotobuf protobuf protobuf-lite protobuf-lite32) endif() - if(NOT ONNX_INCLUDE_DIR OR NOT ONNX_PROTO_LIB OR NOT PROTOBUF_INCLUDE_DIR OR NOT PROTOBUF_LIB) + if(NOT ONNX_INCLUDE_DIR OR NOT PROTOBUF_INCLUDE_DIR OR (NOT ONNX_PROTO_TARGET AND NOT ONNX_PROTO_LIB) OR (NOT PROTOBUF_TARGET AND NOT PROTOBUF_LIB)) message(FATAL_ERROR "ONNX backend requires ONNX protobuf dependencies for .bin.gz model conversion. " "Set ONNX_INCLUDE_DIR (contains onnx/onnx-ml.pb.h), ONNX_PROTO_LIB, PROTOBUF_INCLUDE_DIR, and PROTOBUF_LIB.") endif() target_include_directories(katago SYSTEM PRIVATE "${ONNX_INCLUDE_DIR}") target_include_directories(katago SYSTEM PRIVATE "${PROTOBUF_INCLUDE_DIR}") - target_link_libraries(katago ${ONNX_PROTO_LIB} ${PROTOBUF_LIB}) + if(ONNX_PROTO_TARGET) + target_link_libraries(katago ${ONNX_PROTO_TARGET}) + else() + target_link_libraries(katago ${ONNX_PROTO_LIB}) + endif() + if(PROTOBUF_TARGET) + target_link_libraries(katago ${PROTOBUF_TARGET}) + else() + target_link_libraries(katago ${PROTOBUF_LIB}) + endif() if(WIN32 AND ONNXRUNTIME_DLLS) foreach(_onnxruntime_dll IN LISTS ONNXRUNTIME_DLLS) @@ -809,7 +882,7 @@ if(NO_GIT_REVISION AND (NOT BUILD_DISTRIBUTED)) target_compile_definitions(katago PRIVATE NO_GIT_REVISION) endif() -if(WIN32 AND KATAGO_AUTO_FETCH_DEPS) +if(KATAGO_AUTO_FETCH_DEPS) set(_need_zlib_deps FALSE) if(NOT ZLIB_INCLUDE_DIR OR NOT ZLIB_LIBRARY) set(_need_zlib_deps TRUE) @@ -820,8 +893,9 @@ if(WIN32 AND KATAGO_AUTO_FETCH_DEPS) if(EXISTS "${_katago_vcpkg_installed_root}/include/zlib.h") set(ZLIB_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zlib.h and other header files" FORCE) endif() - if(EXISTS "${_katago_vcpkg_installed_root}/lib/zlib.lib") - set(ZLIB_LIBRARY "${_katago_vcpkg_installed_root}/lib/zlib.lib" CACHE FILEPATH "Path to 'libz.so' on Linux or 'libz.lib' on Windows" FORCE) + find_library(_katago_zlib_lib NAMES zlib z HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) + if(_katago_zlib_lib) + set(ZLIB_LIBRARY "${_katago_zlib_lib}" CACHE FILEPATH "Path to 'libz.so' on Linux or 'libz.lib' on Windows" FORCE) endif() endif() endif() From 115e6daba5f8063fd70d7c89631f123cccced902 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 17 Mar 2026 00:00:25 +0800 Subject: [PATCH 23/37] Edit Compiling.md --- Compiling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compiling.md b/Compiling.md index 3908e8350c..d8bab07cf7 100644 --- a/Compiling.md +++ b/Compiling.md @@ -257,7 +257,7 @@ On Windows, `KATAGO_AUTO_FETCH_DEPS=ON` by default, so missing `zlib`, `onnx`, a ``` cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-win-x64-openvino -cmake --build cpp/build --config Release +cmake --build cpp/build --config Release -j ``` If you want to disable auto-fetch and provide dependencies manually: From 0b0a685d8db12b69de84195140239b6f0ea4a1b3 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 20 Apr 2026 03:15:12 +0800 Subject: [PATCH 24/37] Remove ROCm components --- Compiling.md | 5 +- README.md | 10 +- cpp/CMakeLists.txt | 176 +- cpp/README.md | 4 +- cpp/command/benchmark.cpp | 5 - cpp/main.cpp | 9 - cpp/neuralnet/rocmbackend.cpp | 3026 -------------------------------- cpp/neuralnet/rocmerrorcheck.h | 59 - cpp/neuralnet/rocmhelpers.h | 59 - cpp/neuralnet/rocmhelpers.hip | 1905 -------------------- cpp/neuralnet/rocmincludes.h | 15 - cpp/neuralnet/rocmutils.cpp | 170 -- cpp/neuralnet/rocmutils.h | 21 - cpp/program/gtpconfig.cpp | 3 - cpp/program/setup.cpp | 5 +- 15 files changed, 10 insertions(+), 5462 deletions(-) delete mode 100644 cpp/neuralnet/rocmbackend.cpp delete mode 100644 cpp/neuralnet/rocmerrorcheck.h delete mode 100644 cpp/neuralnet/rocmhelpers.h delete mode 100644 cpp/neuralnet/rocmhelpers.hip delete mode 100644 cpp/neuralnet/rocmincludes.h delete mode 100644 cpp/neuralnet/rocmutils.cpp delete mode 100644 cpp/neuralnet/rocmutils.h diff --git a/Compiling.md b/Compiling.md index d8bab07cf7..da5beed06d 100644 --- a/Compiling.md +++ b/Compiling.md @@ -33,7 +33,6 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the OpenCL backend, a modern GPU that supports OpenCL 1.2 or greater, or else something like [this](https://software.intel.com/en-us/opencl-sdk) for CPU. But if using CPU, Eigen should be better. * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. - * If using the ROCm backend, ROCm 6.4 or later and a GPU capable of supporting them. More information about installation(https://rocm.docs.amd.com/projects/install-on-linux/en/latest/) and please install all possiable ROCm developer packages, instead of just ROCm runtime packages. * If using the Eigen backend, Eigen3. With Debian packages, (i.e. apt or apt-get), this should be `libeigen3-dev`. * If using the ONNX backend, ONNX Runtime headers/libs and ONNX protobuf dependencies (`onnx/onnx-ml.pb.h`, `onnx_proto`, `protobuf-lite`) for `.bin.gz` model conversion support. * zlib, libzip. With Debian packages (i.e. apt or apt-get), these should be `zlib1g-dev`, `libzip-dev`. @@ -43,7 +42,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * `git clone https://github.com/lightvector/KataGo.git` * Compile using CMake and make in the cpp directory: * `cd KataGo/cpp` - * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` or `cmake . -DUSE_BACKEND=ROCM` or `cmake . -DUSE_BACKEND=ONNX` depending on which backend you want. + * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` or `cmake . -DUSE_BACKEND=ONNX` depending on which backend you want. * Specify also `-DUSE_TCMALLOC=1` if using TCMalloc. * Compiling will also call git commands to embed the git hash into the compiled executable, specify also `-DNO_GIT_REVISION=1` to disable it if this is causing issues for you. * Specify `-DUSE_AVX2=1` to also compile Eigen with AVX2 and FMA support, which will make it incompatible with old CPUs but much faster. (If you want to go further, you can also add `-DCMAKE_CXX_FLAGS='-march=native'` which will specialize to precisely your machine's CPU, but the exe might not run on other machines at all). @@ -168,7 +167,7 @@ For `onnxProvider=openvino` on Intel NPU, a single device is typically used. -DLIBZIP_INCLUDE_DIR_ZIPCONF:PATH="C:/msys64/mingw64/include" -DLIBZIP_LIBRARY:FILEPATH="C:/msys64/mingw64/lib/libzip.dll.a" ``` - * Also set `USE_BACKEND` to `OPENCL`, or `CUDA`, or `TENSORRT`, or `EIGEN`, or `ROCM`, or `ONNX` depending on what backend you want to use. + * Also set `USE_BACKEND` to `OPENCL`, or `CUDA`, or `TENSORRT`, or `EIGEN`, or `ONNX` depending on what backend you want to use. * Set any other options you want and re-run "Configure" again as needed after setting them. Such as: * `NO_GIT_REVISION` if you don't have Git or if cmake is not finding it. * `NO_LIBZIP` if you don't care about running self-play training and you don't have libzip. diff --git a/README.md b/README.md index bd9d86b426..7799285ed6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - [GUIs](#guis) - [Windows and Linux](#windows-and-linux) - [MacOS](#macos) - - [OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen vs ONNX](#opencl-vs-cuda-vs-tensorrt-vs-rocm-vs-eigen-vs-onnx) + - [OpenCL vs CUDA vs TensorRT vs Eigen vs ONNX](#opencl-vs-cuda-vs-tensorrt-vs-eigen-vs-onnx) - [How To Use](#how-to-use) - [ONNX/OpenVINO Intel NPU Quick Start (Windows)](#onnxopenvino-intel-npu-quick-start-windows) - [ONNX/OpenVINO Intel NPU Quick Start (Linux)](#onnxopenvino-intel-npu-quick-start-linux) @@ -89,8 +89,8 @@ The community also provides KataGo packages for [Homebrew](https://brew.sh) on M Use `brew install katago`. The latest config files and networks are installed in KataGo's `share` directory. Find them via `brew list --verbose katago`. A basic way to run katago will be `katago gtp -config $(brew list --verbose katago | grep 'gtp.*\.cfg') -model $(brew list --verbose katago | grep .gz | head -1)`. You should choose the Network according to the release notes here and customize the provided example config as with every other way of installing KataGo. -### OpenCL vs CUDA vs TensorRT vs ROCm vs Eigen vs ONNX -KataGo has six backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), ROCm (GPU), Eigen (CPU), and ONNX (CPU/GPU/NPU via providers). +### OpenCL vs CUDA vs TensorRT vs Eigen vs ONNX +KataGo has five backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), Eigen (CPU), and ONNX (CPU/GPU/NPU via providers). The quick summary is: * **To easily get something working, try OpenCL if you have any good or decent GPU.** @@ -98,14 +98,12 @@ The quick summary is: * Use Eigen with AVX2 if you don't have a GPU or if your GPU is too old/weak to work with OpenCL, and you just want a plain CPU KataGo. * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. * The CUDA backend can work for NVIDIA GPUs with CUDA+CUDNN installed but is likely worse than TensorRT. - * The ROCm backend can work for AMD GPUs with ROCm+MIOpen installed. * ONNX backend uses ONNX Runtime execution providers (CPU/OpenVINO/CUDA/TensorRT/MIGraphX/CoreML). It is useful for Intel NPU (OpenVINO) and raw `.onnx` models. More in detail: * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. On most GPUs, the OpenCL implementation will actually beat NVIDIA's own CUDA/CUDNN at performance. The exception is for top-end NVIDIA GPUs that support FP16 and tensor cores, in which case sometimes one is better and sometimes the other is better. * TensorRT is similar to CUDA, but only uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs, it should work whenever CUDA does and will usually be faster than CUDA or any other backend. - * ROCm is a GPU backend specific to AMD GPUs (it will not work with NVIDIA or Intel or any other GPUs) and requires installing [ROCm](https://rocm.docs.amd.com) and [MIOpen](https://rocm.docs.amd.com/projects/MIOpen) and a modern AMD GPU. On most GPUs, the OpenCL implementation will actually beat AMD's own ROCm/MIOpen at performance. The exception is for top-end AMD GPUs that support FP16 and stream processors, in which case sometimes one is better and sometimes the other is better. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, OpenVINO for Intel hardware (including NPU on supported systems), CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers, while OpenVINO NPU setups are typically single-device. @@ -228,8 +226,6 @@ This section summarizes a number of common questions and issues when running Kat #### Issues with specific GPUs or GPU drivers If you are observing any crashes in KataGo while attempting to run the benchmark or the program itself, and you have one of the below GPUs, then this is likely the reason. -* **AMD GPUs** - If you choose to use ROCm backend, uou need a GPU supported with official [System requirements lists](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html) (at least AMD Radeon RX 7700 XT). And ROCm backend only supports Linux now, because MIOpen and CMake HIP Language doesn't support Windows at this moment. We suggest installing the lastest version of ROCm developer stack. - * **AMD Radeon RX 5700** - AMD's drivers for OpenCL for this GPU have been buggy ever since this GPU was released, and as of May 2020 AMD has still never released a fix. If you are using this GPU, you will just not be able to run KataGo (Leela Zero and other Go engines will probably fail too) and will probably also obtain incorrect calculations or crash if doing anything else scientific or mathematical that uses OpenCL. See for example these reddit threads: [[1]](https://www.reddit.com/r/Amd/comments/ebso1x/its_not_just_setihome_any_mathematic_or/) or [[2]](https://www.reddit.com/r/BOINC/comments/ebiz18/psa_please_remove_your_amd_rx5700xt_from_setihome/) or this [L19 thread](https://lifein19x19.com/viewtopic.php?f=18&t=17093). * **OpenCL Mesa** - These drivers for OpenCL are buggy. Particularly if on startup before crashing you see KataGo printing something like `Found OpenCL Platform 0: ... (Mesa) (OpenCL 1.1 Mesa ...) ...` diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 1dd8ba5f74..0dacaa0b9b 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,22 +1,6 @@ cmake_minimum_required(VERSION 3.18.2) if(USE_BACKEND STREQUAL "METAL") project(katago LANGUAGES CXX Swift) -elseif(USE_BACKEND STREQUAL "ROCM") - if(WIN32) - # Windows: Use clang++ from HIP SDK (hipcc doesn't work well on Windows) - # User can override with -DCMAKE_CXX_COMPILER if needed - if(NOT DEFINED CMAKE_CXX_COMPILER) - if(DEFINED ENV{HIP_PATH}) - set(CMAKE_CXX_COMPILER "$ENV{HIP_PATH}/bin/clang++.exe" CACHE FILEPATH "" FORCE) - set(CMAKE_C_COMPILER "$ENV{HIP_PATH}/bin/clang.exe" CACHE FILEPATH "" FORCE) - endif() - endif() - else() - # Linux: Use hipcc - set(CMAKE_C_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) - set(CMAKE_CXX_COMPILER /opt/rocm/bin/hipcc CACHE FILEPATH "" FORCE) - endif() - project(katago LANGUAGES C CXX HIP) else() project(katago) endif() @@ -48,7 +32,7 @@ endif() set(BUILD_DISTRIBUTED 0 CACHE BOOL "Build with http support for contributing to distributed training") set(USE_BACKEND CACHE STRING "Neural net backend") string(TOUPPER "${USE_BACKEND}" USE_BACKEND) -set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN ROCM ONNX) +set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN ONNX) set(USE_TCMALLOC 0 CACHE BOOL "Use TCMalloc") set(NO_GIT_REVISION 0 CACHE BOOL "Disable embedding the git revision into the compiled exe") @@ -268,51 +252,6 @@ elseif(USE_BACKEND STREQUAL "ONNX") neuralnet/onnxbackend.cpp neuralnet/onnxmodelbuilder.cpp ) -# --------------------------- ROCM backend(AMD GPU / HIP MIOpen) --------------------------- -elseif(USE_BACKEND STREQUAL "ROCM") - message(STATUS "-DUSE_BACKEND=ROCM, using AMD ROCm backend.") - - enable_language(HIP) - set(CMAKE_HIP_STANDARD 17) - - if(CMAKE_PREFIX_PATH STREQUAL "" OR NOT DEFINED CMAKE_PREFIX_PATH) - if(WIN32) - # Windows: HIP SDK installed via installer or manually - if(DEFINED ENV{HIP_PATH}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{HIP_PATH}") - message(STATUS "Auto-detected HIP_PATH=$ENV{HIP_PATH} → CMAKE_PREFIX_PATH") - elseif(DEFINED ENV{ROCM_PATH}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{ROCM_PATH}") - message(STATUS "Auto-detected ROCM_PATH=$ENV{ROCM_PATH} → CMAKE_PREFIX_PATH") - else() - message(WARNING "HIP_PATH or ROCM_PATH environment variable not set. Please install HIP SDK for Windows.") - endif() - else() - # Linux: Standard ROCm installation path - if(EXISTS "/opt/rocm") - list(APPEND CMAKE_PREFIX_PATH "/opt/rocm") - message(STATUS "CMAKE_PREFIX_PATH not given; defaulting to /opt/rocm") - endif() - endif() - endif() - - # Users can -DCMAKE_HIP_ARCHITECTURES=gfx90a;gfx942 manually specify GFX architectures - if(NOT DEFINED CMAKE_HIP_ARCHITECTURES) - # Default compile MI200 / RDNA3 cards, can be simplified as needed - # set(CMAKE_HIP_ARCHITECTURES gfx950 gfx942 gfx90a gfx908 gfx1100 gfx1101 gfx1151 gfx1201 gfx1030 CACHE STRING "AMD GPU targets") - add_compile_definitions(-DGPU_TARGETS=gfx950,gfx942,gfx90a,gfx908,gfx1100,gfx1101,gfx1151,gfx1201,gfx1030) - endif() - - # 2) Specify backend source code. rocmhelpers.hip contains GPU kernels, don't forget it - set(NEURALNET_BACKEND_SOURCES - neuralnet/rocmbackend.cpp - neuralnet/rocmutils.cpp - neuralnet/rocmhelpers.hip - ) - - # Optional: Enable model-size‑based autotuning and other macros - # add_compile_definitions(HIP_SUPPORTS_FP16) - elseif(USE_BACKEND STREQUAL "") message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN or -DUSE_BACKEND=ONNX to compile with the respective backend.${ColorReset}") set(NEURALNET_BACKEND_SOURCES neuralnet/dummybackend.cpp) @@ -596,117 +535,6 @@ elseif(USE_BACKEND STREQUAL "OPENCL") link_directories(${OpenCL_LIBRARY}) target_link_libraries(katago ${OpenCL_LIBRARY}) endif() -# --------------------------- ROCM linking stage --------------------------- -elseif(USE_BACKEND STREQUAL "ROCM") - # Macro: used in source code with #ifdef USE_ROCM_BACKEND - target_compile_definitions(katago PRIVATE USE_ROCM_BACKEND) - target_compile_definitions(katago PRIVATE HIP_TARGET_VERSION=${CMAKE_HIP_COMPILER_VERSION}) - - # Option to disable FP16 support - set(ROCM_DISABLE_FP16 OFF CACHE BOOL "Disable FP16 support for ROCm backend") - - string(TOLOWER "${CMAKE_HIP_ARCHITECTURES}" _gfxlist) # e.g. "90a;942" - if(_gfxlist MATCHES "803|900|90a|94[0-9]|110[0-9]|120[0-9]|115[0-9]|1030") - if(ROCM_DISABLE_FP16) - message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}), but ROCM_DISABLE_FP16 is set, NOT defining HIP_SUPPORTS_FP16") - else() - target_compile_definitions(katago PRIVATE HIP_SUPPORTS_FP16) - message(STATUS "Detected FP16‑capable GFX arch (${CMAKE_HIP_ARCHITECTURES}); defining HIP_SUPPORTS_FP16") - endif() - endif() - - # 3) Find ROCm runtime & libraries. Since ROCm 6.x, CMake config-mode packages are included. If not found, add -DCMAKE_PREFIX_PATH=/opt/rocm (Linux) or HIP SDK path (Windows) - find_package(hip QUIET CONFIG) # Export hip::device / hip::host - find_package(hipblas QUIET CONFIG) # Export roc::hipblas - find_package(miopen QUIET CONFIG) # Export roc::miopen or MIOpen - - # ---------- fallback:HIP Runtime ---------- - if(NOT hip_FOUND) - if(WIN32) - # Windows: Search in HIP SDK installation - find_path(HIP_INCLUDE_DIR hip/hip_runtime.h - HINTS ${CMAKE_PREFIX_PATH} ENV HIP_PATH ENV ROCM_PATH - PATH_SUFFIXES include) - find_library(HIP_RUNTIME_LIB - NAMES amdhip64 amdhip64_6 - HINTS ${CMAKE_PREFIX_PATH} ENV HIP_PATH ENV ROCM_PATH - PATH_SUFFIXES lib bin) - else() - # Linux: Search in /opt/rocm - find_path(HIP_INCLUDE_DIR hip/hip_runtime.h - HINTS ${CMAKE_PREFIX_PATH} /opt/rocm - PATH_SUFFIXES include) - find_library(HIP_RUNTIME_LIB amdhip64 - HINTS ${CMAKE_PREFIX_PATH} /opt/rocm - PATH_SUFFIXES lib lib64) - endif() - - if(NOT HIP_INCLUDE_DIR OR NOT HIP_RUNTIME_LIB) - if(WIN32) - message(FATAL_ERROR "HIP headers or runtime NOT found; install HIP SDK for Windows or set CMAKE_PREFIX_PATH to HIP SDK installation path.") - else() - message(FATAL_ERROR "HIP headers or runtime NOT found; install ROCm or set CMAKE_PREFIX_PATH.") - endif() - endif() - add_library(hip::device UNKNOWN IMPORTED) - set_target_properties(hip::device PROPERTIES - IMPORTED_LOCATION "${HIP_RUNTIME_LIB}" - INTERFACE_INCLUDE_DIRECTORIES "${HIP_INCLUDE_DIR}") - target_include_directories(katago SYSTEM PRIVATE ${HIP_INCLUDE_DIR}) - endif() - - # ---------- fallback:hipBLAS / MIOpen ---------- - foreach(_pkg hipblas miopen) - if(NOT ${_pkg}_FOUND) - if(WIN32) - # Windows naming conventions - if(_pkg STREQUAL "hipblas") - set(_lib_names hipblas) - else() - set(_lib_names MIOpen) - endif() - find_library(${_pkg}_LIB - NAMES ${_lib_names} - HINTS ${CMAKE_PREFIX_PATH} ENV HIP_PATH ENV ROCM_PATH - PATH_SUFFIXES lib bin) - else() - # Linux naming - find_library(${_pkg}_LIB ${_pkg} - HINTS ${CMAKE_PREFIX_PATH} /opt/rocm - PATH_SUFFIXES lib lib64) - endif() - - if(${_pkg}_LIB) - add_library(roc::${_pkg} UNKNOWN IMPORTED) - set_target_properties(roc::${_pkg} PROPERTIES - IMPORTED_LOCATION "${${_pkg}_LIB}") - target_include_directories(katago SYSTEM PRIVATE ${HIP_INCLUDE_DIR}) - message(STATUS "Found ${_pkg} at ${${_pkg}_LIB}") - else() - if(WIN32) - message(FATAL_ERROR "Required ROCm component ${_pkg} not found – install HIP SDK for Windows or set CMAKE_PREFIX_PATH.") - else() - message(FATAL_ERROR "Required ROCm component ${_pkg} not found – install it or set CMAKE_PREFIX_PATH.") - endif() - endif() - endif() - endforeach() - - # 4) Link libraries - # Note: On Windows, MIOpen might need to be linked as "MIOpen" directly if the target doesn't exist - if(TARGET MIOpen) - set(_miopen_target MIOpen) - elseif(TARGET roc::miopen) - set(_miopen_target roc::miopen) - else() - set(_miopen_target roc::miopen) - endif() - - target_link_libraries(katago - hip::device # HIP runtime & kernel offload - roc::hipblas # BLAS - ${_miopen_target} # DNN primitives - ) elseif(USE_BACKEND STREQUAL "ONNX") target_compile_definitions(katago PRIVATE USE_ONNX_BACKEND) @@ -998,7 +826,7 @@ if(MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") message(STATUS "Setting up build for GNU, Clang or MinGW.") - if(NOT (${CMAKE_SYSTEM_PROCESSOR} MATCHES "(arm|aarch32|aarch64)") AND NOT USE_BACKEND STREQUAL "ROCM") + if(NOT (${CMAKE_SYSTEM_PROCESSOR} MATCHES "(arm|aarch32|aarch64)")) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse") else() # For ARM architecture, as a hack, ensure that char is signed diff --git a/cpp/README.md b/cpp/README.md index 6f5f95ad78..dabcef5b53 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -9,13 +9,13 @@ Summary of source folders, in approximate dependency order, from lowest level to * `board.{cpp,h}` - Raw board implementation, without move history. Helper functions for Benson's algorithm and ladder search. * `boardhistory.{cpp,h}` - Datastructure that does include move history - handles superko, passing, game end, final scoring, komi, handicap detection, etc. * `graphhash.{cpp,h}` - History-sensitive hash used for [monte-carlo graph search](https://github.com/lightvector/KataGo/blob/master/docs/GraphSearch.md). -* `neuralnet` - Neural net GPU implementation and interface. Contains OpenCL, CUDA, TensorRT, ROCm, Metal, Eigen, and ONNX backends along with common interfaces and model data structures. +* `neuralnet` - Neural net GPU implementation and interface. Contains OpenCL, CUDA, TensorRT, Metal, Eigen, and ONNX backends along with common interfaces and model data structures. * `desc.{cpp,h}` - Data structure holding neural net structure and weights. * `modelversion.{cpp,h}` - Enumerates the various versions of neural net features and models. * `nninputs.{cpp,h}` - Implements the input features for the neural net. * `sgfmetadata.{cpp,h}` - Implements the input features for the [HumanSL neural net](https://github.com/lightvector/KataGo/blob/master/docs/Analysis_Engine.md#human-sl-analysis-guide), for conditioning on various SGF metadata about human players from training data. * `nninterface.h` - Common interface that is implemented by every low-level neural net backend. - * `{cuda,opencl,eigen,trt,rocm,metal,onnx,dummy}backend.cpp` - Various backends. + * `{cuda,opencl,eigen,trt,metal,onnx,dummy}backend.cpp` - Various backends. * `onnxmodelbuilder.{cpp,h}` - Builds ONNX graphs from KataGo model weights for ONNX Runtime. * `nneval.{cpp,h}` - Top-level handle to the neural net used by the rest of the engine, implements thread-safe batching of queries. * `search` - The main search engine. diff --git a/cpp/command/benchmark.cpp b/cpp/command/benchmark.cpp index 63ad26e578..daff8c30f7 100644 --- a/cpp/command/benchmark.cpp +++ b/cpp/command/benchmark.cpp @@ -265,11 +265,6 @@ int MainCmds::benchmark(const vector& args) { cout << "If you have a strong GPU capable of FP16 tensor cores (e.g. RTX2080), " << "using the Cuda version of KataGo instead may give a mild performance boost." << endl; #endif -#ifdef USE_ROCM_BACKEND - cout << "You are currently using the ROCm version of KataGo." << endl; - cout << "If you have a strong GPU capable of FP16 tensor cores (e.g. RX6900XT), " - << "using the ROCm version of KataGo instead may give a mild performance boost." << endl; -#endif #ifdef USE_EIGEN_BACKEND cout << "You are currently using the Eigen (CPU) version of KataGo. Due to having no GPU, it may be slow." << endl; #endif diff --git a/cpp/main.cpp b/cpp/main.cpp index 0d756bfc29..801e36183c 100644 --- a/cpp/main.cpp +++ b/cpp/main.cpp @@ -249,13 +249,6 @@ string Version::getKataGoVersionFullInfo() { out << "Using Metal backend" << endl; #elif defined(USE_OPENCL_BACKEND) out << "Using OpenCL backend" << endl; -#elif defined(USE_ROCM_BACKEND) - out << "Using ROCm backend" << endl; -#if defined(HIP_TARGET_VERSION) -#define STRINGIFY(x) #x -#define STRINGIFY2(x) STRINGIFY(x) - out << "Compiled with HIP runtime version " << STRINGIFY2(HIP_TARGET_VERSION) << endl; -#endif #elif defined(USE_EIGEN_BACKEND) out << "Using Eigen(CPU) backend" << endl; #elif defined(USE_ONNX_BACKEND) @@ -290,8 +283,6 @@ string Version::getGitRevisionWithBackend() { s += "-cuda"; #elif defined(USE_TENSORRT_BACKEND) s += "-trt"; -#elif defined(USE_ROCM_BACKEND) - s += "-rocm"; #elif defined(USE_METAL_BACKEND) s += "-metal"; #elif defined(USE_OPENCL_BACKEND) diff --git a/cpp/neuralnet/rocmbackend.cpp b/cpp/neuralnet/rocmbackend.cpp deleted file mode 100644 index 53e2c8d5ac..0000000000 --- a/cpp/neuralnet/rocmbackend.cpp +++ /dev/null @@ -1,3026 +0,0 @@ -#ifdef USE_ROCM_BACKEND - -#include "../neuralnet/rocmerrorcheck.h" -#include "../neuralnet/rocmincludes.h" - -#include "../neuralnet/rocmhelpers.h" -#include "../neuralnet/rocmutils.h" -#include "../neuralnet/modelversion.h" -#include "../neuralnet/nninterface.h" -#include "../neuralnet/nninputs.h" -#include "../neuralnet/sgfmetadata.h" -#include "../neuralnet/nneval.h" -#include "../neuralnet/desc.h" - -#include "../core/simpleallocator.h" -#include "../core/test.h" - -#include "../external/half-2.2.0/include/half.hpp" - -//------------------------ -#include "../core/using.h" -//------------------------ - -using half_t = half_float::half; - -//Define this to print out some of the intermediate values of the neural net -//#define DEBUG_INTERMEDIATE_VALUES - -void NeuralNet::globalInitialize() { - //Empty for cudnn backend -} - -void NeuralNet::globalCleanup() { - hipDeviceReset(); -} - -struct CudaHandles { - hipblasHandle_t cublas; - miopenHandle_t cudnn; - const int majorComputeCapability; - const int minorComputeCapability; - - CudaHandles(int major, int minor) - : majorComputeCapability(major), - minorComputeCapability(minor) - { - CUBLAS_ERR("CudaHandles",hipblasCreate(&cublas)); - CUDNN_ERR("CudaHandles",miopenCreate(&cudnn)); - } - - ~CudaHandles() { - hipblasDestroy(cublas); - miopenDestroy(cudnn); - } - - static CudaHandles* cudaHandlesTesting() { - const int gpuIdxForThisThread = 0; - hipDeviceProp_t prop; - hipGetDeviceProperties(&prop,gpuIdxForThisThread); - return new CudaHandles(prop.major, prop.minor); - } - - CudaHandles(const CudaHandles&) = delete; - CudaHandles& operator=(const CudaHandles&) = delete; -}; - -//--------------------------------------------------------------------------------- - -template -struct ByBatchSize { - const int maxBatchSize; - T* data; - miopenStatus_t (*destroyFunc)(T); - - ByBatchSize() - : maxBatchSize(0), data(nullptr), destroyFunc(nullptr) - {} - - ByBatchSize( - int maxBatchSize_ - ) : maxBatchSize(maxBatchSize_), data(nullptr), destroyFunc(nullptr) { - data = new T[maxBatchSize]; - } - - ByBatchSize(const ByBatchSize&) = delete; - ByBatchSize& operator=(const ByBatchSize&) = delete; - - ~ByBatchSize() { - if(destroyFunc != nullptr && data != nullptr) { - for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - (*destroyFunc)(data[batchSize-1]); - } - } - if(data != nullptr) { - delete[] data; - data = nullptr; - } - } - T& operator[](int batchSize) { - return data[batchSize-1]; - } - const T& operator[](int batchSize) const { - return data[batchSize-1]; - } -}; - -template -struct ByBatchSizeView { - int maxBatchSize; - T* data; - - ByBatchSizeView() - : maxBatchSize(0), data(nullptr) - {} - - ByBatchSizeView(const ByBatchSize& toView) - : maxBatchSize(toView.maxBatchSize), data(toView.data) - {} - ByBatchSizeView& operator=(const ByBatchSize& toView) { - maxBatchSize = toView.maxBatchSize; - data = toView.data; - } - - ~ByBatchSizeView() { - } - T& operator[](int batchSize) { - return data[batchSize-1]; - } - const T& operator[](int batchSize) const { - return data[batchSize-1]; - } -}; - -//--------------------------------------------------------------------------------- - - -//channels, useFP16, useNHWC -typedef std::tuple CudnnTensorDesc4DKey; - -struct CudnnManager { - const string name; - const int maxBatchSize; - const int nnXLen; - const int nnYLen; - std::map*> tensorDesc4DByBatchSizeByKey; - - CudnnManager(string name_, int maxBatchSize_, int nnXLen_, int nnYLen_) - :name(name_), - maxBatchSize(maxBatchSize_), - nnXLen(nnXLen_), - nnYLen(nnYLen_), - tensorDesc4DByBatchSizeByKey() - { - } - - ~CudnnManager() { - for(auto& iter: tensorDesc4DByBatchSizeByKey) { - delete iter.second; - } - } - - ByBatchSizeView getTensorDesc4DByBatchSize( - int channels, bool useFP16, bool useNHWC - ) { - auto iter = tensorDesc4DByBatchSizeByKey.find({channels, useFP16, useNHWC}); - if(iter != tensorDesc4DByBatchSizeByKey.end()) { - return ByBatchSizeView(*(iter->second)); - } - ByBatchSize* descs = new ByBatchSize(maxBatchSize); - for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - miopenTensorDescriptor_t& desc = (*descs)[batchSize]; - CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&desc)); - CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( - desc, - (useFP16 ? miopenHalf : miopenFloat), - batchSize, - channels, - nnYLen, - nnXLen - )); - } - descs->destroyFunc = miopenDestroyTensorDescriptor; - tensorDesc4DByBatchSizeByKey[{channels, useFP16, useNHWC}] = descs; - return ByBatchSizeView(*descs); - } -}; - -//--------------------------------------------------------------------------------- - -struct ScratchBuffers { - - const size_t batchXYFloatBytes; - const size_t batchFloatBytes; - const size_t batchXYBytes; - const size_t batchBytes; - - SimpleAllocator* allocator; - - // Not scratch, but convenient to have here - void* zeroBuf; - void* oneBuf; - - ScratchBuffers() = delete; - ScratchBuffers(const ScratchBuffers&) = delete; - ScratchBuffers& operator=(const ScratchBuffers&) = delete; - - ScratchBuffers(int maxBatchSize, int nnXLen, int nnYLen, bool useFP16) - : batchXYFloatBytes((size_t)maxBatchSize * nnXLen * nnYLen * sizeof(float)), - batchFloatBytes((size_t)maxBatchSize * sizeof(float)), - batchXYBytes((size_t)maxBatchSize * nnXLen * nnYLen * (useFP16 ? sizeof(half_t) : sizeof(float))), - batchBytes((size_t)maxBatchSize * (useFP16 ? sizeof(half_t) : sizeof(float))) - { - std::function allocateFunc = [](size_t size) { - void* buf; - CUDA_ERR("ScratchBuffers",hipMalloc(&buf, size)); - return buf; - }; - std::function releaseFunc = [](void* buf) { - hipFree(buf); - }; - - allocator = new SimpleAllocator(allocateFunc, releaseFunc); - - CudaUtils::hostMallocZeroOneBufs(zeroBuf, oneBuf, useFP16); - } - ~ScratchBuffers() { - delete allocator; - free(zeroBuf); - free(oneBuf); - } - - size_t getBufSizeXY(int channels) const { - return channels * batchXYBytes; - } - size_t getBufSizeXYFloat(int channels) const { - return channels * batchXYFloatBytes; - } - size_t getBufSizeFloat(int channels) const { - return channels * batchFloatBytes; - } - size_t getBufSize(int channels) const { - return channels * batchBytes; - } - -}; - - -//--------------------------------------------------------------------------------- - -struct ConvLayer { - const string name; - const int inChannels; - const int outChannels; - ByBatchSizeView inputDescriptors; - ByBatchSizeView outputDescriptors; - miopenTensorDescriptor_t filterDescriptor; - miopenConvolutionDescriptor_t convolutionDescriptor; - ByBatchSize* convolutionAlgorithms; //array of one for each batch size - void* filterBuf; - - ConvLayer() = delete; - ConvLayer(const ConvLayer&) = delete; - ConvLayer& operator=(const ConvLayer&) = delete; - - ConvLayer( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ConvLayerDesc* desc, - bool useFP16, - bool useNHWC - ) : ConvLayer(cudaHandles, manager, desc, useFP16, useNHWC, useNHWC) - {} - - ConvLayer( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ConvLayerDesc* desc, - bool useFP16, - bool useNHWCIn, - bool useNHWCOut - ) : - name(desc->name), - inChannels(desc->inChannels), - outChannels(desc->outChannels) - { - int convYSize = desc->convYSize; - int convXSize = desc->convXSize; - int dilationY = desc->dilationY; - int dilationX = desc->dilationX; - int paddingX = (convXSize / 2) * dilationX; - int paddingY = (convYSize / 2) * dilationY; - - assert(convXSize % 2 == 1); - assert(convYSize % 2 == 1); - - inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); - outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); - int maxBatchSize = manager->maxBatchSize; - - bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; - - CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor)); - CUDNN_ERR(name.c_str(),miopenSet4dTensorDescriptor( - filterDescriptor, - (useFP16 ? miopenHalf : miopenFloat), - outChannels, - inChannels, - convYSize, - convXSize - )); - - int yStride = 1; - int xStride = 1; - - - CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor)); - CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( - convolutionDescriptor, - miopenConvolution, - paddingY, - paddingX, - yStride, - xStride, - dilationY, - dilationX - )); - if(useFP16) { - int alt = 1; // non‑zero enables alt‑impl on MI2xx+ GPUs - CUDNN_ERR(name.c_str(),miopenSetConvolutionAttribute(convolutionDescriptor,MIOPEN_CONVOLUTION_ATTRIB_FP16_ALT_IMPL,alt)); - } - - convolutionAlgorithms = new ByBatchSize(maxBatchSize); - - for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { - const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; - const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; - size_t requestedAlgoCount = 8; - size_t returnedAlgoCount = -1; - miopenConvSolution_t solutions[2 * requestedAlgoCount]; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionCount( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptor, - convolutionDescriptor, - outputDescriptor, - &requestedAlgoCount - )); - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolution( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptor, - convolutionDescriptor, - outputDescriptor, - requestedAlgoCount, - &returnedAlgoCount, - solutions - )); - if(returnedAlgoCount <= 0) - throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); - (*convolutionAlgorithms)[batchSize] = solutions[0]; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptor, - convolutionDescriptor, - outputDescriptor, - (*convolutionAlgorithms)[batchSize].solution_id - )); - } - - assert(desc->weights.size() == convYSize * convXSize * inChannels * outChannels); - - if(filterNHWC) { - vector weightsTransposed(desc->weights.size()); - for(int y = 0; y < convYSize; y++) { - for(int x = 0; x < convXSize; x++) { - for(int ic = 0; ic < inChannels; ic++) { - for(int oc = 0; oc < outChannels; oc++) { - weightsTransposed[((oc*convYSize + y)*convXSize + x)*inChannels + ic] = - desc->weights[((oc*inChannels + ic)*convYSize + y)*convXSize + x]; - } - } - } - } - CudaUtils::mallocAndCopyToDevice(name,weightsTransposed,filterBuf,useFP16); - hipDeviceSynchronize(); - } - else - CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf,useFP16); - } - - ~ConvLayer() { - hipFree(filterBuf); - miopenDestroyTensorDescriptor(filterDescriptor); - miopenDestroyConvolutionDescriptor(convolutionDescriptor); - delete convolutionAlgorithms; - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( - cudaHandles->cudnn, - filterDescriptor, - inputDescriptors[batchSize], - convolutionDescriptor, - outputDescriptors[batchSize], - (*convolutionAlgorithms)[batchSize].solution_id, - &workspaceBytes - )); - return workspaceBytes; - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - bool accumulate, - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - const float alpha = 1.0f; - const float beta = accumulate ? 1.0f : 0.0f; - CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( - cudaHandles->cudnn, - filterDescriptor, - filterBuf, - inputDescriptors[batchSize], - inputBuf, - convolutionDescriptor, - outputDescriptors[batchSize], - outputBuf, - workspaceBuf, - workspaceBytes, - (*convolutionAlgorithms)[batchSize].solution_id - )); - } - -}; - -//--------------------------------------------------------------------------------- - -struct BatchNormLayer { - const string name; - const int numChannels; - const float epsilon; - const int activation; - const int nnXLen; - const int nnYLen; - - const bool usingFP16; - const bool usingNHWC; - - void* mergedScaleBuf; - void* mergedBiasBuf; - - BatchNormLayer() = delete; - BatchNormLayer(const BatchNormLayer&) = delete; - BatchNormLayer& operator=(const BatchNormLayer&) = delete; - - BatchNormLayer( - CudaHandles* cudaHandles, - const BatchNormLayerDesc* desc, - const ActivationLayerDesc* actDesc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - numChannels(desc->numChannels), - epsilon(desc->epsilon), - activation(actDesc->activation), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC) - { - (void)cudaHandles; - - assert(desc->mean.size() == numChannels); - assert(desc->variance.size() == numChannels); - assert(desc->scale.size() == numChannels); - assert(desc->bias.size() == numChannels); - assert(desc->mergedScale.size() == numChannels); - assert(desc->mergedBias.size() == numChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->mergedScale,mergedScaleBuf,useFP16); - CudaUtils::mallocAndCopyToDevice(name,desc->mergedBias,mergedBiasBuf,useFP16); - } - ~BatchNormLayer() { - hipFree(mergedScaleBuf); - hipFree(mergedBiasBuf); - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - void* inputBuf, - const void* maskBuf, //ok to be null - void* outputBuf - ) const { - (void)cudaHandles; - if(!usingFP16) { - if(!usingNHWC) - customCudaApplyCScaleBiasNCHW((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, - (const float*)maskBuf, - batchSize,numChannels,nnXLen*nnYLen,activation); - else - customCudaApplyCScaleBiasNHWC((const float*)inputBuf,(float*)outputBuf,(const float*)mergedScaleBuf,(const float*)mergedBiasBuf, - (const float*)maskBuf, - batchSize,nnXLen*nnYLen,numChannels,activation); - } - else { - if(!usingNHWC) - customCudaApplyCScaleBiasNCHW((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, - (const half*)maskBuf, - batchSize,numChannels,nnXLen*nnYLen,activation); - else - customCudaApplyCScaleBiasNHWC((const half*)inputBuf,(half*)outputBuf,(const half*)mergedScaleBuf,(const half*)mergedBiasBuf, - (const half*)maskBuf, - batchSize,nnXLen*nnYLen,numChannels,activation); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - - } - -}; - - -//--------------------------------------------------------------------------------- - -struct MatMulLayer { - const string name; - const int inChannels; - const int outChannels; - const bool usingFP16; - void* matBuf; - - MatMulLayer() = delete; - MatMulLayer(const MatMulLayer&) = delete; - MatMulLayer& operator=(const MatMulLayer&) = delete; - - MatMulLayer( - CudaHandles* cudaHandles, - const MatMulLayerDesc* desc, - bool useFP16 - ) : - name(desc->name), - inChannels(desc->inChannels), - outChannels(desc->outChannels), - usingFP16(useFP16) - { - (void)cudaHandles; - - if(inChannels > 0 && outChannels > 0) { - assert(desc->weights.size() == inChannels * outChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,matBuf,useFP16); - } - else { - matBuf = NULL; - } - } - - ~MatMulLayer() { - if(inChannels > 0 && outChannels > 0) - hipFree(matBuf); - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles - ) const { - (void)cudaHandles; - size_t workspaceBytes = 0; - return workspaceBytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - (void)workspaceBuf; - (void)workspaceBytes; - assert(inChannels > 0 && outChannels > 0); - - if(!usingFP16) { - const float alpha = 1.0f; - const float beta = 0.0f; - CUBLAS_ERR(name.c_str(),hipblasSgemm( - cudaHandles->cublas, - HIPBLAS_OP_N, - HIPBLAS_OP_N, - outChannels, - batchSize, - inChannels, - &alpha, - (const float*)matBuf,outChannels, - (const float*)inputBuf,inChannels, - &beta, - (float*)outputBuf,outChannels - )); - } - else { - const hipblasHalf* alpha = (const hipblasHalf*)scratch->oneBuf; - const hipblasHalf* beta = (const hipblasHalf*)scratch->zeroBuf; - CUBLAS_ERR(name.c_str(),hipblasHgemm( - cudaHandles->cublas, - HIPBLAS_OP_N, - HIPBLAS_OP_N, - outChannels, - batchSize, - inChannels, - alpha, - (const hipblasHalf*)matBuf,outChannels, - (const hipblasHalf*)inputBuf,inChannels, - beta, - (hipblasHalf*)outputBuf,outChannels - )); - } - - } - -}; - -//--------------------------------------------------------------------------------- - -struct MatBiasLayer { - const string name; - const int numChannels; - const bool usingFP16; - const int activation; - - void* biasBuf; - - MatBiasLayer() = delete; - MatBiasLayer(const MatBiasLayer&) = delete; - MatBiasLayer& operator=(const MatBiasLayer&) = delete; - - MatBiasLayer( - CudaHandles* cudaHandles, - const MatBiasLayerDesc* desc, - bool useFP16, - int activation_ - ) : - name(desc->name), - numChannels(desc->numChannels), - usingFP16(useFP16), - activation(activation_) - { - (void)cudaHandles; - if(numChannels > 0) { - assert(desc->weights.size() == numChannels); - CudaUtils::mallocAndCopyToDevice(name,desc->weights,biasBuf,useFP16); - } - else - biasBuf = NULL; - } - - ~MatBiasLayer() { - if(numChannels > 0) - hipFree(biasBuf); - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - void* matBuf - ) const { - (void)cudaHandles; - assert(numChannels > 0); - if(!usingFP16) { - customCudaAddCBiasInplaceNC((float*)matBuf,(const float*)biasBuf,batchSize,numChannels,activation); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - else { - customCudaAddCBiasInplaceNC((half*)matBuf,(const half*)biasBuf,batchSize,numChannels,activation); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - } - -}; - -//--------------------------------------------------------------------------------- - -struct NormActConv { - const BatchNormLayer norm; - const ConvLayer conv; - - const int inChannels; - const int outChannels; - const int nnXLen; - const int nnYLen; - const bool usingFP16; - const bool usingNHWC; - - NormActConv() = delete; - NormActConv(const NormActConv&) = delete; - NormActConv& operator=(const NormActConv&) = delete; - - NormActConv( - CudaHandles* cudaHandles, - CudnnManager* manager, - const BatchNormLayerDesc* normDesc, - const ActivationLayerDesc* actDesc, - const ConvLayerDesc* convDesc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): norm(cudaHandles,normDesc,actDesc,nnX,nnY,useFP16,useNHWC), - conv(cudaHandles,manager,convDesc,useFP16,useNHWC), - inChannels(norm.numChannels), - outChannels(conv.outChannels), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC) - { - assert(norm.numChannels == conv.inChannels); - } - - ~NormActConv() - {} - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - int batchSize, - bool accumulate, - void* inBuf, - void* inScratchBuf, - void* outBuf, - void* maskBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - norm.apply(cudaHandles,batchSize,inBuf,maskBuf,inScratchBuf); -#ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("AFTER NORM "), inScratchBuf, batchSize, inChannels, nnXLen, nnYLen, usingNHWC, usingFP16); -#endif - conv.apply(cudaHandles,batchSize,accumulate,inScratchBuf,outBuf,workspaceBuf,workspaceBytes); - } - -}; - - -//--------------------------------------------------------------------------------- - -struct ResidualBlock { - const string name; - const NormActConv normActConv1; - const NormActConv normActConv2; - - ResidualBlock() = delete; - ResidualBlock(const ResidualBlock&) = delete; - ResidualBlock& operator=(const ResidualBlock&) = delete; - - ResidualBlock( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ResidualBlockDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): name(desc->name), - normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->regularConv,nnX,nnY,useFP16,useNHWC), - normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC) - { - } - - ~ResidualBlock() - {} - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* trunkBuf, - void* trunkScratchBuf, - void* maskBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf midIn(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,midIn.buf,maskBuf,workspaceBuf,workspaceBytes); - normActConv2.apply(cudaHandles,batchSize,true,midIn.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); - } - -}; - - -//---------------------------------------------------------------------------- - - -struct GlobalPoolingResidualBlock { - const string name; - const BatchNormLayer preBN; - const ConvLayer regularConv; - const ConvLayer gpoolConv; - const BatchNormLayer gpoolBN; - const MatMulLayer gpoolToBiasMul; - const NormActConv normActConv2; - - const int nnXLen; - const int nnYLen; - const int regularChannels; - const int gpoolChannels; - const bool usingFP16; - const bool usingNHWC; - - GlobalPoolingResidualBlock() = delete; - GlobalPoolingResidualBlock(const GlobalPoolingResidualBlock&) = delete; - GlobalPoolingResidualBlock& operator=(const GlobalPoolingResidualBlock&) = delete; - - GlobalPoolingResidualBlock( - CudaHandles* cudaHandles, - CudnnManager* manager, - const GlobalPoolingResidualBlockDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): name(desc->name), - preBN(cudaHandles,&desc->preBN,&desc->preActivation,nnX,nnY,useFP16,useNHWC), - regularConv(cudaHandles,manager,&desc->regularConv,useFP16,useNHWC), - gpoolConv(cudaHandles,manager,&desc->gpoolConv,useFP16,useNHWC), - gpoolBN(cudaHandles,&desc->gpoolBN,&desc->gpoolActivation,nnX,nnY,useFP16,useNHWC), - gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,useFP16), - normActConv2(cudaHandles,manager,&desc->midBN,&desc->midActivation,&desc->finalConv,nnX,nnY,useFP16,useNHWC), - nnXLen(nnX), - nnYLen(nnY), - regularChannels(desc->regularConv.outChannels), - gpoolChannels(desc->gpoolConv.outChannels), - usingFP16(useFP16), - usingNHWC(useNHWC) - { - } - - ~GlobalPoolingResidualBlock() { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = regularConv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolConv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*gpoolChannels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* trunkBuf, - void* trunkScratchBuf, - void* maskBuf, - float* maskSumBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf regularOut(scratch->allocator, scratch->getBufSizeXY(regularChannels)); - SizedBuf regularScratch(scratch->allocator, scratch->getBufSizeXY(regularChannels)); - SizedBuf gpoolOut(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); - SizedBuf gpoolOut2(scratch->allocator, scratch->getBufSizeXY(gpoolChannels)); - SizedBuf gpoolConcat(scratch->allocator, scratch->getBufSize(gpoolChannels*3)); - SizedBuf gpoolBias(scratch->allocator, scratch->getBufSize(regularChannels)); - - preBN.apply(cudaHandles,batchSize,trunkBuf,maskBuf,trunkScratchBuf); - regularConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,regularOut.buf,workspaceBuf,workspaceBytes); - gpoolConv.apply(cudaHandles,batchSize,false,trunkScratchBuf,gpoolOut.buf,workspaceBuf,workspaceBytes); - gpoolBN.apply(cudaHandles,batchSize,gpoolOut.buf,maskBuf,gpoolOut2.buf); - - if(!usingFP16) { - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const float*)maskBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const float*)gpoolOut2.buf,(float*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const float*)maskBuf,maskSumBuf); - } - else { - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,gpoolChannels,nnXLen*nnYLen,(const half*)maskBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const half*)gpoolOut2.buf,(half*)gpoolConcat.buf,batchSize,nnXLen*nnYLen,gpoolChannels,(const half*)maskBuf,maskSumBuf); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,gpoolConcat.buf,gpoolBias.buf,workspaceBuf,workspaceBytes); - - if(!usingFP16) { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((float*)regularOut.buf,(const float*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); - } - else { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,regularChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((half*)regularOut.buf,(const half*)gpoolBias.buf,batchSize,nnXLen*nnYLen,regularChannels); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - normActConv2.apply(cudaHandles,batchSize,true,regularOut.buf,regularScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); - } - -}; - -//------------------------------------------------------------------------------ - -struct BlockStack { - const int numBlocks; - const int trunkNumChannels; - const int nnXLen; - const int nnYLen; - const bool usingFP16; - const bool usingNHWC; - vector> blocks; - - BlockStack() = delete; - BlockStack(const BlockStack&) = delete; - BlockStack& operator=(const BlockStack&) = delete; - - BlockStack( - CudaHandles* cudaHandles, - CudnnManager* manager, - int nBlocks, - int trunkChannels, - const std::vector>& descBlocks, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ); - ~BlockStack(); - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const; - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - void* trunkScratchBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const; - -}; - -//------------------------------------------------------------------------------ - -struct NestedBottleneckResidualBlock { - const string name; - const NormActConv normActConv1; - const BlockStack blocks; - const NormActConv normActConv2; - - NestedBottleneckResidualBlock() = delete; - NestedBottleneckResidualBlock(const NestedBottleneckResidualBlock&) = delete; - NestedBottleneckResidualBlock& operator=(const NestedBottleneckResidualBlock&) = delete; - - NestedBottleneckResidualBlock( - CudaHandles* cudaHandles, - CudnnManager* manager, - const NestedBottleneckResidualBlockDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ): name(desc->name), - normActConv1(cudaHandles,manager,&desc->preBN,&desc->preActivation,&desc->preConv,nnX,nnY,useFP16,useNHWC), - blocks(cudaHandles,manager,desc->numBlocks,desc->preConv.outChannels,desc->blocks,nnX,nnY,useFP16,useNHWC), - normActConv2(cudaHandles,manager,&desc->postBN,&desc->postActivation,&desc->postConv,nnX,nnY,useFP16,useNHWC) - { - } - - ~NestedBottleneckResidualBlock() - {} - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - b = normActConv1.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = normActConv2.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* trunkBuf, - void* trunkScratchBuf, - void* maskBuf, - float* maskSumBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf mid(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - SizedBuf midScratch(scratch->allocator, scratch->getBufSizeXY(normActConv1.outChannels)); - assert(normActConv1.outChannels == normActConv2.inChannels); - normActConv1.apply(cudaHandles,batchSize,false,trunkBuf,trunkScratchBuf,mid.buf,maskBuf,workspaceBuf,workspaceBytes); - blocks.apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskSumBuf, - mid.buf, - midScratch.buf, - workspaceBuf, - workspaceBytes - ); - normActConv2.apply(cudaHandles,batchSize,true,mid.buf,midScratch.buf,trunkBuf,maskBuf,workspaceBuf,workspaceBytes); - } - -}; - -//------------------------------------------------------------------------------ - -BlockStack::BlockStack( - CudaHandles* cudaHandles, - CudnnManager* manager, - int nBlocks, - int trunkChannels, - const std::vector>& descBlocks, - int nnX, - int nnY, - bool useFP16, - bool useNHWC -) : - numBlocks(nBlocks), - trunkNumChannels(trunkChannels), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC) -{ - assert(numBlocks == descBlocks.size()); - for(int i = 0; irequiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { - GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); - b = block->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { - NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); - b = block->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - else { - ASSERT_UNREACHABLE; - } - } - return bytes; -} - -void BlockStack::apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - void* trunkScratchBuf, - void* workspaceBuf, - size_t workspaceBytes -) const { - - for(int i = 0; iapply( - cudaHandles, - scratch, - batchSize, - trunkBuf, - trunkScratchBuf, - maskBuf, - workspaceBuf, - workspaceBytes - ); - } - else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { - GlobalPoolingResidualBlock* block = (GlobalPoolingResidualBlock*)blocks[i].second.get(); - block->apply( - cudaHandles, - scratch, - batchSize, - trunkBuf, - trunkScratchBuf, - maskBuf, - maskSumBuf, - workspaceBuf, - workspaceBytes - ); - } - else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { - NestedBottleneckResidualBlock* block = (NestedBottleneckResidualBlock*)blocks[i].second.get(); - block->apply( - cudaHandles, - scratch, - batchSize, - trunkBuf, - trunkScratchBuf, - maskBuf, - maskSumBuf, - workspaceBuf, - workspaceBytes - ); - } - else { - ASSERT_UNREACHABLE; - } - } -} -//------------------------------------------------------------------------------ - -struct SGFMetadataEncoder { - const string name; - - const bool usingFP16; - - const MatMulLayer mul1; - const MatBiasLayer bias1; - const MatMulLayer mul2; - const MatBiasLayer bias2; - const MatMulLayer mul3; - - SGFMetadataEncoder() = delete; - SGFMetadataEncoder(const SGFMetadataEncoder&) = delete; - SGFMetadataEncoder& operator=(const SGFMetadataEncoder&) = delete; - - SGFMetadataEncoder( - CudaHandles* cudaHandles, - const SGFMetadataEncoderDesc* desc, - bool useFP16 - ) : - name(desc->name), - usingFP16(useFP16), - mul1(cudaHandles,&desc->mul1,useFP16), - bias1(cudaHandles,&desc->bias1,useFP16,desc->act1.activation), - mul2(cudaHandles,&desc->mul2,useFP16), - bias2(cudaHandles,&desc->bias2,useFP16,desc->act2.activation), - mul3(cudaHandles,&desc->mul3,useFP16) - { - } - - ~SGFMetadataEncoder() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - (void)batchSize; - size_t bytes = 0; - size_t b; - - b = mul1.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = mul2.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = mul3.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* inputBuf, - void* outputBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf internalBuf1(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); - SizedBuf internalBuf2(scratch->allocator, scratch->getBufSizeFloat(std::max(mul1.outChannels,mul2.outChannels))); - - mul1.apply(cudaHandles,scratch,batchSize,inputBuf,internalBuf1.buf,workspaceBuf,workspaceBytes); - bias1.apply(cudaHandles,batchSize,internalBuf1.buf); - mul2.apply(cudaHandles,scratch,batchSize,internalBuf1.buf,internalBuf2.buf,workspaceBuf,workspaceBytes); - bias2.apply(cudaHandles,batchSize,internalBuf2.buf); - mul3.apply(cudaHandles,scratch,batchSize,internalBuf2.buf,outputBuf,workspaceBuf,workspaceBytes); - } - -}; - - -//---------------------------------------------------------------------------- - -struct Trunk { - const string name; - const int modelVersion; - const int numBlocks; - const int trunkNumChannels; - - const int nnXLen; - const int nnYLen; - const bool usingFP16; - const bool usingNHWC; - - std::unique_ptr initialConv; - std::unique_ptr initialMatMul; - std::unique_ptr sgfMetadataEncoder; - const BlockStack blocks; - std::unique_ptr trunkTipBN; - - Trunk() = delete; - Trunk(const Trunk&) = delete; - Trunk& operator=(const Trunk&) = delete; - - Trunk( - CudaHandles* cudaHandles, - CudnnManager* manager, - const TrunkDesc* desc, - int nnX, - int nnY, - bool inputsUseNHWC, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - numBlocks(desc->numBlocks), - trunkNumChannels(desc->trunkNumChannels), - nnXLen(nnX), - nnYLen(nnY), - usingFP16(useFP16), - usingNHWC(useNHWC), - blocks(cudaHandles,manager,desc->numBlocks,desc->trunkNumChannels,desc->blocks,nnX,nnY,useFP16,useNHWC) - { - int midNumChannels = desc->midNumChannels; - int regularNumChannels = desc->regularNumChannels; - int gpoolNumChannels = desc->gpoolNumChannels; - - int maxBatchSize = manager->maxBatchSize; - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,trunkNumChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,midNumChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,regularNumChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,gpoolNumChannels); - - initialConv = std::make_unique(cudaHandles,manager,&desc->initialConv,useFP16,inputsUseNHWC,useNHWC); - initialMatMul = std::make_unique(cudaHandles,&desc->initialMatMul,useFP16); - if(desc->metaEncoderVersion > 0) { - sgfMetadataEncoder = std::make_unique(cudaHandles,&desc->sgfMetadataEncoder,useFP16); - testAssert(sgfMetadataEncoder->mul3.outChannels == initialMatMul->outChannels); - } - - trunkTipBN = std::make_unique(cudaHandles,&desc->trunkTipBN,&desc->trunkTipActivation,nnXLen,nnYLen,useFP16,useNHWC); - assert(desc->blocks.size() == numBlocks); - } - - ~Trunk() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = initialConv->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - - b = initialMatMul->requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - - if(sgfMetadataEncoder != nullptr) { - b = sgfMetadataEncoder->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - - b = blocks.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* inputBuf, - void* inputGlobalBuf, - void* inputMetaBuf, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - - SizedBuf trunkScratch(scratch->allocator, scratch->getBufSizeXY(trunkNumChannels)); - - //Feed the conv into trunkScratch.buf, not trunkBuf - initialConv->apply(cudaHandles,batchSize,false,inputBuf,trunkScratch.buf,workspaceBuf,workspaceBytes); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("After initial conv"), trunkScratch.buf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); - #endif - - //Feed the matmul into trunkBuf - initialMatMul->apply(cudaHandles,scratch,batchSize,inputGlobalBuf,trunkBuf,workspaceBuf,workspaceBytes); - //Then accumulate it into trunkScratch.buf, broadcasting during the process - if(!usingFP16) { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - else { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - if(sgfMetadataEncoder != nullptr) { - testAssert(inputMetaBuf != NULL); - //Feed the result into trunkBuf - sgfMetadataEncoder->apply(cudaHandles,scratch,batchSize,inputMetaBuf,trunkBuf,workspaceBuf,workspaceBytes); - //Then accumulate it into trunkScratch.buf, broadcasting during the process - if(!usingFP16) { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((float*)trunkScratch.buf,(const float*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - else { - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,trunkNumChannels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC((half*)trunkScratch.buf,(const half*)trunkBuf,batchSize,nnXLen*nnYLen,trunkNumChannels); - } - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - else { - testAssert(inputMetaBuf == NULL); - } - - //Flip trunkBuf and trunkScratch.buf so that the result gets accumulated in trunkScratch.buf - blocks.apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskSumBuf, - trunkScratch.buf, - trunkBuf, - workspaceBuf, - workspaceBytes - ); - - //And now with the final BN port it from trunkScratch.buf to trunkBuf. - trunkTipBN->apply(cudaHandles,batchSize,trunkScratch.buf,maskBuf,trunkBuf); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("Trunk tip"), trunkBuf, batchSize, trunkNumChannels, nnXLen, nnYLen, usingNHWC, usingFP16); - #endif - } - -}; - -//------------------------------------------------------------------------------ - -static void fillMaskFloatBufAndMaskSumBuf(void* maskBuf, float*& maskFloatBuf, float*& maskSumBuf, bool usingFP16, int batchSize, int nnXLen, int nnYLen) { - if(!usingFP16) { - maskFloatBuf = (float*)maskBuf; - customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); - CUDA_ERR("sumMask",hipPeekAtLastError()); - } - else { - customCudaCopyFromHalf((const half*)maskBuf,maskFloatBuf,batchSize*nnXLen*nnYLen); - CUDA_ERR("copyMaskFromHalf",hipPeekAtLastError()); - customCudaPoolRowsSumNCHW((const float*)maskFloatBuf,maskSumBuf,batchSize,1,nnXLen*nnYLen,1.0); - CUDA_ERR("sumMask",hipPeekAtLastError()); - } -} - - -//------------------------------------------------------------------------------ - -struct PolicyHead { - const string name; - const int modelVersion; - const int nnXLen; - const int nnYLen; - const int p1Channels; - const int g1Channels; - const int p2Channels; - const bool usingFP16; - const bool usingNHWC; - - const ConvLayer p1Conv; - const ConvLayer g1Conv; - const BatchNormLayer g1BN; - const MatMulLayer gpoolToBiasMul; - const BatchNormLayer p1BN; - const ConvLayer p2Conv; - const MatMulLayer gpoolToPassMul; - const MatBiasLayer gpoolToPassBias; - const MatMulLayer gpoolToPassMul2; - - PolicyHead() = delete; - PolicyHead(const PolicyHead&) = delete; - PolicyHead& operator=(const PolicyHead&) = delete; - - PolicyHead( - CudaHandles* cudaHandles, - CudnnManager* manager, - const PolicyHeadDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - nnXLen(nnX), - nnYLen(nnY), - p1Channels(desc->p1Conv.outChannels), - g1Channels(desc->g1Conv.outChannels), - p2Channels(desc->p2Conv.outChannels), - usingFP16(useFP16), - usingNHWC(useNHWC), - p1Conv(cudaHandles,manager,&desc->p1Conv,useFP16,useNHWC), - g1Conv(cudaHandles,manager,&desc->g1Conv,useFP16,useNHWC), - g1BN(cudaHandles,&desc->g1BN,&desc->g1Activation,nnX,nnY,useFP16,useNHWC), - gpoolToBiasMul(cudaHandles,&desc->gpoolToBiasMul,false), - p1BN(cudaHandles,&desc->p1BN,&desc->p1Activation,nnX,nnY,false,useNHWC), - p2Conv(cudaHandles,manager,&desc->p2Conv,false,useNHWC), - gpoolToPassMul(cudaHandles,&desc->gpoolToPassMul,false), - gpoolToPassBias(cudaHandles,&desc->gpoolToPassBias,false,desc->passActivation.activation), - gpoolToPassMul2(cudaHandles,&desc->gpoolToPassMul2,false) - { - } - - ~PolicyHead() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = p1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = g1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolToBiasMul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = p2Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = gpoolToPassMul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = gpoolToPassMul2.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*g1Channels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskFloatBuf, - float* maskSumBuf, - void* trunkBuf, - float* policyPassBuf, - float* policyBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - - SizedBuf p1Out(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs - SizedBuf p1Out2(scratch->allocator, scratch->getBufSizeXYFloat(p1Channels)); //Need to hold floats, not just halfs - SizedBuf g1Out(scratch->allocator, scratch->getBufSizeXY(g1Channels)); - SizedBuf g1Out2(scratch->allocator, scratch->getBufSizeXY(g1Channels)); - SizedBuf g1Concat(scratch->allocator, scratch->getBufSizeFloat(g1Channels*3)); - SizedBuf g1Bias(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); - SizedBuf p1Pass(scratch->allocator, scratch->getBufSizeFloat(p1Channels)); - - p1Conv.apply(cudaHandles,batchSize,false,trunkBuf,p1Out.buf,workspaceBuf,workspaceBytes); - g1Conv.apply(cudaHandles,batchSize,false,trunkBuf,g1Out.buf,workspaceBuf,workspaceBytes); - g1BN.apply(cudaHandles,batchSize,g1Out.buf,maskBuf,g1Out2.buf); - - if(!usingFP16) { - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const float*)g1Out2.buf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - else { - customCudaCopyFromHalf((const half*)g1Out2.buf,(float*)workspaceBuf,batchSize*g1Channels*nnXLen*nnYLen); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - if(!usingNHWC) - customCudaPoolRowsGPoolNCHW((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,g1Channels,nnXLen*nnYLen,maskFloatBuf,maskSumBuf); - else - customCudaPoolRowsGPoolNHWC((const float*)workspaceBuf,(float*)g1Concat.buf,batchSize,nnXLen*nnYLen,g1Channels,maskFloatBuf,maskSumBuf); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - } - - gpoolToBiasMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,g1Bias.buf,workspaceBuf,workspaceBytes); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("p1 pre-gpool-sum"), p1Out.buf, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); - CudaUtils::debugPrint4D(string("g1 pre-gpool"), g1Out.buf, batchSize, g1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); - CudaUtils::debugPrint2D(string("g1 pooled"), g1Concat.buf, batchSize, g1Channels*3, false); - CudaUtils::debugPrint2D(string("g1 biases"), g1Bias.buf, batchSize, p1Channels, false); - #endif - - float* p1OutBufA; - float* p1OutBufB; - if(!usingFP16) { - p1OutBufA = (float*)p1Out.buf; - p1OutBufB = (float*)p1Out2.buf; - } - else { - customCudaCopyFromHalf((const half*)p1Out.buf,(float*)p1Out2.buf,batchSize*p1Channels*nnXLen*nnYLen); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - p1OutBufA = (float*)p1Out2.buf; - p1OutBufB = (float*)p1Out.buf; - } - - if(!usingNHWC) - customCudaAddNCBiasInplaceNCHW(p1OutBufA,(float*)g1Bias.buf,batchSize,p1Channels,nnXLen*nnYLen); - else - customCudaAddNCBiasInplaceNHWC(p1OutBufA,(float*)g1Bias.buf,batchSize,nnXLen*nnYLen,p1Channels); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - p1BN.apply(cudaHandles,batchSize,p1OutBufA,maskFloatBuf,p1OutBufB); - p2Conv.apply(cudaHandles,batchSize,false,p1OutBufB,(float*)policyBuf,workspaceBuf,workspaceBytes); - - if(modelVersion >= 15) { - gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,p1Pass.buf,workspaceBuf,workspaceBytes); - gpoolToPassBias.apply(cudaHandles,batchSize,p1Pass.buf); - gpoolToPassMul2.apply(cudaHandles,scratch,batchSize,p1Pass.buf,policyPassBuf,workspaceBuf,workspaceBytes); - } - else { - gpoolToPassMul.apply(cudaHandles,scratch,batchSize,g1Concat.buf,policyPassBuf,workspaceBuf,workspaceBytes); - } - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("p1 after-gpool-sum"), p1OutBufA, batchSize, p1Channels, nnXLen, nnYLen, usingNHWC, false); - CudaUtils::debugPrint2D(string("policypass"), policyPassBuf, batchSize, 1, false); - CudaUtils::debugPrint4D(string("policy"), policyBuf, batchSize, p2Channels, nnXLen, nnYLen, usingNHWC, false); - #endif - - } - -}; - -//------------------------------------------------------------------------------ - -struct ValueHead { - const string name; - const int modelVersion; - const int nnXLen; - const int nnYLen; - const int v1Channels; - const int v2Channels; - const int valueChannels; - const int scoreValueChannels; - const int ownershipChannels; - const bool usingFP16; - const bool usingNHWC; - - const ConvLayer v1Conv; - const BatchNormLayer v1BN; - const MatMulLayer v2Mul; - const MatBiasLayer v2Bias; - const MatMulLayer v3Mul; - const MatBiasLayer v3Bias; - const MatMulLayer sv3Mul; - const MatBiasLayer sv3Bias; - const ConvLayer vOwnershipConv; - - ValueHead() = delete; - ValueHead(const ValueHead&) = delete; - ValueHead& operator=(const ValueHead&) = delete; - - ValueHead( - CudaHandles* cudaHandles, - CudnnManager* manager, - const ValueHeadDesc* desc, - int nnX, - int nnY, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - nnXLen(nnX), - nnYLen(nnY), - v1Channels(desc->v1Conv.outChannels), - v2Channels(desc->v2Mul.outChannels), - valueChannels(desc->v3Mul.outChannels), - scoreValueChannels(desc->sv3Mul.outChannels), - ownershipChannels(desc->vOwnershipConv.outChannels), - usingFP16(useFP16), - usingNHWC(useNHWC), - v1Conv(cudaHandles,manager,&desc->v1Conv,useFP16,useNHWC), - v1BN(cudaHandles,&desc->v1BN,&desc->v1Activation,nnX,nnY,useFP16,useNHWC), - v2Mul(cudaHandles,&desc->v2Mul,false), - v2Bias(cudaHandles,&desc->v2Bias,false,desc->v2Activation.activation), - v3Mul(cudaHandles,&desc->v3Mul,false), - v3Bias(cudaHandles,&desc->v3Bias,false,ACTIVATION_IDENTITY), - sv3Mul(cudaHandles,&desc->sv3Mul,false), - sv3Bias(cudaHandles,&desc->sv3Bias,false,ACTIVATION_IDENTITY), - vOwnershipConv(cudaHandles,manager,&desc->vOwnershipConv,useFP16,useNHWC) - { - } - - ~ValueHead() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = v1Conv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = v2Mul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = v3Mul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*v1Channels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - - b = sv3Mul.requiredWorkspaceBytes(cudaHandles); - bytes = std::max(bytes,b); - b = vOwnershipConv.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = sizeof(float)*batchSize*ownershipChannels*nnXLen*nnYLen; - bytes = std::max(bytes,b); - - return bytes; - } - - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - void* maskBuf, - float* maskSumBuf, - void* trunkBuf, - float* valueBuf, - float* scoreValueBuf, - void* ownershipBuf, - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf v1Out(scratch->allocator, scratch->getBufSizeXY(v1Channels)); - SizedBuf v1Out2(scratch->allocator, scratch->getBufSizeXY(v1Channels)); - SizedBuf v1Mean(scratch->allocator, scratch->getBufSizeFloat(v1Channels*3)); - SizedBuf v2Out(scratch->allocator, scratch->getBufSizeFloat(v2Channels)); - SizedBuf ownershipScratch(scratch->allocator, scratch->getBufSizeXYFloat(ownershipChannels)); - - v1Conv.apply(cudaHandles,batchSize,false,trunkBuf,v1Out.buf,workspaceBuf,workspaceBytes); - v1BN.apply(cudaHandles,batchSize,v1Out.buf,maskBuf,v1Out2.buf); - - void* bufToBePooled = v1Out2.buf; - if(usingFP16) { - customCudaCopyFromHalf((const half*)v1Out2.buf,(float*)workspaceBuf,batchSize*v1Channels*nnXLen*nnYLen); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - bufToBePooled = workspaceBuf; - } - - if(!usingNHWC) - customCudaValueHeadPoolNCHW((float*)bufToBePooled,(float*)v1Mean.buf,batchSize,v1Channels,nnXLen*nnYLen,maskSumBuf); - else - customCudaValueHeadPoolNHWC((const float*)bufToBePooled,(float*)v1Mean.buf,batchSize,nnXLen*nnYLen,v1Channels,maskSumBuf); - CUDA_ERR(name.c_str(),hipPeekAtLastError()); - - v2Mul.apply(cudaHandles,scratch,batchSize,v1Mean.buf,v2Out.buf,workspaceBuf,workspaceBytes); - v2Bias.apply(cudaHandles,batchSize,v2Out.buf); - v3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,valueBuf,workspaceBuf,workspaceBytes); - v3Bias.apply(cudaHandles,batchSize,valueBuf); - - sv3Mul.apply(cudaHandles,scratch,batchSize,v2Out.buf,scoreValueBuf,workspaceBuf,workspaceBytes); - sv3Bias.apply(cudaHandles,batchSize,scoreValueBuf); - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("v1"), v1Out.buf, batchSize, v1Channels, nnXLen, nnYLen, usingNHWC, usingFP16); - CudaUtils::debugPrint2D(string("v1 pooled"), v1Mean.buf, batchSize, v1Channels, false); - CudaUtils::debugPrint2D(string("v2"), v2Out.buf, batchSize, v1Channels, false); - #endif - - if(!usingFP16) { - vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipBuf,workspaceBuf,workspaceBytes); - } - else { - vOwnershipConv.apply(cudaHandles,batchSize,false,v1Out2.buf,ownershipScratch.buf,workspaceBuf,workspaceBytes); - customCudaCopyFromHalf((const half*)ownershipScratch.buf,(float*)ownershipBuf,batchSize*ownershipChannels*nnXLen*nnYLen); - CUDA_ERR("vOwnership copy",hipPeekAtLastError()); - } - - } - -}; - -//------------------------------------------------------------------------------ - -struct Model { - const string name; - const int modelVersion; - const int maxBatchSize; - const int nnXLen; - const int nnYLen; - const int numInputChannels; - const int numInputGlobalChannels; - const int numInputMetaChannels; - const int numPolicyChannels; - const int numValueChannels; - const int numScoreValueChannels; - const int numOwnershipChannels; - const bool usingFP16; - const bool usingNHWC; - const bool inputsUsingNHWC; - - std::unique_ptr trunk; - std::unique_ptr policyHead; - std::unique_ptr valueHead; - std::unique_ptr manager; - - Model() = delete; - Model(const Model&) = delete; - Model& operator=(const Model&) = delete; - - Model( - CudaHandles* cudaHandles, - const ModelDesc* desc, - int maxBatchSz, - int nnX, - int nnY, - bool inputsUseNHWC, - bool useFP16, - bool useNHWC - ) : - name(desc->name), - modelVersion(desc->modelVersion), - maxBatchSize(maxBatchSz), - nnXLen(nnX), - nnYLen(nnY), - numInputChannels(desc->numInputChannels), - numInputGlobalChannels(desc->numInputGlobalChannels), - numInputMetaChannels(desc->numInputMetaChannels), - numPolicyChannels(desc->numPolicyChannels), - numValueChannels(desc->numValueChannels), - numScoreValueChannels(desc->numScoreValueChannels), - numOwnershipChannels(desc->numOwnershipChannels), - usingFP16(useFP16), - usingNHWC(useNHWC), - inputsUsingNHWC(inputsUseNHWC) - { - if(nnXLen > NNPos::MAX_BOARD_LEN) - throw StringError(Global::strprintf("nnXLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", - nnXLen, NNPos::MAX_BOARD_LEN - )); - if(nnYLen > NNPos::MAX_BOARD_LEN) - throw StringError(Global::strprintf("nnYLen (%d) is greater than NNPos::MAX_BOARD_LEN (%d)", - nnYLen, NNPos::MAX_BOARD_LEN - )); - - int numFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); - if(numInputChannels != numFeatures) - throw StringError(Global::strprintf("Neural net numInputChannels (%d) was not the expected number based on version (%d)", - numInputChannels, numFeatures - )); - int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); - if(numInputGlobalChannels != numGlobalFeatures) - throw StringError(Global::strprintf("Neural net numInputGlobalChannels (%d) was not the expected number based on version (%d)", - numInputGlobalChannels, numGlobalFeatures - )); - if(numInputMetaChannels > 0) { - if(numInputMetaChannels != SGFMetadata::METADATA_INPUT_NUM_CHANNELS) - throw StringError(Global::strprintf("Neural net numInputMetaChannels (%d) was not the expected number (%d)", - numInputMetaChannels, SGFMetadata::METADATA_INPUT_NUM_CHANNELS - )); - } - - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputGlobalChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numInputMetaChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numPolicyChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numValueChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numScoreValueChannels); - CudaUtils::checkBufferSize(maxBatchSize,nnXLen,nnYLen,numOwnershipChannels); - - manager = std::make_unique(name, maxBatchSize, nnXLen, nnYLen); - trunk = std::make_unique(cudaHandles,manager.get(),&desc->trunk,nnXLen,nnYLen,inputsUseNHWC,useFP16,useNHWC); - policyHead = std::make_unique(cudaHandles,manager.get(),&desc->policyHead,nnXLen,nnYLen,useFP16,useNHWC); - valueHead = std::make_unique(cudaHandles,manager.get(),&desc->valueHead,nnXLen,nnYLen,useFP16,useNHWC); - } - - ~Model() - { - } - - size_t requiredWorkspaceBytes( - CudaHandles* cudaHandles, - int batchSize - ) const { - size_t bytes = 0; - size_t b; - - b = trunk->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = policyHead->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - b = valueHead->requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - - return bytes; - } - - void apply( - CudaHandles* cudaHandles, - ScratchBuffers* scratch, - int batchSize, - bool requireExactNNLen, - - void* inputBuf, - void* inputGlobalBuf, - void* inputMetaBuf, - - float* policyPassBuf, - float* policyBuf, - - float* valueBuf, - float* scoreValueBuf, - void* ownershipBuf, - - void* workspaceBuf, - size_t workspaceBytes - ) const { - SizedBuf mask(scratch->allocator, scratch->getBufSizeXY(1)); - SizedBuf maskFloat(scratch->allocator, scratch->getBufSizeXYFloat(1)); - SizedBuf maskSum(scratch->allocator, scratch->getBufSizeFloat(1)); - - void* maskBuf = mask.buf; - float* maskFloatBuf = (float*)maskFloat.buf; - float* maskSumBuf = (float*)maskSum.buf; - - if(!usingFP16) { - if(inputsUsingNHWC) - customCudaChannel0ExtractNHWC((const float*)inputBuf, (float*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); - else - customCudaChannel0ExtractNCHW((const float*)inputBuf, (float*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); - CUDA_ERR("modelExtractMask",hipPeekAtLastError()); - } - else { - if(inputsUsingNHWC) - customCudaChannel0ExtractNHWC((const half*)inputBuf, (half*)maskBuf, batchSize, nnXLen*nnYLen, numInputChannels); - else - customCudaChannel0ExtractNCHW((const half*)inputBuf, (half*)maskBuf, batchSize, numInputChannels, nnXLen*nnYLen); - CUDA_ERR("modelExtractMask",hipPeekAtLastError()); - } - - fillMaskFloatBufAndMaskSumBuf(maskBuf,maskFloatBuf,maskSumBuf,usingFP16,batchSize,nnXLen,nnYLen); - - //Don't do any masking if we know the board is exactly the desired size - if(requireExactNNLen) { - //Set to NULL to signal downstream that this buf doesn't need to be used - maskBuf = NULL; - maskFloatBuf = NULL; - //The global pooling structures need this no matter what, for normalizing based on this and its sqrt. - //maskSumBuf = NULL; - } - - #ifdef DEBUG_INTERMEDIATE_VALUES - CudaUtils::debugPrint4D(string("Initial bin features"), inputBuf, batchSize, trunk->initialConv->inChannels, nnXLen, nnYLen, inputsUsingNHWC, usingFP16); - CudaUtils::debugPrint2D(string("Initial global features"), inputGlobalBuf, batchSize, trunk->initialMatMul->inChannels, usingFP16); - if(trunk->sgfMetadataEncoder != nullptr) { - assert(inputMetaBuf != NULL); - CudaUtils::debugPrint2D(string("Initial meta features"), inputMetaBuf, batchSize, trunk->sgfMetadataEncoder->mul1.inChannels, usingFP16); - } - #endif - - SizedBuf trunkBuf(scratch->allocator, scratch->getBufSizeXY(trunk->trunkNumChannels)); - - trunk->apply( - cudaHandles, - scratch, - batchSize, - inputBuf, - inputGlobalBuf, - inputMetaBuf, - maskBuf, - maskSumBuf, - trunkBuf.buf, - workspaceBuf, - workspaceBytes - ); - policyHead->apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskFloatBuf, - maskSumBuf, - trunkBuf.buf, - policyPassBuf, - policyBuf, - workspaceBuf, - workspaceBytes - ); - valueHead->apply( - cudaHandles, - scratch, - batchSize, - maskBuf, - maskSumBuf, - trunkBuf.buf, - valueBuf, - scoreValueBuf, - ownershipBuf, - workspaceBuf, - workspaceBytes - ); - } - -}; - - -//------------------------------------------------------------------------------ - -struct LoadedModel { - ModelDesc modelDesc; - - LoadedModel(const string& fileName, const string& expectedSha256) { - ModelDesc::loadFromFileMaybeGZipped(fileName,modelDesc,expectedSha256); - modelDesc.applyScale8ToReduceActivations(); - } - - LoadedModel() = delete; - LoadedModel(const LoadedModel&) = delete; - LoadedModel& operator=(const LoadedModel&) = delete; -}; - -LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { - LoadedModel* loadedModel = new LoadedModel(file,expectedSha256); - return loadedModel; -} - -void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { - delete loadedModel; -} - -const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { - return loadedModel->modelDesc; -} - -//------------------------------------------------------------------------------ - -struct Buffers { - //All of these are device pointers - - float* inputBufFloat; - void* inputBuf; - float* inputGlobalBufFloat; - void* inputGlobalBuf; - float* inputMetaBufFloat; - void* inputMetaBuf; - size_t inputBufBytesFloat; - size_t inputBufBytes; - size_t inputGlobalBufBytesFloat; - size_t inputGlobalBufBytes; - size_t inputMetaBufBytesFloat; - size_t inputMetaBufBytes; - - float* policyPassBuf; - size_t policyPassBufBytes; - float* policyBuf; - size_t policyBufBytes; - - float* valueBuf; - size_t valueBufBytes; - float* scoreValueBuf; - size_t scoreValueBufBytes; - void* ownershipBuf; - size_t ownershipBufBytes; - - void* workspaceBuf; - size_t workspaceBytes; - - Buffers() = delete; - Buffers(const Buffers&) = delete; - Buffers& operator=(const Buffers&) = delete; - - Buffers(CudaHandles* cudaHandles, const Model& m, const ScratchBuffers& scratch) { - size_t batchXYFloatBytes = (size_t)scratch.batchXYFloatBytes; - size_t batchFloatBytes = (size_t)scratch.batchFloatBytes; - size_t batchXYBytes = (size_t)scratch.batchXYBytes; - size_t batchBytes = (size_t)scratch.batchBytes; - - inputBufBytesFloat = m.numInputChannels * batchXYFloatBytes; - inputBufBytes = m.numInputChannels * batchXYBytes; - inputGlobalBufBytesFloat = m.numInputGlobalChannels * batchFloatBytes; - inputGlobalBufBytes = m.numInputGlobalChannels * batchBytes; - inputMetaBufBytesFloat = m.numInputMetaChannels * batchFloatBytes; - inputMetaBufBytes = m.numInputMetaChannels * batchBytes; - - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputBufFloat), inputBufBytesFloat)); - CUDA_ERR("Buffers",hipMalloc(&inputBuf, inputBufBytes)); - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputGlobalBufFloat), inputGlobalBufBytesFloat)); - CUDA_ERR("Buffers",hipMalloc(&inputGlobalBuf, inputGlobalBufBytes)); - if(m.numInputMetaChannels > 0) { - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&inputMetaBufFloat), inputMetaBufBytesFloat)); - CUDA_ERR("Buffers",hipMalloc(&inputMetaBuf, inputMetaBufBytes)); - } - else { - inputMetaBufFloat = NULL; - inputMetaBuf = NULL; - } - - if(m.modelVersion >= 16) - testAssert(m.policyHead->p2Channels == 4); - else if(m.modelVersion >= 12) - testAssert(m.policyHead->p2Channels == 2); - else - testAssert(m.policyHead->p2Channels == 1); - - policyPassBufBytes = m.policyHead->p2Channels * batchFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyPassBuf), policyPassBufBytes)); - policyBufBytes = m.policyHead->p2Channels * batchXYFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&policyBuf), policyBufBytes)); - - valueBufBytes = m.valueHead->valueChannels * batchFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&valueBuf), valueBufBytes)); - - scoreValueBufBytes = m.valueHead->scoreValueChannels * batchFloatBytes; - CUDA_ERR("Buffers",hipMalloc(reinterpret_cast(&scoreValueBuf), scoreValueBufBytes)); - - //This buf is used for both an intermdiate fp16 result in fp16 mode, and ALSO the final fp32 output, so always must be fp32-sized - ownershipBufBytes = m.valueHead->ownershipChannels * batchXYFloatBytes; - CUDA_ERR("Buffers",hipMalloc(&ownershipBuf, ownershipBufBytes)); - - //In theory the requiredWorkspaceBytes calls could give us values non-monotone in batch size - //such as if the convolution algorithm changes between batch size 1 and larger. - //So we call it for all the batch sizes. - size_t bytes = 0; - size_t b; - for(int batchSize = 1; batchSize <= m.maxBatchSize; batchSize++) { - b = m.requiredWorkspaceBytes(cudaHandles,batchSize); - bytes = std::max(bytes,b); - } - - CUDA_ERR("Buffers",hipMalloc(&workspaceBuf, bytes)); - workspaceBytes = bytes; - } - - ~Buffers() { - hipFree(inputBufFloat); - hipFree(inputBuf); - hipFree(inputGlobalBufFloat); - hipFree(inputGlobalBuf); - if(inputMetaBufFloat != NULL) - hipFree(inputMetaBufFloat); - if(inputMetaBuf != NULL) - hipFree(inputMetaBuf); - - hipFree(policyPassBuf); - hipFree(policyBuf); - - hipFree(valueBuf); - hipFree(scoreValueBuf); - hipFree(ownershipBuf); - - hipFree(workspaceBuf); - } - -}; - -//------------------------------------------------------------------------------ - -struct ComputeContext { - int nnXLen; - int nnYLen; - enabled_t useFP16Mode; - enabled_t useNHWCMode; -}; - -ComputeContext* NeuralNet::createComputeContext( - const std::vector& gpuIdxs, - Logger* logger, - int nnXLen, - int nnYLen, - const string& openCLTunerFile, - const string& homeDataDirOverride, - bool openCLReTunePerBoardSize, - enabled_t useFP16Mode, - enabled_t useNHWCMode, - const LoadedModel* loadedModel -) { - (void)gpuIdxs; - (void)logger; - (void)openCLTunerFile; - (void)homeDataDirOverride; - (void)openCLReTunePerBoardSize; - (void)loadedModel; - - ComputeContext* context = new ComputeContext(); - context->nnXLen = nnXLen; - context->nnYLen = nnYLen; - context->useFP16Mode = useFP16Mode; - context->useNHWCMode = useNHWCMode; - return context; -} - -void NeuralNet::freeComputeContext(ComputeContext* computeContext) { - delete computeContext; -} - -//------------------------------------------------------------------------------ - -struct ComputeHandle { - std::unique_ptr cudaHandles; - std::unique_ptr model; - std::unique_ptr scratch; - std::unique_ptr buffers; - const bool usingFP16; - const int nnXLen; - const int nnYLen; - const bool requireExactNNLen; - const bool inputsUseNHWC; - const bool usingNHWC; - - ComputeHandle( - const ComputeContext* context, - const LoadedModel* loadedModel, - int majorComputeCapability, - int minorComputeCapability, - int maxBatchSize, - bool requireExactNNLen_, - bool inputsUseNHWC_, - bool useFP16, - bool useNHWC - ) : - usingFP16(useFP16), - nnXLen(context->nnXLen), - nnYLen(context->nnYLen), - requireExactNNLen(requireExactNNLen_), - inputsUseNHWC(inputsUseNHWC_), - usingNHWC(useNHWC) - { - cudaHandles = std::make_unique(majorComputeCapability,minorComputeCapability); - model = std::make_unique( - cudaHandles.get(), &(loadedModel->modelDesc), maxBatchSize, - nnXLen, nnYLen, inputsUseNHWC, useFP16, useNHWC - ); - scratch = std::make_unique(maxBatchSize, nnXLen, nnYLen, useFP16); - buffers = std::make_unique(cudaHandles.get(), *model, *scratch); - - //Synchronize after creating buffers and copying all the weights, just in case - CUDA_ERR("ComputeHandle", hipDeviceSynchronize()); - } - ~ComputeHandle() { - } - - ComputeHandle() = delete; - ComputeHandle(const ComputeHandle&) = delete; - ComputeHandle& operator=(const ComputeHandle&) = delete; -}; - -ComputeHandle* NeuralNet::createComputeHandle( - ComputeContext* context, - const LoadedModel* loadedModel, - Logger* logger, - int maxBatchSize, - bool requireExactNNLen, - bool inputsUseNHWC, - int gpuIdxForThisThread, - int serverThreadIdx -) { - //Use whatever CUDA believes GPU 0 to be. - if(gpuIdxForThisThread == -1) - gpuIdxForThisThread = 0; - - CUDA_ERR("createComputeHandle",hipSetDevice(gpuIdxForThisThread)); - - hipDeviceProp_t prop; - hipGetDeviceProperties(&prop,gpuIdxForThisThread); - - bool useFP16 = false; - bool useNHWC = false; - if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) - useFP16 = true; - - // ROCm backend currently only supports NCHW format - if(inputsUseNHWC) { - if(logger != NULL) { - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": WARNING - NHWC format requested but not supported by ROCm backend, falling back to NCHW" - ); - } - } - - if(logger != NULL) { - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Found GPU " + string(prop.name) - + " memory " + Global::uint64ToString(prop.totalGlobalMem) - + " compute capability major " + Global::intToString(prop.major) - + " minor " + Global::intToString(prop.minor) - ); - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion) + - " useFP16 = " + Global::boolToString(useFP16) + - " useNHWC = " + Global::boolToString(useNHWC) - ); - logger->write( - "ROCm backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name - ); - logger->write( - "MIOpen finding convolution algorithms for GPU " + string(prop.name) + ". This may take a while, please wait......" - ); - } - - ComputeHandle* gpuHandle = new ComputeHandle( - context,loadedModel,prop.major,prop.minor,maxBatchSize,requireExactNNLen,inputsUseNHWC,useFP16,useNHWC - ); - return gpuHandle; -} - -void NeuralNet::freeComputeHandle(ComputeHandle* gpuHandle) { - delete gpuHandle; -} - -bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { - return handle->usingFP16; -} - -//------------------------------------------------------------------------------ - -void NeuralNet::printDevices() { - int numDevices = 0; - hipGetDeviceCount(&numDevices); - for(int i = 0; imodelDesc; - - maxBatchSize = maxBatchSz; - singleInputElts = (size_t)m.numInputChannels * nnXLen * nnYLen; - singleInputBytes = (size_t)m.numInputChannels * nnXLen * nnYLen * sizeof(float); - singleInputGlobalElts = (size_t)m.numInputGlobalChannels; - singleInputGlobalBytes = (size_t)m.numInputGlobalChannels * sizeof(float); - singleInputMetaElts = (size_t)m.numInputMetaChannels; - singleInputMetaBytes = (size_t)m.numInputMetaChannels * sizeof(float); - singlePolicyPassResultElts = (size_t)(m.numPolicyChannels); - singlePolicyPassResultBytes = (size_t)(m.numPolicyChannels) * sizeof(float); - singlePolicyResultElts = (size_t)(m.numPolicyChannels * nnXLen * nnYLen); - singlePolicyResultBytes = (size_t)(m.numPolicyChannels * nnXLen * nnYLen) * sizeof(float); - singleValueResultElts = (size_t)m.numValueChannels; - singleValueResultBytes = (size_t)m.numValueChannels * sizeof(float); - singleScoreValueResultElts = (size_t)m.numScoreValueChannels; - singleScoreValueResultBytes = (size_t)m.numScoreValueChannels * sizeof(float); - singleOwnershipResultElts = (size_t)m.numOwnershipChannels * nnXLen * nnYLen; - singleOwnershipResultBytes = (size_t)m.numOwnershipChannels * nnXLen * nnYLen * sizeof(float); - - assert(NNModelVersion::getNumSpatialFeatures(m.modelVersion) == m.numInputChannels); - assert(NNModelVersion::getNumGlobalFeatures(m.modelVersion) == m.numInputGlobalChannels); - if(m.numInputMetaChannels > 0) { - assert(SGFMetadata::METADATA_INPUT_NUM_CHANNELS == m.numInputMetaChannels); - } - - userInputBufferBytes = (size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen * sizeof(float); - userInputGlobalBufferBytes = (size_t)m.numInputGlobalChannels * maxBatchSize * sizeof(float); - userInputMetaBufferBytes = (size_t)m.numInputMetaChannels * maxBatchSize * sizeof(float); - policyPassResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * sizeof(float); - policyResultBufferBytes = (size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen * sizeof(float); - valueResultBufferBytes = (size_t)maxBatchSize * m.numValueChannels * sizeof(float); - scoreValueResultBufferBytes = (size_t)maxBatchSize * m.numScoreValueChannels * sizeof(float); - ownershipResultBufferBytes = (size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels * sizeof(float); - - userInputBuffer = new float[(size_t)m.numInputChannels * maxBatchSize * nnXLen * nnYLen]; - userInputGlobalBuffer = new float[(size_t)m.numInputGlobalChannels * maxBatchSize]; - if(m.numInputMetaChannels > 0) - userInputMetaBuffer = new float[(size_t)m.numInputMetaChannels * maxBatchSize]; - else - userInputMetaBuffer = NULL; - - policyPassResults = new float[(size_t)maxBatchSize * m.numPolicyChannels]; - policyResults = new float[(size_t)maxBatchSize * m.numPolicyChannels * nnXLen * nnYLen]; - valueResults = new float[(size_t)maxBatchSize * m.numValueChannels]; - - scoreValueResults = new float[(size_t)maxBatchSize * m.numScoreValueChannels]; - ownershipResults = new float[(size_t)maxBatchSize * nnXLen * nnYLen * m.numOwnershipChannels]; - } - - ~InputBuffers() { - delete[] userInputBuffer; - delete[] userInputGlobalBuffer; - if(userInputMetaBuffer != NULL) - delete[] userInputMetaBuffer; - delete[] policyPassResults; - delete[] policyResults; - delete[] valueResults; - delete[] scoreValueResults; - delete[] ownershipResults; - } - - InputBuffers() = delete; - InputBuffers(const InputBuffers&) = delete; - InputBuffers& operator=(const InputBuffers&) = delete; - -}; - -InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { - return new InputBuffers(loadedModel,maxBatchSize,nnXLen,nnYLen); -} -void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { - delete inputBuffers; -} - -//--------------------------------------------------------------------------------------- - - -void NeuralNet::getOutput( - ComputeHandle* gpuHandle, - InputBuffers* inputBuffers, - int numBatchEltsFilled, - NNResultBuf** inputBufs, - vector& outputs -) { - assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); - assert(numBatchEltsFilled > 0); - const int batchSize = numBatchEltsFilled; - const int nnXLen = gpuHandle->nnXLen; - const int nnYLen = gpuHandle->nnYLen; - const int modelVersion = gpuHandle->model->modelVersion; - - const int numSpatialFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); - const int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); - const int numMetaFeatures = inputBuffers->singleInputMetaElts; - assert(numSpatialFeatures == gpuHandle->model->numInputChannels); - assert(numSpatialFeatures * nnXLen * nnYLen == inputBuffers->singleInputElts); - assert(numGlobalFeatures == inputBuffers->singleInputGlobalElts); - const int numPolicyChannels = gpuHandle->model->numPolicyChannels; - - for(int nIdx = 0; nIdxuserInputBuffer + (inputBuffers->singleInputElts * nIdx); - float* rowGlobalInput = inputBuffers->userInputGlobalBuffer + (inputBuffers->singleInputGlobalElts * nIdx); - float* rowMetaInput = inputBuffers->userInputMetaBuffer + (inputBuffers->singleInputMetaElts * nIdx); - - const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); - const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); - const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); - bool hasRowMeta = inputBufs[nIdx]->hasRowMeta; - std::copy(rowGlobal,rowGlobal+numGlobalFeatures,rowGlobalInput); - if(numMetaFeatures > 0) { - testAssert(rowMeta != NULL); - testAssert(hasRowMeta); - std::copy(rowMeta,rowMeta+numMetaFeatures,rowMetaInput); - } - else { - testAssert(!hasRowMeta); - } - SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, gpuHandle->inputsUseNHWC, inputBufs[nIdx]->symmetry); - } - - Buffers* buffers = gpuHandle->buffers.get(); - ScratchBuffers* scratch = gpuHandle->scratch.get(); - - if(!gpuHandle->usingFP16) { - assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes); - assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes); - assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes); - assert(inputBuffers->policyPassResultBufferBytes == buffers->policyPassBufBytes); - assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); - assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); - assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); - assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); - assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); - assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); - assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); - assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); - assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); - assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); - assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); - assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); - assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); - - CUDA_ERR("getOutput",hipMemcpy(buffers->inputBuf, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); - CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBuf, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); - if(numMetaFeatures > 0) { - CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBuf, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); - } - } - else { - assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytesFloat); - assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytesFloat); - assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytesFloat); - assert(inputBuffers->policyResultBufferBytes == buffers->policyBufBytes); - assert(inputBuffers->valueResultBufferBytes == buffers->valueBufBytes); - assert(inputBuffers->userInputBufferBytes == buffers->inputBufBytes*2); - assert(inputBuffers->userInputGlobalBufferBytes == buffers->inputGlobalBufBytes*2); - assert(inputBuffers->userInputMetaBufferBytes == buffers->inputMetaBufBytes*2); - assert(inputBuffers->singleInputBytes == inputBuffers->singleInputElts*4); - assert(inputBuffers->singleInputGlobalBytes == inputBuffers->singleInputGlobalElts*4); - assert(inputBuffers->singleInputMetaBytes == inputBuffers->singleInputMetaElts*4); - assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); - assert(inputBuffers->singlePolicyPassResultBytes == numPolicyChannels * sizeof(float)); - assert(inputBuffers->singlePolicyResultElts == numPolicyChannels*nnXLen*nnYLen); - assert(inputBuffers->singlePolicyResultBytes == numPolicyChannels*nnXLen*nnYLen * sizeof(float)); - assert(inputBuffers->scoreValueResultBufferBytes == buffers->scoreValueBufBytes); - assert(inputBuffers->ownershipResultBufferBytes == buffers->ownershipBufBytes); - assert(inputBuffers->singleOwnershipResultElts == nnXLen*nnYLen); - assert(inputBuffers->singleOwnershipResultBytes == nnXLen*nnYLen * sizeof(float)); - - CUDA_ERR("getOutput",hipMemcpy(buffers->inputBufFloat, inputBuffers->userInputBuffer, inputBuffers->singleInputBytes*batchSize, hipMemcpyHostToDevice)); - CUDA_ERR("getOutput",hipMemcpy(buffers->inputGlobalBufFloat, inputBuffers->userInputGlobalBuffer, inputBuffers->singleInputGlobalBytes*batchSize, hipMemcpyHostToDevice)); - if(numMetaFeatures > 0) { - CUDA_ERR("getOutput",hipMemcpy(buffers->inputMetaBufFloat, inputBuffers->userInputMetaBuffer, inputBuffers->singleInputMetaBytes*batchSize, hipMemcpyHostToDevice)); - } - - customCudaCopyToHalf((const float*)buffers->inputBufFloat,(half*)buffers->inputBuf,inputBuffers->singleInputElts*batchSize); - CUDA_ERR("getOutput",hipPeekAtLastError()); - customCudaCopyToHalf((const float*)buffers->inputGlobalBufFloat,(half*)buffers->inputGlobalBuf,inputBuffers->singleInputGlobalElts*batchSize); - CUDA_ERR("getOutput",hipPeekAtLastError()); - if(numMetaFeatures > 0) { - customCudaCopyToHalf((const float*)buffers->inputMetaBufFloat,(half*)buffers->inputMetaBuf,inputBuffers->singleInputMetaElts*batchSize); - CUDA_ERR("getOutput",hipPeekAtLastError()); - } - } - - gpuHandle->model->apply( - gpuHandle->cudaHandles.get(), - scratch, - batchSize, - gpuHandle->requireExactNNLen, - - buffers->inputBuf, - buffers->inputGlobalBuf, - buffers->inputMetaBuf, - - buffers->policyPassBuf, - buffers->policyBuf, - - buffers->valueBuf, - buffers->scoreValueBuf, - buffers->ownershipBuf, - - buffers->workspaceBuf, - buffers->workspaceBytes - ); - - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyPassResults, buffers->policyPassBuf, inputBuffers->singlePolicyPassResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->policyResults, buffers->policyBuf, inputBuffers->singlePolicyResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->valueResults, buffers->valueBuf, inputBuffers->singleValueResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->scoreValueResults, buffers->scoreValueBuf, inputBuffers->singleScoreValueResultBytes*batchSize, hipMemcpyDeviceToHost)); - CUDA_ERR("getOutput",hipMemcpy(inputBuffers->ownershipResults, buffers->ownershipBuf, inputBuffers->singleOwnershipResultBytes*batchSize, hipMemcpyDeviceToHost)); - - assert(outputs.size() == batchSize); - - float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; - - for(int row = 0; row < batchSize; row++) { - NNOutput* output = outputs[row]; - assert(output->nnXLen == nnXLen); - assert(output->nnYLen == nnYLen); - float policyOptimism = (float)inputBufs[row]->policyOptimism; - - const float* policyPassSrcBuf = inputBuffers->policyPassResults + row * numPolicyChannels; - const float* policySrcBuf = inputBuffers->policyResults + row * numPolicyChannels * nnXLen * nnYLen; - float* policyProbs = output->policyProbs; - - // These are in logits, the client does the postprocessing to turn them into - // policy probabilities and white game outcome probabilities - // Also we don't fill in the nnHash here either - // Handle version >= 12 policy optimism - if(numPolicyChannels == 2 || (numPolicyChannels == 4 && modelVersion >= 16)) { - if(gpuHandle->usingNHWC) { - for(int i = 0; isymmetry); - policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; - } - else { - for(int i = 0; isymmetry); - policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; - } - } - else { - assert(numPolicyChannels == 1); - SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0]; - } - - int numValueChannels = gpuHandle->model->numValueChannels; - assert(numValueChannels == 3); - output->whiteWinProb = inputBuffers->valueResults[row * numValueChannels]; - output->whiteLossProb = inputBuffers->valueResults[row * numValueChannels + 1]; - output->whiteNoResultProb = inputBuffers->valueResults[row * numValueChannels + 2]; - - //As above, these are NOT actually from white's perspective, but rather the player to move. - //As usual the client does the postprocessing. - if(output->whiteOwnerMap != NULL) { - const float* ownershipSrcBuf = inputBuffers->ownershipResults + row * nnXLen * nnYLen; - assert(gpuHandle->model->numOwnershipChannels == 1); - SymmetryHelpers::copyOutputsWithSymmetry(ownershipSrcBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - } - - if(modelVersion >= 9) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 6); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; - output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; - output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 4]; - output->shorttermScoreError = inputBuffers->scoreValueResults[row * numScoreValueChannels + 5]; - } - else if(modelVersion >= 8) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 4); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; - output->whiteLead = inputBuffers->scoreValueResults[row * numScoreValueChannels + 2]; - output->varTimeLeft = inputBuffers->scoreValueResults[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(modelVersion >= 4) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 2); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - output->whiteScoreMeanSq = inputBuffers->scoreValueResults[row * numScoreValueChannels + 1]; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(modelVersion >= 3) { - int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; - assert(numScoreValueChannels == 1); - output->whiteScoreMean = inputBuffers->scoreValueResults[row * numScoreValueChannels]; - //Version 3 neural nets don't have any second moment output, implicitly already folding it in, so we just use the mean squared - output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else { - ASSERT_UNREACHABLE; - } - } - -} - -//TESTING ---------------------------------------------------------------------------------- - - -bool NeuralNet::testEvaluateConv( - const ConvLayerDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->inChannels; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->outChannels; - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateConv: unexpected input buffer size"); - - void* deviceInput; - void* deviceOutput; - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); - - int maxBatchSize = desiredBatchSize; - - CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); - ConvLayer* convLayer = new ConvLayer(cudaHandles,manager,desc,useFP16,useNHWC); - - size_t workspaceBytes = - convLayer->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); - void* deviceWorkspace; - CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); - - - bool accumulate = false; - convLayer->apply( - cudaHandles, - desiredBatchSize, - accumulate, - deviceInput, - deviceOutput, - deviceWorkspace, - workspaceBytes - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); - - hipFree(deviceWorkspace); - - delete convLayer; - delete manager; - hipFree(deviceInput); - hipFree(deviceOutput); - delete cudaHandles; - - return true; -} - - -bool NeuralNet::testEvaluateBatchNorm( - const BatchNormLayerDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - const vector& maskBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; - size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->numChannels; - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateBatchNorm: unexpected input buffer size"); - if(numMaskFloats != maskBuffer.size()) - throw StringError("testEvaluateBatchNorm: unexpected mask buffer size"); - - ActivationLayerDesc actDesc; - actDesc.activation = ACTIVATION_IDENTITY; - - void* deviceInput; - void* deviceMask; - void* deviceOutput; - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); - CudaUtils::mallocOnDevice("deviceOutput", numOutputFloats, deviceOutput, useFP16); - - BatchNormLayer* batchNormLayer = new BatchNormLayer(cudaHandles,desc,&actDesc,nnXLen,nnYLen,useFP16,useNHWC); - - batchNormLayer->apply( - cudaHandles, - desiredBatchSize, - deviceInput, - deviceMask, - deviceOutput - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceOutput, useFP16); - - delete batchNormLayer; - - hipFree(deviceInput); - hipFree(deviceMask); - hipFree(deviceOutput); - delete cudaHandles; - - return true; -} - - -bool NeuralNet::testEvaluateResidualBlock( - const ResidualBlockDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - const vector& maskBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; - size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateResidualBlock: unexpected input buffer size"); - if(numMaskFloats != maskBuffer.size()) - throw StringError("testEvaluateResidualBlock: unexpected mask buffer size"); - - ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); - - void* deviceInput; - void* deviceMask; - void* deviceScratch; - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); - CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); - - int maxBatchSize = desiredBatchSize; - - CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); - ResidualBlock* residualBlock = new ResidualBlock(cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC); - - size_t workspaceBytes = - residualBlock->requiredWorkspaceBytes(cudaHandles,desiredBatchSize); - void* deviceWorkspace; - CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); - - residualBlock->apply( - cudaHandles, - scratch, - desiredBatchSize, - deviceInput, - deviceScratch, - deviceMask, - deviceWorkspace, - workspaceBytes - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); - - hipFree(deviceWorkspace); - - delete residualBlock; - delete manager; - hipFree(deviceInput); - hipFree(deviceMask); - hipFree(deviceScratch); - delete scratch; - delete cudaHandles; - - return true; -} - -bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( - const GlobalPoolingResidualBlockDesc* desc, - int desiredBatchSize, - int nnXLen, - int nnYLen, - bool useFP16, - bool useNHWC, - const vector& inputBuffer, - const vector& maskBuffer, - vector& outputBuffer -) { - hipDeviceSynchronize(); - CudaHandles* cudaHandles = CudaHandles::cudaHandlesTesting(); - - size_t numInputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->preBN.numChannels; - size_t numMaskFloats = (size_t)desiredBatchSize * nnXLen * nnYLen; - size_t numMaskSumFloats = (size_t)desiredBatchSize; - size_t numOutputFloats = (size_t)desiredBatchSize * nnXLen * nnYLen * desc->finalConv.outChannels; - - if(numInputFloats != inputBuffer.size()) - throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected input buffer size"); - if(numMaskFloats != maskBuffer.size()) - throw StringError("testEvaluateGlobalPoolingResidualBlock: unexpected mask buffer size"); - - ScratchBuffers* scratch = new ScratchBuffers(desiredBatchSize, nnXLen, nnYLen, useFP16); - - void* deviceInput; - void* deviceMask; - float* deviceMaskFloatOrig; - float* deviceMaskFloat; - float* deviceMaskSum; - void* deviceScratch; - - CudaUtils::mallocAndCopyToDevice("deviceInput", inputBuffer.data(), numInputFloats, deviceInput, useFP16); - CudaUtils::mallocAndCopyToDevice("deviceMask", maskBuffer.data(), numMaskFloats, deviceMask, useFP16); - CUDA_ERR("deviceMaskFloat",hipMalloc(reinterpret_cast(&deviceMaskFloat), numMaskFloats * sizeof(float))); - CUDA_ERR("deviceMaskSum",hipMalloc(reinterpret_cast(&deviceMaskSum), numMaskSumFloats * sizeof(float))); - deviceMaskFloatOrig = deviceMaskFloat; - CudaUtils::mallocOnDevice("deviceScratch", numInputFloats, deviceScratch, useFP16); - - fillMaskFloatBufAndMaskSumBuf(deviceMask, deviceMaskFloat, deviceMaskSum, useFP16, desiredBatchSize, nnXLen, nnYLen); - - int maxBatchSize = desiredBatchSize; - - CudnnManager* manager = new CudnnManager("manager",maxBatchSize,nnXLen,nnYLen); - GlobalPoolingResidualBlock* residualBlock = new GlobalPoolingResidualBlock( - cudaHandles,manager,desc,nnXLen,nnYLen,useFP16,useNHWC - ); - - size_t workspaceBytes = - residualBlock->requiredWorkspaceBytes( - cudaHandles,desiredBatchSize - ); - - void* deviceWorkspace; - CUDA_ERR("deviceWorkspace",hipMalloc(&deviceWorkspace, workspaceBytes)); - - residualBlock->apply( - cudaHandles, - scratch, - desiredBatchSize, - deviceInput, - deviceScratch, - deviceMask, - deviceMaskSum, - deviceWorkspace, - workspaceBytes - ); - - outputBuffer.resize(numOutputFloats); - CudaUtils::expensiveCopyFromDevice("copyResultsToHost", outputBuffer.data(), numOutputFloats, deviceInput, useFP16); - - hipFree(deviceWorkspace); - - delete residualBlock; - delete manager; - - hipFree(deviceInput); - hipFree(deviceMask); - hipFree(deviceMaskFloatOrig); - hipFree(deviceMaskSum); - hipFree(deviceScratch); - delete scratch; - delete cudaHandles; - - return true; -} - - -#endif // USE_ROCM_BACKEND diff --git a/cpp/neuralnet/rocmerrorcheck.h b/cpp/neuralnet/rocmerrorcheck.h deleted file mode 100644 index 8cb214ad7e..0000000000 --- a/cpp/neuralnet/rocmerrorcheck.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef NEURALNET_ROCMERRORCHECK_H_ -#define NEURALNET_ROCMERRORCHECK_H_ - -#include "../neuralnet/rocmincludes.h" -#include "../core/global.h" - -// ---------- HIP runtime ---------- -static inline void checkCudaError(hipError_t status, - const char* opName, - const char* file, - const char* func, - int line) { - if(status != hipSuccess) - throw StringError(std::string("HIP Error @") + opName + " " + - file + ":" + func + ":" + Global::intToString(line) + - " : " + hipGetErrorString(status)); -} -#define CUDA_ERR(opName,x) checkCudaError((x),opName,__FILE__,#x,__LINE__) - -// ---------- hipBLAS ---------- -static inline const char* cublasGetErrorString(hipblasStatus_t s) { - switch(s) { - case HIPBLAS_STATUS_SUCCESS: return "HIPBLAS_STATUS_SUCCESS"; - case HIPBLAS_STATUS_ALLOC_FAILED: return "HIPBLAS_STATUS_ALLOC_FAILED"; - case HIPBLAS_STATUS_MAPPING_ERROR: return "HIPBLAS_STATUS_MAPPING_ERROR"; - case HIPBLAS_STATUS_EXECUTION_FAILED: return "HIPBLAS_STATUS_EXECUTION_FAILED"; - case HIPBLAS_STATUS_INTERNAL_ERROR: return "HIPBLAS_STATUS_INTERNAL_ERROR"; - case HIPBLAS_STATUS_INVALID_VALUE: return "HIPBLAS_STATUS_INVALID_VALUE"; - case HIPBLAS_STATUS_NOT_INITIALIZED: return "HIPBLAS_STATUS_NOT_INITIALIZED"; - case HIPBLAS_STATUS_NOT_SUPPORTED: return "HIPBLAS_STATUS_NOT_SUPPORTED"; - default: return "HIPBLAS_STATUS_UNKNOWN"; - } -} -static inline void checkCublasError(hipblasStatus_t status, - const char* opName, - const char* file, - const char* func, - int line) { - if(status != HIPBLAS_STATUS_SUCCESS) - throw StringError(std::string("hipBLAS Error @") + opName + " " + - file + ":" + func + ":" + Global::intToString(line) + - " : " + cublasGetErrorString(status)); -} -#define CUBLAS_ERR(opName,x) checkCublasError((x),opName,__FILE__,#x,__LINE__) - -// ---------- MIOpen ---------- -static inline void checkCudnnError(miopenStatus_t status, - const char* opName, - const char* file, - const char* func, - int line) { - if(status != miopenStatusSuccess) - throw StringError(std::string("MIOpen Error @") + opName + " " + - file + ":" + func + ":" + Global::intToString(line) + - " : " + miopenGetErrorString(status)); -} -#define CUDNN_ERR(opName,x) checkCudnnError((x),opName,__FILE__,#x,__LINE__) - -#endif // NEURALNET_ROCMERRORCHECK_H_ diff --git a/cpp/neuralnet/rocmhelpers.h b/cpp/neuralnet/rocmhelpers.h deleted file mode 100644 index 489142cfd3..0000000000 --- a/cpp/neuralnet/rocmhelpers.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef NEURALNET_ROCMHELPERS_H_ -#define NEURALNET_ROCMHELPERS_H_ - -#include "../neuralnet/rocmincludes.h" -#include "../neuralnet/activations.h" - -//Given two tensors with shapes inA: [n,cA,h,w] and inB: [n,cB,h,w], that are on the GPU -//Copy them into a single tensor out: [n,cA+cB,h,w] that is also allocated on the gpu -void customCudaChannelConcat(const float* inA, const float* inB, float* out, int chwA, int chwB, int n); -void customCudaChannelConcat(const half* inA, const half* inB, half* out, int chwA, int chwB, int n); - -//Given a tensor [n,c,hw], extract out channel 0 to [n,hw] -void customCudaChannel0ExtractNCHW(const float* in, float* out, int n, int c, int hw); -void customCudaChannel0ExtractNCHW(const half* in, half* out, int n, int c, int hw); -//Given a tensor [n,hw,c], extract out channel 0 to [n,hw] -void customCudaChannel0ExtractNHWC(const float* in, float* out, int n, int hw, int c); -void customCudaChannel0ExtractNHWC(const half* in, half* out, int n, int hw, int c); - -//Given an input tensor and an output buffer of shape [n,c], fill output buffer with sum or max over c. -void customCudaPoolRowsSumNCHW(const float* in, float* out, int nSize, int cSize, int xySize, float scaleSum); -void customCudaPoolRowsSumNHWC(const float* in, float* out, int nSize, int xySize, int cSize, float scaleSum); - -//Specialized operations for value head and general global pooling. Same as the other pooling, but fusedly fills -//an output buffer of shape [n,c*3]. -void customCudaValueHeadPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* maskSum); -void customCudaValueHeadPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* maskSum); -void customCudaPoolRowsGPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* mask, const float* maskSum); -void customCudaPoolRowsGPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* mask, const float* maskSum); -void customCudaPoolRowsGPoolNCHW(const half* in, half* out, int nSize, int cSize, int xySize, const half* mask, const float* maskSum); -void customCudaPoolRowsGPoolNHWC(const half* in, half* out, int nSize, int xySize, int cSize, const half* mask, const float* maskSum); - -void customCudaCopyToHalf(const float* in, half* out, int n); -void customCudaCopyFromHalf(const half* in, float* out, int n); - -//Given a tensor, add another tensor to it. -void customCudaAddTensorInplace(half* buf, const half* biases, int n); -//Given an input with shape [n,c] and biases of shape [c], add the biases in-place. -void customCudaAddCBiasInplaceNC(float* buf, const float* biases, int n, int c, int activation); -void customCudaAddCBiasInplaceNC(half* buf, const half* biases, int n, int c, int activation); -//Given an input with shape [n,c,xy] and biases of shape [n,c], add the biases in-place. -void customCudaAddNCBiasInplaceNCHW(float *buf, const float* biases, int nSize, int cSize, int xySize); -void customCudaAddNCBiasInplaceNCHW(half *buf, const half* biases, int nSize, int cSize, int xySize); -//Given an input with shape [n,xy,c] and biases of shape [n,c], add the biases in-place. -void customCudaAddNCBiasInplaceNHWC(float *buf, const float* biases, int nSize, int xySize, int cSize); -void customCudaAddNCBiasInplaceNHWC(half *buf, const half* biases, int nSize, int xySize, int cSize); - -//Given an input with shape [n,c,xy] and scale and biases of shape [c], multiply by scale and add the biases -//Optionally also apply an activation. -//Optionally also multiply by mask (can be null), with shape [n,xy] -void customCudaApplyCScaleBiasNCHW(const float* in, float* out, const float* scale, const float* biases, const float* mask, int n, int c, int xy, int activation); -void customCudaApplyCScaleBiasNCHW(const half* in, half* out, const half* scale, const half* biases, const half* mask, int n, int c, int xy, int activation); -//Given an input with shape [n,xy,c] and scale and biases of shape [c], multiply by scale and add the biases -//Optionally also apply relu. -//Optionally also multiply by mask (can be null), with shape [n,xy] -void customCudaApplyCScaleBiasNHWC(const float* in, float* out, const float* scale, const float* biases, const float* mask, int n, int xy, int c, int activation); -void customCudaApplyCScaleBiasNHWC(const half* in, half* out, const half* scale, const half* biases, const half* mask, int n, int xy, int c, int activation); - - -#endif // NEURALNET_ROCMHELPERS_H_ diff --git a/cpp/neuralnet/rocmhelpers.hip b/cpp/neuralnet/rocmhelpers.hip deleted file mode 100644 index 730b373613..0000000000 --- a/cpp/neuralnet/rocmhelpers.hip +++ /dev/null @@ -1,1905 +0,0 @@ -#include "hip/hip_runtime.h" - -#include "../neuralnet/rocmhelpers.h" - -#include - -#if defined(__HIP_ARCH_HAS_FP16__) || (defined(__HIP_DEVICE_COMPILE__) && (__HIP_ARCH_GFX803__ || __HIP_ARCH_GFX900__)) -#define HIP_SUPPORTS_FP16 -#endif - -//TODO maybe tune this number, it varies by GPU -static const int targetNumThreads = 512; - -void splitThreadsAcrossDim01(int dim0Size, int dim1Size, int& threads0, int& blocks0, int& threads1, int& blocks1) { - if(dim0Size > targetNumThreads) { - threads0 = targetNumThreads/2; - blocks0 = (dim0Size + threads0 - 1) / threads0; - threads1 = 1; - blocks1 = dim1Size; - } - else if(dim0Size > targetNumThreads/2) { - threads0 = dim0Size; - blocks0 = 1; - threads1 = 1; - blocks1 = dim1Size; - } - else { - threads0 = dim0Size; - blocks0 = 1; - threads1 = targetNumThreads / dim0Size; - blocks1 = (dim1Size + threads1 - 1) / threads1; - } -} - -__forceinline__ __device__ float mishf(float a) { - return a * tanhf(a < 20.0f ? log1pf(expf(a)) : a); -} -__forceinline__ __device__ float mishf_scale8(float a) { - return a < 2.5f ? a * tanhf(log1pf(expf(a*8.0f))) : a; -} - -#ifdef HIP_SUPPORTS_FP16 -__forceinline__ __device__ half mishh(half h) { - float a = __half2float(h); - return __float2half(a * tanhf(a < 20.0f ? log1pf(expf(a)) : a)); -} -__forceinline__ __device__ half mishh_scale8(half h) { - float a = __half2float(h); - return __float2half(a < 2.5f ? a * tanhf(log1pf(expf(a*8.0f))) : a); -} -#endif - -//-------------------------------------------------------------------------------------------------------------- - -template -__global__ -void channelConcatKernel( - const T* inA, - const T* inB, - T* out, - int chwA, - int chwB, - int numBlocksA, - int numBlocksB, - int n -) { - if(blockIdx.x < numBlocksA) { - int index = blockIdx.x * blockDim.x + threadIdx.x; - if(index < chwA) { - int nchwA = n*chwA; - int chwOut = (chwA+chwB); - - int aIdx = index; - int outIdx = index; - while(aIdx < nchwA) { - out[outIdx] = inA[aIdx]; - aIdx += chwA; - outIdx += chwOut; - } - } - } - else { - int index = (blockIdx.x - numBlocksA) * blockDim.x + threadIdx.x; - if(index < chwB) { - int nchwB = n*chwB; - int chwOut = (chwA+chwB); - - int bIdx = index; - int outIdx = chwA+index; - while(bIdx < nchwB) { - out[outIdx] = inB[bIdx]; - bIdx += chwB; - outIdx += chwOut; - } - } - } -} - -template -void customCudaChannelConcatTemplate(const T* inA, const T* inB, T* out, int chwA, int chwB, int n) { - int blockSize = targetNumThreads; - int numBlocksA = (chwA + blockSize-1) / blockSize; - int numBlocksB = (chwB + blockSize-1) / blockSize; - int numBlocks = numBlocksA + numBlocksB; - channelConcatKernel<<>>(inA,inB,out,chwA,chwB,numBlocksA,numBlocksB,n); -} -template void customCudaChannelConcatTemplate(const float* inA, const float* inB, float* out, int chwA, int chwB, int n); -template void customCudaChannelConcatTemplate(const half* inA, const half* inB, half* out, int chwA, int chwB, int n); - -void customCudaChannelConcat(const float* inA, const float* inB, float* out, int chwA, int chwB, int n) { - customCudaChannelConcatTemplate(inA,inB,out,chwA,chwB,n); -} -void customCudaChannelConcat(const half* inA, const half* inB, half* out, int chwA, int chwB, int n) { - customCudaChannelConcatTemplate(inA,inB,out,chwA,chwB,n); -} - -//-------------------------------------------------------------------------------------------------------------- - -template -__global__ -void extractChannel0KernelNHWC(const T *in, T* out, int nhwSize, int cSize) -{ - int nhwIdx = blockIdx.x * blockDim.x + threadIdx.x; - if(nhwIdx < nhwSize) { - out[nhwIdx] = in[nhwIdx*cSize]; - } -} -template -void customCudaChannel0ExtractNHWCTemplate(const T *in, T* out, int n, int hw, int c) { - int nhw = n*hw; - int blockSize = targetNumThreads; - int numBlocks = (nhw+blockSize-1)/blockSize; - extractChannel0KernelNHWC<<>>(in,out,nhw,c); -} - -template -__global__ -void extractChannel0KernelNCHW(const T *in, T* out, int nSize, int cSize, int hwSize) -{ - int hwIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(hwIdx < hwSize && nIdx < nSize) { - out[nIdx * hwSize + hwIdx] = in[nIdx * cSize * hwSize + hwIdx]; - } -} -template -void customCudaChannel0ExtractNCHWTemplate(const T *in, T* out, int nSize, int cSize, int hwSize) { - int hwThreads; - int hwBlocks; - int nThreads; - int nBlocks; - splitThreadsAcrossDim01(hwSize, nSize, hwThreads, hwBlocks, nThreads, nBlocks); - - if(nBlocks > 65536) - throw std::runtime_error("customCudaChannel0ExtractNCHW: nSize too large given hwSize"); - - dim3 grid(hwBlocks,nBlocks,1); - dim3 threads(hwThreads,nThreads,1); - extractChannel0KernelNCHW<<>>(in,out,nSize,cSize,hwSize); -} - -void customCudaChannel0ExtractNCHW(const float* in, float* out, int n, int c, int hw) { - customCudaChannel0ExtractNCHWTemplate(in,out,n,c,hw); -} -void customCudaChannel0ExtractNCHW(const half* in, half* out, int n, int c, int hw) { - customCudaChannel0ExtractNCHWTemplate(in,out,n,c,hw); -} -void customCudaChannel0ExtractNHWC(const float* in, float* out, int n, int hw, int c) { - customCudaChannel0ExtractNHWCTemplate(in,out,n,hw,c); -} -void customCudaChannel0ExtractNHWC(const half* in, half* out, int n, int hw, int c) { - customCudaChannel0ExtractNHWCTemplate(in,out,n,hw,c); -} - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void sumChannelsNCHWKernel(const float* in, float* out, int cSize, int xySize, float scaleSum) -{ - extern __shared__ float sumPoolNCHWShared[]; - int xyId = threadIdx.x; - int xyBlockDim = blockDim.x; - int cId = threadIdx.y; - int cBlockDim = blockDim.y; - int cIdx = blockIdx.y * cBlockDim + cId; - int nIdx = blockIdx.z; - - int xycSize = xySize*cSize; - int sharedIdx = xyId + cId * xyBlockDim; - - float acc = 0.0f; - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - acc += in[xyIdx + cIdx * xySize + nIdx * xycSize]; - xyIdx += xyBlockDim; - } - sumPoolNCHWShared[sharedIdx] = acc; - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumPoolNCHWShared[sharedIdx] += sumPoolNCHWShared[sharedIdx + s]; - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) - out[cIdx + nIdx * cSize] = sumPoolNCHWShared[sharedIdx] * scaleSum; -} -__global__ -void valueHeadPoolChannelsNCHWKernel(const float* in, float* out, int nSize, int cSize, int xySize, const float* maskSum) -{ - extern __shared__ float sumPoolNCHWShared[]; - int xyId = threadIdx.x; - int xyBlockDim = blockDim.x; - int cId = threadIdx.y; - int cBlockDim = blockDim.y; - int cIdx = blockIdx.y * cBlockDim + cId; - int nIdx = blockIdx.z; - - int xycSize = xySize*cSize; - int sharedIdx = xyId + cId * xyBlockDim; - - float acc = 0.0f; - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - acc += in[xyIdx + cIdx * xySize + nIdx * xycSize]; - xyIdx += xyBlockDim; - } - sumPoolNCHWShared[sharedIdx] = acc; - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumPoolNCHWShared[sharedIdx] += sumPoolNCHWShared[sharedIdx + s]; - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumPoolNCHWShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - out[cIdx + nIdx * cSize*3] = mean; - out[cIdx + nIdx * cSize*3 + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; - out[cIdx + nIdx * cSize*3 + cSize*2] = mean * ((sqrtdiv - 14.0f) * (sqrtdiv - 14.0f) * 0.01f - 0.1f); - } -} -__global__ -void gPoolChannelsNCHWKernel(const float* in, float* out, int cSize, int xySize, const float* maskSum, int sharedMemElts) -{ - extern __shared__ float poolNCHWShared[]; - float* sumShared = (float*)poolNCHWShared; - float* maxShared = (float*)poolNCHWShared + sharedMemElts; - - int xyId = threadIdx.x; - int xyBlockDim = blockDim.x; - int cId = threadIdx.y; - int cBlockDim = blockDim.y; - int cIdx = blockIdx.y * cBlockDim + cId; - int nIdx = blockIdx.z; - - int xycSize = xySize*cSize; - int sharedIdx = xyId + cId * xyBlockDim; - - if(cIdx < cSize) { - float accSum = 0.0f; - float accMax = -1.0f; - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = in[xyIdx + cIdx * xySize + nIdx * xycSize]; - accSum += a; - accMax = fmaxf(accMax, a); - xyIdx += xyBlockDim; - } - sumShared[sharedIdx] = accSum; - maxShared[sharedIdx] = accMax; - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = mean; - out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; - out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; - } -} -__global__ -void gPoolChannelsNCHWMaskKernel(const float* in, float* out, int cSize, int xySize, const float* mask, const float* maskSum, int sharedMemElts) -{ - extern __shared__ float poolNCHWShared[]; - float* sumShared = (float*)poolNCHWShared; - float* maxShared = (float*)poolNCHWShared + sharedMemElts; - - int xyId = threadIdx.x; - int xyBlockDim = blockDim.x; - int cId = threadIdx.y; - int cBlockDim = blockDim.y; - int cIdx = blockIdx.y * cBlockDim + cId; - int nIdx = blockIdx.z; - - int xycSize = xySize*cSize; - int sharedIdx = xyId + cId * xyBlockDim; - - if(cIdx < cSize) { - float accSum = 0.0f; - float accMax = -1.0f; - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = in[xyIdx + cIdx * xySize + nIdx * xycSize]; - accSum += a; - // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 - // which is lower than the lowest value that any current activation function will produce. - // so the max over all valid spaces will the same as the mask over all spaces including padding - // We're relying on all padded space being equal to 0 because this gpool only ever follows a BN+Activate with a mask. - accMax = fmaxf(accMax, a + (mask[xyIdx + nIdx * xySize] - 1.0f)); - xyIdx += xyBlockDim; - } - sumShared[sharedIdx] = accSum; - maxShared[sharedIdx] = accMax; - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = mean; - out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; - out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; - } -} - -void customCudaPoolRowsSumNCHW(const float* in, float* out, int nSize, int cSize, int xySize, float scaleSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaPoolRowsSumNCHW: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaPoolRowsSumNCHW: cSize too large"); - - //Use up as many threads as possible along the xy dimension. - int xyThreads = 1; - while(xyThreads < targetNumThreads && xyThreads < xySize/2) - xyThreads *= 2; - - //Distribute the extra threads along the c dimension. - int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //We need one shared memory spot per thread - int sharedMemSize = sizeof(float) * cThreads * xyThreads; - - dim3 grid(1,cBlocks,nSize); - dim3 threads(xyThreads,cThreads,1); - sumChannelsNCHWKernel<<>>(in,out,cSize,xySize,scaleSum); -} -void customCudaValueHeadPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* maskSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaValueHeadPoolNCHW: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaValueHeadPoolNCHW: cSize too large"); - - //Use up as many threads as possible along the xy dimension. - int xyThreads = 1; - while(xyThreads < targetNumThreads && xyThreads < xySize/2) - xyThreads *= 2; - - //Distribute the extra threads along the c dimension. - int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //We need one shared memory spot per thread - int sharedMemSize = sizeof(float) * cThreads * xyThreads; - - dim3 grid(1,cBlocks,nSize); - dim3 threads(xyThreads,cThreads,1); - valueHeadPoolChannelsNCHWKernel<<>>(in,out,nSize,cSize,xySize,maskSum); -} -void customCudaPoolRowsGPoolNCHW(const float* in, float* out, int nSize, int cSize, int xySize, const float* mask, const float* maskSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNCHW: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNCHW: cSize too large"); - - //Use up as many threads as possible along the xy dimension. - int xyThreads = 1; - while(xyThreads < targetNumThreads && xyThreads < xySize/2) - xyThreads *= 2; - - //Distribute the extra threads along the c dimension. - int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //We need one shared memory spot per thread, and then we double it because we need both sum and max. - //We also make sure it's a power of two to address any alignment concerns. - int sharedMemElts = 128; - while(sharedMemElts < cThreads * xyThreads) - sharedMemElts *= 2; - int sharedMemSize = sizeof(float) * sharedMemElts * 2; - - dim3 grid(1,cBlocks,nSize); - dim3 threads(xyThreads,cThreads,1); - if(mask != NULL) - gPoolChannelsNCHWMaskKernel<<>>(in,out,cSize,xySize,mask,maskSum,sharedMemElts); - else - gPoolChannelsNCHWKernel<<>>(in,out,cSize,xySize,maskSum,sharedMemElts); -} - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void gPoolChannelsNCHWHalfKernel(const half* in, half* out, int cSize, int xySize, const float* maskSum, int sharedMemElts) -{ -#ifdef HIP_SUPPORTS_FP16 - extern __shared__ float poolNCHWShared[]; - float* sumShared = (float*)poolNCHWShared; - float* maxShared = (float*)poolNCHWShared + sharedMemElts; - - int xyId = threadIdx.x; - int xyBlockDim = blockDim.x; - int cId = threadIdx.y; - int cBlockDim = blockDim.y; - int cIdx = blockIdx.y * cBlockDim + cId; - int nIdx = blockIdx.z; - - int xycSize = xySize*cSize; - int sharedIdx = xyId + cId * xyBlockDim; - - if(cIdx < cSize) { - float accSum = 0.0f; - float accMax = -1.0f; - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = __half2float(in[xyIdx + cIdx * xySize + nIdx * xycSize]); - accSum += a; - accMax = fmaxf(accMax, a); - xyIdx += xyBlockDim; - } - sumShared[sharedIdx] = accSum; - maxShared[sharedIdx] = accMax; - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = __float2half(mean); - out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); - out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void gPoolChannelsNCHWHalfMaskKernel(const half* in, half* out, int cSize, int xySize, const half* mask, const float* maskSum, int sharedMemElts) -{ -#ifdef HIP_SUPPORTS_FP16 - extern __shared__ float poolNCHWShared[]; - float* sumShared = (float*)poolNCHWShared; - float* maxShared = (float*)poolNCHWShared + sharedMemElts; - - int xyId = threadIdx.x; - int xyBlockDim = blockDim.x; - int cId = threadIdx.y; - int cBlockDim = blockDim.y; - int cIdx = blockIdx.y * cBlockDim + cId; - int nIdx = blockIdx.z; - - int xycSize = xySize*cSize; - int sharedIdx = xyId + cId * xyBlockDim; - - if(cIdx < cSize) { - float accSum = 0.0f; - float accMax = -1.0f; - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = __half2float(in[xyIdx + cIdx * xySize + nIdx * xycSize]); - accSum += a; - // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 - // which is lower than the lowest value that any current activation function will produce. - // so the max over all valid spaces will the same as the mask over all spaces including padding - accMax = fmaxf(accMax, a + (__half2float(mask[xyIdx + nIdx * xySize]) - 1.0f)); - xyIdx += xyBlockDim; - } - sumShared[sharedIdx] = accSum; - maxShared[sharedIdx] = accMax; - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], maxShared[sharedIdx + s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = __float2half(mean); - out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); - out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void customCudaPoolRowsGPoolNCHW(const half* in, half* out, int nSize, int cSize, int xySize, const half* mask, const float* maskSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNCHW: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNCHW: cSize too large"); - - //Use up as many threads as possible along the xy dimension. - int xyThreads = 1; - while(xyThreads < targetNumThreads && xyThreads < xySize/2) - xyThreads *= 2; - - //Distribute the extra threads along the c dimension. - int cThreads = (targetNumThreads < xyThreads) ? 1 : (targetNumThreads / xyThreads); - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //We need one shared memory spot per thread, and then we double it because we need both sum and max. - //We also make sure it's a power of two to address any alignment concerns. - int sharedMemElts = 128; - while(sharedMemElts < cThreads * xyThreads) - sharedMemElts *= 2; - int sharedMemSize = sizeof(float) * sharedMemElts * 2; - - dim3 grid(1,cBlocks,nSize); - dim3 threads(xyThreads,cThreads,1); - if(mask != NULL) - gPoolChannelsNCHWHalfMaskKernel<<>>(in,out,cSize,xySize,mask,maskSum,sharedMemElts); - else - gPoolChannelsNCHWHalfKernel<<>>(in,out,cSize,xySize,maskSum,sharedMemElts); -} - - - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void sumChannelsNHWCKernel(const float* in, float* out, int xySize, int cSize, float scaleSum) -{ - extern __shared__ float sumPoolNHWCShared[]; - int cId = threadIdx.x; - int cBlockDim = blockDim.x; - int xyId = threadIdx.y; - int xyBlockDim = blockDim.y; - - int cIdx = blockIdx.x * cBlockDim + cId; - int nIdx = blockIdx.z; - int sharedIdx = cId + cBlockDim * xyId; - int xycSize = xySize*cSize; - - sumPoolNHWCShared[sharedIdx] = 0; - - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - sumPoolNHWCShared[sharedIdx] += in[cIdx + xyIdx * cSize + nIdx * xycSize]; - xyIdx += xyBlockDim; - } - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumPoolNHWCShared[sharedIdx] += sumPoolNHWCShared[sharedIdx + cBlockDim * s]; - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) - out[cIdx + nIdx * cSize] = sumPoolNHWCShared[sharedIdx] * scaleSum; -} -__global__ -void valueHeadPoolChannelsNHWCKernel(const float* in, float* out, int nSize, int xySize, int cSize, const float* maskSum) -{ - extern __shared__ float sumPoolNHWCShared[]; - int cId = threadIdx.x; - int cBlockDim = blockDim.x; - int xyId = threadIdx.y; - int xyBlockDim = blockDim.y; - - int cIdx = blockIdx.x * cBlockDim + cId; - int nIdx = blockIdx.z; - int sharedIdx = cId + cBlockDim * xyId; - int xycSize = xySize*cSize; - - sumPoolNHWCShared[sharedIdx] = 0; - - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - sumPoolNHWCShared[sharedIdx] += in[cIdx + xyIdx * cSize + nIdx * xycSize]; - xyIdx += xyBlockDim; - } - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumPoolNHWCShared[sharedIdx] += sumPoolNHWCShared[sharedIdx + cBlockDim * s]; - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumPoolNHWCShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - out[cIdx + nIdx * cSize*3] = mean; - out[cIdx + nIdx * cSize*3 + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; - out[cIdx + nIdx * cSize*3 + cSize*2] = mean * ((sqrtdiv - 14.0f) * (sqrtdiv - 14.0f) * 0.01f - 0.1f); - } -} -__global__ -void gPoolChannelsNHWCKernel(const float* in, float* out, int xySize, int cSize, const float* maskSum, int sharedMemElts) -{ - extern __shared__ float poolNHWCShared[]; - float* sumShared = (float*)poolNHWCShared; - float* maxShared = (float*)poolNHWCShared + sharedMemElts; - - int cId = threadIdx.x; - int cBlockDim = blockDim.x; - int xyId = threadIdx.y; - int xyBlockDim = blockDim.y; - - int cIdx = blockIdx.x * cBlockDim + cId; - int nIdx = blockIdx.z; - int sharedIdx = cId + cBlockDim * xyId; - int xycSize = xySize*cSize; - - sumShared[sharedIdx] = 0; - maxShared[sharedIdx] = -1.0f; - - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = in[cIdx + xyIdx * cSize + nIdx * xycSize]; - sumShared[sharedIdx] += a; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a); - xyIdx += xyBlockDim; - } - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = mean; - out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; - out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; - } -} -__global__ -void gPoolChannelsNHWCMaskKernel(const float* in, float* out, int xySize, int cSize, const float* mask, const float* maskSum, int sharedMemElts) -{ - extern __shared__ float poolNHWCShared[]; - float* sumShared = (float*)poolNHWCShared; - float* maxShared = (float*)poolNHWCShared + sharedMemElts; - - int cId = threadIdx.x; - int cBlockDim = blockDim.x; - int xyId = threadIdx.y; - int xyBlockDim = blockDim.y; - - int cIdx = blockIdx.x * cBlockDim + cId; - int nIdx = blockIdx.z; - int sharedIdx = cId + cBlockDim * xyId; - int xycSize = xySize*cSize; - - sumShared[sharedIdx] = 0; - maxShared[sharedIdx] = -1.0f; - - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = in[cIdx + xyIdx * cSize + nIdx * xycSize]; - sumShared[sharedIdx] += a; - // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 - // which is lower than the lowest value that any current activation function will produce. - // so the max over all valid spaces will the same as the mask over all spaces including padding - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a + (mask[xyIdx + nIdx * xySize] - 1.0f)); - xyIdx += xyBlockDim; - } - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = mean; - out[cIdx + nIdx * (cSize*3) + cSize] = mean * (sqrtdiv - 14.0f) * 0.1f; - out[cIdx + nIdx * (cSize*3) + cSize*2] = maxShared[sharedIdx]; - } -} - - -void customCudaPoolRowsSumNHWC(const float* in, float* out, int nSize, int xySize, int cSize, float scaleSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaPoolRowsSumNHWC: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaPoolRowsSumNHWC: cSize too large"); - - //Use up to two warps worth of threads along the channel dimension, which is the - //most compact - int cThreads = 1; - while(cThreads < 64 && cThreads < cSize/2) - cThreads *= 2; - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //Distribute the extra threads to perform parallel reduction along the xy dimension. - int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); - - //We need one shared memory spot per thread - int sharedMemSize = sizeof(float) * cThreads * xyThreads; - - dim3 grid(cBlocks,1,nSize); - dim3 threads(cThreads,xyThreads,1); - sumChannelsNHWCKernel<<>>(in,out,xySize,cSize,scaleSum); -} - -void customCudaValueHeadPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* maskSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaValueHeadPoolNHWC: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaValueHeadPoolNHWC: cSize too large"); - - //Use up to two warps worth of threads along the channel dimension, which is the - //most compact - int cThreads = 1; - while(cThreads < 64 && cThreads < cSize/2) - cThreads *= 2; - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //Distribute the extra threads to perform parallel reduction along the xy dimension. - int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); - - //We need one shared memory spot per thread - int sharedMemSize = sizeof(float) * cThreads * xyThreads; - - dim3 grid(cBlocks,1,nSize); - dim3 threads(cThreads,xyThreads,1); - valueHeadPoolChannelsNHWCKernel<<>>(in,out,nSize,xySize,cSize,maskSum); -} - -void customCudaPoolRowsGPoolNHWC(const float* in, float* out, int nSize, int xySize, int cSize, const float* mask, const float* maskSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNHWC: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNHWC: cSize too large"); - - //Use up to two warps worth of threads along the channel dimension, which is the - //most compact - int cThreads = 1; - while(cThreads < 64 && cThreads < cSize/2) - cThreads *= 2; - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //Distribute the extra threads to perform parallel reduction along the xy dimension. - int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); - - //We need one shared memory spot per thread, and then we double it because we need both sum and max. - //We also make sure it's a power of two to address any alignment concerns. - int sharedMemElts = 128; - while(sharedMemElts < cThreads * xyThreads) - sharedMemElts *= 2; - int sharedMemSize = sizeof(float) * sharedMemElts * 2; - - dim3 grid(cBlocks,1,nSize); - dim3 threads(cThreads,xyThreads,1); - if(mask != NULL) - gPoolChannelsNHWCMaskKernel<<>>(in,out,xySize,cSize,mask,maskSum,sharedMemElts); - else - gPoolChannelsNHWCKernel<<>>(in,out,xySize,cSize,maskSum,sharedMemElts); -} - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void gPoolChannelsNHWCHalfKernel(const half* in, half* out, int xySize, int cSize, const float* maskSum, int sharedMemElts) -{ -#ifdef HIP_SUPPORTS_FP16 - extern __shared__ float poolNHWCShared[]; - float* sumShared = (float*)poolNHWCShared; - float* maxShared = (float*)poolNHWCShared + sharedMemElts; - - int cId = threadIdx.x; - int cBlockDim = blockDim.x; - int xyId = threadIdx.y; - int xyBlockDim = blockDim.y; - - int cIdx = blockIdx.x * cBlockDim + cId; - int nIdx = blockIdx.z; - int sharedIdx = cId + cBlockDim * xyId; - int xycSize = xySize*cSize; - - sumShared[sharedIdx] = 0; - maxShared[sharedIdx] = -1.0f; - - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = __half2float(in[cIdx + xyIdx * cSize + nIdx * xycSize]); - sumShared[sharedIdx] += a; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a); - xyIdx += xyBlockDim; - } - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = __float2half(mean); - out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); - out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void gPoolChannelsNHWCHalfMaskKernel(const half* in, half* out, int xySize, int cSize, const half* mask, const float* maskSum, int sharedMemElts) -{ -#ifdef HIP_SUPPORTS_FP16 - extern __shared__ float poolNHWCShared[]; - float* sumShared = (float*)poolNHWCShared; - float* maxShared = (float*)poolNHWCShared + sharedMemElts; - - int cId = threadIdx.x; - int cBlockDim = blockDim.x; - int xyId = threadIdx.y; - int xyBlockDim = blockDim.y; - - int cIdx = blockIdx.x * cBlockDim + cId; - int nIdx = blockIdx.z; - int sharedIdx = cId + cBlockDim * xyId; - int xycSize = xySize*cSize; - - sumShared[sharedIdx] = 0; - maxShared[sharedIdx] = -1.0f; - - if(cIdx < cSize) { - int xyIdx = xyId; - while(xyIdx < xySize) { - float a = __half2float(in[cIdx + xyIdx * cSize + nIdx * xycSize]); - sumShared[sharedIdx] += a; - // Init to -1.0 above and + mask - 1.0 is because it will effectively make all padded space into -1.0 - // which is lower than the lowest value that any current activation function will produce. - // so the max over all valid spaces will the same as the mask over all spaces including padding - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx], a + (__half2float(mask[xyIdx + nIdx * xySize]) - 1.0f)); - xyIdx += xyBlockDim; - } - } - __syncthreads(); - - for(int s = xyBlockDim>>1; s > 0; s >>= 1) { - if(xyId < s) { - sumShared[sharedIdx] += sumShared[sharedIdx + cBlockDim * s]; - maxShared[sharedIdx] = fmaxf(maxShared[sharedIdx],maxShared[sharedIdx + cBlockDim * s]); - } - __syncthreads(); - } - if(xyId == 0 && cIdx < cSize) { - float sum = sumShared[sharedIdx]; - float div = maskSum[nIdx]; - float sqrtdiv = sqrt(div); - float mean = sum/div; - - out[cIdx + nIdx * (cSize*3)] = __float2half(mean); - out[cIdx + nIdx * (cSize*3) + cSize] = __float2half(mean * (sqrtdiv - 14.0f) * 0.1f); - out[cIdx + nIdx * (cSize*3) + cSize*2] = __float2half(maxShared[sharedIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void customCudaPoolRowsGPoolNHWC(const half* in, half* out, int nSize, int xySize, int cSize, const half* mask, const float* maskSum) { - if(nSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNHWC: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaPoolRowsGPoolNHWC: cSize too large"); - - //Use up to two warps worth of threads along the channel dimension, which is the - //most compact - int cThreads = 1; - while(cThreads < 64 && cThreads < cSize/2) - cThreads *= 2; - int cBlocks = (cSize + cThreads - 1) / cThreads; - - //Distribute the extra threads to perform parallel reduction along the xy dimension. - int xyThreads = (targetNumThreads < cThreads) ? 1 : (targetNumThreads / cThreads); - - //We need one shared memory spot per thread, and then we double it because we need both sum and max. - //We also make sure it's a power of two to address any alignment concerns. - int sharedMemElts = 128; - while(sharedMemElts < cThreads * xyThreads) - sharedMemElts *= 2; - int sharedMemSize = sizeof(float) * sharedMemElts * 2; - - dim3 grid(cBlocks,1,nSize); - dim3 threads(cThreads,xyThreads,1); - if(mask != NULL) - gPoolChannelsNHWCHalfMaskKernel<<>>(in,out,xySize,cSize,mask,maskSum,sharedMemElts); - else - gPoolChannelsNHWCHalfKernel<<>>(in,out,xySize,cSize,maskSum,sharedMemElts); -} - - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void copyToHalfKernel(const float *in, half* out, int n) -{ - int idx = blockIdx.x * blockDim.x + threadIdx.x; - if(idx < n) { - out[idx] = __float2half(in[idx]); - } -} -__global__ -void copyFromHalfKernel(const half *in, float* out, int n) -{ - int idx = blockIdx.x * blockDim.x + threadIdx.x; - if(idx < n) { - out[idx] = __half2float(in[idx]); - } -} - -void customCudaCopyToHalf(const float* in, half* out, int n) { - int blockSize = targetNumThreads; - int numBlocks = (n+blockSize-1)/blockSize; - copyToHalfKernel<<>>(in,out,n); -} -void customCudaCopyFromHalf(const half* in, float* out, int n) { - int blockSize = targetNumThreads; - int numBlocks = (n+blockSize-1)/blockSize; - copyFromHalfKernel<<>>(in,out,n); -} - -//-------------------------------------------------------------------------------------------------------------- - - -__global__ -void addTensorInplaceHalfKernel(half *buf, const half* biases, int nSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int idx = blockIdx.x * blockDim.x + threadIdx.x; - if(idx < nSize) { - buf[idx] = __hadd(buf[idx],biases[idx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -void customCudaAddTensorInplace(half* buf, const half* biases, int nSize) { - int blockSize = targetNumThreads; - int numBlocks = (nSize+blockSize-1)/blockSize; - addTensorInplaceHalfKernel<<>>(buf,biases,nSize); -} - -//-------------------------------------------------------------------------------------------------------------- - - -__global__ -void addCBiasInplaceNCKernel(float *buf, const float* biases, int nSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - buf[idx] = buf[idx] + biases[cIdx]; - } -} -__global__ -void addCBiasInplaceNCHalfKernel(half *buf, const half* biases, int nSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - buf[idx] = __hadd(buf[idx],biases[cIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} - -__global__ -void addCBiasInplaceNCKernelRelu(float *buf, const float* biases, int nSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - buf[idx] = fmaxf(buf[idx] + biases[cIdx],0.0f); - } -} -__global__ -void addCBiasInplaceNCHalfKernelRelu(half *buf, const half* biases, int nSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - const half halfzero = __float2half(0.0f); - half a = __hadd(buf[idx],biases[cIdx]); - buf[idx] = __hgt(a,halfzero) ? a : halfzero; - } -#else - //Do nothing, FP16 not supported -#endif -} - -__global__ -void addCBiasInplaceNCKernelMish(float *buf, const float* biases, int nSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - buf[idx] = mishf(buf[idx] + biases[cIdx]); - } -} -__global__ -void addCBiasInplaceNCHalfKernelMish(half *buf, const half* biases, int nSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - half a = __hadd(buf[idx],biases[cIdx]); - buf[idx] = mishh(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void addCBiasInplaceNCKernelMishScale8(float *buf, const float* biases, int nSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - buf[idx] = mishf_scale8(buf[idx] + biases[cIdx]); - } -} -__global__ -void addCBiasInplaceNCHalfKernelMishScale8(half *buf, const half* biases, int nSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int nIdx = blockIdx.y * blockDim.y + threadIdx.y; - if(cIdx < cSize && nIdx < nSize) { - int idx = nIdx * cSize + cIdx; - half a = __hadd(buf[idx],biases[cIdx]); - buf[idx] = mishh_scale8(a); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void sharedAddCBiasInplaceNC(void* buf, const void* biases, int nSize, int cSize, bool isHalf, int activation) { - int cThreads; - int cBlocks; - int nThreads; - int nBlocks; - splitThreadsAcrossDim01(cSize, nSize, cThreads, cBlocks, nThreads, nBlocks); - - if(nBlocks > 65536) - throw std::runtime_error("customCudaAddCBiasInplaceNC: nSize too large given cSize"); - - dim3 grid(cBlocks,nBlocks,1); - dim3 threads(cThreads,nThreads,1); - - if(activation == ACTIVATION_IDENTITY) { - if(isHalf) - addCBiasInplaceNCHalfKernel<<>>((half*)buf,(const half*)biases,nSize,cSize); - else - addCBiasInplaceNCKernel<<>>((float*)buf,(const float*)biases,nSize,cSize); - } - else if(activation == ACTIVATION_RELU) { - if(isHalf) - addCBiasInplaceNCHalfKernelRelu<<>>((half*)buf,(const half*)biases,nSize,cSize); - else - addCBiasInplaceNCKernelRelu<<>>((float*)buf,(const float*)biases,nSize,cSize); - } - else if(activation == ACTIVATION_MISH) { - if(isHalf) - addCBiasInplaceNCHalfKernelMish<<>>((half*)buf,(const half*)biases,nSize,cSize); - else - addCBiasInplaceNCKernelMish<<>>((float*)buf,(const float*)biases,nSize,cSize); - } - else if(activation == ACTIVATION_MISH_SCALE8) { - if(isHalf) - addCBiasInplaceNCHalfKernelMishScale8<<>>((half*)buf,(const half*)biases,nSize,cSize); - else - addCBiasInplaceNCKernelMishScale8<<>>((float*)buf,(const float*)biases,nSize,cSize); - } - else { - throw std::runtime_error("customCudaAddCBiasInplaceNC: unsupported activation"); - } -} - -void customCudaAddCBiasInplaceNC(float* buf, const float* biases, int nSize, int cSize, int activation) { - sharedAddCBiasInplaceNC(buf,biases,nSize,cSize,false,activation); -} -void customCudaAddCBiasInplaceNC(half* buf, const half* biases, int nSize, int cSize, int activation) { - sharedAddCBiasInplaceNC(buf,biases,nSize,cSize,true,activation); -} - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void addNCBiasInplaceNCHWKernel(float *buf, const float* biases, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int ncIdx = nIdx * cSize + cIdx; - int idx = ncIdx * sSize + sIdx; - buf[idx] = buf[idx] + biases[ncIdx]; - } -} -__global__ -void addNCBiasInplaceNCHWHalfKernel(half *buf, const half* biases, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int ncIdx = nIdx * cSize + cIdx; - int idx = ncIdx * sSize + sIdx; - buf[idx] = __hadd(buf[idx],biases[ncIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void sharedAddNCBiasInplaceNCHW(void *buf, const void* biases, int nSize, int cSize, int xySize, bool isHalf) { - if(nSize > 65536) - throw std::runtime_error("customCudaAddNCBiasInplaceNCHW: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaAddNCBiasInplaceNCHW: cSize too large"); - - int sSize = xySize; - int sThreads; - int sBlocks; - int cThreads; - int cBlocks; - splitThreadsAcrossDim01(sSize, cSize, sThreads, sBlocks, cThreads, cBlocks); - - dim3 grid(sBlocks,cBlocks,nSize); - dim3 threads(sThreads,cThreads,1); - if(isHalf) - addNCBiasInplaceNCHWHalfKernel<<>>((half*)buf,(const half*)biases,cSize,sSize); - else - addNCBiasInplaceNCHWKernel<<>>((float*)buf,(const float*)biases,cSize,sSize); -} - -void customCudaAddNCBiasInplaceNCHW(float *buf, const float* biases, int nSize, int cSize, int xySize) { - sharedAddNCBiasInplaceNCHW(buf,biases,nSize,cSize,xySize,false); -} -void customCudaAddNCBiasInplaceNCHW(half *buf, const half* biases, int nSize, int cSize, int xySize) { - sharedAddNCBiasInplaceNCHW(buf,biases,nSize,cSize,xySize,true); -} - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void addNCBiasInplaceNHWCKernel(float *buf, const float* biases, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int ncIdx = nIdx * cSize + cIdx; - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - buf[idx] = buf[idx] + biases[ncIdx]; - } -} -__global__ -void addNCBiasInplaceNHWCHalfKernel(half *buf, const half* biases, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int ncIdx = nIdx * cSize + cIdx; - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - buf[idx] = __hadd(buf[idx],biases[ncIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void sharedAddNCBiasInplaceNHWC(void *buf, const void* biases, int nSize, int xySize, int cSize, bool isHalf) { - if(nSize > 65536) - throw std::runtime_error("customCudaAddNCBiasInplaceNHWC: nSize too large"); - if(xySize > 65536) - throw std::runtime_error("customCudaAddNCBiasInplaceNHWC: xySize too large"); - - int sSize = xySize; - int cThreads; - int cBlocks; - int sThreads; - int sBlocks; - splitThreadsAcrossDim01(cSize, sSize, cThreads, cBlocks, sThreads, sBlocks); - - dim3 grid(cBlocks,sBlocks,nSize); - dim3 threads(cThreads,sThreads,1); - if(isHalf) - addNCBiasInplaceNHWCHalfKernel<<>>((half*)buf,(const half*)biases,sSize,cSize); - else - addNCBiasInplaceNHWCKernel<<>>((float*)buf,(const float*)biases,sSize,cSize); -} - -void customCudaAddNCBiasInplaceNHWC(float *buf, const float* biases, int nSize, int xySize, int cSize) { - sharedAddNCBiasInplaceNHWC(buf,biases,nSize,xySize,cSize,false); -} -void customCudaAddNCBiasInplaceNHWC(half *buf, const half* biases, int nSize, int xySize, int cSize) { - sharedAddNCBiasInplaceNHWC(buf,biases,nSize,xySize,cSize,true); -} - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void applyCScaleBiasNCHWKernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = in[idx] * scale[cIdx] + biases[cIdx]; - } -} -__global__ -void applyCScaleBiasNCHWReluKernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f); - } -} -__global__ -void applyCScaleBiasNCHWMishKernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]); - } -} -__global__ -void applyCScaleBiasNCHWMishScale8Kernel(const float *in, float* out, const float* scale, const float* biases, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]); - } -} -__global__ -void applyCScaleBiasNCHWMaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = (in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNCHWReluMaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNCHWMishMaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNCHWMishScale8MaskKernel(const float *in, float* out, const float* scale, const float* biases, const float* mask, int cSize, int sSize) -{ - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNCHWHalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = __hfma(in[idx],scale[cIdx],biases[cIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWReluHalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); - const half halfzero = __float2half(0.0f); - out[idx] = __hgt(a,halfzero) ? a : halfzero; - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWMishHalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); - out[idx] = mishh(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWMishScale8HalfKernel(const half *in, half* out, const half* scale, const half* biases, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); - out[idx] = mishh_scale8(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWMaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - out[idx] = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWReluMaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - const half halfzero = __float2half(0.0f); - out[idx] = __hgt(a,halfzero) ? a : halfzero; - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWMishMaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - out[idx] = mishh(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNCHWMishScale8MaskHalfKernel(const half *in, half* out, const half* scale, const half* biases, const half* mask, int cSize, int sSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int sIdx = blockIdx.x * blockDim.x + threadIdx.x; - int cIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * cSize + cIdx) * sSize + sIdx; - half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - out[idx] = mishh_scale8(a); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void sharedApplyCScaleBiasNCHW(const void* in, void* out, const void* scale, const void* biases, const void* mask, int nSize, int cSize, int xySize, bool isHalf, int activation) { - if(nSize > 65536) - throw std::runtime_error("customCudaApplyCScaleBiasNCHW: nSize too large"); - if(cSize > 65536) - throw std::runtime_error("customCudaApplyCScaleBiasNCHW: cSize too large"); - - int sSize = xySize; - int sThreads; - int sBlocks; - int cThreads; - int cBlocks; - splitThreadsAcrossDim01(sSize, cSize, sThreads, sBlocks, cThreads, cBlocks); - - dim3 grid(sBlocks,cBlocks,nSize); - dim3 threads(sThreads,cThreads,1); - if(mask == NULL) { - if(activation == ACTIVATION_IDENTITY) { - if(isHalf) - applyCScaleBiasNCHWHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); - else - applyCScaleBiasNCHWKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); - } - else if(activation == ACTIVATION_RELU) { - if(isHalf) - applyCScaleBiasNCHWReluHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); - else - applyCScaleBiasNCHWReluKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); - } - else if(activation == ACTIVATION_MISH) { - if(isHalf) - applyCScaleBiasNCHWMishHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); - else - applyCScaleBiasNCHWMishKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); - } - else if(activation == ACTIVATION_MISH_SCALE8) { - if(isHalf) - applyCScaleBiasNCHWMishScale8HalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,cSize,sSize); - else - applyCScaleBiasNCHWMishScale8Kernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,cSize,sSize); - } - else { - throw std::runtime_error("customCudaApplyCScaleBiasNCHW: unsupported activation"); - } - } - else { - if(activation == ACTIVATION_IDENTITY) { - if(isHalf) - applyCScaleBiasNCHWMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); - else - applyCScaleBiasNCHWMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); - } - else if(activation == ACTIVATION_RELU) { - if(isHalf) - applyCScaleBiasNCHWReluMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); - else - applyCScaleBiasNCHWReluMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); - } - else if(activation == ACTIVATION_MISH) { - if(isHalf) - applyCScaleBiasNCHWMishMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); - else - applyCScaleBiasNCHWMishMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); - } - else if(activation == ACTIVATION_MISH_SCALE8) { - if(isHalf) - applyCScaleBiasNCHWMishScale8MaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,cSize,sSize); - else - applyCScaleBiasNCHWMishScale8MaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,cSize,sSize); - } - else { - throw std::runtime_error("customCudaApplyCScaleBiasNCHW: unsupported activation"); - } - } -} - -void customCudaApplyCScaleBiasNCHW(const float* in, float* out, const float* scale, const float* biases, const float* mask, int nSize, int cSize, int xySize, int activation) { - sharedApplyCScaleBiasNCHW(in,out,scale,biases,mask,nSize,cSize,xySize,false,activation); -} -void customCudaApplyCScaleBiasNCHW(const half* in, half* out, const half* scale, const half* biases, const half* mask, int nSize, int cSize, int xySize, int activation) { - sharedApplyCScaleBiasNCHW(in,out,scale,biases,mask,nSize,cSize,xySize,true,activation); -} - - -//-------------------------------------------------------------------------------------------------------------- - -__global__ -void applyCScaleBiasNHWCKernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = in[idx] * scale[cIdx] + biases[cIdx]; - } -} -__global__ -void applyCScaleBiasNHWCReluKernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f); - } -} -__global__ -void applyCScaleBiasNHWCMishKernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]); - } -} -__global__ -void applyCScaleBiasNHWCMishScale8Kernel(const float* in, float* out, const float* scale, const float* biases, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]); - } -} -__global__ -void applyCScaleBiasNHWCMaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = (in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNHWCReluMaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = fmaxf(in[idx] * scale[cIdx] + biases[cIdx],0.0f) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNHWCMishMaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = mishf(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNHWCMishScale8MaskKernel(const float* in, float* out, const float* scale, const float* biases, const float* mask, int sSize, int cSize) -{ - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = mishf_scale8(in[idx] * scale[cIdx] + biases[cIdx]) * mask[nIdx*sSize+sIdx]; - } -} -__global__ -void applyCScaleBiasNHWCHalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = __hfma(in[idx],scale[cIdx],biases[cIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCReluHalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); - const half halfzero = __float2half(0.0f); - out[idx] = __hgt(a,halfzero) ? a : halfzero; - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCMishHalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); - out[idx] = mishh(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCMishScale8HalfKernel(const half* in, half* out, const half* scale, const half* biases, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - half a = __hfma(in[idx],scale[cIdx],biases[cIdx]); - out[idx] = mishh_scale8(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCMaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - out[idx] = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCReluMaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - const half halfzero = __float2half(0.0f); - out[idx] = __hgt(a,halfzero) ? a : halfzero; - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCMishMaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - out[idx] = mishh(a); - } -#else - //Do nothing, FP16 not supported -#endif -} -__global__ -void applyCScaleBiasNHWCMishScale8MaskHalfKernel(const half* in, half* out, const half* scale, const half* biases, const half* mask, int sSize, int cSize) -{ -#ifdef HIP_SUPPORTS_FP16 - int cIdx = blockIdx.x * blockDim.x + threadIdx.x; - int sIdx = blockIdx.y * blockDim.y + threadIdx.y; - int nIdx = blockIdx.z; - if(cIdx < cSize && sIdx < sSize) { - int idx = (nIdx * sSize + sIdx) * cSize + cIdx; - half a = __hmul(__hfma(in[idx],scale[cIdx],biases[cIdx]),mask[nIdx*sSize+sIdx]); - out[idx] = mishh_scale8(a); - } -#else - //Do nothing, FP16 not supported -#endif -} - -void sharedApplyCScaleBiasNHWC(const void* in, void* out, const void* scale, const void* biases, const void* mask, int nSize, int xySize, int cSize, bool isHalf, int activation) { - if(nSize > 65536) - throw std::runtime_error("customCudaApplyCScaleBiasNHWC: nSize too large"); - if(xySize > 65536) - throw std::runtime_error("customCudaApplyCScaleBiasNHWC: xySize too large"); - - int sSize = xySize; - int cThreads; - int cBlocks; - int sThreads; - int sBlocks; - splitThreadsAcrossDim01(cSize, sSize, cThreads, cBlocks, sThreads, sBlocks); - - dim3 grid(cBlocks,sBlocks,nSize); - dim3 threads(cThreads,sThreads,1); - if(mask == NULL) { - if(activation == ACTIVATION_IDENTITY) { - if(isHalf) - applyCScaleBiasNHWCHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); - else - applyCScaleBiasNHWCKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); - } - else if(activation == ACTIVATION_RELU) { - if(isHalf) - applyCScaleBiasNHWCReluHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); - else - applyCScaleBiasNHWCReluKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); - } - else if(activation == ACTIVATION_MISH) { - if(isHalf) - applyCScaleBiasNHWCMishHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); - else - applyCScaleBiasNHWCMishKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); - } - else if(activation == ACTIVATION_MISH_SCALE8) { - if(isHalf) - applyCScaleBiasNHWCMishScale8HalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,sSize,cSize); - else - applyCScaleBiasNHWCMishScale8Kernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,sSize,cSize); - } - else { - throw std::runtime_error("customCudaApplyCScaleBiasNHWC: unsupported activation"); - } - } - else { - if(activation == ACTIVATION_IDENTITY) { - if(isHalf) - applyCScaleBiasNHWCMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); - else - applyCScaleBiasNHWCMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); - } - else if(activation == ACTIVATION_RELU) { - if(isHalf) - applyCScaleBiasNHWCReluMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); - else - applyCScaleBiasNHWCReluMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); - } - else if(activation == ACTIVATION_MISH) { - if(isHalf) - applyCScaleBiasNHWCMishMaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); - else - applyCScaleBiasNHWCMishMaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); - } - else if(activation == ACTIVATION_MISH_SCALE8) { - if(isHalf) - applyCScaleBiasNHWCMishScale8MaskHalfKernel<<>>((const half*)in,(half*)out,(const half*)scale,(const half*)biases,(const half*)mask,sSize,cSize); - else - applyCScaleBiasNHWCMishScale8MaskKernel<<>>((const float*)in,(float*)out,(const float*)scale,(const float*)biases,(const float*)mask,sSize,cSize); - } - else { - throw std::runtime_error("customCudaApplyCScaleBiasNHWC: unsupported activation"); - } - } -} - -void customCudaApplyCScaleBiasNHWC(const float* in, float* out, const float* scale, const float* biases, const float* mask, int nSize, int xySize, int cSize, int activation) { - sharedApplyCScaleBiasNHWC(in,out,scale,biases,mask,nSize,xySize,cSize,false,activation); -} -void customCudaApplyCScaleBiasNHWC(const half* in, half* out, const half* scale, const half* biases, const half* mask, int nSize, int xySize, int cSize, int activation) { - sharedApplyCScaleBiasNHWC(in,out,scale,biases,mask,nSize,xySize,cSize,true,activation); -} diff --git a/cpp/neuralnet/rocmincludes.h b/cpp/neuralnet/rocmincludes.h deleted file mode 100644 index 8b494a37e1..0000000000 --- a/cpp/neuralnet/rocmincludes.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef NEURALNET_ROCMINCLUDES_H -#define NEURALNET_ROCMINCLUDES_H - -//Ensure that CUDA_API_PER_THREAD_DEFAULT_STREAM is always defined -//before any cuda headers are included so that we get the desired threading behavior for CUDA. - -#define CUDA_API_PER_THREAD_DEFAULT_STREAM -#include -#include - -#include -#include - - -#endif //NEURALNET_ROCMINCLUDES_H diff --git a/cpp/neuralnet/rocmutils.cpp b/cpp/neuralnet/rocmutils.cpp deleted file mode 100644 index 752298b7ff..0000000000 --- a/cpp/neuralnet/rocmutils.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "../neuralnet/rocmutils.h" - -#include -#include "../neuralnet/rocmerrorcheck.h" -#include "../neuralnet/rocmincludes.h" -#include "../neuralnet/rocmhelpers.h" - -#include "../external/half-2.2.0/include/half.hpp" - -//------------------------ -#include "../core/using.h" -//------------------------ - -using half_t = half_float::half; - -void CudaUtils::mallocOnDevice(const string& name, int numWeights, void*& deviceBuf, bool useFP16) { - if(useFP16) { - size_t halfBytes = numWeights * sizeof(half_t); - CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, halfBytes)); - } - else { - size_t floatBytes = numWeights * sizeof(float); - CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, floatBytes)); - } -} - -void CudaUtils::mallocAndCopyToDevice(const string& name, const vector& weights, void*& deviceBuf, bool useFP16) { - size_t numWeights = weights.size(); - if(useFP16) { - size_t halfBytes = numWeights * sizeof(half_t); - vector weightsHalf(weights.size()); - for(size_t i = 0; i(weights[i]); - CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, halfBytes)); - CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weightsHalf.data(), halfBytes, hipMemcpyHostToDevice)); - } - else { - size_t floatBytes = numWeights * sizeof(float); - CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, floatBytes)); - CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weights.data(), floatBytes, hipMemcpyHostToDevice)); - } -} - -void CudaUtils::mallocAndCopyToDevice(const string& name, const float* weights, int numWeights, void*& deviceBuf, bool useFP16) { - if(useFP16) { - size_t halfBytes = numWeights * sizeof(half_t); - vector weightsHalf(numWeights); - for(int i = 0; i(weights[i]); - CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, halfBytes)); - CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weightsHalf.data(), halfBytes, hipMemcpyHostToDevice)); - } - else { - size_t floatBytes = numWeights * sizeof(float); - CUDA_ERR(name.c_str(),hipMalloc(&deviceBuf, floatBytes)); - CUDA_ERR(name.c_str(),hipMemcpy(deviceBuf, weights, floatBytes, hipMemcpyHostToDevice)); - } -} - -//Only use in testing, allocates an intermediate buffer in the case of FP16 which will be very slow. -void CudaUtils::expensiveCopyFromDevice(const string& name, float* weights, int numWeights, const void* deviceBuf, bool useFP16) { - if(useFP16) { - vector weightsHalf(numWeights); - size_t halfBytes = numWeights * sizeof(half_t); - CUDA_ERR(name.c_str(),hipMemcpy(weightsHalf.data(), deviceBuf, halfBytes, hipMemcpyDeviceToHost)); - for(int i = 0; i values(batchSize * cSize); - expensiveCopyFromDevice(name, values.data(), values.size(), deviceBuf, useFP16); - cout << "=========================================================" << endl; - cout << "TENSOR" << endl; - cout << name << endl; - cout << std::setprecision(8); - int i = 0; - for(int n = 0; n values(batchSize * cSize * xSize * ySize); - expensiveCopyFromDevice(name, values.data(), values.size(), deviceBuf, useFP16); - cout << "=========================================================" << endl; - cout << "TENSOR" << endl; - cout << name << endl; - cout << std::setprecision(8); - int i = 0; - double total1 = 0; - double total2 = 0; - double total3 = 0; - for(int n = 0; n= (int64_t)1 << 31) - throw StringError("Batch size too large, resulting GPU buffers might exceed 2^31 entries which is not currently supported"); -} - -void CudaUtils::hostMallocZeroOneBufs(void*& zeroBuf, void*& oneBuf, bool useFP16) { - if(!useFP16) { - zeroBuf = malloc(sizeof(float)); - oneBuf = malloc(sizeof(float)); - *((float*)zeroBuf) = 0.0f; - *((float*)oneBuf) = 1.0f; - } - else { - //Convert to FP16 on the device, then copy back so we have it in host memory - float zero = 0.0f; - float one = 1.0f; - void* zeroTmp; - void* oneTmp; - mallocAndCopyToDevice("Buffers",&zero,1,zeroTmp,useFP16); - mallocAndCopyToDevice("Buffers",&one,1,oneTmp,useFP16); - zeroBuf = malloc(sizeof(half_t)); - oneBuf = malloc(sizeof(half_t)); - CUDA_ERR("Buffers",hipMemcpy(zeroBuf,zeroTmp,sizeof(half_t),hipMemcpyDeviceToHost)); - CUDA_ERR("Buffers",hipMemcpy(oneBuf,oneTmp,sizeof(half_t),hipMemcpyDeviceToHost)); - hipFree(zeroTmp); - hipFree(oneTmp); - } -} diff --git a/cpp/neuralnet/rocmutils.h b/cpp/neuralnet/rocmutils.h deleted file mode 100644 index d438684026..0000000000 --- a/cpp/neuralnet/rocmutils.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef NEURALNET_ROCMUTILS_H -#define NEURALNET_ROCMUTILS_H - -#include "../core/global.h" - -namespace CudaUtils { - void mallocOnDevice(const std::string& name, int numWeights, void*& deviceBuf, bool useFP16); - void mallocAndCopyToDevice(const std::string& name, const std::vector& weights, void*& deviceBuf, bool useFP16); - void mallocAndCopyToDevice(const std::string& name, const float* weights, int numWeights, void*& deviceBuf, bool useFP16); - - //Only use in testing, allocates an intermediate buffer in the case of FP16 which will be very slow. - void expensiveCopyFromDevice(const std::string& name, float* weights, int numWeights, const void* deviceBuf, bool useFP16); - - void debugPrint2D(const std::string& name, const void* deviceBuf, int batchSize, int cSize, bool useFP16); - void debugPrint4D(const std::string& name, const void* deviceBuf, int batchSize, int cSize, int xSize, int ySize, bool useNHWC, bool useFP16); - - void checkBufferSize(int batchSize, int xSize, int ySize, int channels); - void hostMallocZeroOneBufs(void*& zeroBuf, void*& oneBuf, bool useFP16); -} - -#endif // NEURALNET_ROCMUTILS_H diff --git a/cpp/program/gtpconfig.cpp b/cpp/program/gtpconfig.cpp index aa0e8393e2..8d1c6dc7d1 100644 --- a/cpp/program/gtpconfig.cpp +++ b/cpp/program/gtpconfig.cpp @@ -554,9 +554,6 @@ string GTPConfig::makeConfig( #ifdef USE_OPENCL_BACKEND replacement += "openclDeviceToUseThread" + Global::intToString(i) + " = " + Global::intToString(deviceIdxs[i]) + "\n"; #endif -#ifdef USE_ROCM_BACKEND - replacement += "rocmDeviceToUseThread" + Global::intToString(i) + " = " + Global::intToString(deviceIdxs[i]) + "\n"; -#endif #ifdef USE_ONNX_BACKEND if(onnxProviderSupportsThreadDeviceMap) replacement += "onnxDeviceToUseThread" + Global::intToString(i) + " = " + Global::intToString(deviceIdxs[i]) + "\n"; diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index 2c7ec0847a..1a9043bc33 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -19,7 +19,6 @@ std::vector Setup::getBackendPrefixes() { prefixes.push_back("trt"); prefixes.push_back("metal"); prefixes.push_back("opencl"); - prefixes.push_back("rocm"); prefixes.push_back("eigen"); prefixes.push_back("onnx"); prefixes.push_back("dummybackend"); @@ -88,8 +87,6 @@ vector Setup::initializeNNEvaluators( string backendPrefix = "metal"; #elif defined(USE_OPENCL_BACKEND) string backendPrefix = "opencl"; - #elif defined(USE_ROCM_BACKEND) - string backendPrefix = "rocm"; #elif defined(USE_ONNX_BACKEND) string backendPrefix = "onnx"; #elif defined(USE_EIGEN_BACKEND) @@ -162,7 +159,7 @@ vector Setup::initializeNNEvaluators( requireExactNNLen = cfg.getBool("requireMaxBoardSize"); } - bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" || backendPrefix == "rocm" || backendPrefix == "onnx" ? false : true; + bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" || backendPrefix == "onnx" ? false : true; if(cfg.contains(backendPrefix+"InputsUseNHWC"+idxStr)) inputsUseNHWC = cfg.getBool(backendPrefix+"InputsUseNHWC"+idxStr); else if(cfg.contains("inputsUseNHWC"+idxStr)) From 2630a9c0106717c3c8c34abfd79b1b03fa1de567 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Sun, 12 Jul 2026 17:53:45 +0800 Subject: [PATCH 25/37] Update to v1.16.5 --- .gitignore | 1 + Compiling.md | 29 ++++ cpp/CMakeLists.txt | 209 +++++++++++++++++++++- cpp/command/dumpcalibrationdata.cpp | 257 ++++++++++++++++++++++++++++ cpp/command/misc.cpp | 17 +- cpp/command/sandbox.cpp | 2 +- cpp/main.cpp | 3 + cpp/main.h | 1 + cpp/neuralnet/nneval.cpp | 20 ++- cpp/neuralnet/onnxbackend.cpp | 248 ++++++++++++++++++--------- cpp/neuralnet/onnxmodelbuilder.cpp | 32 +++- cpp/neuralnet/onnxmodelbuilder.h | 12 +- cpp/neuralnet/trtbackend.cpp | 2 +- cpp/program/setup.cpp | 45 +---- python/quantize_vitisai.py | 182 ++++++++++++++++++++ 15 files changed, 923 insertions(+), 137 deletions(-) create mode 100644 cpp/command/dumpcalibrationdata.cpp create mode 100644 python/quantize_vitisai.py diff --git a/.gitignore b/.gitignore index 5e8ac9f95c..6cc7ff125d 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,4 @@ cpp/build.ninja cpp/KataGoSwift.* cpp/include/KataGoSwift/KataGoSwift-swift.h cpp/external/katagocoreml/proto/ +cpp/external/onnxruntime-win-x64-vitisai/ diff --git a/Compiling.md b/Compiling.md index 0c6f63391d..ee29184abc 100644 --- a/Compiling.md +++ b/Compiling.md @@ -271,6 +271,35 @@ Typical run config for Intel NPU: Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). For `onnxProvider=openvino` on Intel NPU, a single device is typically used. +##### Windows AMD NPU (VitisAI EP) Setup +This branch defaults to the `onnxruntime-win-x64-vitisai` ONNX Runtime package (built with the VitisAI execution provider) rather than the OpenVINO one used above. It targets AMD Ryzen AI NPUs via the [AMD Ryzen AI / VitisAI SDK](https://ryzenai.docs.amd.com/). + +1. Install the Ryzen AI SDK (provides `onnxruntime_providers_vitisai.dll`'s runtime dependencies, `vaip_config.json`, and NPU `xclbin` firmware images). Typical install path: `C:\Program Files\RyzenAI\`. +2. Prepare `cpp/external/onnxruntime-win-x64-vitisai/{include,lib,bin}` with an ONNX Runtime build that includes the VitisAI EP (`onnxruntime_providers_vitisai.dll`/`.lib`), matching the ORT ABI version bundled with your Ryzen AI SDK. +3. CMake auto-detects the newest `RyzenAI\` folder under `%ProgramFiles%` at configure time (validated by the presence of `voe-*-win_amd64\vaip_config.json` inside it -- a stale `PATH` entry pointing at an uninstalled version is not trusted). Override with `-DRYZENAI_ROOT=...` or the `RYZENAI_ROOT` environment variable if auto-detection picks the wrong install or you have a nonstandard layout. +4. The build copies `vaip_config.json`, the `xclbins/` firmware directory, `xrt_coreutil.dll`, and the VitisAI EP's runtime dependency DLLs (`dyn_dispatch_core.dll`, `vaiml.dll`, `flexmlrt.dll`, etc., all from the Ryzen AI SDK's `deployment/` folder) next to `katago.exe` automatically. The ONNX Runtime core DLLs (`onnxruntime.dll`, `onnxruntime_providers_shared.dll`, `onnxruntime_providers_vitisai.dll`) come from `ONNXRUNTIME_ROOT` instead, to keep the ABI consistent with what KataGo was linked against. + +``` +cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX +cmake --build cpp/build --config Release -j +``` + +(`ONNXRUNTIME_ROOT` defaults to `cpp/external/onnxruntime-win-x64-vitisai` on this branch, so it does not need to be passed explicitly unless overriding.) + +Typical run config for AMD Ryzen AI NPU: +* `onnxProvider = vitisai` +* `onnxVitisAIConfigFile = ...` (optional; defaults to the auto-detected `vaip_config.json` baked in at build time) +* `onnxVitisAICacheDir = ...` (optional; defaults to `/vitisaicache` -- the NPU model compile is slow, on the order of minutes, so this cache avoids recompiling on every launch) +* `onnxVitisAIDisableCPUFallback = true` (default; fails loudly at session creation if any node can't run on the NPU, rather than silently falling back to CPU for that node) + +VitisAI only accelerates a quantized (INT8 QDQ) ONNX graph -- FP32 nodes fall back to CPU. To quantize a KataGo model: +1. `katago exportonnx -model .bin.gz -xlen 19 -ylen 19 -output model-fp32.onnx` -- export a fixed-size FP32 ONNX graph. +2. `katago dumpcalibrationdata -model .bin.gz -sgfdir -output calib.npz` -- sample calibration input tensors from real games (reuses the same feature-encoding path as inference). +3. `python python/quantize_vitisai.py --input model-fp32.onnx --calibration calib.npz --output model-int8.onnx` -- offline quantize via AMD's `amd-quark` (`quark.onnx`), bundled with the Ryzen AI SDK's Python environment. +4. Point `nnModelFile` at `model-int8.onnx` and set `onnxProvider = vitisai`. + +This quantization step is entirely offline/manual -- `katago.exe` does not invoke it automatically. + ## MacOS * TLDR (Metal backend - recommended for most users, hybrid CPU+GPU+Neural Engine for maximum throughput): ``` diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 9c94aeee83..7a47998dd7 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -60,9 +60,13 @@ else() set(_katago_auto_fetch_default OFF) endif() option(KATAGO_AUTO_FETCH_DEPS "Automatically fetch missing dependencies into build/deps (Windows/Linux use vcpkg)." ${_katago_auto_fetch_default}) -set(KATAGO_DEPS_DIR "${CMAKE_SOURCE_DIR}/build/deps" CACHE PATH "Directory for auto-fetched third-party dependencies") +set(KATAGO_DEPS_DIR "${CMAKE_BINARY_DIR}/deps" CACHE PATH "Directory for auto-fetched third-party dependencies") if(WIN32) - set(_katago_vcpkg_triplet_default "x64-windows") + # Static libs (not DLLs), but still linked against the dynamic CRT (matches how katago.exe + # itself is built). Using static libs here avoids a class of heap-corruption crash where a + # dependency (e.g. abseil_dll.dll, a transitive dependency of protobuf) ends up loaded as two + # separate DLL instances at runtime, corrupting the heap during static initialization. + set(_katago_vcpkg_triplet_default "x64-windows-static-md") elseif(UNIX AND NOT APPLE) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$") set(_katago_vcpkg_triplet_default "arm64-linux") @@ -460,6 +464,7 @@ add_executable(katago command/analysis.cpp command/benchmark.cpp command/contribute.cpp + command/dumpcalibrationdata.cpp command/evalsgf.cpp command/gatekeeper.cpp command/genbook.cpp @@ -610,8 +615,67 @@ elseif(USE_BACKEND STREQUAL "OPENCL") elseif(USE_BACKEND STREQUAL "ONNX") target_compile_definitions(katago PRIVATE USE_ONNX_BACKEND) + # ---- AMD Ryzen AI / VitisAI SDK discovery (Windows) ---- + # Done here, ahead of ONNXRUNTIME_ROOT, so that when a Ryzen AI SDK install is found, its own + # bundled onnxruntime/ package (include+lib+bin, all one matched build) can be preferred as the + # ONNXRUNTIME_ROOT default. This matters: onnxruntime_providers_vitisai.dll / vaiml.dll / + # dyn_bins.dll / onnxruntime_vitisai_ep.dll are NOT independently versioned components -- they're + # part of one cohesive ORT+VitisAI-EP build, and mixing DLLs of the same name from two + # differently-sourced ORT packages (e.g. a separately-downloaded ORT vs. the SDK's own copy) + # produces a runtime ABI mismatch deep in the VitisAI EP's own call chain: session creation and + # even NPU compilation succeed, but actually creating an inference "runner" against the compiled + # model fails (observed as "Failed to create runner: Failed to open library ... xrt_core.dll", + # which is misleading -- the file opens fine standalone; the real cause is a symbol/ABI mismatch + # triggered only once several of the mismatched DLLs are loaded into the same process together). + # Not hardcoded to any particular Ryzen AI SDK version or install path: scans + # %ProgramFiles%\RyzenAI\ for the highest installed version, validated by the + # actual presence of voe-*-win_amd64/vaip_config.json inside it (a bare PATH entry is not a + # reliable signal -- e.g. a stale entry can point at an uninstalled older version). A manual + # override is available via -DRYZENAI_ROOT=... or the RYZENAI_ROOT environment variable. if(WIN32) - set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-win-x64-openvino") + set(RYZENAI_ROOT "" CACHE PATH "Path to an AMD Ryzen AI / VitisAI SDK installation (e.g. C:/Program Files/RyzenAI/1.7.1). Auto-detected if not set.") + if(NOT RYZENAI_ROOT AND DEFINED ENV{RYZENAI_ROOT}) + set(RYZENAI_ROOT "$ENV{RYZENAI_ROOT}") + endif() + if(NOT RYZENAI_ROOT) + set(_ryzenai_search_roots "") + if(DEFINED ENV{ProgramFiles}) + list(APPEND _ryzenai_search_roots "$ENV{ProgramFiles}/RyzenAI") + endif() + if(DEFINED ENV{ProgramW6432}) + list(APPEND _ryzenai_search_roots "$ENV{ProgramW6432}/RyzenAI") + endif() + list(REMOVE_DUPLICATES _ryzenai_search_roots) + foreach(_ryzenai_search_root IN LISTS _ryzenai_search_roots) + file(GLOB _ryzenai_candidate_dirs "${_ryzenai_search_root}/*") + set(_ryzenai_valid_candidates "") + foreach(_ryzenai_candidate IN LISTS _ryzenai_candidate_dirs) + if(IS_DIRECTORY "${_ryzenai_candidate}") + file(GLOB _ryzenai_vaip_configs_probe "${_ryzenai_candidate}/voe-*-win_amd64/vaip_config.json") + if(_ryzenai_vaip_configs_probe) + list(APPEND _ryzenai_valid_candidates "${_ryzenai_candidate}") + endif() + endif() + endforeach() + if(_ryzenai_valid_candidates) + list(SORT _ryzenai_valid_candidates COMPARE NATURAL ORDER DESCENDING) + list(GET _ryzenai_valid_candidates 0 _ryzenai_best) + set(RYZENAI_ROOT "${_ryzenai_best}") + break() + endif() + endforeach() + endif() + if(RYZENAI_ROOT AND IS_DIRECTORY "${RYZENAI_ROOT}") + string(REPLACE "\\" "/" RYZENAI_ROOT "${RYZENAI_ROOT}") + endif() + endif() + + if(WIN32 AND RYZENAI_ROOT AND EXISTS "${RYZENAI_ROOT}/onnxruntime/lib/onnxruntime.lib" AND EXISTS "${RYZENAI_ROOT}/onnxruntime/include/onnxruntime/core/session/onnxruntime_cxx_api.h") + # Prefer the Ryzen AI SDK's own bundled ONNX Runtime + VitisAI EP build over a separately + # prepared cpp/external/onnxruntime-win-x64-vitisai package -- see comment above. + set(_onnx_default_root "${RYZENAI_ROOT}/onnxruntime") + elseif(WIN32) + set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-win-x64-vitisai") elseif(UNIX AND NOT APPLE) set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-linux-x64-openvino") else() @@ -623,7 +687,19 @@ elseif(USE_BACKEND STREQUAL "ONNX") message(FATAL_ERROR "ONNXRUNTIME_ROOT does not exist: ${ONNXRUNTIME_ROOT}") endif() - set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include") + # Package layouts vary: some ship headers directly under include/ (e.g. the openvino package), + # some nest them one level deeper under include/onnxruntime/ (e.g. the standalone vitisai + # package), and the Ryzen AI SDK's own bundled copy nests them two levels deeper under + # include/onnxruntime/core/session/. + if(EXISTS "${ONNXRUNTIME_ROOT}/include/onnxruntime_cxx_api.h") + set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include") + elseif(EXISTS "${ONNXRUNTIME_ROOT}/include/onnxruntime/onnxruntime_cxx_api.h") + set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include/onnxruntime") + elseif(EXISTS "${ONNXRUNTIME_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_api.h") + set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include/onnxruntime/core/session") + else() + set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include") + endif() if(NOT IS_DIRECTORY "${ONNXRUNTIME_INCLUDE_DIR}") message(FATAL_ERROR "ONNX Runtime include directory not found: ${ONNXRUNTIME_INCLUDE_DIR}") endif() @@ -631,7 +707,9 @@ elseif(USE_BACKEND STREQUAL "ONNX") if(WIN32) set(ONNXRUNTIME_LIB "${ONNXRUNTIME_ROOT}/lib/onnxruntime.lib") - file(GLOB ONNXRUNTIME_DLLS "${ONNXRUNTIME_ROOT}/lib/*.dll") + # Package layouts vary: some ship runtime DLLs under lib/ (e.g. the openvino package), others + # under bin/ (e.g. the vitisai package) -- glob both. + file(GLOB ONNXRUNTIME_DLLS "${ONNXRUNTIME_ROOT}/lib/*.dll" "${ONNXRUNTIME_ROOT}/bin/*.dll") else() find_library(ONNXRUNTIME_LIB onnxruntime HINTS "${ONNXRUNTIME_ROOT}/lib" "${ONNXRUNTIME_ROOT}") endif() @@ -751,6 +829,90 @@ elseif(USE_BACKEND STREQUAL "ONNX") ) endforeach() endif() + + # ---- AMD Ryzen AI / VitisAI EP runtime deployment (Windows) ---- + # RYZENAI_ROOT was already located above (ahead of ONNXRUNTIME_ROOT). This section copies the + # remaining pieces needed at runtime: vaip_config.json, xclbins, XRT, and the handful of VitisAI + # deployment DLLs not already part of RYZENAI_ROOT/onnxruntime/bin (which, when used as + # ONNXRUNTIME_ROOT, is already fully copied by the ONNXRUNTIME_DLLS loop above -- see the ABI + # matching rationale in the RYZENAI_ROOT detection comment above). + if(WIN32 AND RYZENAI_ROOT AND IS_DIRECTORY "${RYZENAI_ROOT}") + file(GLOB _ryzenai_voe_dirs "${RYZENAI_ROOT}/voe-*-win_amd64") + set(_ryzenai_vaip_config "") + set(_ryzenai_xclbins_dir "") + if(_ryzenai_voe_dirs) + list(SORT _ryzenai_voe_dirs COMPARE NATURAL ORDER DESCENDING) + list(GET _ryzenai_voe_dirs 0 _ryzenai_voe_dir) + if(EXISTS "${_ryzenai_voe_dir}/vaip_config.json") + set(_ryzenai_vaip_config "${_ryzenai_voe_dir}/vaip_config.json") + endif() + if(IS_DIRECTORY "${_ryzenai_voe_dir}/xclbins") + set(_ryzenai_xclbins_dir "${_ryzenai_voe_dir}/xclbins") + endif() + endif() + + if(_ryzenai_vaip_config) + message(STATUS "VitisAI: found Ryzen AI installation at ${RYZENAI_ROOT}, vaip_config.json = ${_ryzenai_vaip_config}") + # Baked in only as a fallback default (see ComputeContext's vitisaiConfigFile init in + # onnxbackend.cpp); always overridable at runtime via the onnxVitisAIConfigFile config key, + # so copying the exe to a machine with a different Ryzen AI install layout doesn't break -- + # it just requires setting that key. + target_compile_definitions(katago PRIVATE "KATAGO_VITISAI_DEFAULT_CONFIG_FILE=\"${_ryzenai_vaip_config}\"") + + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${_ryzenai_vaip_config}" $ + ) + if(_ryzenai_xclbins_dir) + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${_ryzenai_xclbins_dir}" $/xclbins + ) + endif() + + # XRT (NPU device driver userspace lib). Not ORT/VitisAI-EP-versioned, so no ABI concern + # sourcing this from RYZENAI_ROOT/xrt regardless of where ONNXRUNTIME_ROOT points. + if(EXISTS "${RYZENAI_ROOT}/xrt/xrt_coreutil.dll") + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${RYZENAI_ROOT}/xrt/xrt_coreutil.dll" $ + ) + endif() + + # Remaining VitisAI deployment DLLs that RYZENAI_ROOT/onnxruntime/bin does not ship (as of + # SDK 1.7.1: flexmlrt.dll, onnx_custom_ops.dll, ryzen_mm.dll, ryzenai_onnx_utils.dll). Prefer + # them from RYZENAI_ROOT/onnxruntime/bin first in case a future SDK version adds them there + # (keeping the whole set ABI-matched), falling back to RYZENAI_ROOT/deployment otherwise -- + # these four are lower-level utility/custom-op libraries outside the tightly-coupled + # onnxruntime.dll <-> onnxruntime_providers_vitisai.dll <-> onnxruntime_vitisai_ep.dll <-> + # vaiml.dll chain, so sourcing them from deployment/ alongside an onnxruntime/bin-derived + # ONNXRUNTIME_ROOT is not expected to reintroduce the ABI mismatch that motivated this change. + set(_ryzenai_extra_dlls + flexmlrt.dll + onnx_custom_ops.dll + ryzen_mm.dll + ryzenai_onnx_utils.dll + ) + foreach(_ryzenai_dll_name IN LISTS _ryzenai_extra_dlls) + set(_ryzenai_dll_src "") + if(EXISTS "${RYZENAI_ROOT}/onnxruntime/bin/${_ryzenai_dll_name}") + set(_ryzenai_dll_src "${RYZENAI_ROOT}/onnxruntime/bin/${_ryzenai_dll_name}") + elseif(EXISTS "${RYZENAI_ROOT}/deployment/${_ryzenai_dll_name}") + set(_ryzenai_dll_src "${RYZENAI_ROOT}/deployment/${_ryzenai_dll_name}") + endif() + if(_ryzenai_dll_src) + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${_ryzenai_dll_src}" $ + ) + endif() + endforeach() + else() + message(STATUS "VitisAI: Ryzen AI installation found at ${RYZENAI_ROOT} but no voe-*-win_amd64/vaip_config.json inside it -- onnxProvider=vitisai will require onnxVitisAIConfigFile to be set manually in your config") + endif() + elseif(WIN32) + message(STATUS "VitisAI: no Ryzen AI / VitisAI SDK installation auto-detected (set -DRYZENAI_ROOT=... to override) -- onnxProvider=vitisai will require onnxVitisAIConfigFile to be set manually in your config") + endif() elseif(USE_BACKEND STREQUAL "EIGEN") target_compile_definitions(katago PRIVATE USE_EIGEN_BACKEND) # Allow EIGEN3_INCLUDE_DIRS as a manual override (for users who downloaded @@ -803,7 +965,8 @@ if(KATAGO_AUTO_FETCH_DEPS) if(EXISTS "${_katago_vcpkg_installed_root}/include/zlib.h") set(ZLIB_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zlib.h and other header files" FORCE) endif() - find_library(_katago_zlib_lib NAMES zlib z HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) + # "zs" is vcpkg's name for the static zlib lib (as opposed to "zlib"/"z" for the DLL import lib). + find_library(_katago_zlib_lib NAMES zlib z zs HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) if(_katago_zlib_lib) set(ZLIB_LIBRARY "${_katago_zlib_lib}" CACHE FILEPATH "Path to 'libz.so' on Linux or 'libz.lib' on Windows" FORCE) endif() @@ -821,15 +984,45 @@ else() message(SEND_ERROR "${ColorBoldRed}zlib was not found, if zlib is actually installed but not being found you can set ZLIB_INCLUDE_DIR to the directory with zlib.h and other headers, and ZLIB_LIBRARY to the compiled library 'libz.so' on Linux or 'libz.lib' on Windows. On the command line, this is -DZLIB_INCLUDE_DIR=... and -DZLIB_LIBRARY=... ${ColorReset}") endif(ZLIB_FOUND) +if(KATAGO_AUTO_FETCH_DEPS) + set(_need_libzip_deps FALSE) + if((NOT LIBZIP_LIBRARY) OR (NOT LIBZIP_INCLUDE_DIR_ZIP) OR (NOT LIBZIP_INCLUDE_DIR_ZIPCONF)) + set(_need_libzip_deps TRUE) + endif() + if(_need_libzip_deps) + # libzip's vcpkg port pulls in bzip2 as a dependency (needed for the BZip2 compression + # method); since we link against the raw .lib below rather than via vcpkg's CMake config + # (which would propagate transitive link deps automatically), bz2 must also be located + # and linked explicitly, or the final link fails with unresolved BZ2_bz* symbols. + katago_vcpkg_install_if_needed("libzip") + set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") + if(EXISTS "${_katago_vcpkg_installed_root}/include/zip.h") + set(LIBZIP_INCLUDE_DIR_ZIP "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zip.h and other header files" FORCE) + endif() + if(EXISTS "${_katago_vcpkg_installed_root}/include/zipconf.h") + set(LIBZIP_INCLUDE_DIR_ZIPCONF "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zipconf.h and other header files" FORCE) + endif() + find_library(_katago_libzip_lib NAMES zip HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) + find_library(_katago_bz2_lib NAMES bz2 HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) + if(_katago_libzip_lib) + if(_katago_bz2_lib) + set(LIBZIP_LIBRARY "${_katago_libzip_lib};${_katago_bz2_lib}" CACHE FILEPATH "Path to 'libzip.so' on Linux or 'libzip.lib' or 'zip.lib' on Windows" FORCE) + else() + set(LIBZIP_LIBRARY "${_katago_libzip_lib}" CACHE FILEPATH "Path to 'libzip.so' on Linux or 'libzip.lib' or 'zip.lib' on Windows" FORCE) + endif() + endif() + endif() +endif() + find_library(LIBZIP_LIBRARY NAMES zip) find_path(LIBZIP_INCLUDE_DIR_ZIP NAMES zip.h) find_path(LIBZIP_INCLUDE_DIR_ZIPCONF NAMES zipconf.h) if((NOT LIBZIP_LIBRARY) OR (NOT LIBZIP_INCLUDE_DIR_ZIP) OR (NOT LIBZIP_INCLUDE_DIR_ZIPCONF)) if(BUILD_DISTRIBUTED) - message(SEND_ERROR "${ColorBoldRed}WARNING: BUILD_DISTRIBUTED was requested but libzip library was NOT found. KataGo needs this for writing training data so libzip is required. On Linux, install through your normal package manager. On Windows, set LIBZIP_INCLUDE_DIR_ZIP to the directory that includes zip.h and other files, and LIBZIP_INCLUDE_DIR_ZIPCONF to the directory that includes zipconf.h and other files, and LIBZIP_LIBRARY to the libzip.lib or zip.lib file. ${ColorReset}") + message(SEND_ERROR "${ColorBoldRed}WARNING: BUILD_DISTRIBUTED was requested but libzip library was NOT found. KataGo needs this for writing training data so libzip is required. On Linux, install through your normal package manager. On Windows, set LIBZIP_INCLUDE_DIR_ZIP to the directory that includes zip.h and other files, and LIBZIP_INCLUDE_DIR_ZIPCONF to the directory that includes zipconf.h and other files, and LIBZIP_LIBRARY to the libzip.lib or zip.lib file, or enable KATAGO_AUTO_FETCH_DEPS=ON to auto-install via vcpkg. ${ColorReset}") endif() target_compile_definitions(katago PRIVATE NO_LIBZIP) - message(WARNING "${ColorBoldRed}WARNING: libzip library was NOT found. KataGo should still work for GTP/matches/analysis if everything else is good, but selfplay for writing training data will not be possible.${ColorReset}") + message(WARNING "${ColorBoldRed}WARNING: libzip library was NOT found. KataGo should still work for GTP/matches/analysis if everything else is good, but selfplay for writing training data will not be possible. Enable KATAGO_AUTO_FETCH_DEPS=ON to auto-install libzip via vcpkg.${ColorReset}") set(LIBZIP_INCLUDE_DIR_ZIP ${LIBZIP_INCLUDE_DIR_ZIP} CACHE PATH "Path to directory with zip.h and other header files") set(LIBZIP_INCLUDE_DIR_ZIPCONF ${LIBZIP_INCLUDE_DIR_ZIPCONF} CACHE PATH "Path to directory with zipconf.h and other header files") set(LIBZIP_LIBRARY ${LIBZIP_LIBRARY} CACHE FILEPATH "Path to 'libzip.so' on Linux or 'libzip.lib' or 'zip.lib' on Windows") diff --git a/cpp/command/dumpcalibrationdata.cpp b/cpp/command/dumpcalibrationdata.cpp new file mode 100644 index 0000000000..6ef78d9a63 --- /dev/null +++ b/cpp/command/dumpcalibrationdata.cpp @@ -0,0 +1,257 @@ +#include "../core/global.h" +#include "../core/fileutils.h" +#include "../core/rand.h" +#include "../dataio/sgf.h" +#include "../dataio/files.h" +#include "../dataio/numpywrite.h" +#include "../neuralnet/nninputs.h" +#include "../neuralnet/nninterface.h" +#include "../neuralnet/modelversion.h" +#include "../command/commandline.h" +#include "../main.h" + +using namespace std; + +// Dumps a calibration dataset (NN input feature tensors, sampled from real games) for offline +// post-training static quantization of an exported .onnx model -- e.g. via AMD's amd-quark +// (quark.onnx), to produce an INT8 QDQ model that the VitisAI EP can actually accelerate on NPU +// (the VitisAI EP falls back to CPU for FP32 ops, so quantization is a prerequisite for NPU +// offload, not an optimization). See Compiling.md's ONNX/VitisAI section. +// +// Deliberately reuses NNInputs::fillRowV7 -- the exact same feature-encoding code path used at +// real inference time -- rather than any separate/reimplemented extraction logic, so calibration +// data is guaranteed to match what the network actually sees at inference. Does NOT load any +// neural net compute backend (GPU/NPU/CPU session) -- feature extraction only depends on the +// model's channel counts (from ModelDesc, no session needed), not on a working backend. This +// keeps the tool fast and usable on any machine, independent of any particular execution +// provider's availability or quirks. +int MainCmds::dumpcalibrationdata(const vector& args) { + Board::initHash(); + + string modelFile; + vector sgfFilesFromCmdline; + vector sgfDirs; + vector sgfsDirs; + string outputFile; + int nnXLen; + int nnYLen; + int positionsPerGame; + int maxPositions; + string randSeed; + + try { + KataGoCommandLine cmd( + "Dump a calibration dataset of NN input tensors (spatial+global features) sampled from sgf " + "games, for offline INT8 quantization of an exported ONNX model (e.g. via AMD's amd-quark, " + "for the VitisAI/NPU execution provider). Does not require a GPU/NPU or a config file -- " + "purely extracts board features from the model's channel counts." + ); + cmd.addModelFileArg(); + + TCLAP::MultiArg sgfArg("","sgf","Sgf file",false,"SGF"); + TCLAP::MultiArg sgfDirArg("","sgfdir","Directory of sgf files",false,"DIR"); + TCLAP::MultiArg sgfsDirArg("","sgfsdir","Directory of sgfs (multi-game-per-file) files",false,"DIR"); + TCLAP::ValueArg outputArg("o","output","Output npz file path",true,string(),"FILE"); + TCLAP::ValueArg xLenArg("x","xlen","Board x size baked into calibration tensors",false,19,"N"); + TCLAP::ValueArg yLenArg("y","ylen","Board y size baked into calibration tensors",false,19,"N"); + TCLAP::ValueArg positionsPerGameArg( + "","positions-per-game","How many positions to sample per game, evenly spaced across its move range",false,8,"N" + ); + TCLAP::ValueArg maxPositionsArg("","max-positions","Stop after collecting this many total positions",false,2000,"N"); + TCLAP::ValueArg randSeedArg("","rand-seed","Random seed for shuffling game order",false,string(),"SEED"); + + cmd.add(sgfArg); + cmd.add(sgfDirArg); + cmd.add(sgfsDirArg); + cmd.add(outputArg); + cmd.add(xLenArg); + cmd.add(yLenArg); + cmd.add(positionsPerGameArg); + cmd.add(maxPositionsArg); + cmd.add(randSeedArg); + cmd.parseArgs(args); + + modelFile = cmd.getModelFile(); + sgfFilesFromCmdline = sgfArg.getValue(); + sgfDirs = sgfDirArg.getValue(); + sgfsDirs = sgfsDirArg.getValue(); + outputFile = outputArg.getValue(); + nnXLen = xLenArg.getValue(); + nnYLen = yLenArg.getValue(); + positionsPerGame = positionsPerGameArg.getValue(); + maxPositions = maxPositionsArg.getValue(); + randSeed = randSeedArg.getValue(); + } + catch(TCLAP::ArgException& e) { + cerr << "Error: " << e.error() << " for argument " << e.argId() << endl; + return 1; + } + + if(nnXLen < 2 || nnXLen > NNPos::MAX_BOARD_LEN || nnYLen < 2 || nnYLen > NNPos::MAX_BOARD_LEN) + throw StringError("Invalid board size for dumpcalibrationdata"); + if(positionsPerGame <= 0) + throw StringError("positions-per-game must be positive"); + if(maxPositions <= 0) + throw StringError("max-positions must be positive"); + if(randSeed.size() <= 0) + randSeed = Global::uint64ToString(Rand().nextUInt64()); + + // Load just the model's channel-count metadata -- no compute backend/session is created. + const string expectedSha256 = ""; + std::unique_ptr loadedModel( + NeuralNet::loadModelFile(modelFile, expectedSha256), + NeuralNet::freeLoadedModel + ); + const ModelDesc& modelDesc = NeuralNet::getModelDesc(loadedModel.get()); + int numSpatialFeatures = modelDesc.numInputChannels; + int numGlobalFeatures = modelDesc.numInputGlobalChannels; + if(numSpatialFeatures != NNInputs::NUM_FEATURES_SPATIAL_V7 || numGlobalFeatures != NNInputs::NUM_FEATURES_GLOBAL_V7) { + throw StringError( + "dumpcalibrationdata only supports the current V7 feature set (spatial=" + + Global::intToString(NNInputs::NUM_FEATURES_SPATIAL_V7) + ", global=" + + Global::intToString(NNInputs::NUM_FEATURES_GLOBAL_V7) + "), but the model reports spatial=" + + Global::intToString(numSpatialFeatures) + " global=" + Global::intToString(numGlobalFeatures) + ); + } + if(modelDesc.numInputMetaChannels > 0) { + cerr << "Warning: model has " << modelDesc.numInputMetaChannels + << " metadata input channels; dumpcalibrationdata does not populate these (left as zero)." << endl; + } + + // Collect sgf files -------------------------------------------------------- + vector sgfFiles; + FileHelpers::collectSgfsFromDirsOrFiles(sgfDirs,sgfFiles); + for(const string& s: sgfFilesFromCmdline) + sgfFiles.push_back(s); + + vector sgfsFiles; + FileHelpers::collectMultiSgfsFromDirsOrFiles(sgfsDirs,sgfsFiles); + + if(sgfFiles.size() <= 0 && sgfsFiles.size() <= 0) + throw StringError("No sgf files specified or found (use -sgf, -sgfdir, and/or -sgfsdir)"); + + vector> compactSgfs; + for(const string& f : sgfFiles) { + try { + compactSgfs.push_back(CompactSgf::loadFile(f)); + } + catch(const std::exception& e) { + cerr << "Warning: skipping sgf that failed to load: " << f << " (" << e.what() << ")" << endl; + } + } + for(const string& f : sgfsFiles) { + vector> sgfs; + try { + sgfs = Sgf::loadSgfsFile(f); + } + catch(const std::exception& e) { + cerr << "Warning: skipping sgfs file that failed to load: " << f << " (" << e.what() << ")" << endl; + continue; + } + for(auto& sgf : sgfs) { + try { + compactSgfs.push_back(std::unique_ptr(new CompactSgf(std::move(*sgf)))); + } + catch(const std::exception& e) { + cerr << "Warning: skipping one game within " << f << " that failed to compact (" << e.what() << ")" << endl; + } + } + } + + if(compactSgfs.size() <= 0) + throw StringError("No sgf games successfully loaded"); + + cout << "Loaded " << compactSgfs.size() << " games." << endl; + + // Shuffle game order deterministically so a max-positions cutoff doesn't bias toward + // whatever happens to sort first (e.g. alphabetically-early filenames). + Rand rand(randSeed); + rand.shuffle(compactSgfs); + + // Sample positions ----------------------------------------------------------- + int64_t maxRows = (int64_t)maxPositions; + NumpyBuffer binaryInputNCHW(std::vector({maxRows,(int64_t)numSpatialFeatures,(int64_t)nnYLen,(int64_t)nnXLen})); + NumpyBuffer globalInputNC(std::vector({maxRows,(int64_t)numGlobalFeatures})); + + int64_t numRowsWritten = 0; + int numGamesUsed = 0; + MiscNNInputParams nnInputParams; + const bool inputsUseNHWC = false; + + for(size_t gameIdx = 0; gameIdx < compactSgfs.size() && numRowsWritten < maxRows; gameIdx++) { + CompactSgf* sgf = compactSgfs[gameIdx].get(); + int64_t numMoves = (int64_t)sgf->moves.size(); + if(numMoves <= 0) + continue; + if(sgf->xSize != nnXLen || sgf->ySize != nnYLen) + continue; // Skip games whose board size doesn't match the requested calibration board size + + Rules initialRules; + try { + initialRules = sgf->getRulesOrWarn( + Rules::getTrompTaylorish(), + [](const string& msg) { (void)msg; } // Suppress per-game rules warnings; too noisy over many games. + ); + } + catch(const std::exception& e) { + cerr << "Warning: skipping game with unparseable rules: " << e.what() << endl; + continue; + } + + bool usedAnyPositionThisGame = false; + for(int i = 0; i < positionsPerGame && numRowsWritten < maxRows; i++) { + // Evenly space sampled move numbers across the game, skewed away from move 0 (near-empty + // boards contribute little to calibration) and away from the very last move. + int64_t moveNum = (numMoves * (int64_t)(i+1)) / (positionsPerGame + 1); + if(moveNum < 0) moveNum = 0; + if(moveNum > numMoves) moveNum = numMoves; + + Board board; + Player nextPla; + BoardHistory hist; + bool ok = true; + try { + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->playMovesTolerant(board, nextPla, hist, moveNum, false); + } + catch(const std::exception&) { + ok = false; // Skip this position (e.g. an illegal move somewhere in the replay) + } + if(!ok) + continue; + + float* spatialRow = binaryInputNCHW.data + numRowsWritten * (int64_t)numSpatialFeatures * nnXLen * nnYLen; + float* globalRow = globalInputNC.data + numRowsWritten * (int64_t)numGlobalFeatures; + NNInputs::fillRowV7(board, hist, nextPla, nnInputParams, nnXLen, nnYLen, inputsUseNHWC, spatialRow, globalRow); + + numRowsWritten++; + usedAnyPositionThisGame = true; + } + if(usedAnyPositionThisGame) { + numGamesUsed++; + if(numGamesUsed % 200 == 0) + cout << "..." << numRowsWritten << " positions collected from " << numGamesUsed << " games" << endl; + } + } + + if(numRowsWritten <= 0) + throw StringError("Collected zero calibration positions (check board size matches your sgfs, and that games have moves)"); + + cout << "Collected " << numRowsWritten << " calibration positions from " << numGamesUsed << " games." << endl; + + uint64_t spatialBytes = binaryInputNCHW.prepareHeaderWithNumRows(numRowsWritten); + uint64_t globalBytes = globalInputNC.prepareHeaderWithNumRows(numRowsWritten); + + ZipFile zipFile(outputFile); + zipFile.writeBuffer("binaryInputNCHW", binaryInputNCHW.dataIncludingHeader, spatialBytes); + zipFile.writeBuffer("globalInputNC", globalInputNC.dataIncludingHeader, globalBytes); + zipFile.close(); + + cout << "Wrote " << numRowsWritten << " rows to " << outputFile << endl; + cout << " binaryInputNCHW shape: [" << numRowsWritten << ", " << numSpatialFeatures << ", " << nnYLen << ", " << nnXLen << "]" << endl; + cout << " globalInputNC shape: [" << numRowsWritten << ", " << numGlobalFeatures << "]" << endl; + cout << "Note: channel 0 of binaryInputNCHW is the on-board mask (per KataGo convention), matching" << endl; + cout << "the InputSpatial tensor consumed by the exported ONNX graph (see exportonnx)." << endl; + + return 0; +} diff --git a/cpp/command/misc.cpp b/cpp/command/misc.cpp index 0eeb69d4f4..e73acf9c55 100644 --- a/cpp/command/misc.cpp +++ b/cpp/command/misc.cpp @@ -50,21 +50,34 @@ int MainCmds::exportonnx(const vector& args) { string outputFile; int nnXLen; int nnYLen; + bool emitFusedMishOp; try { KataGoCommandLine cmd("Export KataGo .bin/.bin.gz model to ONNX file."); cmd.addModelFileArg(); TCLAP::ValueArg outputArg("o","output","Output ONNX file path",true,string(),"FILE"); TCLAP::ValueArg xLenArg("x","xlen","Board x size baked into exported model",false,19,"N"); TCLAP::ValueArg yLenArg("y","ylen","Board y size baked into exported model",false,19,"N"); + TCLAP::SwitchArg emitFusedMishOpArg( + "","emitFusedMishOp", + "Emit KataGo's Mish activation as a single native ONNX Mish node instead of the decomposed " + "Softplus+Tanh+Mul. Off by default (matches what TensorRT's nvonnxparser and the live ONNX " + "backends are tested against). Turn this on when exporting for external quantizers targeting " + "AMD VitisAI/Ryzen AI NPU: its DPU compiler recognizes the fused Mish op for XINT8 " + "quantization but not the decomposed Softplus primitive, so without this flag the exported " + "graph's Conv/activation layers fail to fuse into NPU-executable subgraphs.", + false + ); cmd.add(outputArg); cmd.add(xLenArg); cmd.add(yLenArg); + cmd.add(emitFusedMishOpArg); cmd.parseArgs(args); modelFile = cmd.getModelFile(); outputFile = outputArg.getValue(); nnXLen = xLenArg.getValue(); nnYLen = yLenArg.getValue(); + emitFusedMishOp = emitFusedMishOpArg.getValue(); } catch(TCLAP::ArgException& e) { cerr << "Error: " << e.error() << " for argument " << e.argId() << endl; @@ -80,7 +93,9 @@ int MainCmds::exportonnx(const vector& args) { NeuralNet::freeLoadedModel ); const ModelDesc& modelDesc = NeuralNet::getModelDesc(loadedModel.get()); - string onnxBytes = OnnxModelBuilder::buildOnnxModel(modelDesc, nnXLen, nnYLen); + OnnxModelBuilder::Result onnxResult = + OnnxModelBuilder::build(modelDesc, nnXLen, nnYLen, /*requireExactNNLen=*/false, /*transformerNHWC=*/false, nullptr, emitFusedMishOp); + string onnxBytes = std::move(onnxResult.serializedModel); ofstream out; FileUtils::open(out, outputFile, std::ios::binary | std::ios::out); diff --git a/cpp/command/sandbox.cpp b/cpp/command/sandbox.cpp index a8dbc358c5..4b82a57189 100644 --- a/cpp/command/sandbox.cpp +++ b/cpp/command/sandbox.cpp @@ -197,7 +197,7 @@ using namespace std; #include #include -#include "onnx.pb.h" +#include "onnx/onnx_pb.h" namespace { // Minimal TensorRT logger for the smoke test. diff --git a/cpp/main.cpp b/cpp/main.cpp index aa6079bbff..d07f2bfe65 100644 --- a/cpp/main.cpp +++ b/cpp/main.cpp @@ -30,6 +30,7 @@ gtp : Runs GTP engine that can be plugged into any standard Go GUI for play/anal benchmark : Test speed with different numbers of search threads. genconfig : User-friendly interface to generate a config with rules and automatic performance tuning. exportonnx : Export KataGo .bin/.bin.gz model to a fixed-size .onnx model. +dumpcalibrationdata : Dump NN input tensors sampled from sgf games, for offline quantization (e.g. for VitisAI/NPU). contribute : Connect to online distributed KataGo training and run perpetually contributing selfplay games. @@ -170,6 +171,8 @@ static int handleSubcommand(const string& subcommand, const vector& args return MainCmds::printclockinfo(subArgs); else if(subcommand == "exportonnx") return MainCmds::exportonnx(subArgs); + else if(subcommand == "dumpcalibrationdata") + return MainCmds::dumpcalibrationdata(subArgs); else if(subcommand == "sandbox") return MainCmds::sandbox(); else if(subcommand == "version") { diff --git a/cpp/main.h b/cpp/main.h index 1e3353d50c..73a6d231b6 100644 --- a/cpp/main.h +++ b/cpp/main.h @@ -53,6 +53,7 @@ namespace MainCmds { int printclockinfo(const std::vector& args); int exportonnx(const std::vector& args); + int dumpcalibrationdata(const std::vector& args); int sampleinitializations(const std::vector& args); int evalrandominits(const std::vector& args); int searchentropyanalysis(const std::vector& args); diff --git a/cpp/neuralnet/nneval.cpp b/cpp/neuralnet/nneval.cpp index ca90e0598a..6e44547c78 100644 --- a/cpp/neuralnet/nneval.cpp +++ b/cpp/neuralnet/nneval.cpp @@ -359,10 +359,22 @@ static void serveEvals( NNServerBuf* buf = new NNServerBuf(*nnEval,loadedModel); Rand rand(randSeedThisThread); - // Used to have a try catch around this but actually we're in big trouble if this raises an exception - // and causes possibly the only nnEval thread to die, so actually go ahead and let the exception escape to - // toplevel for easier debugging - nnEval->serve(*buf,rand,gpuIdxForThisThread,serverThreadIdx); + // An uncaught exception escaping a std::thread's entry function does NOT propagate to any + // try/catch at toplevel on the main thread - it calls std::terminate() directly, which aborts + // the process with no message printed. So catch here instead, print what actually went wrong, + // and then exit - achieving the same "fail fast, nnEval thread dying is fatal" intent as before, + // but with a diagnosable error message instead of a silent abort(). + try { + nnEval->serve(*buf,rand,gpuIdxForThisThread,serverThreadIdx); + } + catch(const std::exception& e) { + cerr << "Uncaught exception in NN eval server thread " << serverThreadIdx << ": " << e.what() << endl; + std::exit(1); + } + catch(...) { + cerr << "Uncaught exception of unknown type in NN eval server thread " << serverThreadIdx << endl; + std::exit(1); + } delete buf; } diff --git a/cpp/neuralnet/onnxbackend.cpp b/cpp/neuralnet/onnxbackend.cpp index 4a537a977e..b156e55ccc 100644 --- a/cpp/neuralnet/onnxbackend.cpp +++ b/cpp/neuralnet/onnxbackend.cpp @@ -1,7 +1,7 @@ // ONNX Runtime backend for KataGo. // Loads standard .bin.gz model files (builds ONNX graph from ModelDesc) or // raw .onnx model files directly, and runs inference via ONNX Runtime with a -// configurable execution provider (CPU, OpenVINO, CUDA, TensorRT, MIGraphX, CoreML) +// configurable execution provider (CPU, OpenVINO, CUDA, TensorRT, MIGraphX, VitisAI, CoreML) // selected at // runtime via the onnxProvider config key. @@ -10,6 +10,8 @@ #include "../neuralnet/nninputs.h" #include "../neuralnet/modelversion.h" #include "../neuralnet/onnxmodelbuilder.h" +#include "../core/makedir.h" +#include "../dataio/homedata.h" #include #ifdef __APPLE__ @@ -106,13 +108,21 @@ struct LoadedModel { auto typeInfo = tmpSession.GetInputTypeInfo(i); auto tensorInfo = typeInfo.GetTensorTypeAndShapeInfo(); auto shape = tensorInfo.GetShape(); - if(name.find("spatial") != string::npos) { + // Name-based matching must be case-insensitive: the graph node names emitted by + // OnnxModelBuilder::build() (and expected by default elsewhere in this file) are + // PascalCase ("InputSpatial", "InputGlobal", "InputMask", "InputMeta"), not lowercase. + string lowerName = name; + for(auto& c : lowerName) c = (char)tolower((unsigned char)c); + if(lowerName.find("mask") != string::npos) { + // The on-board mask is its own single-channel input, not part of the spatial feature + // channel count -- explicitly ignored here so it can't clobber numInputChannels below. + } else if(lowerName.find("spatial") != string::npos) { if(shape.size() >= 2) numInputChannels = (int)shape[1]; - } else if(name.find("global") != string::npos) { + } else if(lowerName.find("global") != string::npos) { if(shape.size() >= 2) numInputGlobalChannels = (int)shape[1]; - } else if(name.find("meta") != string::npos) { + } else if(lowerName.find("meta") != string::npos) { if(shape.size() >= 2) numInputMetaChannels = (int)shape[1]; } else if(shape.size() == 4) { @@ -143,19 +153,23 @@ struct LoadedModel { auto tensorInfo = typeInfo.GetTensorTypeAndShapeInfo(); auto shape = tensorInfo.GetShape(); - if(name.find("policy") != string::npos) { - // Policy: [N, C, H*W+1] -> dim 1 is policy channels + // Case-insensitive for the same reason as the input-side matching above; also match + // "scorevalue" (the actual "OutputScoreValue" node name), not "miscvalue". + string lowerName = name; + for(auto& c : lowerName) c = (char)tolower((unsigned char)c); + if(lowerName.find("policy") != string::npos) { + // Policy: [N, C, H, W] -> dim 1 is policy channels if(shape.size() >= 2) numPolicyChannels = (int)shape[1]; - } else if(name.find("miscvalue") != string::npos) { - // MiscValue: [N, numScoreValueChannels] -- check before "value" since "miscvalue" contains "value" + } else if(lowerName.find("scorevalue") != string::npos) { + // ScoreValue (aka MiscValue): [N, numScoreValueChannels] if(shape.size() >= 2) numScoreValueChannels = (int)shape[1]; - } else if(name.find("value") != string::npos) { + } else if(lowerName.find("value") != string::npos) { // Value: [N, 3] if(shape.size() >= 2) numValueChannels = (int)shape[1]; - } else if(name.find("ownership") != string::npos) { + } else if(lowerName.find("ownership") != string::npos) { // Ownership: [N, 1, H, W] if(shape.size() >= 2) numOwnershipChannels = (int)shape[1]; @@ -219,10 +233,20 @@ struct ComputeContext { bool openvinoEnableNPUFastCompile; string openvinoCacheDir; - // Configurable input/output node names + // VitisAI (AMD Ryzen AI NPU) EP options. + string vitisaiConfigFile; + string vitisaiCacheDir; + bool vitisaiDisableCPUFallback; + + // Configurable input/output node names. Defaults match the node names emitted by the shared + // OnnxModelBuilder::build() (see onnxmodelbuilder.cpp) used for .bin.gz -> ONNX conversion, + // which is also what trtbackend.cpp consumes. Raw .onnx models can override these if they use + // different names. + string inputMaskName; string inputSpatialName; string inputGlobalName; string inputMetaName; + string outputPolicyPassName; string outputPolicyName; string outputValueName; string outputMiscvalueName; @@ -232,7 +256,9 @@ struct ComputeContext { int configModelVersion; ComputeContext(int xLen, int yLen, const string& provider) - : env(ORT_LOGGING_LEVEL_WARNING, "KataGoOnnx"), + // TEMP DEBUG: KATAGO_ONNX_VERBOSE_EP_LOG=1 bumps the ORT Env's own logging level to VERBOSE to + // surface ONNX Runtime's node-placement dump (VerifyEachNodeIsAssignedToAnEp). + : env(std::getenv("KATAGO_ONNX_VERBOSE_EP_LOG") != nullptr ? ORT_LOGGING_LEVEL_VERBOSE : ORT_LOGGING_LEVEL_WARNING, "KataGoOnnx"), nnXLen(xLen), nnYLen(yLen), providerName(provider), @@ -240,13 +266,22 @@ struct ComputeContext { openvinoDeviceId(""), openvinoEnableNPUFastCompile(false), openvinoCacheDir(""), - inputSpatialName("input_spatial"), - inputGlobalName("input_global"), - inputMetaName("input_meta"), - outputPolicyName("out_policy"), - outputValueName("out_value"), - outputMiscvalueName("out_miscvalue"), - outputOwnershipName("out_ownership"), + vitisaiConfigFile( +#ifdef KATAGO_VITISAI_DEFAULT_CONFIG_FILE + KATAGO_VITISAI_DEFAULT_CONFIG_FILE +#endif + ), + vitisaiCacheDir(""), + vitisaiDisableCPUFallback(true), + inputMaskName("InputMask"), + inputSpatialName("InputSpatial"), + inputGlobalName("InputGlobal"), + inputMetaName("InputMeta"), + outputPolicyPassName("OutputPolicyPass"), + outputPolicyName("OutputPolicy"), + outputValueName("OutputValue"), + outputMiscvalueName("OutputScoreValue"), + outputOwnershipName("OutputOwnership"), configModelVersion(-1) {} }; @@ -300,7 +335,11 @@ struct ComputeHandle { } else { if(logger != NULL) logger->write("ONNX backend: building ONNX graph from model weights..."); - builtOnnxBytes = OnnxModelBuilder::buildOnnxModel(loadedModel.modelDesc, ctx->nnXLen, ctx->nnYLen); + OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build( + loadedModel.modelDesc, ctx->nnXLen, ctx->nnYLen, + /*requireExactNNLen=*/false, /*transformerNHWC=*/false, logger, /*emitFusedMishOp=*/false + ); + builtOnnxBytes = std::move(onnxResult.serializedModel); if(logger != NULL) logger->write("ONNX backend: ONNX graph built (" + Global::uint64ToString(builtOnnxBytes.size()) + " bytes)"); onnxData = builtOnnxBytes.data(); @@ -384,11 +423,43 @@ struct ComputeHandle { (deviceId.empty() ? "" : (", device_id=" + deviceId)) ); } + } else if(provider == "vitisai") { + std::unordered_map vitisOpts; + if(!ctx->vitisaiConfigFile.empty()) + vitisOpts["config_file"] = ctx->vitisaiConfigFile; + else + throw StringError( + "ONNX backend: onnxProvider=vitisai requires a VitisAI EP config file (vaip_config.json, " + "shipped with the AMD Ryzen AI / VitisAI SDK). Set 'onnxVitisAIConfigFile' in your config, " + "or rebuild with a locatable Ryzen AI installation so a default gets baked in." + ); + // The VitisAI EP's enable_cache_file_io_in_mem provider option defaults to 1 (in-memory + // only -- nothing is ever written to cache_dir), so it must be explicitly set to 0 to make + // the compiled model actually persist to disk across process launches. Without this, every + // katago.exe launch pays the full NPU compile cost again (can take on the order of minutes). + vitisOpts["cache_dir"] = ctx->vitisaiCacheDir; + vitisOpts["enable_cache_file_io_in_mem"] = "0"; + sessionOpts.AppendExecutionProvider_VitisAI(vitisOpts); + if(ctx->vitisaiDisableCPUFallback) { + // Force a hard failure at session-creation time if any node can't be claimed by VitisAI, + // instead of ONNX Runtime silently assigning it to the always-registered CPU EP. Without + // this, "session created successfully" is not evidence that anything actually runs on the + // NPU. Set onnxVitisAIDisableCPUFallback=false to relax this if partial CPU fallback is + // acceptable for your use case. + sessionOpts.AddConfigEntry("session.disable_cpu_ep_fallback", "1"); + } + if(logger != NULL) { + logger->write( + "ONNX backend: VitisAI execution provider enabled, config_file=" + ctx->vitisaiConfigFile + + ", cache_dir=" + ctx->vitisaiCacheDir + + ", disable_cpu_ep_fallback=" + Global::boolToString(ctx->vitisaiDisableCPUFallback) + ); + } } else if(provider == "cpu" || provider.empty()) { if(logger != NULL) logger->write("ONNX backend: using CPU execution provider"); } else { - throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', or 'openvino'"); + throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', 'openvino', or 'vitisai'"); } // Create session from in-memory bytes @@ -477,42 +548,16 @@ ComputeContext* NeuralNet::createComputeContext( Logger* logger, int nnXLen, int nnYLen, - const string& backendExtraParam, const string& homeDataDirOverride, - bool openCLReTunePerBoardSize, enabled_t useFP16Mode, - enabled_t useNHWCMode, - const LoadedModel* loadedModel + const LoadedModel* loadedModel, + ConfigParser& cfg ) { (void)gpuIdxs; - (void)homeDataDirOverride; - (void)openCLReTunePerBoardSize; (void)useFP16Mode; - (void)useNHWCMode; (void)loadedModel; - // Parse backendExtraParam as "key=value;key=value;..." - string providerName = "cpu"; - map params; - if(!backendExtraParam.empty()) { - vector parts = Global::split(backendExtraParam, ';'); - for(const string& part : parts) { - size_t eq = part.find('='); - if(eq != string::npos) { - string key = Global::trim(part.substr(0, eq)); - string val = Global::trim(part.substr(eq + 1)); - params[key] = val; - } else { - // Legacy: bare string is provider name - string trimmed = Global::trim(part); - if(!trimmed.empty()) - providerName = trimmed; - } - } - if(params.count("provider")) - providerName = params["provider"]; - } - providerName = Global::toLower(providerName); + string providerName = cfg.contains("onnxProvider") ? Global::toLower(cfg.getString("onnxProvider")) : "cpu"; if(logger != NULL) logger->write("ONNX backend: creating compute context for " + @@ -521,23 +566,36 @@ ComputeContext* NeuralNet::createComputeContext( ComputeContext* ctx = new ComputeContext(nnXLen, nnYLen, providerName); - // Apply configured node names - if(params.count("inputSpatial")) ctx->inputSpatialName = params["inputSpatial"]; - if(params.count("inputGlobal")) ctx->inputGlobalName = params["inputGlobal"]; - if(params.count("inputMeta")) ctx->inputMetaName = params["inputMeta"]; - if(params.count("outputPolicy")) ctx->outputPolicyName = params["outputPolicy"]; - if(params.count("outputValue")) ctx->outputValueName = params["outputValue"]; - if(params.count("outputMiscvalue")) ctx->outputMiscvalueName = params["outputMiscvalue"]; - if(params.count("outputOwnership")) ctx->outputOwnershipName = params["outputOwnership"]; - if(params.count("openvinoDeviceType")) ctx->openvinoDeviceType = params["openvinoDeviceType"]; - if(params.count("openvinoDeviceId")) ctx->openvinoDeviceId = params["openvinoDeviceId"]; - if(params.count("openvinoEnableNPUFastCompile")) { - string v = Global::toLower(params["openvinoEnableNPUFastCompile"]); - ctx->openvinoEnableNPUFastCompile = (v == "1" || v == "true" || v == "yes" || v == "on"); + // Apply configured node names / options, read directly off cfg. + if(cfg.contains("onnxInputMask")) ctx->inputMaskName = cfg.getString("onnxInputMask"); + if(cfg.contains("onnxInputSpatial")) ctx->inputSpatialName = cfg.getString("onnxInputSpatial"); + if(cfg.contains("onnxInputGlobal")) ctx->inputGlobalName = cfg.getString("onnxInputGlobal"); + if(cfg.contains("onnxInputMeta")) ctx->inputMetaName = cfg.getString("onnxInputMeta"); + if(cfg.contains("onnxOutputPolicyPass")) ctx->outputPolicyPassName = cfg.getString("onnxOutputPolicyPass"); + if(cfg.contains("onnxOutputPolicy")) ctx->outputPolicyName = cfg.getString("onnxOutputPolicy"); + if(cfg.contains("onnxOutputValue")) ctx->outputValueName = cfg.getString("onnxOutputValue"); + if(cfg.contains("onnxOutputMiscvalue")) ctx->outputMiscvalueName = cfg.getString("onnxOutputMiscvalue"); + if(cfg.contains("onnxOutputOwnership")) ctx->outputOwnershipName = cfg.getString("onnxOutputOwnership"); + if(cfg.contains("onnxOpenVINODeviceType")) ctx->openvinoDeviceType = cfg.getString("onnxOpenVINODeviceType"); + if(cfg.contains("onnxOpenVINODeviceId")) ctx->openvinoDeviceId = cfg.getString("onnxOpenVINODeviceId"); + if(cfg.contains("onnxOpenVINOEnableNPUFastCompile")) + ctx->openvinoEnableNPUFastCompile = cfg.getBool("onnxOpenVINOEnableNPUFastCompile"); + if(cfg.contains("onnxOpenVINOCacheDir")) ctx->openvinoCacheDir = cfg.getString("onnxOpenVINOCacheDir"); + if(cfg.contains("onnxVitisAIConfigFile")) ctx->vitisaiConfigFile = cfg.getString("onnxVitisAIConfigFile"); + if(cfg.contains("onnxVitisAICacheDir")) ctx->vitisaiCacheDir = cfg.getString("onnxVitisAICacheDir"); + if(cfg.contains("onnxVitisAIDisableCPUFallback")) + ctx->vitisaiDisableCPUFallback = cfg.getBool("onnxVitisAIDisableCPUFallback"); + if(providerName == "vitisai" && ctx->vitisaiCacheDir.empty()) { + // No explicit override: default to a fixed subdir of katagodata, same convention as + // trtbackend.cpp's "trtcache" (see HomeData::getHomeDataDir), so the (slow, ~minutes-long) + // NPU compile only has to happen once per model rather than on every process launch. + string homeDataDir = HomeData::getHomeDataDir(true, homeDataDirOverride); + string cacheDir = homeDataDir + "/vitisaicache"; + MakeDir::make(cacheDir); + ctx->vitisaiCacheDir = cacheDir; } - if(params.count("openvinoCacheDir")) ctx->openvinoCacheDir = params["openvinoCacheDir"]; - if(params.count("modelVersion")) { - int v = Global::stringToInt(params["modelVersion"]); + if(cfg.contains("onnxModelVersion")) { + int v = Global::stringToInt(cfg.getString("onnxModelVersion")); if(v >= 0) ctx->configModelVersion = v; } @@ -574,6 +632,8 @@ ComputeHandle* NeuralNet::createComputeHandle( string deviceInfo = context->providerName == "openvino" ? "n/a (use onnxOpenVINODeviceType/onnxOpenVINODeviceId)" + : context->providerName == "vitisai" + ? "n/a (single NPU device)" : Global::intToString(gpuIdxForThisThread); logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + ": provider=" + context->providerName + @@ -647,7 +707,8 @@ void NeuralNet::getOutput( spatialShape.data(), spatialShape.size() ); - std::array globalShape = {batchSize, numGlobalFeatures}; + // NC11 (rank 4), matching OnnxModelBuilder::build()'s addInputNC11("InputGlobal", ...). + std::array globalShape = {batchSize, numGlobalFeatures, 1, 1}; Ort::Value globalTensor = Ort::Value::CreateTensor( memInfo, inputBuffers->globalInput.data(), inputBuffers->singleInputGlobalElts * batchSize, globalShape.data(), globalShape.size() @@ -660,13 +721,35 @@ void NeuralNet::getOutput( if(spatialIdx < 0 || globalIdx < 0) throw StringError("ONNX backend: could not find expected input names"); + const int spatialPolicyLen = nnXLen * nnYLen; + + // InputMask (the on-board mask, [N,1,H,W]) is required by graphs built by OnnxModelBuilder::build() + // (used for .bin.gz models), but may be absent from hand-exported raw .onnx models - only require + // it if the session actually declares it. It's channel 0 of the spatial input (KataGo convention), + // but not contiguous across rows within the spatial buffer, so gather it into its own buffer. + int maskIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMaskName}); + vector maskBuf; + Ort::Value maskTensor(nullptr); + if(maskIdx >= 0) { + maskBuf.resize((size_t)batchSize * spatialPolicyLen); + for(int r = 0; r < batchSize; r++) { + const float* rowSpatial = inputBuffers->spatialInput.data() + inputBuffers->singleInputElts * r; + std::copy(rowSpatial, rowSpatial + spatialPolicyLen, maskBuf.data() + (size_t)r * spatialPolicyLen); + } + std::array maskShape = {batchSize, 1, nnYLen, nnXLen}; + maskTensor = Ort::Value::CreateTensor( + memInfo, maskBuf.data(), maskBuf.size(), maskShape.data(), maskShape.size() + ); + } + int metaIdx = -1; Ort::Value metaTensor(nullptr); if(computeHandle->numInputMetaChannels > 0) { metaIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMetaName}); if(metaIdx < 0) - throw StringError("ONNX backend: model has metadata channels but could not find input_meta"); - std::array metaShape = {batchSize, computeHandle->numInputMetaChannels}; + throw StringError("ONNX backend: model has metadata channels but could not find " + ctx->inputMetaName); + // NC11 (rank 4), matching trtbackend.cpp's InputMeta declaration. + std::array metaShape = {batchSize, computeHandle->numInputMetaChannels, 1, 1}; metaTensor = Ort::Value::CreateTensor( memInfo, inputBuffers->metaInput.data(), inputBuffers->singleInputMetaElts * batchSize, metaShape.data(), metaShape.size() @@ -682,9 +765,11 @@ void NeuralNet::getOutput( inputTensors.push_back(std::move(globalTensor)); else if((int)i == metaIdx) inputTensors.push_back(std::move(metaTensor)); + else if((int)i == maskIdx) + inputTensors.push_back(std::move(maskTensor)); else { throw StringError("ONNX backend: unexpected input node '" + computeHandle->inputNames[i] + - "' -- only spatial, global, and meta inputs are supported"); + "' -- only mask, spatial, global, and meta inputs are supported"); } } @@ -698,12 +783,17 @@ void NeuralNet::getOutput( computeHandle->outputNamePtrs.size() ); - // Find output indices using configured node names + // Find output indices using configured node names. OutputPolicyPass ([N,C]) and OutputPolicy + // ([N,C,H,W]) are separate tensors in graphs built by OnnxModelBuilder::build() - the pass logit + // isn't appended to the spatial policy tensor. + int policyPassOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyPassName}); int policyOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyName}); int valueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputValueName}); int miscvalueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputMiscvalueName}); int ownershipOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputOwnershipName}); + if(policyPassOutputIdx < 0) + throw StringError("ONNX backend: could not find policy-pass output node '" + ctx->outputPolicyPassName + "'"); if(policyOutputIdx < 0) throw StringError("ONNX backend: could not find policy output node '" + ctx->outputPolicyName + "'"); if(valueOutputIdx < 0) @@ -713,19 +803,19 @@ void NeuralNet::getOutput( if(ownershipOutputIdx < 0) throw StringError("ONNX backend: could not find ownership output node '" + ctx->outputOwnershipName + "'"); + const float* policyPassData = outputTensors[policyPassOutputIdx].GetTensorData(); const float* policyData = outputTensors[policyOutputIdx].GetTensorData(); const float* valueData = outputTensors[valueOutputIdx].GetTensorData(); const float* miscvalueData = outputTensors[miscvalueOutputIdx].GetTensorData(); const float* ownershipData = outputTensors[ownershipOutputIdx].GetTensorData(); + assert(policyPassData != nullptr); assert(policyData != nullptr); assert(valueData != nullptr); assert(miscvalueData != nullptr); assert(ownershipData != nullptr); assert((int)outputs.size() == batchSize); - const int policyResultLen = computeHandle->policyResultLen; - const int spatialPolicyLen = nnXLen * nnYLen; float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; for(int row = 0; row < batchSize; row++) { @@ -734,26 +824,28 @@ void NeuralNet::getOutput( assert(output->nnYLen == nnYLen); float policyOptimism = (float)inputBufs[row]->policyOptimism; - // Policy: [N, C, H*W+1] + // Policy: OutputPolicy is [N, C, H*W] (channel-major, NCHW), OutputPolicyPass is [N, C] + // (one pass logit per channel). These are two separate tensors, not a single [N,C,H*W+1]. { - const float* policyRowBase = policyData + row * numPolicyChannels * policyResultLen; + const float* policyRowBase = policyData + (size_t)row * numPolicyChannels * spatialPolicyLen; + const float* policyPassRowBase = policyPassData + (size_t)row * numPolicyChannels; float* policyProbs = output->policyProbs; if(numPolicyChannels >= 2) { const float* ch0 = policyRowBase; - const float* ch1 = policyRowBase + policyResultLen; + const float* ch1 = policyRowBase + spatialPolicyLen; for(int i = 0; i < spatialPolicyLen; i++) { float p = ch0[i]; float pOpt = ch1[i]; policyProbsTmp[i] = p + (pOpt - p) * policyOptimism; } SymmetryHelpers::copyOutputsWithSymmetry(policyProbsTmp, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[spatialPolicyLen] = ch0[spatialPolicyLen] + (ch1[spatialPolicyLen] - ch0[spatialPolicyLen]) * policyOptimism; + policyProbs[spatialPolicyLen] = policyPassRowBase[0] + (policyPassRowBase[1] - policyPassRowBase[0]) * policyOptimism; } else { assert(numPolicyChannels == 1); const float* ch0 = policyRowBase; SymmetryHelpers::copyOutputsWithSymmetry(ch0, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[spatialPolicyLen] = ch0[spatialPolicyLen]; + policyProbs[spatialPolicyLen] = policyPassRowBase[0]; } } diff --git a/cpp/neuralnet/onnxmodelbuilder.cpp b/cpp/neuralnet/onnxmodelbuilder.cpp index 991c79e901..a8a294745b 100644 --- a/cpp/neuralnet/onnxmodelbuilder.cpp +++ b/cpp/neuralnet/onnxmodelbuilder.cpp @@ -8,7 +8,7 @@ #include "../neuralnet/modelversion.h" #include "../neuralnet/nninputs.h" -#include "onnx.pb.h" +#include "onnx/onnx_pb.h" using namespace std; @@ -23,6 +23,7 @@ struct Builder { int nnYLen; bool requireExactNNLen; bool transformerNHWC; // run the trunk block stack channel-last (NHWC) vs NCHW + bool emitFusedMishOp; // emit a native ONNX Mish node instead of Softplus+Tanh+Mul (see header) // Mask-derived feature tensor names (computed once, reused by every gpool). Empty if exact. string maskSumName; // [N,1,1,1] sum of mask over H,W (only when !exact) @@ -177,7 +178,14 @@ struct Builder { string out = uniq(desc.name); addNode("Conv", {input, wName}, out, desc.name); onnx::NodeProto* node = lastNode(); + // strides/pads/dilations default to (1,1)/(0,0,0,0)/(1,1) per the ONNX spec when omitted, which + // is exactly what a 1x1 conv needs here -- but some EPs' graph compilers (e.g. AMD VitisAI's xir, + // which requires "strides" to be explicitly present) don't apply ONNX's own default semantics, so + // set them explicitly rather than relying on the (spec-compliant but not universally honored) omission. { onnx::AttributeProto* a = addAttr(node, "kernel_shape"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(1); a->add_ints(1); } + { onnx::AttributeProto* a = addAttr(node, "strides"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(1); a->add_ints(1); } + { onnx::AttributeProto* a = addAttr(node, "pads"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(0); a->add_ints(0); a->add_ints(0); a->add_ints(0); } + { onnx::AttributeProto* a = addAttr(node, "dilations"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(1); a->add_ints(1); } return out; } @@ -244,6 +252,22 @@ struct Builder { // The SCALE8 variant is the runtime applyScale8ToReduceActivations() transform that keeps // FP16 activations small. ONNX Softplus has no beta, so for SCALE8 we // scale the input by 8 before Softplus and do NOT scale the result. + if(emitFusedMishOp) { + // Native ONNX `Mish` (opset 18+) computes y = y*tanh(softplus(y)) with no beta parameter. + // For plain mish that's exactly mish(x), one node. For mish_scale8, substitute y=8x: + // Mish(8x) = 8x*tanh(softplus(8x)), so mish_scale8(x) = x*tanh(softplus(8x)) = Mish(8x)/8. + string mishIn = input; + if(act == ACTIVATION_MISH_SCALE8) { + string bName = addScalarInitializer(uniq(desc.name + "/beta8"), 8.0f); + mishIn = addNode("Mul", {input, bName}, uniq(desc.name + "/beta8mul"), desc.name + "/beta8mul"); + } + string m = addNode("Mish", {mishIn}, uniq(desc.name + "/mish"), desc.name + "/mish"); + if(act == ACTIVATION_MISH_SCALE8) { + string invBName = addScalarInitializer(uniq(desc.name + "/invbeta8"), 0.125f); + return addNode("Mul", {m, invBName}, uniq(desc.name), desc.name); + } + return m; + } string spIn = input; if(act == ACTIVATION_MISH_SCALE8) { string bName = addScalarInitializer(uniq(desc.name + "/beta8"), 8.0f); @@ -812,13 +836,14 @@ Result build( int nnYLen, bool requireExactNNLen, bool transformerNHWC, - Logger* logger + Logger* logger, + bool emitFusedMishOp ) { if(desc.metaEncoderVersion > 0) throw StringError("OnnxModelBuilder: SGF metadata encoder not yet supported"); if(logger != NULL) - logger->write("Building internal onnx model, requireExactNNLen=" + Global::boolToString(requireExactNNLen) + " transformerNHWC=" + Global::boolToString(transformerNHWC)); + logger->write("Building internal onnx model, requireExactNNLen=" + Global::boolToString(requireExactNNLen) + " transformerNHWC=" + Global::boolToString(transformerNHWC) + " emitFusedMishOp=" + Global::boolToString(emitFusedMishOp)); int numInputChannels = desc.numInputChannels; int numInputGlobalChannels = desc.numInputGlobalChannels; @@ -848,6 +873,7 @@ Result build( b.nnYLen = nnYLen; b.requireExactNNLen = requireExactNNLen; b.transformerNHWC = transformerNHWC; + b.emitFusedMishOp = emitFusedMishOp; // ---- Inputs (NCHW, dynamic batch) ---- auto addInput = [&](const string& name, int channels) { diff --git a/cpp/neuralnet/onnxmodelbuilder.h b/cpp/neuralnet/onnxmodelbuilder.h index 10d3819150..055e01739d 100644 --- a/cpp/neuralnet/onnxmodelbuilder.h +++ b/cpp/neuralnet/onnxmodelbuilder.h @@ -32,13 +32,23 @@ namespace OnnxModelBuilder { }; // Build a serialized ONNX ModelProto for the given model. + // + // emitFusedMishOp: if true, KataGo's Mish activation (x * tanh(softplus(x))) is emitted as a + // single native ONNX `Mish` node (opset 18+) instead of the decomposed Softplus+Tanh+Mul used + // by default. The decomposition is what TensorRT's nvonnxparser and the live ONNX/WinML runtime + // backends have actually been tested against, so this defaults to false and only exportonnx (the + // offline FP32 export consumed by external quantizers, e.g. for AMD VitisAI/NPU) opts in: AMD's + // Ryzen AI DPU compiler recognizes the fused `Mish` op for XINT8 quantization but not the + // decomposed Softplus primitive, so without this the exported graph's Conv/activation layers + // fail to fuse into NPU-executable subgraphs and silently fall back to CPU end to end. Result build( const ModelDesc& desc, int nnXLen, int nnYLen, bool requireExactNNLen, bool transformerNHWC, - Logger* logger + Logger* logger, + bool emitFusedMishOp ); } diff --git a/cpp/neuralnet/trtbackend.cpp b/cpp/neuralnet/trtbackend.cpp index 8af6e623a8..c15aaa0bb0 100644 --- a/cpp/neuralnet/trtbackend.cpp +++ b/cpp/neuralnet/trtbackend.cpp @@ -1230,7 +1230,7 @@ struct ComputeHandle { if(useOnnxEmit) { logger->write("TensorRT backend: building network via ONNX emitter"); const ModelDesc& desc = loadedModel->modelDesc; - OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build(desc, ctx->nnXLen, ctx->nnYLen, requireExactNNLen, ctx->transformerNHWC, logger); + OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build(desc, ctx->nnXLen, ctx->nnYLen, requireExactNNLen, ctx->transformerNHWC, logger, /*emitFusedMishOp=*/false); onnxBytes = std::move(onnxResult.serializedModel); if(dumpDebugPlan) { diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index 07a0b4ca59..b904099a34 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -239,45 +239,11 @@ vector Setup::initializeNNEvaluators( string homeDataDirOverride = loadHomeDataDirOverride(cfg); - // Backend-specific options (e.g. openclTunerFile, cudaDisableGraphSDPA) are read directly by the - // relevant compute backend off of cfg (see createComputeContext). Because they follow the backend - // prefix convention, the getBackendPrefixes() loop above already marks them used for the backends - // that don't read them, so no explicit mark-used is needed here. - string backendExtraParam; -#if defined(USE_ONNX_BACKEND) - string onnxProvider = cfg.contains("onnxProvider") ? cfg.getString("onnxProvider") : "cpu"; - backendExtraParam = "provider=" + onnxProvider; - if(cfg.contains("onnxInputSpatial")) - backendExtraParam += ";inputSpatial=" + cfg.getString("onnxInputSpatial"); - if(cfg.contains("onnxInputGlobal")) - backendExtraParam += ";inputGlobal=" + cfg.getString("onnxInputGlobal"); - if(cfg.contains("onnxInputMeta")) - backendExtraParam += ";inputMeta=" + cfg.getString("onnxInputMeta"); - if(cfg.contains("onnxOutputPolicy")) - backendExtraParam += ";outputPolicy=" + cfg.getString("onnxOutputPolicy"); - if(cfg.contains("onnxOutputValue")) - backendExtraParam += ";outputValue=" + cfg.getString("onnxOutputValue"); - if(cfg.contains("onnxOutputMiscvalue")) - backendExtraParam += ";outputMiscvalue=" + cfg.getString("onnxOutputMiscvalue"); - if(cfg.contains("onnxOutputOwnership")) - backendExtraParam += ";outputOwnership=" + cfg.getString("onnxOutputOwnership"); - if(cfg.contains("onnxModelVersion")) - backendExtraParam += ";modelVersion=" + cfg.getString("onnxModelVersion"); - if(cfg.contains("onnxOpenVINODeviceType")) - backendExtraParam += ";openvinoDeviceType=" + cfg.getString("onnxOpenVINODeviceType"); - if(cfg.contains("onnxOpenVINODeviceId")) - backendExtraParam += ";openvinoDeviceId=" + cfg.getString("onnxOpenVINODeviceId"); - if(cfg.contains("onnxOpenVINOEnableNPUFastCompile")) - backendExtraParam += ";openvinoEnableNPUFastCompile=" + cfg.getString("onnxOpenVINOEnableNPUFastCompile"); - if(cfg.contains("onnxOpenVINOCacheDir")) - backendExtraParam += ";openvinoCacheDir=" + cfg.getString("onnxOpenVINOCacheDir"); -#else - if(cfg.contains("openclTunerFile")) - backendExtraParam = cfg.getString("openclTunerFile"); -#endif - bool openCLReTunePerBoardSize = false; - if(cfg.contains("openclReTunePerBoardSize")) - openCLReTunePerBoardSize = cfg.getBool("openclReTunePerBoardSize"); + // Backend-specific options (e.g. openclTunerFile, cudaDisableGraphSDPA, onnxProvider, + // onnxVitisAIConfigFile) are read directly by the relevant compute backend off of cfg (see + // each backend's createComputeContext). Because they follow the backend prefix convention, + // the getBackendPrefixes() loop above already marks them used for the backends that don't + // read them, so no explicit mark-used or pass-through is needed here. enabled_t useFP16Mode = enabled_t::Auto; if(cfg.contains(backendPrefix+"UseFP16-"+idxStr)) @@ -361,7 +327,6 @@ vector Setup::initializeNNEvaluators( nnCacheSizePowerOfTwo, nnMutexPoolSizePowerOfTwo, debugSkipNeuralNet, - backendExtraParam, homeDataDirOverride, useFP16Mode, numNNServerThreadsPerModel, diff --git a/python/quantize_vitisai.py b/python/quantize_vitisai.py new file mode 100644 index 0000000000..a023b3281c --- /dev/null +++ b/python/quantize_vitisai.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +"""Quantize a KataGo FP32 ONNX graph to INT8 QDQ for the VitisAI (AMD Ryzen AI NPU) execution +provider, for use with katago.exe's ONNX backend (onnxProvider=vitisai). + +Offline tool -- katago.exe does NOT invoke this automatically. Requires `amd-quark` (AMD's ONNX +quantizer, providing the `quark.onnx` module, bundled with the Ryzen AI / VitisAI SDK), `onnx`, +and `numpy`. + +Typical usage: first export an FP32 ONNX graph from a .bin.gz KataGo model (`katago exportonnx`), +sample calibration data from real games (`katago dumpcalibrationdata`), then run: + + python quantize_vitisai.py --input model-fp32.onnx --calibration calib.npz --output model-int8.onnx +""" +import argparse +import sys + +import numpy as np +import onnx + + +def load_calibration(npz_path): + data = np.load(npz_path) + return data["binaryInputNCHW"], data["globalInputNC"] + + +def classify_input_name(name): + lname = name.lower() + if "mask" in lname: + return "mask" + if "spatial" in lname: + return "spatial" + if "global" in lname: + return "global" + if "meta" in lname: + return "meta" + return None + + +class KataGoCalibrationDataReader: + """Feeds calibration rows sampled by KataGo's dumpcalibrationdata. + binaryInputNCHW has shape [N, spatialChannels, H, W] where channel 0 is the on-board mask + (KataGo convention); globalInputNC has shape [N, globalChannels]. These get mapped onto + whatever the graph's actual input names are (InputSpatial/InputMask/InputGlobal/InputMeta by + default, but matched generically here by substring in case of custom names). + """ + + def __init__(self, spatial, global_, input_names): + self.spatial = spatial + self.global_ = global_ + self.input_names = input_names + self.idx = 0 + self.n = spatial.shape[0] + + def get_next(self): + if self.idx >= self.n: + return None + i = self.idx + self.idx += 1 + feed = {} + if "spatial" in self.input_names: + feed[self.input_names["spatial"]] = self.spatial[i : i + 1] + if "mask" in self.input_names: + feed[self.input_names["mask"]] = self.spatial[i : i + 1, 0:1] + if "global" in self.input_names: + g = self.global_[i : i + 1] + feed[self.input_names["global"]] = g.reshape(g.shape[0], g.shape[1], 1, 1) + if "meta" in self.input_names: + feed[self.input_names["meta"]] = np.zeros(self.input_names["meta_shape"], dtype=np.float32) + return feed + + def rewind(self): + self.idx = 0 + + +def build_input_map(model): + input_names = {} + for inp in model.graph.input: + role = classify_input_name(inp.name) + if role is None: + print(f'[quantize_vitisai] warning: unrecognized graph input "{inp.name}", ignoring', flush=True) + continue + input_names[role] = inp.name + if role == "meta": + dims = [d.dim_value if d.dim_value > 0 else 1 for d in inp.type.tensor_type.shape.dim] + input_names["meta_shape"] = tuple(dims) + return input_names + + +def quantize(input_path, output_path, reader): + # Preferred path: quark's high-level ModelQuantizer with the XINT8 preset config, which is + # AMD's own recommended power-of-2-scale INT8 scheme for Ryzen AI NPU CNN deployment. + try: + from quark.onnx import XINT8_QCONFIG, ModelQuantizer + + print("[quantize_vitisai] using quark.onnx ModelQuantizer with XINT8_QCONFIG preset", flush=True) + quantizer = ModelQuantizer(XINT8_QCONFIG) + result = quantizer.quantize_model( + model_input=input_path, + model_output=output_path, + calibration_data_reader=reader, + ) + if result is not None and not _file_nonempty(output_path): + onnx.save(result, output_path) + return + except ImportError as e: + print(f"[quantize_vitisai] quark.onnx ModelQuantizer/XINT8_QCONFIG unavailable ({e}), " + f"falling back to quark.onnx.quantize_static", flush=True) + + # Fallback: the lower-level quantize_static function. XINT8_QCONFIG (the preferred path above) + # is int8 with POWER-OF-2 scaling and MinMSE calibration (quark.onnx.quantization.config.spec. + # XInt8Spec) -- NOT the same as generic int8 with float32 scaling and MinMax calibration, which + # is quark's own *default* if calibrate_method/scale type are left unspecified here. Using the + # wrong scale representation produces a QDQ graph the VitisAI DPU compiler's pattern-matcher + # does not recognize as fusable, so activation_type/weight_type alone are not sufficient -- + # calibrate_method must explicitly be quark's PowerOfTwoMethod, not onnxruntime's CalibrationMethod. + reader.rewind() + import quark.onnx as qo + from onnxruntime.quantization import QuantFormat, QuantType + from quark.onnx.calibration import PowerOfTwoMethod + + qo.quantize_static( + model_input=input_path, + model_output=output_path, + calibration_data_reader=reader, + quant_format=QuantFormat.QDQ, + calibrate_method=PowerOfTwoMethod.MinMSE, + activation_type=QuantType.QInt8, + weight_type=QuantType.QInt8, + enable_npu_cnn=True, + ) + + +def _file_nonempty(path): + try: + import os + + return os.path.exists(path) and os.path.getsize(path) > 0 + except OSError: + return False + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--input", required=True, help="Input FP32 ONNX model path") + parser.add_argument("--calibration", required=True, help="Calibration .npz path (binaryInputNCHW, globalInputNC)") + parser.add_argument("--output", required=True, help="Output INT8 QDQ ONNX model path") + args = parser.parse_args() + + print(f"[quantize_vitisai] loading model: {args.input}", flush=True) + model = onnx.load(args.input) + + input_names = build_input_map(model) + printable = {k: v for k, v in input_names.items() if k != "meta_shape"} + print(f"[quantize_vitisai] graph inputs mapped: {printable}", flush=True) + if "spatial" not in input_names or "global" not in input_names: + print("[quantize_vitisai] ERROR: could not find InputSpatial/InputGlobal in the graph", flush=True) + sys.exit(1) + + print(f"[quantize_vitisai] loading calibration data: {args.calibration}", flush=True) + spatial, global_ = load_calibration(args.calibration) + print(f"[quantize_vitisai] calibration: {spatial.shape[0]} positions", flush=True) + + reader = KataGoCalibrationDataReader(spatial, global_, input_names) + + try: + quantize(args.input, args.output, reader) + except Exception as e: # noqa: BLE001 -- deliberately broad: any failure must be reported, not swallowed + print(f"[quantize_vitisai] ERROR: quantization failed: {e}", flush=True) + import traceback + + traceback.print_exc() + sys.exit(1) + + if not _file_nonempty(args.output): + print(f"[quantize_vitisai] ERROR: expected output {args.output} was not created", flush=True) + sys.exit(1) + + print(f"[quantize_vitisai] wrote {args.output}", flush=True) + + +if __name__ == "__main__": + main() From 4bfca431b2511a9fd6dbb6e66158cb4c2600bd9d Mon Sep 17 00:00:00 2001 From: Looong01 Date: Wed, 5 Aug 2026 18:55:47 +0800 Subject: [PATCH 26/37] Update to v1.17.1 --- README.md | 57 ++++-------- cpp/configs/gtp_example.cfg | 74 ++++++++++----- cpp/neuralnet/onnxbackend.cpp | 139 ++++++++++++++++------------- cpp/neuralnet/onnxmodelbuilder.cpp | 27 ++++-- cpp/neuralnet/onnxmodelbuilder.h | 5 ++ cpp/program/setup.cpp | 11 +++ 6 files changed, 180 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index 0821bc89e1..3db84497a5 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,7 @@ - [MacOS](#macos) - [OpenCL vs CUDA vs TensorRT vs Eigen vs ONNX](#opencl-vs-cuda-vs-tensorrt-vs-eigen-vs-onnx) - [How To Use](#how-to-use) - - [ONNX/OpenVINO Intel NPU Quick Start (Windows)](#onnxopenvino-intel-npu-quick-start-windows) - - [ONNX/OpenVINO Intel NPU Quick Start (Linux)](#onnxopenvino-intel-npu-quick-start-linux) + - [ONNX/VitisAI AMD Ryzen AI NPU Quick Start (Windows)](#onnxvitisai-amd-ryzen-ai-npu-quick-start-windows) - [Human-style Play and Analysis](#human-style-play-and-analysis) - [Other Commands:](#other-commands) - [Tuning for Performance](#tuning-for-performance) @@ -99,14 +98,14 @@ The quick summary is: * Use Eigen with AVX2 if you don't have a GPU or if your GPU is too old/weak to work with OpenCL, and you just want a plain CPU KataGo. * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. * The CUDA backend can work for NVIDIA GPUs with CUDA+CUDNN installed but is likely worse than TensorRT. - * ONNX backend uses ONNX Runtime execution providers (CPU/OpenVINO/CUDA/TensorRT/MIGraphX/CoreML). It is useful for Intel NPU (OpenVINO) and raw `.onnx` models. + * ONNX backend uses ONNX Runtime execution providers (CPU/CUDA/TensorRT/MIGraphX/VitisAI/CoreML). It is useful for AMD Ryzen AI NPU (VitisAI) and raw `.onnx` models. More in detail: * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. On most GPUs, the OpenCL implementation will actually beat NVIDIA's own CUDA/CUDNN at performance. The exception is for top-end NVIDIA GPUs that support FP16 and tensor cores, in which case sometimes one is better and sometimes the other is better. * TensorRT is similar to CUDA, but only uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs, it should work whenever CUDA does and will usually be faster than CUDA or any other backend. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. - * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, OpenVINO for Intel hardware (including NPU on supported systems), CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers, while OpenVINO NPU setups are typically single-device. + * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, VitisAI for AMD Ryzen AI NPU, CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers; VitisAI NPU setups are single-device. For **any** implementation, it's recommended that you also tune the number of threads used if you care about optimal performance, as it can make a factor of 2-3 difference in the speed. See "Tuning for Performance" below. However, if you mostly just want to get it working, then the default untuned settings should also be still reasonable. @@ -140,49 +139,23 @@ path/to/katago.exe gtp -model path/to/.bin.gz path/to/katago.exe gtp -model path/to/.bin.gz -config path/to/gtp_custom.cfg ``` -#### ONNX/OpenVINO Intel NPU Quick Start (Windows) +#### ONNX/VitisAI AMD Ryzen AI NPU Quick Start (Windows) -If you want to use ONNX Runtime + OpenVINO on Intel NPU: -* Install Intel NPU driver: https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html -* Install OpenVINO archive package (Windows): https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html -* Typical install root looks like: `C:\Program Files (x86)\Intel\openvino_2026.0` -* Add `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\bin\intel64\Release` and `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\3rdparty\tbb\bin` to System PATH +The ONNX backend supports AMD's Ryzen AI NPU via the VitisAI execution provider +(`onnxProvider = vitisai`). It loads a standard `.bin.gz` KataGo model **directly** — no conversion +step needed (it can also load a raw `.onnx` file, e.g. via `exportonnx`). See [Compiling.md](Compiling.md) +for installing the Ryzen AI / VitisAI SDK and building against it (CMake auto-detects a Ryzen AI +installation and bakes in a default `vaip_config.json` path when found). -Minimal commands: ``` -# 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) -./katago.exe exportonnx -model .bin.gz -output .onnx - -# 2) Benchmark on Intel NPU (OpenVINO provider) -./katago.exe benchmark -config cpp/configs/gtp_example.cfg -model .onnx - -# 3) Run GTP for GUI tools (Sabaki/Lizzie/q5Go/etc) -./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .onnx - -If you don't prepare config file, then use -override-config args, like: -./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU +./katago.exe benchmark -config cpp/configs/gtp_example.cfg -model .bin.gz -override-config onnxProvider=vitisai +./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .bin.gz -override-config onnxProvider=vitisai ``` -#### ONNX/OpenVINO Intel NPU Quick Start (Linux) - -If you want to use ONNX Runtime + OpenVINO on Intel NPU: -* Install Intel NPU driver (Linux): https://github.com/intel/linux-npu-driver -* Install OpenVINO via system package manager (APT example): https://docs.openvino.ai/2025/get-started/install-openvino/install-openvino-apt.html - -Minimal commands: -```bash -# 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) -./katago exportonnx -model .bin.gz -output .onnx - -# 2) Benchmark on Intel NPU (OpenVINO provider) -./katago benchmark -config cpp/configs/gtp_example.cfg -model .onnx - -# 3) Run GTP for GUI tools (Sabaki/Lizzie/q5Go/etc) -./katago gtp -config cpp/configs/gtp_example.cfg -model .onnx - -# If you don't prepare config file, use -override-config: -./katago gtp -config cpp/configs/gtp_example.cfg -model .onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU -``` +The compiled NPU model is cached (by default under `/vitisaicache`) so the multi-minute +compile cost is only paid once per model. See the `onnxVitisAI*` keys in +[`cpp/configs/gtp_example.cfg`](cpp/configs/gtp_example.cfg) to override the config file path, cache +directory, or CPU-fallback behavior. #### Human-style Play and Analysis diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index 0b71d7ab03..d3ee64a823 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -571,36 +571,62 @@ searchFactorWhenWinningThreshold = 0.95 # ------------------------------ # ONNX backend settings # ------------------------------ -# These only apply when using the ONNX version of KataGo. - -# Execution provider: -# cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only). +# These only apply when using the ONNX version of KataGo (USE_BACKEND=ONNX). This backend reuses +# the same ONNX graph emitter as the TensorRT backend, so its .bin.gz model support and IO protocol +# are identical to TensorRT; only the runtime differs. It also supports loading a raw .onnx file +# directly (see onnxInput*/onnxOutput* below). + +# Execution provider. One of: +# cpu (default), cuda, tensorrt, migraphx, vitisai, coreml (macOS only). +# Use "vitisai" for AMD Ryzen AI NPU. # onnxProvider = cpu -# Provider-specific device selection for multi-server-thread setups. -# Primarily for onnxProvider = cuda / tensorrt / migraphx. +# Provider-specific device selection (mostly for cuda / tensorrt / migraphx). # onnxDeviceToUse = 0 # onnxDeviceToUseThread0 = 0 # onnxDeviceToUseThread1 = 1 -# OpenVINO EP options (useful for Intel NPU on Windows): -# NPU, CPU, GPU, AUTO:NPU,CPU, MULTI:NPU.0,NPU.1, etc. -# onnxOpenVINODeviceType = NPU -# Optional explicit OpenVINO device id (usually unnecessary for single NPU setups) -# onnxOpenVINODeviceId = 0 -# Optional fast compile mode for NPU -# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build -# Optional cache directory for compiled OpenVINO blobs -# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache - -# Override input/output tensor names for raw .onnx models: -# onnxInputSpatial = input_spatial -# onnxInputGlobal = input_global -# onnxInputMeta = input_meta -# onnxOutputPolicy = out_policy -# onnxOutputValue = out_value -# onnxOutputMiscvalue = out_miscvalue -# onnxOutputOwnership = out_ownership +# NOTE: the ONNX backend does not support the global useFP16 flag used by other backends. Setting +# "useFP16 = true" fails with an error, since ONNX Runtime execution providers decide inference +# precision themselves. Leave useFP16 unset/auto. + +# Skip the scale8 FP16-range workaround (default false = apply it). scale8 keeps convnet +# activations 8x smaller so they stay inside typical FP16 execution-provider ranges; the cost is +# MISH_SCALE8 subgraphs that can block fused-Mish optimizations on some providers. Keep off/default; +# set true only for FP32 precision or workloads where FP16 overflow is not a practical risk. Forced +# to false for -contribute (distributed selfplay) regardless of this setting, since contributed +# training data must never contain FP16-overflow NaNs. +# onnxSkipScale8 = false + +# Run the trunk block stack channel-last (NHWC) for transformer models. Default true (NHWC, +# matching the TensorRT backend). Only takes effect for models with transformer blocks; convnets +# ignore this. +# onnxTransformerNHWC = true + +# VitisAI EP options (only used when onnxProvider = vitisai; AMD Ryzen AI / VitisAI NPU): +# Path to vaip_config.json, shipped with the AMD Ryzen AI SDK. A default is baked in at build time +# if a Ryzen AI installation was auto-detected; otherwise this is required. +# onnxVitisAIConfigFile = C:\\Program Files\\RyzenAI\\\\voe-...\\vaip_config.json +# Cache directory for the compiled NPU model, so the (slow, minutes-long) compile only happens +# once per model instead of on every process launch. Defaults to a "vitisaicache" subdir of +# katagodata (homeDataDir) if unset. +# onnxVitisAICacheDir = C:\\temp\\katago_vitisai_cache +# Fail hard at session-creation time if any graph node can't run on the NPU, instead of silently +# falling back to CPU for that node (default true). +# onnxVitisAIDisableCPUFallback = true + +# Override input/output tensor names -- only needed for raw .onnx models using non-default names. +# Defaults match the names emitted by KataGo's ONNX graph builder (also used by the TensorRT +# backend's ONNX path). +# onnxInputMask = InputMask +# onnxInputSpatial = InputSpatial +# onnxInputGlobal = InputGlobal +# onnxInputMeta = InputMeta +# onnxOutputPolicyPass = OutputPolicyPass +# onnxOutputPolicy = OutputPolicy +# onnxOutputValue = OutputValue +# onnxOutputMiscvalue = OutputScoreValue +# onnxOutputOwnership = OutputOwnership # Override auto-detected model version for raw .onnx model files. # onnxModelVersion = 15 diff --git a/cpp/neuralnet/onnxbackend.cpp b/cpp/neuralnet/onnxbackend.cpp index b156e55ccc..34f75794b3 100644 --- a/cpp/neuralnet/onnxbackend.cpp +++ b/cpp/neuralnet/onnxbackend.cpp @@ -1,7 +1,7 @@ // ONNX Runtime backend for KataGo. // Loads standard .bin.gz model files (builds ONNX graph from ModelDesc) or // raw .onnx model files directly, and runs inference via ONNX Runtime with a -// configurable execution provider (CPU, OpenVINO, CUDA, TensorRT, MIGraphX, VitisAI, CoreML) +// configurable execution provider (CPU, CUDA, TensorRT, MIGraphX, VitisAI, CoreML) // selected at // runtime via the onnxProvider config key. @@ -20,6 +20,8 @@ #include #include +#include +#include using namespace std; @@ -66,10 +68,18 @@ struct LoadedModel { bool isRawOnnx; string rawOnnxBytes; + // One-time scale8 transform (see maybeApplyScale8), only meaningful for the .bin.gz path. All + // server threads share this LoadedModel, so whichever ComputeHandle is created first decides + // for everyone. + mutable std::atomic scale8Resolved; + mutable std::mutex scale8Mutex; + // Constructor for .bin.gz files LoadedModel(const string& fileName, const string& expectedSha256, bool rawOnnx) : isRawOnnx(rawOnnx) { + scale8Resolved.store(false); + if(!rawOnnx) { ModelDesc::loadFromFileMaybeGZipped(fileName, modelDesc, expectedSha256); return; @@ -201,6 +211,20 @@ struct LoadedModel { ); // postProcessParams gets default values from its constructor (already set) + + scale8Resolved.store(true); // scale8 only applies to modelDesc weights, which raw .onnx has none of. + } + + // Apply the scale8 FP16-range workaround exactly once per model, unless skipped via + // onnxSkipScale8. Must run before any ComputeHandle builds the ONNX graph from modelDesc. + // No-op for the raw .onnx path (scale8Resolved is already true from the constructor above). + void maybeApplyScale8(bool skip) const { + std::lock_guard lock(scale8Mutex); + if(!scale8Resolved.load()) { + if(!skip) + const_cast(this)->modelDesc.applyScale8ToReduceActivations(); + scale8Resolved.store(true); + } } LoadedModel() = delete; @@ -228,10 +252,9 @@ struct ComputeContext { int nnXLen; int nnYLen; string providerName; - string openvinoDeviceType; - string openvinoDeviceId; - bool openvinoEnableNPUFastCompile; - string openvinoCacheDir; + + bool transformerNHWC; // run the trunk block stack channel-last (NHWC) for transformer models + bool skipScale8; // skip the scale8 FP16-range workaround (see createComputeContext) // VitisAI (AMD Ryzen AI NPU) EP options. string vitisaiConfigFile; @@ -262,10 +285,8 @@ struct ComputeContext { nnXLen(xLen), nnYLen(yLen), providerName(provider), - openvinoDeviceType("NPU"), - openvinoDeviceId(""), - openvinoEnableNPUFastCompile(false), - openvinoCacheDir(""), + transformerNHWC(true), + skipScale8(false), vitisaiConfigFile( #ifdef KATAGO_VITISAI_DEFAULT_CONFIG_FILE KATAGO_VITISAI_DEFAULT_CONFIG_FILE @@ -337,13 +358,28 @@ struct ComputeHandle { logger->write("ONNX backend: building ONNX graph from model weights..."); OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build( loadedModel.modelDesc, ctx->nnXLen, ctx->nnYLen, - /*requireExactNNLen=*/false, /*transformerNHWC=*/false, logger, /*emitFusedMishOp=*/false + /*requireExactNNLen=*/false, ctx->transformerNHWC, logger, /*emitFusedMishOp=*/false ); builtOnnxBytes = std::move(onnxResult.serializedModel); if(logger != NULL) logger->write("ONNX backend: ONNX graph built (" + Global::uint64ToString(builtOnnxBytes.size()) + " bytes)"); onnxData = builtOnnxBytes.data(); onnxSize = builtOnnxBytes.size(); + + // Dump the ONNX model to a file when KATAGO_DUMP_ONNX is set (debug aid). + const char* dumpPath = getenv("KATAGO_DUMP_ONNX"); + if(dumpPath != nullptr && dumpPath[0] != '\0') { + ofstream dumpFile(dumpPath, ios::binary); + if(dumpFile.is_open()) { + dumpFile.write(builtOnnxBytes.data(), (streamsize)builtOnnxBytes.size()); + dumpFile.close(); + if(logger != NULL) + logger->write(string("ONNX backend: dumped ONNX model to ") + dumpPath + + " (" + Global::uint64ToString(builtOnnxBytes.size()) + " bytes)"); + } else if(logger != NULL) { + logger->write(string("ONNX backend: WARNING - could not open dump path ") + dumpPath); + } + } } if(logger != NULL) @@ -381,48 +417,6 @@ struct ComputeHandle { sessionOpts.AppendExecutionProvider_MIGraphX(migraphxOpts); if(logger != NULL) logger->write("ONNX backend: MIGraphX execution provider enabled, device_id=" + Global::intToString(migraphxOpts.device_id)); - } else if(provider == "openvino") { - std::unordered_map openvinoOpts; - openvinoOpts["device_type"] = ctx->openvinoDeviceType; - if(!ctx->openvinoDeviceId.empty()) - openvinoOpts["device_id"] = ctx->openvinoDeviceId; - if(!ctx->openvinoCacheDir.empty()) - openvinoOpts["cache_dir"] = ctx->openvinoCacheDir; - - if(ctx->openvinoEnableNPUFastCompile && logger != NULL) { - logger->write( - "ONNX backend: onnxOpenVINOEnableNPUFastCompile requested, but this ORT build may not " - "accept 'enable_npu_fast_compile'; currently ignoring this option for compatibility." - ); - } - - // Some ORT OpenVINO builds may not accept optional keys like cache_dir. - // Retry with only core device keys if optional keys are rejected. - try { - sessionOpts.AppendExecutionProvider_OpenVINO_V2(openvinoOpts); - } - catch(const Ort::Exception& e) { - bool hadOptionalKeys = openvinoOpts.count("cache_dir") > 0; - if(!hadOptionalKeys) - throw; - - if(logger != NULL) { - logger->write( - string("ONNX backend: OpenVINO optional provider options rejected, retrying without optional keys. Error: ") + - e.what() - ); - } - openvinoOpts.erase("cache_dir"); - sessionOpts.AppendExecutionProvider_OpenVINO_V2(openvinoOpts); - } - - if(logger != NULL) { - string deviceId = openvinoOpts.count("device_id") > 0 ? openvinoOpts["device_id"] : ""; - logger->write( - "ONNX backend: OpenVINO execution provider enabled, device_type=" + ctx->openvinoDeviceType + - (deviceId.empty() ? "" : (", device_id=" + deviceId)) - ); - } } else if(provider == "vitisai") { std::unordered_map vitisOpts; if(!ctx->vitisaiConfigFile.empty()) @@ -459,7 +453,7 @@ struct ComputeHandle { if(logger != NULL) logger->write("ONNX backend: using CPU execution provider"); } else { - throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', 'openvino', or 'vitisai'"); + throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', or 'vitisai'"); } // Create session from in-memory bytes @@ -554,8 +548,14 @@ ComputeContext* NeuralNet::createComputeContext( ConfigParser& cfg ) { (void)gpuIdxs; - (void)useFP16Mode; (void)loadedModel; + // The emitted ONNX graph is fp32; inference precision is chosen internally by the execution + // provider. KataGo's global useFP16 flag therefore cannot be honored here - fail loudly instead + // of silently ignoring a request. + if(useFP16Mode == enabled_t::True) + throw StringError( + "ONNX backend: the global useFP16 flag is not supported and cannot be honored. " + "Precision is controlled by the execution provider. Leave useFP16 unset or set it to false/auto."); string providerName = cfg.contains("onnxProvider") ? Global::toLower(cfg.getString("onnxProvider")) : "cpu"; @@ -576,11 +576,18 @@ ComputeContext* NeuralNet::createComputeContext( if(cfg.contains("onnxOutputValue")) ctx->outputValueName = cfg.getString("onnxOutputValue"); if(cfg.contains("onnxOutputMiscvalue")) ctx->outputMiscvalueName = cfg.getString("onnxOutputMiscvalue"); if(cfg.contains("onnxOutputOwnership")) ctx->outputOwnershipName = cfg.getString("onnxOutputOwnership"); - if(cfg.contains("onnxOpenVINODeviceType")) ctx->openvinoDeviceType = cfg.getString("onnxOpenVINODeviceType"); - if(cfg.contains("onnxOpenVINODeviceId")) ctx->openvinoDeviceId = cfg.getString("onnxOpenVINODeviceId"); - if(cfg.contains("onnxOpenVINOEnableNPUFastCompile")) - ctx->openvinoEnableNPUFastCompile = cfg.getBool("onnxOpenVINOEnableNPUFastCompile"); - if(cfg.contains("onnxOpenVINOCacheDir")) ctx->openvinoCacheDir = cfg.getString("onnxOpenVINOCacheDir"); + + // Trunk layout for transformer models. Default NHWC (channel-last), matching the TensorRT + // backend's trtTransformerNHWC default; ignored entirely for models without transformer blocks. + ctx->transformerNHWC = cfg.contains("onnxTransformerNHWC") ? cfg.getBool("onnxTransformerNHWC") : true; + + // Skip the scale8 FP16-range workaround (default false = apply it). scale8 keeps convnet + // activations 8x smaller so they stay inside typical FP16 execution-provider ranges; the cost is + // MISH_SCALE8 subgraphs that can block fused-Mish optimizations on some providers. Keep on + // (default); set true only for FP32 precision or workloads where FP16 overflow is not a + // practical risk. + ctx->skipScale8 = cfg.contains("onnxSkipScale8") ? cfg.getBool("onnxSkipScale8") : false; + if(cfg.contains("onnxVitisAIConfigFile")) ctx->vitisaiConfigFile = cfg.getString("onnxVitisAIConfigFile"); if(cfg.contains("onnxVitisAICacheDir")) ctx->vitisaiCacheDir = cfg.getString("onnxVitisAICacheDir"); if(cfg.contains("onnxVitisAIDisableCPUFallback")) @@ -624,15 +631,17 @@ ComputeHandle* NeuralNet::createComputeHandle( if(inputsUseNHWC) throw StringError("ONNX backend: inputsUseNHWC = true not supported, must use NCHW"); + // Apply the scale8 FP16-range workaround exactly once per model (unless onnxSkipScale8), + // before this handle builds the ONNX graph from modelDesc. + loadedModel->maybeApplyScale8(context->skipScale8); + if(logger != NULL) { logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion)); logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name); string deviceInfo = - context->providerName == "openvino" - ? "n/a (use onnxOpenVINODeviceType/onnxOpenVINODeviceId)" - : context->providerName == "vitisai" + context->providerName == "vitisai" ? "n/a (single NPU device)" : Global::intToString(gpuIdxForThisThread); logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + @@ -652,6 +661,12 @@ bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { return false; } +bool NeuralNet::setIsWarmup(const ComputeHandle* handle, bool isWarmup) { + (void)handle; + (void)isWarmup; + return false; +} + //-------------------------------------------------------------- // Helper to find the index of a name in a vector, checking multiple alternatives. diff --git a/cpp/neuralnet/onnxmodelbuilder.cpp b/cpp/neuralnet/onnxmodelbuilder.cpp index a8a294745b..03aa371d22 100644 --- a/cpp/neuralnet/onnxmodelbuilder.cpp +++ b/cpp/neuralnet/onnxmodelbuilder.cpp @@ -429,7 +429,10 @@ struct Builder { testAssert((int)desc.weight.size() == C); int rmsStart = graph->node_size(); // meanSq over channels (axis 1), keepdims -> [N,1,H,W] - string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); + // Pow(x, 2.0) instead of Mul(x, x): OpenVINO's RMSFusion matcher requires Power(x, const(2)) + // and silently skips Mul(x,x), leaving the RMSNorm as an unfused ReduceMean->Sqrt->Div chain. + string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); + string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); string meanSq = addNode("ReduceMean", {sq, addInt64Initializer(uniq(desc.name + "/axC"), {1})}, uniq(desc.name + "/meansq"), desc.name + "/meansq"); { onnx::NodeProto* n = lastNode(); onnx::AttributeProto* a = addAttr(n, "keepdims"); a->set_type(onnx::AttributeProto::INT); a->set_i(1); } @@ -464,7 +467,9 @@ struct Builder { int C = desc.numChannels; testAssert((int)desc.weight.size() == C); int rmsStart = graph->node_size(); - string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); + // Pow(x, 2.0) instead of Mul(x, x): see transformerRMSNorm (NCHW variant) above. + string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); + string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); string meanSq = addNode("ReduceMean", {sq, addInt64Initializer(uniq(desc.name + "/axC"), {3})}, // C is axis 3 of [N,H,W,C] uniq(desc.name + "/meansq"), desc.name + "/meansq"); { onnx::NodeProto* n = lastNode(); onnx::AttributeProto* a = addAttr(n, "keepdims"); a->set_type(onnx::AttributeProto::INT); a->set_i(1); } @@ -495,7 +500,9 @@ struct Builder { string meanSq; if(!spatial) { // Per-position mean of squares over channels (axis 1) -> [N,1,H,W] - string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); + // Pow(x, 2.0) instead of Mul(x, x): see transformerRMSNorm above (same OpenVINO fusion requirement). + string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); + string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); meanSq = addNode("ReduceMean", {sq, addInt64Initializer(uniq(desc.name + "/axC"), {1})}, uniq(desc.name + "/meansq"), desc.name + "/meansq"); { onnx::NodeProto* n = lastNode(); onnx::AttributeProto* a = addAttr(n, "keepdims"); a->set_type(onnx::AttributeProto::INT); a->set_i(1); } @@ -514,7 +521,9 @@ struct Builder { // masked: meanSq = ReduceMean_{C,H,W}(x^2 * mask) / maskMean (recover the on-board mean; // maskMean = on-board fraction of the buffer, so dividing by it cancels the off-board // zeros that ReduceMean averaged over). maskMean is itself FP32-pinned. - string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); + // Pow(x, 2.0) instead of Mul(x, x): see transformerRMSNorm above (same OpenVINO fusion requirement). + string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); + string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); string reduceInput = sq; if(!requireExactNNLen) reduceInput = addNode("Mul", {sq, maskName}, uniq(desc.name + "/sqmask"), desc.name + "/sqmask"); @@ -898,9 +907,17 @@ Result build( shape->add_dim()->set_dim_value(1); shape->add_dim()->set_dim_value(1); }; - addInput("InputMask", 1); + // Declaration order matters for the OpenVINO execution provider under ONNX Runtime: the EP builds + // its name->index map from declaration order while the runtime feeds the EP kernel input ports in + // a different order. With InputMask declared first, the two disagree and the EP misroutes the + // [N,1,H,W] mask tensor into the InputSpatial port, failing at runtime with a shape mismatch (e.g. + // "can't handle input tensor ...:InputSpatial, because model input (shape=[?,22,19,19]) and tensor + // (shape=[1,1,19,19]) are incompatible"). Declaring InputSpatial, InputGlobal, InputMask (in that + // order) fixes it. This is NOT the graph's first-reference order; it is an empirical, + // OpenVINO-EP-specific requirement. addInput("InputSpatial", numInputChannels); addInputNC11("InputGlobal", numInputGlobalChannels); + addInput("InputMask", 1); // ---- Mask-derived features ---- if(!requireExactNNLen) { diff --git a/cpp/neuralnet/onnxmodelbuilder.h b/cpp/neuralnet/onnxmodelbuilder.h index 055e01739d..b6cb64447d 100644 --- a/cpp/neuralnet/onnxmodelbuilder.h +++ b/cpp/neuralnet/onnxmodelbuilder.h @@ -32,6 +32,11 @@ namespace OnnxModelBuilder { }; // Build a serialized ONNX ModelProto for the given model. + // Inputs are always declared in the fixed order InputSpatial, InputGlobal, InputMask. This order + // is required by the OpenVINO execution provider under ONNX Runtime (its name->index map is built + // from declaration order while the runtime feeds the EP input ports in the order it expects; the + // default InputMask-first order misroutes the mask tensor at runtime). See onnxmodelbuilder.cpp + // for the full rationale. // // emitFusedMishOp: if true, KataGo's Mish activation (x * tanh(softplus(x))) is emitted as a // single native ONNX `Mish` node (opset 18+) instead of the decomposed Softplus+Tanh+Mul used diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index b904099a34..ce635e7ccb 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -111,6 +111,17 @@ vector Setup::initializeNNEvaluators( } #endif +#if defined(USE_ONNX_BACKEND) + // Distributed selfplay (contribute) uploads training data, which must never contain FP16-overflow + // NaN rows, so always apply the scale8 workaround regardless of onnxSkipScale8. + if(setupFor == SETUP_FOR_DISTRIBUTED && cfg.contains("onnxSkipScale8") && cfg.getBool("onnxSkipScale8")) { + cfg.overrideKey("onnxSkipScale8", "false"); + logger.write( + "WARNING: onnxSkipScale8 = true is not allowed for contribute (distributed selfplay); " + "forcing it to false so FP16-overflow NaNs cannot poison contributed training data."); + } +#endif + //Automatically flag keys that are for other backends as used so that we don't warn about unused keys //for those options for(const string& prefix: getBackendPrefixes()) { From c79800e0a6b0d91a6606a84e1432a39ae798609a Mon Sep 17 00:00:00 2001 From: Looong01 Date: Thu, 13 Aug 2026 02:36:23 +0800 Subject: [PATCH 27/37] Update --- Compiling.md | 42 ++ README.md | 41 +- cpp/CMakeLists.txt | 29 +- cpp/neuralnet/onnxbackend.cpp | 824 +++++++++++++++++++++++++++++++--- 4 files changed, 860 insertions(+), 76 deletions(-) diff --git a/Compiling.md b/Compiling.md index ee29184abc..bce44487e8 100644 --- a/Compiling.md +++ b/Compiling.md @@ -300,6 +300,48 @@ VitisAI only accelerates a quantized (INT8 QDQ) ONNX graph -- FP32 nodes fall ba This quantization step is entirely offline/manual -- `katago.exe` does not invoke it automatically. +##### Windows AMD NPU with Python-Embedded ONNX Runtime (Workaround) + +On some Ryzen AI SDK versions (observed with 1.7.1), the native C++ VitisAI execution provider path can fail during session creation for quantized models with many `EPContext` nodes, producing repeated errors such as `Failed to create runner: Failed to open library '...\xrt_core.dll'`. This appears to be an SDK/ORT C++ API initialization issue: the C++ API creates a fresh runner per subgraph, while Python's `onnxruntime.InferenceSession` reuses a single XRT context. + +This branch provides an optional workaround that embeds a Python interpreter and routes VitisAI inference through Python's `onnxruntime.InferenceSession`. Enable it with: + +``` +cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DPYTHON_ONNXRUNTIME=ON +cmake --build cpp/build --config Release -j +``` + +Requirements: +* A Python installation with development headers/libs that matches the Ryzen AI SDK's recommended environment (e.g., the `ryzen-ai-1.7.1` conda env with Python 3.12). CMake uses `CONDA_PREFIX` if set, or you can point it with `Python3_ROOT_DIR`. +* The `onnxruntime` Python package installed in that environment, with a version matching the SDK's bundled ONNX Runtime ABI. +* The Ryzen AI SDK installed (auto-detected as described above). + +The build bakes in the path to the Python interpreter (`KATAGO_PYTHON_EXE_PATH`). At runtime, `katago.exe` initializes Python from that installation and imports `numpy` and `onnxruntime`. + +Deployment/runtime notes: +* The directory containing `katago.exe` should also contain the matching `python312.dll` (or whichever Python version you built against) and the conda `onnxruntime.dll`. This prevents Windows from loading the older `C:\Windows\System32\onnxruntime.dll` (1.17.1), which causes API version mismatch errors such as `TarWriter` failures. +* The conda `...\Lib\site-packages\onnxruntime\capi` directory must be on `PATH` so the VitisAI EP DLLs (`onnxruntime_vitisai_ep.dll`, etc.) are found. +* `PATH` must also include the Ryzen AI SDK's `xrt` and `voe-*-win_amd64` directories. + +Example wrapper (`sabaki_katago.bat`) that keeps these PATH changes process-local: + +```bat +@echo off +setlocal +set PATH=C:\Users\\miniconda3\envs\ryzen-ai-1.7.1;%PATH% +set PATH=C:\Users\\miniconda3\envs\ryzen-ai-1.7.1\Lib\site-packages\onnxruntime\capi;%PATH% +set PATH=C:\Program Files\RyzenAI\1.7.1\xrt;%PATH% +set PATH=C:\Program Files\RyzenAI\1.7.1\voe-4.0-win_amd64;%PATH% +cd /d "C:\Envs\katago-v1.16.5-vitisai1.7.1-windows-x64" +katago.exe gtp -config gtp_npu.cfg -model kata1-zhizi-b40c768nbt-s11272M-d5935M-mish-int8_sdk_ctx.onnx +endlocal +``` + +Caveats: +* The Python C API holds the GIL around bookkeeping calls. `session.run` releases it internally, but multi-threaded throughput has not been fully benchmarked. +* First inference can take 15–30 seconds while the NPU session is created and the model is compiled/cached. +* `katago benchmark` may time out because it creates a second session while the first is still active. This workaround is mainly intended for interactive GTP play. + ## MacOS * TLDR (Metal backend - recommended for most users, hybrid CPU+GPU+Neural Engine for maximum throughput): ``` diff --git a/README.md b/README.md index 0821bc89e1..2c1c6907d2 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ - [How To Use](#how-to-use) - [ONNX/OpenVINO Intel NPU Quick Start (Windows)](#onnxopenvino-intel-npu-quick-start-windows) - [ONNX/OpenVINO Intel NPU Quick Start (Linux)](#onnxopenvino-intel-npu-quick-start-linux) + - [ONNX/VitisAI AMD NPU Quick Start (Windows)](#onnxvitisai-amd-npu-quick-start-windows) - [Human-style Play and Analysis](#human-style-play-and-analysis) - [Other Commands:](#other-commands) - [Tuning for Performance](#tuning-for-performance) @@ -99,14 +100,14 @@ The quick summary is: * Use Eigen with AVX2 if you don't have a GPU or if your GPU is too old/weak to work with OpenCL, and you just want a plain CPU KataGo. * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. * The CUDA backend can work for NVIDIA GPUs with CUDA+CUDNN installed but is likely worse than TensorRT. - * ONNX backend uses ONNX Runtime execution providers (CPU/OpenVINO/CUDA/TensorRT/MIGraphX/CoreML). It is useful for Intel NPU (OpenVINO) and raw `.onnx` models. + * ONNX backend uses ONNX Runtime execution providers (CPU/OpenVINO/VitisAI/CUDA/TensorRT/MIGraphX/CoreML). It is useful for Intel NPU (OpenVINO), AMD Ryzen AI NPU (VitisAI), and raw `.onnx` models. More in detail: * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. On most GPUs, the OpenCL implementation will actually beat NVIDIA's own CUDA/CUDNN at performance. The exception is for top-end NVIDIA GPUs that support FP16 and tensor cores, in which case sometimes one is better and sometimes the other is better. * TensorRT is similar to CUDA, but only uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs, it should work whenever CUDA does and will usually be faster than CUDA or any other backend. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. - * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, OpenVINO for Intel hardware (including NPU on supported systems), CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers, while OpenVINO NPU setups are typically single-device. + * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, OpenVINO for Intel hardware (including NPU on supported systems), VitisAI for AMD Ryzen AI NPU, CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers, while NPU setups (OpenVINO/VitisAI) are typically single-device. For **any** implementation, it's recommended that you also tune the number of threads used if you care about optimal performance, as it can make a factor of 2-3 difference in the speed. See "Tuning for Performance" below. However, if you mostly just want to get it working, then the default untuned settings should also be still reasonable. @@ -184,6 +185,42 @@ Minimal commands: ./katago gtp -config cpp/configs/gtp_example.cfg -model .onnx -override-config onnxProvider=openvino,onnxOpenVINODeviceType=NPU ``` +#### ONNX/VitisAI AMD NPU Quick Start (Windows) + +If you want to use ONNX Runtime + VitisAI on an AMD Ryzen AI NPU: + +* Install the AMD Ryzen AI SDK: https://ryzenai.docs.amd.com/ +* Use the `ryzen-ai-` conda environment (or equivalent) with Python's `onnxruntime` package matching the SDK. +* This branch has a `PYTHON_ONNXRUNTIME` build option that embeds Python to work around a RyzenAI 1.7.1 C++ API bug when loading quantized models with many EPContext nodes. + +Build with: +```bash +cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DPYTHON_ONNXRUNTIME=ON +cmake --build cpp/build --config Release -j +``` + +At runtime, to avoid Windows loading the wrong `onnxruntime.dll` from `C:\Windows\System32`, deploy `katago.exe` together with the matching `python312.dll` and the conda `onnxruntime.dll`. Also ensure `PATH` includes: +* your conda environment directory, +* `...\Lib\site-packages\onnxruntime\capi`, +* `C:\Program Files\RyzenAI\\xrt`, +* `C:\Program Files\RyzenAI\\voe-*-win_amd64`. + +A `.bat` wrapper is the recommended way to set PATH only for the KataGo process (see [Compiling.md](Compiling.md) for an example). + +Minimal commands: +```bash +# 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) +./katago.exe exportonnx -model .bin.gz -output .onnx + +# 2) Quantize to INT8 for VitisAI NPU (uses AMD quark in the RyzenAI conda env) +python python/quantize_vitisai.py --input .onnx --calibration calib.npz --output -int8.onnx + +# 3) Run GTP for GUI tools +./katago.exe gtp -config cpp/configs/gtp_example.cfg -model -int8.onnx -override-config onnxProvider=vitisai +``` + +First inference may take 15–30 seconds while the NPU compiles/caches the model. `katago benchmark` may time out with this workaround; it is mainly intended for interactive GTP play. + #### Human-style Play and Analysis You can also have KataGo imitate human play if you download the human SL model b18c384nbt-humanv0.bin.gz from https://github.com/lightvector/KataGo/releases/tag/v1.15.0, and run a command like the following, providing both the normal model and the human SL model: diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 7a47998dd7..0507a9c5c2 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -718,6 +718,33 @@ elseif(USE_BACKEND STREQUAL "ONNX") endif() target_link_libraries(katago ${ONNXRUNTIME_LIB}) + # ---- Optional: embedded Python onnxruntime path for VitisAI ---- + # The RyzenAI 1.7.1 SDK's VitisAI EP works through Python's onnxruntime binding but fails + # when the model is loaded via the public C/C++ API (Ort::Session). Allow users to opt into + # embedding a Python interpreter and using onnxruntime.InferenceSession directly for the + # VitisAI provider. Requires Python development headers/library and a numpy/onnxruntime + # environment that can reach the VitisAI provider (e.g. the ryzen-ai conda env). + if(WIN32) + set(PYTHON_ONNXRUNTIME OFF CACHE BOOL "Embed Python and route VitisAI inference through Python's onnxruntime") + if(PYTHON_ONNXRUNTIME) + if(DEFINED ENV{CONDA_PREFIX}) + set(Python3_ROOT_DIR "$ENV{CONDA_PREFIX}") + endif() + find_package(Python3 COMPONENTS Interpreter Development REQUIRED) + if(Python3_FOUND) + target_compile_definitions(katago PRIVATE ENABLE_PYTHON_ONNXRUNTIME) + # Pass the Python interpreter path into the binary so Py_SetProgramName can point the + # embedded interpreter at the correct stdlib / site-packages (e.g. the ryzen-ai conda env). + target_compile_definitions(katago PRIVATE KATAGO_PYTHON_EXE_PATH="${Python3_EXECUTABLE}") + target_include_directories(katago SYSTEM PRIVATE ${Python3_INCLUDE_DIRS}) + target_link_libraries(katago ${Python3_LIBRARIES}) + message(STATUS "Python embedded onnxruntime enabled (VitisAI Python path): ${Python3_EXECUTABLE}") + else() + message(FATAL_ERROR "PYTHON_ONNXRUNTIME requested but Python3 development files were not found. Set CONDA_PREFIX or Python3_ROOT_DIR.") + endif() + endif() + endif() + # Required by onnxmodelbuilder.cpp for building ONNX graphs from .bin.gz. # These are intentionally configurable because package layouts vary. set(ONNX_INCLUDE_DIR "" CACHE PATH "Directory containing onnx/onnx-ml.pb.h (required for .bin.gz -> ONNX conversion)") @@ -1057,7 +1084,7 @@ if (WIN32) # handles both x86 and x64 target_compile_definitions(katago PRIVATE LITTLE_ENDIAN=1234) target_compile_definitions(katago PRIVATE BIG_ENDIAN=4321) # core/rand.cpp uses winsock for a gethostname - target_link_libraries(katago ws2_32) + target_link_libraries(katago ws2_32 ole32) if (MINGW) message(STATUS "Setting up build for mingw.") if(USE_BACKEND STREQUAL "CUDA" OR USE_BACKEND STREQUAL "TENSORRT") diff --git a/cpp/neuralnet/onnxbackend.cpp b/cpp/neuralnet/onnxbackend.cpp index b156e55ccc..ad0b38abac 100644 --- a/cpp/neuralnet/onnxbackend.cpp +++ b/cpp/neuralnet/onnxbackend.cpp @@ -18,13 +18,50 @@ #include #endif +#include + #include #include +#include +#include + +#ifdef _WIN32 +#include // For CoInitializeEx/CoUninitialize +#endif + +#ifdef ENABLE_PYTHON_ONNXRUNTIME +#include +#endif using namespace std; //-------------------------------------------------------------- +// Convert a narrow (ASCII) path string to ONNX Runtime's ORTCHAR_T path type. +static std::basic_string toOrtPath(const string& path) { +#ifdef _WIN32 + return std::basic_string(path.begin(), path.end()); +#else + return path; +#endif +} + +// Extract concrete dimensions from an ONNX TensorShapeProto. Symbolic dimensions +// (e.g. "batch") are treated as unknown and reported as -1. +static vector getOnnxTensorShape(const onnx::TensorShapeProto& shapeProto) { + vector shape; + shape.reserve(shapeProto.dim_size()); + for(const auto& dim : shapeProto.dim()) { + if(dim.has_dim_value()) + shape.push_back(dim.dim_value()); + else + shape.push_back(-1); + } + return shape; +} + +//-------------------------------------------------------------- + // Auto-detect modelVersion from introspected channel counts. // // Detection is based on channel-count heuristics for raw .onnx files where the @@ -65,6 +102,7 @@ struct LoadedModel { ModelDesc modelDesc; bool isRawOnnx; string rawOnnxBytes; + string rawOnnxFileName; // only valid when isRawOnnx is true // Constructor for .bin.gz files LoadedModel(const string& fileName, const string& expectedSha256, bool rawOnnx) @@ -75,6 +113,8 @@ struct LoadedModel { return; } + rawOnnxFileName = fileName; + // Read raw .onnx file bytes { std::ifstream in(fileName, std::ios::binary | std::ios::ate); @@ -89,25 +129,24 @@ struct LoadedModel { throw StringError("ONNX backend: failed to read raw ONNX file: " + fileName); } - // Create a temporary CPU session to introspect shapes - Ort::Env tmpEnv(ORT_LOGGING_LEVEL_WARNING, "KataGoOnnxIntrospect"); - Ort::SessionOptions tmpOpts; - tmpOpts.SetIntraOpNumThreads(1); - Ort::Session tmpSession(tmpEnv, rawOnnxBytes.data(), rawOnnxBytes.size(), tmpOpts); + // Parse the ONNX ModelProto directly to introspect input/output shapes. This avoids + // creating a temporary CPU-only ONNX Runtime session, which cannot load EP context cache + // models that contain EPContext nodes (the CPU EP has no kernel for them). + onnx::ModelProto modelProto; + if(!modelProto.ParseFromArray(rawOnnxBytes.data(), (int)rawOnnxBytes.size())) + throw StringError("ONNX backend: failed to parse raw ONNX file as ModelProto: " + fileName); - Ort::AllocatorWithDefaultOptions allocator; + const onnx::GraphProto& graph = modelProto.graph(); // Introspect inputs by name first, falling back to shape-based heuristic int numInputChannels = 0; int numInputGlobalChannels = 0; int numInputMetaChannels = 0; - size_t numInputs = tmpSession.GetInputCount(); - for(size_t i = 0; i < numInputs; i++) { - Ort::AllocatedStringPtr namePtr = tmpSession.GetInputNameAllocated(i, allocator); - string name = namePtr.get(); - auto typeInfo = tmpSession.GetInputTypeInfo(i); - auto tensorInfo = typeInfo.GetTensorTypeAndShapeInfo(); - auto shape = tensorInfo.GetShape(); + for(const auto& input : graph.input()) { + string name = input.name(); + if(!input.type().has_tensor_type()) + continue; + auto shape = getOnnxTensorShape(input.type().tensor_type().shape()); // Name-based matching must be case-insensitive: the graph node names emitted by // OnnxModelBuilder::build() (and expected by default elsewhere in this file) are // PascalCase ("InputSpatial", "InputGlobal", "InputMask", "InputMeta"), not lowercase. @@ -145,13 +184,11 @@ struct LoadedModel { int numValueChannels = 0; int numScoreValueChannels = 0; int numOwnershipChannels = 0; - size_t numOutputs = tmpSession.GetOutputCount(); - for(size_t i = 0; i < numOutputs; i++) { - Ort::AllocatedStringPtr namePtr = tmpSession.GetOutputNameAllocated(i, allocator); - string name = namePtr.get(); - auto typeInfo = tmpSession.GetOutputTypeInfo(i); - auto tensorInfo = typeInfo.GetTensorTypeAndShapeInfo(); - auto shape = tensorInfo.GetShape(); + for(const auto& output : graph.output()) { + string name = output.name(); + if(!output.type().has_tensor_type()) + continue; + auto shape = getOnnxTensorShape(output.type().tensor_type().shape()); // Case-insensitive for the same reason as the input-side matching above; also match // "scorevalue" (the actual "OutputScoreValue" node name), not "miscvalue". @@ -237,6 +274,13 @@ struct ComputeContext { string vitisaiConfigFile; string vitisaiCacheDir; bool vitisaiDisableCPUFallback; + bool vitisaiUsePythonRuntime; + + // ONNX Runtime EP context cache options (VitisAI). See + // https://onnxruntime.ai/docs/execution-providers/EP-Context-Design.html + bool vitisaiUseEpContextCache; + string vitisaiEpContextFilePath; + int vitisaiEpContextEmbedMode; // Configurable input/output node names. Defaults match the node names emitted by the shared // OnnxModelBuilder::build() (see onnxmodelbuilder.cpp) used for .bin.gz -> ONNX conversion, @@ -273,6 +317,18 @@ struct ComputeContext { ), vitisaiCacheDir(""), vitisaiDisableCPUFallback(true), +#ifdef ENABLE_PYTHON_ONNXRUNTIME + // When Python embedding is compiled in, default to the Python onnxruntime path for + // VitisAI. This works around a RyzenAI SDK bug where the native C/C++ API fails to + // create runners for EP context cache models. The user can still opt out by setting + // onnxVitisAIUsePythonRuntime=false in the config. + vitisaiUsePythonRuntime(true), +#else + vitisaiUsePythonRuntime(false), +#endif + vitisaiUseEpContextCache(false), + vitisaiEpContextFilePath(""), + vitisaiEpContextEmbedMode(1), inputMaskName("InputMask"), inputSpatialName("InputSpatial"), inputGlobalName("InputGlobal"), @@ -288,10 +344,206 @@ struct ComputeContext { //-------------------------------------------------------------- +#ifdef ENABLE_PYTHON_ONNXRUNTIME +namespace { + +struct PythonOnnxState { + static std::atomic initialized; + static std::mutex initMutex; + static PyObject* npModule; + static PyObject* ortModule; + static PyObject* npFloat32; + static PyObject* npFrombuffer; +}; + +std::atomic PythonOnnxState::initialized{false}; +std::mutex PythonOnnxState::initMutex; +PyObject* PythonOnnxState::npModule = nullptr; +PyObject* PythonOnnxState::ortModule = nullptr; +PyObject* PythonOnnxState::npFloat32 = nullptr; +PyObject* PythonOnnxState::npFrombuffer = nullptr; + +static void pythonPrintError() { + if(PyErr_Occurred()) + PyErr_Print(); +} + +static void ensurePythonInitialized() { + std::lock_guard lock(PythonOnnxState::initMutex); + if(PythonOnnxState::initialized) + return; + +#ifdef KATAGO_PYTHON_EXE_PATH + // Point the embedded interpreter at the Python installation that was detected at build time + // (e.g. the ryzen-ai conda environment). This ensures Python finds its stdlib, site-packages, + // and the onnxruntime package even when katago.exe is launched from a directory that does not + // contain a full Python installation. The buffers must remain valid for the interpreter lifetime. + { + static std::wstring pyExeW; + static std::wstring pyHomeW; + if(pyExeW.empty()) { + const char* pyExe = KATAGO_PYTHON_EXE_PATH; + int wlen = MultiByteToWideChar(CP_UTF8, 0, pyExe, -1, nullptr, 0); + if(wlen > 0) { + pyExeW.resize(wlen); + MultiByteToWideChar(CP_UTF8, 0, pyExe, -1, pyExeW.data(), wlen); + Py_SetProgramName(pyExeW.c_str()); + } + // Derive PYTHONHOME from the directory containing python.exe. + const char* lastSlash = strrchr(pyExe, '/'); + if(!lastSlash) lastSlash = strrchr(pyExe, '\\'); + std::string pyHome(pyExe, lastSlash ? (size_t)(lastSlash - pyExe) : strlen(pyExe)); + wlen = MultiByteToWideChar(CP_UTF8, 0, pyHome.c_str(), -1, nullptr, 0); + if(wlen > 0) { + pyHomeW.resize(wlen); + MultiByteToWideChar(CP_UTF8, 0, pyHome.c_str(), -1, pyHomeW.data(), wlen); + Py_SetPythonHome(pyHomeW.c_str()); + } + } + } +#endif + + Py_Initialize(); + if(!Py_IsInitialized()) + throw StringError("ONNX backend: Py_Initialize failed"); + PythonOnnxState::npModule = PyImport_ImportModule("numpy"); + PythonOnnxState::ortModule = PyImport_ImportModule("onnxruntime"); + if(!PythonOnnxState::npModule || !PythonOnnxState::ortModule) { + pythonPrintError(); + throw StringError("ONNX backend: failed to import numpy or onnxruntime"); + } + PythonOnnxState::npFloat32 = PyObject_GetAttrString(PythonOnnxState::npModule, "float32"); + PythonOnnxState::npFrombuffer = PyObject_GetAttrString(PythonOnnxState::npModule, "frombuffer"); + if(!PythonOnnxState::npFloat32 || !PythonOnnxState::npFrombuffer) { + pythonPrintError(); + throw StringError("ONNX backend: failed to get numpy helpers"); + } + PythonOnnxState::initialized = true; +} + +static PyObject* buildPythonProviderOptions(const ComputeContext* ctx) { + PyObject* opts = PyDict_New(); + PyDict_SetItemString(opts, "config_file", PyUnicode_FromString(ctx->vitisaiConfigFile.c_str())); + return opts; +} + +static PyObject* buildPythonSessionOptions(const ComputeContext* ctx) { + PyObject* cls = PyObject_GetAttrString(PythonOnnxState::ortModule, "SessionOptions"); + PyObject* opts = PyObject_CallObject(cls, nullptr); + PyObject_CallMethod(opts, "__setattr__", "si", "intra_op_num_threads", 1); + Py_DECREF(cls); + return opts; +} + +static PyObject* createPythonSession(const ComputeContext* ctx, const string& modelPath) { + ensurePythonInitialized(); + PyGILState_STATE gil = PyGILState_Ensure(); + PyObject* sessOptions = buildPythonSessionOptions(ctx); + PyObject* providerOpts = buildPythonProviderOptions(ctx); + PyObject* providerOptionsList = PyList_New(1); + PyList_SET_ITEM(providerOptionsList, 0, providerOpts); + PyObject* providersList = PyList_New(1); + PyList_SET_ITEM(providersList, 0, PyUnicode_FromString("VitisAIExecutionProvider")); + PyObject* sessionCls = PyObject_GetAttrString(PythonOnnxState::ortModule, "InferenceSession"); + PyObject* modelPathObj = PyUnicode_FromString(modelPath.c_str()); + PyObject* kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "sess_options", sessOptions); + PyDict_SetItemString(kwargs, "providers", providersList); + PyDict_SetItemString(kwargs, "provider_options", providerOptionsList); + PyObject* session = PyObject_Call(sessionCls, PyTuple_Pack(1, modelPathObj), kwargs); + Py_DECREF(sessOptions); Py_DECREF(providersList); Py_DECREF(providerOptionsList); + Py_DECREF(sessionCls); Py_DECREF(modelPathObj); Py_DECREF(kwargs); + if(!session) { + pythonPrintError(); + PyGILState_Release(gil); + throw StringError("ONNX backend: failed to create Python InferenceSession"); + } + PyGILState_Release(gil); + return session; +} + +static PyObject* createPythonSessionFromBytes(const ComputeContext* ctx, const char* data, size_t size) { + ensurePythonInitialized(); + PyGILState_STATE gil = PyGILState_Ensure(); + PyObject* sessOptions = buildPythonSessionOptions(ctx); + PyObject* providerOpts = buildPythonProviderOptions(ctx); + PyObject* providerOptionsList = PyList_New(1); + PyList_SET_ITEM(providerOptionsList, 0, providerOpts); + PyObject* providersList = PyList_New(1); + PyList_SET_ITEM(providersList, 0, PyUnicode_FromString("VitisAIExecutionProvider")); + PyObject* sessionCls = PyObject_GetAttrString(PythonOnnxState::ortModule, "InferenceSession"); + PyObject* modelBytes = PyBytes_FromStringAndSize(data, size); + PyObject* kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "sess_options", sessOptions); + PyDict_SetItemString(kwargs, "providers", providersList); + PyDict_SetItemString(kwargs, "provider_options", providerOptionsList); + PyObject* session = PyObject_Call(sessionCls, PyTuple_Pack(1, modelBytes), kwargs); + Py_DECREF(sessOptions); Py_DECREF(providersList); Py_DECREF(providerOptionsList); + Py_DECREF(sessionCls); Py_DECREF(modelBytes); Py_DECREF(kwargs); + if(!session) { + pythonPrintError(); + PyGILState_Release(gil); + throw StringError("ONNX backend: failed to create Python InferenceSession from bytes"); + } + PyGILState_Release(gil); + return session; +} + +// Create a NumPy float32 array (reshaped) that views an existing C++ float buffer. +// The returned object is a new reference; the caller must Py_DECREF it. +static PyObject* numpyArrayFromBuffer(float* data, size_t numFloats, const vector& shape) { + PyObject* memview = PyMemoryView_FromMemory( + reinterpret_cast(data), static_cast(numFloats * sizeof(float)), PyBUF_WRITE); + if(!memview) + return nullptr; + PyObject* arr = PyObject_CallFunctionObjArgs( + PythonOnnxState::npFrombuffer, memview, PythonOnnxState::npFloat32, nullptr); + Py_DECREF(memview); + if(!arr) + return nullptr; + PyObject* shapeTuple = PyTuple_New(shape.size()); + for(size_t i = 0; i < shape.size(); i++) + PyTuple_SET_ITEM(shapeTuple, i, PyLong_FromLongLong(shape[i])); + PyObject* reshaped = PyObject_CallMethod(arr, "reshape", "O", shapeTuple); + Py_DECREF(arr); Py_DECREF(shapeTuple); + return reshaped; +} + +} // namespace +#endif // ENABLE_PYTHON_ONNXRUNTIME + +//-------------------------------------------------------------- + struct ComputeHandle { ComputeContext* context; std::unique_ptr session; int modelVersion; + +#ifdef ENABLE_PYTHON_ONNXRUNTIME + bool usePythonRuntime; + PyObject* pySession; + std::vector> outputShapes; +#endif + +#ifdef _WIN32 + // COM initialization state for this thread. Some NPU runtime components (XRT/ + // VitisAI) appear to require COM on the thread that creates/runs the session. + HRESULT comInitResult; +#endif + + ~ComputeHandle() { +#ifdef ENABLE_PYTHON_ONNXRUNTIME + if(usePythonRuntime && pySession) { + PyGILState_STATE gil = PyGILState_Ensure(); + Py_DECREF(pySession); + PyGILState_Release(gil); + } +#endif +#ifdef _WIN32 + if(comInitResult == S_OK || comInitResult == S_FALSE) + CoUninitialize(); +#endif + } int numInputChannels; int numInputGlobalChannels; int numPolicyChannels; @@ -310,6 +562,10 @@ struct ComputeHandle { ComputeHandle(ComputeContext* ctx, const LoadedModel& loadedModel, Logger* logger, int deviceIdxForThread) : context(ctx), modelVersion(loadedModel.modelDesc.modelVersion), +#ifdef ENABLE_PYTHON_ONNXRUNTIME + usePythonRuntime(false), + pySession(nullptr), +#endif numInputChannels(loadedModel.modelDesc.numInputChannels), numInputGlobalChannels(loadedModel.modelDesc.numInputGlobalChannels), numPolicyChannels(loadedModel.modelDesc.numPolicyChannels), @@ -318,7 +574,14 @@ struct ComputeHandle { numOwnershipChannels(loadedModel.modelDesc.numOwnershipChannels), numInputMetaChannels(loadedModel.modelDesc.numInputMetaChannels), policyResultLen(ctx->nnXLen * ctx->nnYLen + 1) +#ifdef _WIN32 + , comInitResult(S_OK) +#endif { +#ifdef _WIN32 + comInitResult = CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + // Apply config model version override if set if(ctx->configModelVersion >= 0) modelVersion = ctx->configModelVersion; @@ -354,6 +617,14 @@ struct ComputeHandle { // Select execution provider based on providerName const string& provider = ctx->providerName; + +#ifdef ENABLE_PYTHON_ONNXRUNTIME + // When Python embedding is compiled in, VitisAI defaults to the Python onnxruntime path + // to work around the RyzenAI 1.7.1 SDK C/C++ API bug. The user can opt out via + // onnxVitisAIUsePythonRuntime=false in the config. + usePythonRuntime = (provider == "vitisai" && ctx->vitisaiUsePythonRuntime); +#endif + if(provider == "coreml") { #ifdef __APPLE__ uint32_t coremlFlags = COREML_FLAG_CREATE_MLPROGRAM; @@ -424,36 +695,71 @@ struct ComputeHandle { ); } } else if(provider == "vitisai") { - std::unordered_map vitisOpts; - if(!ctx->vitisaiConfigFile.empty()) - vitisOpts["config_file"] = ctx->vitisaiConfigFile; - else - throw StringError( - "ONNX backend: onnxProvider=vitisai requires a VitisAI EP config file (vaip_config.json, " - "shipped with the AMD Ryzen AI / VitisAI SDK). Set 'onnxVitisAIConfigFile' in your config, " - "or rebuild with a locatable Ryzen AI installation so a default gets baked in." - ); - // The VitisAI EP's enable_cache_file_io_in_mem provider option defaults to 1 (in-memory - // only -- nothing is ever written to cache_dir), so it must be explicitly set to 0 to make - // the compiled model actually persist to disk across process launches. Without this, every - // katago.exe launch pays the full NPU compile cost again (can take on the order of minutes). - vitisOpts["cache_dir"] = ctx->vitisaiCacheDir; - vitisOpts["enable_cache_file_io_in_mem"] = "0"; - sessionOpts.AppendExecutionProvider_VitisAI(vitisOpts); - if(ctx->vitisaiDisableCPUFallback) { - // Force a hard failure at session-creation time if any node can't be claimed by VitisAI, - // instead of ONNX Runtime silently assigning it to the always-registered CPU EP. Without - // this, "session created successfully" is not evidence that anything actually runs on the - // NPU. Set onnxVitisAIDisableCPUFallback=false to relax this if partial CPU fallback is - // acceptable for your use case. - sessionOpts.AddConfigEntry("session.disable_cpu_ep_fallback", "1"); - } - if(logger != NULL) { - logger->write( - "ONNX backend: VitisAI execution provider enabled, config_file=" + ctx->vitisaiConfigFile + - ", cache_dir=" + ctx->vitisaiCacheDir + - ", disable_cpu_ep_fallback=" + Global::boolToString(ctx->vitisaiDisableCPUFallback) - ); +#ifdef ENABLE_PYTHON_ONNXRUNTIME + if(usePythonRuntime) { + if(logger != NULL) + logger->write("ONNX backend: using Python-embedded onnxruntime path for VitisAI"); + } else +#endif + { + std::unordered_map vitisOpts; + if(!ctx->vitisaiConfigFile.empty()) + vitisOpts["config_file"] = ctx->vitisaiConfigFile; + else + throw StringError( + "ONNX backend: onnxProvider=vitisai requires a VitisAI EP config file (vaip_config.json, " + "shipped with the AMD Ryzen AI / VitisAI SDK). Set 'onnxVitisAIConfigFile' in your config, " + "or rebuild with a locatable Ryzen AI installation so a default gets baked in." + ); + // The VitisAI EP's enable_cache_file_io_in_mem provider option defaults to 1 (in-memory + // only -- nothing is ever written to cache_dir), so it must be explicitly set to 0 to make + // the compiled model actually persist to disk across process launches. Without this, every + // katago.exe launch pays the full NPU compile cost again (can take on the order of minutes). + // For pre-built EP context cache models, leave the cache options at their defaults; the + // compiled context is already embedded in the ONNX model and does not need to be persisted. + bool isContextModel = loadedModel.isRawOnnx && + loadedModel.rawOnnxFileName.find("_ctx.onnx") != string::npos; + if(!isContextModel) { + vitisOpts["cache_dir"] = ctx->vitisaiCacheDir; + vitisOpts["enable_cache_file_io_in_mem"] = "0"; + } + // Use the generic provider-registration path rather than the VitisAI-specific C++ helper. + // The generic path loads the provider by name and also registers any associated custom-op + // libraries (e.g. onnxruntime_vitis_ai_custom_ops.dll), which is required for EP context + // cache models containing EPContext nodes. + sessionOpts.AppendExecutionProvider("VitisAIExecutionProvider", vitisOpts); + if(ctx->vitisaiDisableCPUFallback) { + // Force a hard failure at session-creation time if any node can't be claimed by VitisAI, + // instead of ONNX Runtime silently assigning it to the always-registered CPU EP. Without + // this, "session created successfully" is not evidence that anything actually runs on the + // NPU. Set onnxVitisAIDisableCPUFallback=false to relax this if partial CPU fallback is + // acceptable for your use case. + sessionOpts.AddConfigEntry("session.disable_cpu_ep_fallback", "1"); + } + if(ctx->vitisaiUseEpContextCache) { + // ONNX Runtime EP context cache: ask the VitisAI EP to dump a self-contained context model + // (compiled subgraphs embedded as EPContext nodes). This may avoid per-subgraph repeated + // initialization of the NPU runtime. See https://onnxruntime.ai/docs/execution-providers/EP-Context-Design.html + string ctxFilePath = ctx->vitisaiEpContextFilePath; + if(ctxFilePath.empty()) + ctxFilePath = ctx->vitisaiCacheDir + "/katago_vitisai_ctx.onnx"; + sessionOpts.AddConfigEntry("ep.context_enable", "1"); + sessionOpts.AddConfigEntry("ep.context_file_path", ctxFilePath.c_str()); + sessionOpts.AddConfigEntry("ep.context_embed_mode", Global::intToString(ctx->vitisaiEpContextEmbedMode).c_str()); + if(logger != NULL) { + logger->write( + "ONNX backend: VitisAI EP context cache enabled, context_file_path=" + ctxFilePath + + ", embed_mode=" + Global::intToString(ctx->vitisaiEpContextEmbedMode) + ); + } + } + if(logger != NULL) { + logger->write( + "ONNX backend: VitisAI execution provider enabled, config_file=" + ctx->vitisaiConfigFile + + ", cache_dir=" + ctx->vitisaiCacheDir + + ", disable_cpu_ep_fallback=" + Global::boolToString(ctx->vitisaiDisableCPUFallback) + ); + } } } else if(provider == "cpu" || provider.empty()) { if(logger != NULL) @@ -462,31 +768,115 @@ struct ComputeHandle { throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', 'openvino', or 'vitisai'"); } - // Create session from in-memory bytes - session = std::make_unique(ctx->env, onnxData, onnxSize, sessionOpts); + // Create session. For raw .onnx files we have the original file path, so prefer loading + // from disk: some EPs (notably VitisAI when consuming an EP context cache model) need the + // model file path to resolve embedded context binaries or to correctly claim EPContext nodes. + // For .bin.gz-derived models we only have in-memory bytes. +#ifdef ENABLE_PYTHON_ONNXRUNTIME + if(usePythonRuntime) { + if(loadedModel.isRawOnnx && !loadedModel.rawOnnxFileName.empty()) { + if(logger != NULL) + logger->write("ONNX backend: creating Python session from file path: " + loadedModel.rawOnnxFileName); + pySession = createPythonSession(ctx, loadedModel.rawOnnxFileName); + } else { + if(logger != NULL) + logger->write("ONNX backend: creating Python session from in-memory bytes"); + pySession = createPythonSessionFromBytes(ctx, onnxData, onnxSize); + } - // Query and store input names - Ort::AllocatorWithDefaultOptions allocator; - size_t numInputs = session->GetInputCount(); - for(size_t i = 0; i < numInputs; i++) { - Ort::AllocatedStringPtr name = session->GetInputNameAllocated(i, allocator); - inputNames.push_back(name.get()); - } - for(auto& n : inputNames) - inputNamePtrs.push_back(n.c_str()); - - // Query and store output names - size_t numOutputs = session->GetOutputCount(); - for(size_t i = 0; i < numOutputs; i++) { - Ort::AllocatedStringPtr name = session->GetOutputNameAllocated(i, allocator); - outputNames.push_back(name.get()); - } - for(auto& n : outputNames) - outputNamePtrs.push_back(n.c_str()); + // Query input/output names from the Python session and store output shapes. + PyGILState_STATE gil = PyGILState_Ensure(); + PyObject* pyInputs = PyObject_CallMethod(pySession, "get_inputs", nullptr); + if(!pyInputs) { pythonPrintError(); PyGILState_Release(gil); throw StringError("ONNX backend: Python get_inputs failed"); } + Py_ssize_t numInputs = PySequence_Size(pyInputs); + for(Py_ssize_t i = 0; i < numInputs; i++) { + PyObject* inp = PySequence_GetItem(pyInputs, i); + PyObject* nameObj = PyObject_GetAttrString(inp, "name"); + inputNames.push_back(PyUnicode_AsUTF8(nameObj)); + Py_DECREF(nameObj); Py_DECREF(inp); + } + Py_DECREF(pyInputs); + + PyObject* pyOutputs = PyObject_CallMethod(pySession, "get_outputs", nullptr); + if(!pyOutputs) { pythonPrintError(); PyGILState_Release(gil); throw StringError("ONNX backend: Python get_outputs failed"); } + Py_ssize_t numOutputs = PySequence_Size(pyOutputs); + for(Py_ssize_t i = 0; i < numOutputs; i++) { + PyObject* out = PySequence_GetItem(pyOutputs, i); + PyObject* nameObj = PyObject_GetAttrString(out, "name"); + outputNames.push_back(PyUnicode_AsUTF8(nameObj)); + PyObject* shapeObj = PyObject_GetAttrString(out, "shape"); + Py_ssize_t shapeLen = PySequence_Size(shapeObj); + vector shape; + for(Py_ssize_t s = 0; s < shapeLen; s++) { + PyObject* dim = PySequence_GetItem(shapeObj, s); + if(PyLong_Check(dim)) shape.push_back(PyLong_AsLongLong(dim)); + else shape.push_back(-1); // symbolic dimension (batch) + Py_DECREF(dim); + } + outputShapes.push_back(shape); + Py_DECREF(nameObj); Py_DECREF(shapeObj); Py_DECREF(out); + } + Py_DECREF(pyOutputs); + PyGILState_Release(gil); - if(logger != NULL) - logger->write("ONNX backend: session created, inputs=" + Global::uint64ToString(numInputs) + - " outputs=" + Global::uint64ToString(numOutputs)); + for(auto& n : inputNames) inputNamePtrs.push_back(n.c_str()); + for(auto& n : outputNames) outputNamePtrs.push_back(n.c_str()); + + if(logger != NULL) { + logger->write("ONNX backend: Python session created, inputs=" + Global::int64ToString(numInputs) + + " outputs=" + Global::int64ToString(numOutputs)); + // Log which onnxruntime Python package is being used. This is useful for diagnosing + // DLL shadowing: if the directory containing katago.exe also contains an onnxruntime.dll + // (or XRT/VitisAI DLLs) from a different build, the embedded Python path may load the + // wrong one and fail with xrt_core.dll / runner-creation errors. + PyGILState_STATE gil = PyGILState_Ensure(); + PyObject* ortModule = PyImport_ImportModule("onnxruntime"); + if(ortModule) { + PyObject* fileObj = PyObject_GetAttrString(ortModule, "__file__"); + if(fileObj) { + logger->write(string("ONNX backend: Python onnxruntime loaded from: ") + PyUnicode_AsUTF8(fileObj)); + Py_DECREF(fileObj); + } + Py_DECREF(ortModule); + } + PyGILState_Release(gil); + } + } else +#endif + { + if(loadedModel.isRawOnnx && !loadedModel.rawOnnxFileName.empty()) { + if(logger != NULL) + logger->write("ONNX backend: creating session from file path: " + loadedModel.rawOnnxFileName); + session = std::make_unique(ctx->env, toOrtPath(loadedModel.rawOnnxFileName).c_str(), sessionOpts); + } else { + if(logger != NULL) + logger->write("ONNX backend: creating session from in-memory bytes"); + session = std::make_unique(ctx->env, onnxData, onnxSize, sessionOpts); + } + + // Query and store input names + Ort::AllocatorWithDefaultOptions allocator; + size_t numInputs = session->GetInputCount(); + for(size_t i = 0; i < numInputs; i++) { + Ort::AllocatedStringPtr name = session->GetInputNameAllocated(i, allocator); + inputNames.push_back(name.get()); + } + for(auto& n : inputNames) + inputNamePtrs.push_back(n.c_str()); + + // Query and store output names + size_t numOutputs = session->GetOutputCount(); + for(size_t i = 0; i < numOutputs; i++) { + Ort::AllocatedStringPtr name = session->GetOutputNameAllocated(i, allocator); + outputNames.push_back(name.get()); + } + for(auto& n : outputNames) + outputNamePtrs.push_back(n.c_str()); + + if(logger != NULL) + logger->write("ONNX backend: session created, inputs=" + Global::uint64ToString(numInputs) + + " outputs=" + Global::uint64ToString(numOutputs)); + } } ComputeHandle() = delete; @@ -585,6 +975,14 @@ ComputeContext* NeuralNet::createComputeContext( if(cfg.contains("onnxVitisAICacheDir")) ctx->vitisaiCacheDir = cfg.getString("onnxVitisAICacheDir"); if(cfg.contains("onnxVitisAIDisableCPUFallback")) ctx->vitisaiDisableCPUFallback = cfg.getBool("onnxVitisAIDisableCPUFallback"); + if(cfg.contains("onnxVitisAIUsePythonRuntime")) + ctx->vitisaiUsePythonRuntime = cfg.getBool("onnxVitisAIUsePythonRuntime"); + if(cfg.contains("onnxVitisAIUseEpContextCache")) + ctx->vitisaiUseEpContextCache = cfg.getBool("onnxVitisAIUseEpContextCache"); + if(cfg.contains("onnxVitisAIEpContextFilePath")) + ctx->vitisaiEpContextFilePath = cfg.getString("onnxVitisAIEpContextFilePath"); + if(cfg.contains("onnxVitisAIEpContextEmbedMode")) + ctx->vitisaiEpContextEmbedMode = Global::stringToInt(cfg.getString("onnxVitisAIEpContextEmbedMode")); if(providerName == "vitisai" && ctx->vitisaiCacheDir.empty()) { // No explicit override: default to a fixed subdir of katagodata, same convention as // trtbackend.cpp's "trtcache" (see HomeData::getHomeDataDir), so the (slow, ~minutes-long) @@ -654,6 +1052,279 @@ bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { //-------------------------------------------------------------- +static int findNameIndex(const vector& names, const vector& targets); + +#ifdef ENABLE_PYTHON_ONNXRUNTIME +// Run inference through the embedded Python onnxruntime.InferenceSession and copy the +// resulting NumPy arrays back into KataGo's output buffers. This path is used for the +// VitisAI provider when the public C/C++ API path fails (RyzenAI 1.7.1 SDK bug). +static void getOutputPython( + ComputeHandle* computeHandle, + InputBuffers* inputBuffers, + int numBatchEltsFilled, + NNResultBuf** inputBufs, + vector& outputs +) { + const int batchSize = numBatchEltsFilled; + const int nnXLen = computeHandle->context->nnXLen; + const int nnYLen = computeHandle->context->nnYLen; + const int numSpatialFeatures = computeHandle->numInputChannels; + const int numGlobalFeatures = computeHandle->numInputGlobalChannels; + const int numInputMetaChannels = computeHandle->numInputMetaChannels; + const ComputeContext* ctx = computeHandle->context; + + // Fill input buffers (same logic as the Ort::Session path). + for(int nIdx = 0; nIdx < batchSize; nIdx++) { + float* rowSpatialInput = inputBuffers->spatialInput.data() + (inputBuffers->singleInputElts * nIdx); + float* rowGlobalInput = inputBuffers->globalInput.data() + (inputBuffers->singleInputGlobalElts * nIdx); + const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); + const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); + std::copy(rowGlobal, rowGlobal + numGlobalFeatures, rowGlobalInput); + SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, false, inputBufs[nIdx]->symmetry); + if(numInputMetaChannels > 0) { + float* rowMetaInput = inputBuffers->metaInput.data() + (inputBuffers->singleInputMetaElts * nIdx); + const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); + std::copy(rowMeta, rowMeta + numInputMetaChannels, rowMetaInput); + } + } + + int spatialIdx = findNameIndex(computeHandle->inputNames, {ctx->inputSpatialName}); + int globalIdx = findNameIndex(computeHandle->inputNames, {ctx->inputGlobalName}); + if(spatialIdx < 0 || globalIdx < 0) + throw StringError("ONNX backend (Python path): could not find expected input names"); + + const int spatialPolicyLen = nnXLen * nnYLen; + int maskIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMaskName}); + vector maskBuf; + if(maskIdx >= 0) { + maskBuf.resize((size_t)batchSize * spatialPolicyLen); + for(int r = 0; r < batchSize; r++) { + const float* rowSpatial = inputBuffers->spatialInput.data() + inputBuffers->singleInputElts * r; + std::copy(rowSpatial, rowSpatial + spatialPolicyLen, maskBuf.data() + (size_t)r * spatialPolicyLen); + } + } + + int metaIdx = -1; + if(numInputMetaChannels > 0) { + metaIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMetaName}); + if(metaIdx < 0) + throw StringError("ONNX backend (Python path): model has metadata channels but could not find " + ctx->inputMetaName); + } + + PyGILState_STATE gil = PyGILState_Ensure(); + + // Build input_feed dict. + PyObject* inputFeed = PyDict_New(); + for(size_t i = 0; i < computeHandle->inputNames.size(); i++) { + float* data = nullptr; + size_t numFloats = 0; + vector shape; + if((int)i == spatialIdx) { + data = inputBuffers->spatialInput.data(); + numFloats = inputBuffers->singleInputElts * batchSize; + shape = {batchSize, numSpatialFeatures, nnYLen, nnXLen}; + } else if((int)i == globalIdx) { + data = inputBuffers->globalInput.data(); + numFloats = inputBuffers->singleInputGlobalElts * batchSize; + shape = {batchSize, numGlobalFeatures, 1, 1}; + } else if((int)i == metaIdx) { + data = inputBuffers->metaInput.data(); + numFloats = inputBuffers->singleInputMetaElts * batchSize; + shape = {batchSize, numInputMetaChannels, 1, 1}; + } else if((int)i == maskIdx) { + data = maskBuf.data(); + numFloats = maskBuf.size(); + shape = {batchSize, 1, nnYLen, nnXLen}; + } else { + PyGILState_Release(gil); + throw StringError("ONNX backend (Python path): unexpected input node '" + computeHandle->inputNames[i] + + "' -- only mask, spatial, global, and meta inputs are supported"); + } + PyObject* arr = numpyArrayFromBuffer(data, numFloats, shape); + if(!arr) { + pythonPrintError(); + PyGILState_Release(gil); + throw StringError("ONNX backend (Python path): failed to create numpy array for input '" + computeHandle->inputNames[i] + "'"); + } + PyDict_SetItemString(inputFeed, computeHandle->inputNames[i].c_str(), arr); + Py_DECREF(arr); + } + + // Run inference. + PyObject* runResult = PyObject_CallMethod(computeHandle->pySession, "run", "OO", Py_None, inputFeed); + Py_DECREF(inputFeed); + if(!runResult) { + pythonPrintError(); + PyGILState_Release(gil); + throw StringError("ONNX backend (Python path): session.run failed"); + } + + // Copy outputs and wrap them in Ort::Value tensors so the rest of getOutput can stay unchanged. + Py_ssize_t numOutputs = PyList_Size(runResult); + vector outputTensors; + outputTensors.reserve(numOutputs); + vector> outputData(numOutputs); + Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); + + for(Py_ssize_t i = 0; i < numOutputs; i++) { + PyObject* outArr = PyList_GET_ITEM(runResult, i); + PyObject* bytes = PyObject_CallMethod(outArr, "tobytes", nullptr); + if(!bytes) { + pythonPrintError(); + Py_DECREF(runResult); + PyGILState_Release(gil); + throw StringError("ONNX backend (Python path): failed to get output bytes"); + } + char* buf = nullptr; + Py_ssize_t len = 0; + PyBytes_AsStringAndSize(bytes, &buf, &len); + size_t numFloats = len / sizeof(float); + outputData[i].resize(numFloats); + std::memcpy(outputData[i].data(), buf, len); + Py_DECREF(bytes); + + // Use the stored output shape, replacing any symbolic dimension with the current batch size. + vector shape = computeHandle->outputShapes[i]; + int64_t product = 1; + for(size_t s = 0; s < shape.size(); s++) { + if(shape[s] < 0) shape[s] = batchSize; + product *= shape[s]; + } + // Fallback: if stored shape is empty or inconsistent, flatten to [batchSize, numFloats/batchSize]. + if(shape.empty() || product != (int64_t)numFloats) { + shape = {(int64_t)batchSize, (int64_t)(numFloats / batchSize)}; + } + outputTensors.push_back( + Ort::Value::CreateTensor(memInfo, outputData[i].data(), outputData[i].size(), shape.data(), shape.size()) + ); + } + Py_DECREF(runResult); + PyGILState_Release(gil); + + // The remainder of output extraction is identical to the C++ API path. + int policyPassOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyPassName}); + int policyOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyName}); + int valueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputValueName}); + int miscvalueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputMiscvalueName}); + int ownershipOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputOwnershipName}); + + if(policyPassOutputIdx < 0) + throw StringError("ONNX backend (Python path): could not find policy-pass output node '" + ctx->outputPolicyPassName + "'"); + if(policyOutputIdx < 0) + throw StringError("ONNX backend (Python path): could not find policy output node '" + ctx->outputPolicyName + "'"); + if(valueOutputIdx < 0) + throw StringError("ONNX backend (Python path): could not find value output node '" + ctx->outputValueName + "'"); + if(miscvalueOutputIdx < 0) + throw StringError("ONNX backend (Python path): could not find miscvalue output node '" + ctx->outputMiscvalueName + "'"); + if(ownershipOutputIdx < 0) + throw StringError("ONNX backend (Python path): could not find ownership output node '" + ctx->outputOwnershipName + "'"); + + const float* policyPassData = outputTensors[policyPassOutputIdx].GetTensorData(); + const float* policyData = outputTensors[policyOutputIdx].GetTensorData(); + const float* valueData = outputTensors[valueOutputIdx].GetTensorData(); + const float* miscvalueData = outputTensors[miscvalueOutputIdx].GetTensorData(); + const float* ownershipData = outputTensors[ownershipOutputIdx].GetTensorData(); + + assert(policyPassData != nullptr); + assert(policyData != nullptr); + assert(valueData != nullptr); + assert(miscvalueData != nullptr); + assert(ownershipData != nullptr); + assert((int)outputs.size() == batchSize); + + float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; + + for(int row = 0; row < batchSize; row++) { + NNOutput* output = outputs[row]; + assert(output->nnXLen == nnXLen); + assert(output->nnYLen == nnYLen); + float policyOptimism = (float)inputBufs[row]->policyOptimism; + + { + const float* policyRowBase = policyData + (size_t)row * computeHandle->numPolicyChannels * spatialPolicyLen; + const float* policyPassRowBase = policyPassData + (size_t)row * computeHandle->numPolicyChannels; + float* policyProbs = output->policyProbs; + + if(computeHandle->numPolicyChannels >= 2) { + const float* ch0 = policyRowBase; + const float* ch1 = policyRowBase + spatialPolicyLen; + for(int i = 0; i < spatialPolicyLen; i++) { + float p = ch0[i]; + float pOpt = ch1[i]; + policyProbsTmp[i] = p + (pOpt - p) * policyOptimism; + } + SymmetryHelpers::copyOutputsWithSymmetry(policyProbsTmp, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[spatialPolicyLen] = policyPassRowBase[0] + (policyPassRowBase[1] - policyPassRowBase[0]) * policyOptimism; + } else { + assert(computeHandle->numPolicyChannels == 1); + const float* ch0 = policyRowBase; + SymmetryHelpers::copyOutputsWithSymmetry(ch0, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[spatialPolicyLen] = policyPassRowBase[0]; + } + } + + { + int numVC = computeHandle->numValueChannels; + assert(numVC == 3); + output->whiteWinProb = valueData[row * numVC]; + output->whiteLossProb = valueData[row * numVC + 1]; + output->whiteNoResultProb = valueData[row * numVC + 2]; + } + + { + int numScoreValueChannels = computeHandle->numScoreValueChannels; + if(computeHandle->modelVersion >= 9) { + assert(numScoreValueChannels >= 6); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; + output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; + output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = miscvalueData[row * numScoreValueChannels + 4]; + output->shorttermScoreError = miscvalueData[row * numScoreValueChannels + 5]; + } + else if(computeHandle->modelVersion >= 8) { + assert(numScoreValueChannels >= 4); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; + output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; + output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(computeHandle->modelVersion >= 4) { + assert(numScoreValueChannels >= 2); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(computeHandle->modelVersion >= 3) { + assert(numScoreValueChannels >= 1); + output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else { + ASSERT_UNREACHABLE; + } + } + + if(output->whiteOwnerMap != NULL) { + assert(computeHandle->numOwnershipChannels == 1); + const float* ownershipRowBuf = ownershipData + row * nnXLen * nnYLen; + SymmetryHelpers::copyOutputsWithSymmetry(ownershipRowBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + } + } +} +#endif // ENABLE_PYTHON_ONNXRUNTIME + +//-------------------------------------------------------------- + // Helper to find the index of a name in a vector, checking multiple alternatives. static int findNameIndex(const vector& names, const vector& targets) { for(size_t i = 0; i < names.size(); i++) { @@ -681,6 +1352,13 @@ void NeuralNet::getOutput( const int numGlobalFeatures = computeHandle->numInputGlobalChannels; const int numPolicyChannels = computeHandle->numPolicyChannels; +#ifdef ENABLE_PYTHON_ONNXRUNTIME + if(computeHandle->usePythonRuntime) { + getOutputPython(computeHandle, inputBuffers, numBatchEltsFilled, inputBufs, outputs); + return; + } +#endif + // Fill input buffers for(int nIdx = 0; nIdx < batchSize; nIdx++) { float* rowSpatialInput = inputBuffers->spatialInput.data() + (inputBuffers->singleInputElts * nIdx); From 8f3773fe16a7e78f5b8e422ec59d0caa0325a55b Mon Sep 17 00:00:00 2001 From: Looong01 Date: Thu, 13 Aug 2026 03:38:59 +0800 Subject: [PATCH 28/37] Roll back to 1.17.2 --- .gitignore | 2 +- CONTRIBUTORS | 7 +- Compiling.md | 243 +-- README.md | 137 +- cpp/CMakeLists.txt | 515 +---- cpp/README.md | 5 +- cpp/book/book.cpp | 68 +- cpp/book/book.h | 19 +- cpp/command/analysis.cpp | 29 +- cpp/command/benchmark.cpp | 99 +- cpp/command/dumpcalibrationdata.cpp | 257 --- cpp/command/evalsgf.cpp | 15 +- cpp/command/genbook.cpp | 78 +- cpp/command/gtp.cpp | 183 +- cpp/command/misc.cpp | 330 +++- cpp/command/runtests.cpp | 6 +- cpp/command/sandbox.cpp | 2 +- cpp/command/selfplay.cpp | 8 + cpp/command/startposes.cpp | 12 +- cpp/command/writetrainingdata.cpp | 11 +- cpp/configs/analysis_example.cfg | 61 +- cpp/configs/contribute_example.cfg | 58 +- cpp/configs/gtp_example.cfg | 99 +- cpp/configs/match_example.cfg | 60 +- cpp/dataio/loadmodel.cpp | 19 +- cpp/dataio/sgf.cpp | 42 +- cpp/dataio/sgf.h | 8 +- cpp/dataio/trainingwrite.cpp | 90 +- cpp/dataio/trainingwrite.h | 52 +- .../include/katagocoreml/KataGoConverter.hpp | 5 + cpp/external/katagocoreml/src/Converter.cpp | 28 +- .../katagocoreml/src/builder/MILBuilder.cpp | 1054 ++++++++++- .../katagocoreml/src/builder/MILBuilder.hpp | 113 +- .../katagocoreml/src/builder/Operations.cpp | 22 +- .../katagocoreml/src/builder/Operations.hpp | 54 +- .../katagocoreml/src/parser/KataGoParser.cpp | 614 ++++-- .../katagocoreml/src/parser/KataGoParser.hpp | 34 +- .../src/serializer/CoreMLSerializer.cpp | 65 +- .../src/serializer/WeightSerializer.cpp | 19 +- .../katagocoreml/src/types/KataGoTypes.hpp | 68 +- cpp/game/boardhistory.cpp | 40 +- cpp/game/boardhistory.h | 23 +- cpp/game/rules.cpp | 4 +- cpp/game/rules.h | 5 +- cpp/main.cpp | 23 +- cpp/main.h | 3 +- cpp/neuralnet/cudabackend.cpp | 15 +- cpp/neuralnet/cudahelpers.cu | 14 +- cpp/neuralnet/cudahelpers.h | 6 +- cpp/neuralnet/desc.cpp | 209 ++- cpp/neuralnet/desc.h | 34 + cpp/neuralnet/eigenbackend.cpp | 26 +- cpp/neuralnet/metalbackend.cpp | 164 +- cpp/neuralnet/metalbackend.h | 20 + cpp/neuralnet/metalbackend.swift | 7 + cpp/neuralnet/metallayers.swift | 616 +++++- cpp/neuralnet/nneval.cpp | 36 +- cpp/neuralnet/nneval.h | 7 + cpp/neuralnet/nninputs.cpp | 29 +- cpp/neuralnet/nninputs.h | 12 + cpp/neuralnet/onnxbackend.cpp | 1650 ----------------- cpp/neuralnet/onnxmodelbuilder.cpp | 101 +- cpp/neuralnet/onnxmodelbuilder.h | 17 +- cpp/neuralnet/openclbackend.cpp | 1 + cpp/neuralnet/opencltuner.cpp | 4 +- cpp/neuralnet/opencltuner.h | 24 +- cpp/neuralnet/trtbackend.cpp | 90 +- cpp/program/gtpconfig.cpp | 31 +- cpp/program/gtpconfig.h | 3 +- cpp/program/play.cpp | 459 ++++- cpp/program/play.h | 9 +- cpp/program/playsettings.cpp | 14 +- cpp/program/playsettings.h | 29 + cpp/program/playutils.cpp | 16 +- cpp/program/selfplaymanager.cpp | 19 + cpp/program/selfplaymanager.h | 5 + cpp/program/setup.cpp | 43 +- cpp/rungpuerrortest.sh | 33 + cpp/runonnxtests.sh | 43 - cpp/search/patternbonustable.cpp | 3 +- cpp/search/search.cpp | 35 +- cpp/search/search.h | 11 + cpp/search/searchnnhelpers.cpp | 13 +- cpp/search/searchparams.cpp | 4 + cpp/search/searchparams.h | 5 + cpp/tests/gtp/passalivemode.txt | 25 + .../results/analysis/badoverride.txt.log | 4 +- .../results/analysis/badoverride.txt.stderr | 4 +- cpp/tests/results/analysis/basic.txt.log | 4 +- cpp/tests/results/analysis/basic.txt.stderr | 4 +- .../results/analysis/basic_sidetomove.stderr | 4 +- .../results/analysis/basic_sidetomove.txt.log | 4 +- .../results/analysis/clear_cache.txt.stderr | 4 +- cpp/tests/results/analysis/eval_cache.txt.log | 4 +- .../analysis/humansl_sidetomove.stderr | 6 +- cpp/tests/results/analysis/pvvisits.txt.log | 4 +- .../results/analysis/pvvisits.txt.stderr | 4 +- .../results/analysis/pvvisits_nograph.stderr | 4 +- .../results/analysis/pvvisits_nograph.txt.log | 4 +- cpp/tests/results/analysis/symmetry.txt.log | 4 +- .../results/analysis/symmetry.txt.stderr | 4 +- .../analysis/symmetry_with_pruning.stderr | 4 +- .../analysis/symmetry_with_pruning.txt.log | 4 +- cpp/tests/results/gtp/avoidcorners.log | 4 +- cpp/tests/results/gtp/avoidcorners.stderr | 2 +- cpp/tests/results/gtp/basic.txt.log | 6 +- cpp/tests/results/gtp/basic.txt.stderr | 2 +- cpp/tests/results/gtp/defaultkomibutton.log | 4 +- .../results/gtp/defaultkomibutton.stderr | 2 +- cpp/tests/results/gtp/defaultkomiterr.log | 4 +- cpp/tests/results/gtp/defaultkomiterr.stderr | 2 +- cpp/tests/results/gtp/defaultkomitt.log | 4 +- cpp/tests/results/gtp/defaultkomitt.stderr | 2 +- cpp/tests/results/gtp/ending.txt.log | 6 +- cpp/tests/results/gtp/ending.txt.stderr | 2 +- cpp/tests/results/gtp/forcedkomi.log | 4 +- cpp/tests/results/gtp/forcedkomi.stderr | 2 +- cpp/tests/results/gtp/genmoveanalyze.log | 4 +- cpp/tests/results/gtp/genmoveanalyze.stderr | 2 +- cpp/tests/results/gtp/handicap.txt.log | 8 +- cpp/tests/results/gtp/handicap.txt.stderr | 2 +- cpp/tests/results/gtp/humansl.log | 8 +- cpp/tests/results/gtp/humansl.stderr | 2 +- cpp/tests/results/gtp/humansl.stdout | 2 +- cpp/tests/results/gtp/humansl2.stderr | 2 +- cpp/tests/results/gtp/misc.txt.log | 8 +- cpp/tests/results/gtp/misc.txt.stderr | 2 +- cpp/tests/results/gtp/misc.txt.stdout | 4 +- cpp/tests/results/gtp/nologconfig.log | 4 +- cpp/tests/results/gtp/nologconfig.stderr | 2 +- .../results/gtp/passalivemode.txt.stderr | 63 + .../results/gtp/passalivemode.txt.stdout | 70 + cpp/tests/results/gtp/printsgf.txt.log | 8 +- cpp/tests/results/gtp/printsgf.txt.stderr | 2 +- .../results/gtp/printsgffinalscore.txt.log | 6 +- .../results/gtp/printsgffinalscore.txt.stderr | 2 +- cpp/tests/results/gtp/rawnn.txt.log | 8 +- cpp/tests/results/gtp/rawnn.txt.stderr | 2 +- cpp/tests/results/gtp/rootsymprune.log | 4 +- cpp/tests/results/gtp/rootsymprune.stderr | 2 +- cpp/tests/results/gtp/rules.txt.log | 4 +- cpp/tests/results/gtp/rules.txt.stderr | 2 +- cpp/tests/results/gtp/searchcancellable.log | 4 +- .../results/gtp/searchcancellable.stderr | 2 +- .../results/gtp/set_boardsize_twice.txt.log | 8 +- .../gtp/set_boardsize_twice.txt.stderr | 2 +- cpp/tests/results/gtp/set_position.txt.log | 8 +- cpp/tests/results/gtp/set_position.txt.stderr | 2 +- cpp/tests/results/gtp/setparams.txt.log | 8 +- cpp/tests/results/gtp/setparams.txt.stderr | 2 +- cpp/tests/results/gtp/setparams.txt.stdout | 4 +- cpp/tests/results/gtp/time.txt.log | 4 +- cpp/tests/results/gtp/time.txt.stderr | 2 +- cpp/tests/results/runNNCanaryTests.txt | 6 +- cpp/tests/results/runNNOnTinyBoardTest.txt | 2 +- cpp/tests/results/runNNOnTinyBoardTestB28.txt | 2 +- cpp/tests/results/runNNSymmetriesTest.txt | 2 +- cpp/tests/results/runNNSymmetriesTestFP16.txt | 2 +- cpp/tests/results/runOutputTests.txt | 1194 +++++++++++- .../results/runSearchTests-iNCHW-cNCHW.txt | 2 +- .../results/runSearchTests-iNHWC-cNCHW.txt | 2 +- .../results/runSearchTests-iNHWC-cNHWC.txt | 2 +- .../results/runSearchTests-r4-iNCHW-cNCHW.txt | 2 +- .../results/runSearchTests-r4-iNHWC-cNCHW.txt | 2 +- .../results/runSearchTests-r4-iNHWC-cNHWC.txt | 2 +- cpp/tests/results/runSearchTests-r4-s1.txt | 2 +- cpp/tests/results/runSearchTests-s1.txt | 2 +- .../runSearchTestsFP16-iNHWC-cNCHW.txt | 2 +- .../runSearchTestsFP16-iNHWC-cNHWC.txt | 2 +- .../runSearchTestsFP16-r4-iNHWC-cNCHW.txt | 2 +- .../runSearchTestsFP16-r4-iNHWC-cNHWC.txt | 2 +- .../results/runSearchTestsFP16-r4-s1.txt | 2 +- cpp/tests/results/runSearchTestsFP16-s1.txt | 2 +- .../runSearchTestsV3-g2-iNCHW-cNCHW.txt | 6 +- .../runSearchTestsV3-g2-iNHWC-cNCHW.txt | 6 +- .../runSearchTestsV3-g2-iNHWC-cNHWC.txt | 6 +- cpp/tests/results/runSearchTestsV3-g2-s1.txt | 6 +- cpp/tests/results/runSearchTestsV3-g2-s5.txt | 6 +- .../runSearchTestsV3FP16-g2-iNHWC-cNCHW.txt | 6 +- .../runSearchTestsV3FP16-g2-iNHWC-cNHWC.txt | 6 +- .../results/runSearchTestsV3FP16-g2-s1.txt | 6 +- cpp/tests/results/runSearchTestsV8.txt | 48 +- cpp/tests/results/runSearchTestsV8Bin.txt | 48 +- cpp/tests/results/runSearchTestsV8FP16.txt | 48 +- cpp/tests/results/runSearchTestsV9.txt | 2 +- cpp/tests/results/runSearchTestsV9B18NBT.txt | 2 +- .../results/runSearchTestsV9B18NBTFP16.txt | 2 +- cpp/tests/results/runSearchTestsV9B40.txt | 2 +- cpp/tests/results/runSekiTrainWriteTests.txt | 50 +- .../results/runSelfplayInitStatTests.txt | 2 +- cpp/tests/results/runSelfplayInitTests.txt | 596 +++++- cpp/tests/results/runTinyNNTests.txt | 6 +- cpp/tests/results/sampletest-hint/log.log | 2 +- cpp/tests/results/sampletest-vf/log.log | 2 +- cpp/tests/results/sampletest2-hint/log.log | 2 +- cpp/tests/testboardbasic.cpp | 14 +- cpp/tests/testbook.cpp | 3 +- cpp/tests/testmisc.cpp | 55 + cpp/tests/testnnevalcanary.cpp | 84 +- cpp/tests/testnninputs.cpp | 38 +- cpp/tests/testownership.cpp | 2 +- cpp/tests/testpassalivesuicide.cpp | 303 +++ cpp/tests/testrules.cpp | 144 +- cpp/tests/tests.h | 4 + cpp/tests/testscore.cpp | 8 +- cpp/tests/testsearchcommon.cpp | 3 +- cpp/tests/testsearchmisc.cpp | 8 +- cpp/tests/testsearchnonn.cpp | 72 +- cpp/tests/testsearchv3.cpp | 18 +- cpp/tests/testsearchv8.cpp | 80 +- cpp/tests/testsearchv9.cpp | 34 +- cpp/tests/testsgf.cpp | 6 +- cpp/tests/testsymmetries.cpp | 2 +- cpp/tests/testtime.cpp | 8 +- cpp/tests/testtrainingwrite.cpp | 598 +++++- cpp/tests/tinymodel.cpp | 6 +- docs/Analysis_Engine.md | 4 +- docs/GTP_Extensions.md | 7 +- docs/releasepackaging/README.txt | 101 + python/benchmark_fresh_model.py | 347 +++- python/export_model_pytorch.py | 46 +- .../katago/train/data_processing_pytorch.py | 17 +- python/katago/train/metrics_pytorch.py | 74 +- python/katago/train/model_pytorch.py | 372 +++- python/katago/train/trainloop_helpers.py | 467 +++++ python/muon/muon.py | 722 ++++++-- python/quantize_vitisai.py | 182 -- python/refresh_batchnorm_stats.py | 387 ++++ python/shuffle.py | 25 +- python/train.py | 251 ++- 230 files changed, 10447 insertions(+), 5097 deletions(-) delete mode 100644 cpp/command/dumpcalibrationdata.cpp delete mode 100644 cpp/neuralnet/onnxbackend.cpp delete mode 100644 cpp/runonnxtests.sh create mode 100644 cpp/tests/gtp/passalivemode.txt create mode 100644 cpp/tests/results/gtp/passalivemode.txt.stderr create mode 100644 cpp/tests/results/gtp/passalivemode.txt.stdout create mode 100644 cpp/tests/testpassalivesuicide.cpp create mode 100644 docs/releasepackaging/README.txt create mode 100644 python/katago/train/trainloop_helpers.py delete mode 100644 python/quantize_vitisai.py create mode 100644 python/refresh_batchnorm_stats.py diff --git a/.gitignore b/.gitignore index 6cc7ff125d..7799d05291 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,7 @@ CMakeCache.txt CMakeFiles/ Makefile cmake_install.cmake +cpp/builds/ .DS_Store GPATH @@ -91,4 +92,3 @@ cpp/build.ninja cpp/KataGoSwift.* cpp/include/KataGoSwift/KataGoSwift-swift.h cpp/external/katagocoreml/proto/ -cpp/external/onnxruntime-win-x64-vitisai/ diff --git a/CONTRIBUTORS b/CONTRIBUTORS index a6fa13b374..0f5f442095 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -38,22 +38,23 @@ Emanuel-de-Jong - For minor improvement to GTP command. "simon300000" - For minor update to .gitignore. Dave Jarvis - For improved inline documentation for GTP example config. Yuji Ichikiwa - For a minor fix to include paths. -"hzyhhzy" - For suggestions/improvements for training speed, and for a minor fix for rules parsing. +"hzyhhzy" - For suggestions/improvements for training speed, various major training performance optimizations, and for a minor fix for rules parsing. Thaddee Tyl ("espadrine") - Reporting and fixing of issue with half library intrinsics. Sebastian H ("nerai") - Minor code cleanups and fixes. Jochen Voss ("seehuhn") - Typo fix in doc "kinfkong" - Added trt build configuration option "TTXS123OK" - Minor code style improvement. -Chin-Chang Yang - For maintaining and implementing the Metal backend for MacOS and a variety of other GPU-related testing. +Chin-Chang Yang - For maintaining and implementing the Metal and CoreML backends for MacOS and a variety of other GPU-related testing. "tterava" - For improvements to build instructions. "Stanley" - Minor typo fixes. "Traveler" - Minor readme edits. Ivan Kochurkin ("kvanttt") - for work and testing for Mingw and Metal backends, GitHub CI, various bugfixes and performance improvements. -loker404 - One-line bugfix for python script. +loker404 - One-line bugfixes for python scripts. "HarangPanul" - minor code style improvement awei-mj - CUDA 13.0 support. Cheng Chang ("changcheng967") - Python script bugfix. Evgeny Kurnevsky ("kurnevsky") - Out-of-bounds write fix. +Suqin Zhang ("zsqdx") - Testing and optimizations to TensorRT and other gpu performance, various other collaboration on model training. Separately from the authors of the content in this repo, additional special thanks to: Junyan Xu ("alreadydone") - for much testing and troubleshooting for Windows support diff --git a/Compiling.md b/Compiling.md index bce44487e8..abe7de36fc 100644 --- a/Compiling.md +++ b/Compiling.md @@ -34,7 +34,6 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. * If using the Eigen backend, Eigen3. With Debian packages, (i.e. apt or apt-get), this should be `libeigen3-dev`. - * If using the ONNX backend, ONNX Runtime headers/libs and ONNX protobuf dependencies (`onnx/onnx-ml.pb.h`, `onnx_proto`, `protobuf-lite`) for `.bin.gz` model conversion support. * zlib, libzip. With Debian packages (i.e. apt or apt-get), these should be `zlib1g-dev`, `libzip-dev`. * If you want to do self-play training and research, probably Google perftools `libgoogle-perftools-dev` for TCMalloc or some other better malloc implementation. For unknown reasons, the allocation pattern in self-play with large numbers of threads and parallel games causes a lot of memory fragmentation under glibc malloc that will eventually run your machine out of memory, but better mallocs handle it fine. * If compiling to contribute to public distributed training runs, OpenSSL is required (`libssl-dev`). @@ -42,7 +41,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * `git clone https://github.com/lightvector/KataGo.git` * Compile using CMake and make in the cpp directory: * `cd KataGo/cpp` - * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` or `cmake . -DUSE_BACKEND=ONNX` depending on which backend you want. + * `cmake . -DUSE_BACKEND=OPENCL` or `cmake . -DUSE_BACKEND=CUDA` or `cmake . -DUSE_BACKEND=TENSORRT` or `cmake . -DUSE_BACKEND=EIGEN` depending on which backend you want. * Specify also `-DUSE_TCMALLOC=1` if using TCMalloc. * Compiling will also call git commands to embed the git hash into the compiled executable, specify also `-DNO_GIT_REVISION=1` to disable it if this is causing issues for you. * Specify `-DUSE_AVX2=1` to also compile Eigen with AVX2 and FMA support, which will make it incompatible with old CPUs but much faster. (If you want to go further, you can also add `-DCMAKE_CXX_FLAGS='-march=native'` which will specialize to precisely your machine's CPU, but the exe might not run on other machines at all). @@ -55,80 +54,6 @@ As also mentioned in the instructions below but repeated here for visibility, if * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device when you run it (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). -##### ONNX Runtime Backend (Linux) -The ONNX backend uses ONNX Runtime for inference, and supports both: -* `.onnx` models loaded directly. -* `.bin.gz` KataGo models via internal conversion to ONNX graph (requires ONNX protobuf dependencies in CMake). - -##### Linux Intel NPU (OpenVINO EP) Setup -1. Install Intel NPU driver on Linux: - * https://github.com/intel/linux-npu-driver -2. Install OpenVINO via system package manager (APT example): - * https://docs.openvino.ai/2025/get-started/install-openvino/install-openvino-apt.html -3. Build ONNX Runtime with OpenVINO EP for NPU (same ORT flow as Windows): - * https://onnxruntime.ai/docs/build/eps.html#openvino - * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). - -##### Prepare `ONNXRUNTIME_ROOT` in KataGo (Linux) -Use package root: -* `cpp/external/onnxruntime-linux-x64-openvino` - -Linux one-to-one mapping (`` -> KataGo): - -Include files: - -| Source (``) | Destination (KataGo) | -| --- | --- | -| `include/core/*` | `cpp/external/onnxruntime-linux-x64-openvino/include/core/` | -| `include/cpu_provider_factory.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/cpu_provider_factory.h` | -| `include/provider_options.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/provider_options.h` | -| `include/onnxruntime_c_api.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_c_api.h` | -| `include/onnxruntime_cxx_api.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_cxx_api.h` | -| `include/onnxruntime_cxx_inline.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_cxx_inline.h` | -| `include/onnxruntime_env_config_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_env_config_keys.h` | -| `include/onnxruntime_ep_c_api.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_ep_c_api.h` | -| `include/onnxruntime_ep_device_ep_metadata_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_ep_device_ep_metadata_keys.h` | -| `include/onnxruntime_float16.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_float16.h` | -| `include/onnxruntime_lite_custom_op.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_lite_custom_op.h` | -| `include/onnxruntime_run_options_config_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_run_options_config_keys.h` | -| `include/onnxruntime_session_options_config_keys.h` | `cpp/external/onnxruntime-linux-x64-openvino/include/onnxruntime_session_options_config_keys.h` | - -Library/config/pkgconfig files: - -| Source (``) | Destination (KataGo) | -| --- | --- | -| `lib/libonnxruntime_providers_openvino.so` | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime_providers_openvino.so` | -| `lib/libonnxruntime_providers_shared.so` | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime_providers_shared.so` | -| `lib/libonnxruntime.so.1.24.3` | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime.so.1.24.3` | -| `lib/libonnxruntime.so.1` (symlink to `.1.24.3`) | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime.so.1` | -| `lib/libonnxruntime.so` (symlink to `.1`) | `cpp/external/onnxruntime-linux-x64-openvino/lib/libonnxruntime.so` | -| `lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | -| `lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | -| `lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | -| `lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | `cpp/external/onnxruntime-linux-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | -| `lib/pkgconfig/libonnxruntime.pc` | `cpp/external/onnxruntime-linux-x64-openvino/lib/pkgconfig/libonnxruntime.pc` | - -##### Minimal KataGo Build Commands (Linux, ONNX backend) -On Linux, `KATAGO_AUTO_FETCH_DEPS=ON` can auto-fetch missing `zlib`, `onnx`, and `protobuf` dependencies via vcpkg into `cpp/build/deps/vcpkg`. - -```bash -cmake -S cpp -B cpp/build -G Ninja -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-linux-x64-openvino -cmake --build cpp/build -j -``` - -If you want to disable auto-fetch and provide dependencies manually: -* `-DKATAGO_AUTO_FETCH_DEPS=OFF` -* plus `-DONNX_INCLUDE_DIR=... -DONNX_PROTO_LIB=... -DPROTOBUF_INCLUDE_DIR=... -DPROTOBUF_LIB=... -DZLIB_INCLUDE_DIR=... -DZLIB_LIBRARY=...` - -Typical run config for Intel NPU: -* `onnxProvider = openvino` -* `onnxOpenVINODeviceType = NPU` -* `onnxOpenVINOEnableNPUFastCompile = true` (optional; may be ignored on ORT builds that do not support this key) - -Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). -For `onnxProvider=openvino` on Intel NPU, a single device is typically used. - - ## Windows * TLDR: * Building from source on Windows is actually a bit tricky, depending on what version you're building, there's not necessarily a super-fast way. @@ -139,8 +64,13 @@ For `onnxProvider=openvino` on Intel NPU, a single device is typically used. * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. I'm unsure how version compatibility works with CUDA, there's a good chance that later versions than these work just as well, but they have not been tested. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. * If using the Eigen backend, Eigen3, version 3.3.x. (http://eigen.tuxfamily.org/index.php?title=Main_Page#Download). - * If using the ONNX backend, ONNX Runtime package (headers + import libs + runtime DLLs). - * On Windows, missing `zlib` and ONNX model-conversion dependencies (`onnx`, `protobuf`) can be auto-fetched by CMake into `cpp/build/deps/vcpkg` (default `KATAGO_AUTO_FETCH_DEPS=ON`). + * zlib. Easy way to build zlib on Windows is to use vcpkg. Run in Powershell: + * git clone https://github.com/microsoft/vcpkg.git + * cd .\vcpkg\ + * .\bootstrap-vcpkg.bat + * .\vcpkg.exe install zlib:x64-windows + * Set CMake ZLIB_LIBRARY to vcpkg\installed\x64-windows\lib\zlib.lib and ZLIB_INCLUDE_DIRECTORY to vcpkg\installed\x64-windows\include. + * Copy zlib1.dll from vcpkg\installed\x64-windows\bin to Katago folder after you've built Katago executable. * libzip (optional, needed only for self-play training) - for example https://github.com/kiyolee/libzip-win-build * For MinGW it's recommended to use [MSYS2](https://www.msys2.org/) building platform to get necessary zlib and libzip dependencies: * Install MSYS2 according to the instruction on the official site @@ -167,7 +97,7 @@ For `onnxProvider=openvino` on Intel NPU, a single device is typically used. -DLIBZIP_INCLUDE_DIR_ZIPCONF:PATH="C:/msys64/mingw64/include" -DLIBZIP_LIBRARY:FILEPATH="C:/msys64/mingw64/lib/libzip.dll.a" ``` - * Also set `USE_BACKEND` to `OPENCL`, or `CUDA`, or `TENSORRT`, or `EIGEN`, or `ONNX` depending on what backend you want to use. + * Also set `USE_BACKEND` to `OPENCL`, or `CUDA`, or `TENSORRT`, or `EIGEN` depending on what backend you want to use. * Set any other options you want and re-run "Configure" again as needed after setting them. Such as: * `NO_GIT_REVISION` if you don't have Git or if cmake is not finding it. * `NO_LIBZIP` if you don't care about running self-play training and you don't have libzip. @@ -187,161 +117,6 @@ For `onnxProvider=openvino` on Intel NPU, a single device is typically used. * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). -##### ONNX Runtime Backend -The ONNX backend uses ONNX Runtime for inference, and supports both: -* `.onnx` models loaded directly. -* `.bin.gz` KataGo models via internal conversion to ONNX graph (requires ONNX protobuf dependencies in CMake). - -##### Windows Intel NPU (OpenVINO EP) Setup -1. Install Visual Studio 2026 Community or Visual Studio 2026 Build Tools: - * https://visualstudio.microsoft.com/zh-hans/downloads/ - * In installer workloads, select **Desktop development with C++**. -2. Install Intel NPU driver: - * https://www.intel.com/content/www/us/en/download/794734/intel-npu-driver-windows.html -3. Install OpenVINO 2026 archive package on Windows: - * https://docs.openvino.ai/2026/get-started/install-openvino/install-openvino-archive-windows.html - * Typical install root looks like: `C:\Program Files (x86)\Intel\openvino_2026.0` -4. Add these to System PATH: - * `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\bin\intel64\Release` - * `C:\Program Files (x86)\Intel\openvino_2026.0\runtime\3rdparty\tbb\bin` -5. Build ONNX Runtime with OpenVINO EP for NPU (follow official docs): - * https://onnxruntime.ai/docs/build/eps.html#openvino - * Set OpenVINO EP build option so `use_openvino` is `NPU` (for example `--use_openvino NPU` in ORT build.py). - -##### Prepare `ONNXRUNTIME_ROOT` in KataGo (Windows) -Use package root: -* `cpp/external/onnxruntime-win-x64-openvino` - -Windows one-to-one mapping (`` -> KataGo): - -Windows and Linux generally share the same ORT include/config layout. -The main differences are binary file names/extensions (`.dll/.lib` vs `.so`). - -Include files: - -| Source (``) | Destination (KataGo) | -| --- | --- | -| `include/core/*` | `cpp/external/onnxruntime-win-x64-openvino/include/core/` | -| `include/cpu_provider_factory.h` | `cpp/external/onnxruntime-win-x64-openvino/include/cpu_provider_factory.h` | -| `include/provider_options.h` | `cpp/external/onnxruntime-win-x64-openvino/include/provider_options.h` | -| `include/onnxruntime_c_api.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_c_api.h` | -| `include/onnxruntime_cxx_api.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_cxx_api.h` | -| `include/onnxruntime_cxx_inline.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_cxx_inline.h` | -| `include/onnxruntime_env_config_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_env_config_keys.h` | -| `include/onnxruntime_ep_c_api.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_ep_c_api.h` | -| `include/onnxruntime_ep_device_ep_metadata_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_ep_device_ep_metadata_keys.h` | -| `include/onnxruntime_float16.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_float16.h` | -| `include/onnxruntime_lite_custom_op.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_lite_custom_op.h` | -| `include/onnxruntime_run_options_config_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_run_options_config_keys.h` | -| `include/onnxruntime_session_options_config_keys.h` | `cpp/external/onnxruntime-win-x64-openvino/include/onnxruntime_session_options_config_keys.h` | - -Library/config/pkgconfig files: - -| Source (``) | Destination (KataGo) | -| --- | --- | -| `lib/onnxruntime.lib` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.lib` | -| `lib/onnxruntime.dll` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime.dll` | -| `lib/onnxruntime_providers_shared.dll` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.dll` | -| `lib/onnxruntime_providers_openvino.dll` | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.dll` | -| `lib/onnxruntime_providers_shared.lib` (optional import lib) | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_shared.lib` | -| `lib/onnxruntime_providers_openvino.lib` (optional import lib) | `cpp/external/onnxruntime-win-x64-openvino/lib/onnxruntime_providers_openvino.lib` | -| `lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfig.cmake` | -| `lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeConfigVersion.cmake` | -| `lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets.cmake` | -| `lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | `cpp/external/onnxruntime-win-x64-openvino/lib/cmake/onnxruntime/onnxruntimeTargets-release.cmake` | -| `lib/pkgconfig/libonnxruntime.pc` (optional) | `cpp/external/onnxruntime-win-x64-openvino/lib/pkgconfig/libonnxruntime.pc` | - -##### Minimal KataGo Build Commands (Windows, ONNX backend) -On Windows, `KATAGO_AUTO_FETCH_DEPS=ON` by default, so missing `zlib`, `onnx`, and `protobuf` dependencies are auto-fetched via vcpkg into `cpp/build/deps/vcpkg`. - -``` -cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DONNXRUNTIME_ROOT=cpp/external/onnxruntime-win-x64-openvino -cmake --build cpp/build --config Release -j -``` - -If you want to disable auto-fetch and provide dependencies manually: -* `-DKATAGO_AUTO_FETCH_DEPS=OFF` -* plus `-DONNX_INCLUDE_DIR=... -DONNX_PROTO_LIB=... -DPROTOBUF_INCLUDE_DIR=... -DPROTOBUF_LIB=... -DZLIB_INCLUDE_DIR=... -DZLIB_LIBRARY=...` - -Typical run config for Intel NPU: -* `onnxProvider = openvino` -* `onnxOpenVINODeviceType = NPU` -* `onnxOpenVINOEnableNPUFastCompile = true` (optional; may be ignored on ORT builds that do not support this key) - -Multi-device assignment is mainly for `onnxProvider=cuda/tensorrt/migraphx` (`onnxDeviceToUseThread*`). -For `onnxProvider=openvino` on Intel NPU, a single device is typically used. - -##### Windows AMD NPU (VitisAI EP) Setup -This branch defaults to the `onnxruntime-win-x64-vitisai` ONNX Runtime package (built with the VitisAI execution provider) rather than the OpenVINO one used above. It targets AMD Ryzen AI NPUs via the [AMD Ryzen AI / VitisAI SDK](https://ryzenai.docs.amd.com/). - -1. Install the Ryzen AI SDK (provides `onnxruntime_providers_vitisai.dll`'s runtime dependencies, `vaip_config.json`, and NPU `xclbin` firmware images). Typical install path: `C:\Program Files\RyzenAI\`. -2. Prepare `cpp/external/onnxruntime-win-x64-vitisai/{include,lib,bin}` with an ONNX Runtime build that includes the VitisAI EP (`onnxruntime_providers_vitisai.dll`/`.lib`), matching the ORT ABI version bundled with your Ryzen AI SDK. -3. CMake auto-detects the newest `RyzenAI\` folder under `%ProgramFiles%` at configure time (validated by the presence of `voe-*-win_amd64\vaip_config.json` inside it -- a stale `PATH` entry pointing at an uninstalled version is not trusted). Override with `-DRYZENAI_ROOT=...` or the `RYZENAI_ROOT` environment variable if auto-detection picks the wrong install or you have a nonstandard layout. -4. The build copies `vaip_config.json`, the `xclbins/` firmware directory, `xrt_coreutil.dll`, and the VitisAI EP's runtime dependency DLLs (`dyn_dispatch_core.dll`, `vaiml.dll`, `flexmlrt.dll`, etc., all from the Ryzen AI SDK's `deployment/` folder) next to `katago.exe` automatically. The ONNX Runtime core DLLs (`onnxruntime.dll`, `onnxruntime_providers_shared.dll`, `onnxruntime_providers_vitisai.dll`) come from `ONNXRUNTIME_ROOT` instead, to keep the ABI consistent with what KataGo was linked against. - -``` -cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -cmake --build cpp/build --config Release -j -``` - -(`ONNXRUNTIME_ROOT` defaults to `cpp/external/onnxruntime-win-x64-vitisai` on this branch, so it does not need to be passed explicitly unless overriding.) - -Typical run config for AMD Ryzen AI NPU: -* `onnxProvider = vitisai` -* `onnxVitisAIConfigFile = ...` (optional; defaults to the auto-detected `vaip_config.json` baked in at build time) -* `onnxVitisAICacheDir = ...` (optional; defaults to `/vitisaicache` -- the NPU model compile is slow, on the order of minutes, so this cache avoids recompiling on every launch) -* `onnxVitisAIDisableCPUFallback = true` (default; fails loudly at session creation if any node can't run on the NPU, rather than silently falling back to CPU for that node) - -VitisAI only accelerates a quantized (INT8 QDQ) ONNX graph -- FP32 nodes fall back to CPU. To quantize a KataGo model: -1. `katago exportonnx -model .bin.gz -xlen 19 -ylen 19 -output model-fp32.onnx` -- export a fixed-size FP32 ONNX graph. -2. `katago dumpcalibrationdata -model .bin.gz -sgfdir -output calib.npz` -- sample calibration input tensors from real games (reuses the same feature-encoding path as inference). -3. `python python/quantize_vitisai.py --input model-fp32.onnx --calibration calib.npz --output model-int8.onnx` -- offline quantize via AMD's `amd-quark` (`quark.onnx`), bundled with the Ryzen AI SDK's Python environment. -4. Point `nnModelFile` at `model-int8.onnx` and set `onnxProvider = vitisai`. - -This quantization step is entirely offline/manual -- `katago.exe` does not invoke it automatically. - -##### Windows AMD NPU with Python-Embedded ONNX Runtime (Workaround) - -On some Ryzen AI SDK versions (observed with 1.7.1), the native C++ VitisAI execution provider path can fail during session creation for quantized models with many `EPContext` nodes, producing repeated errors such as `Failed to create runner: Failed to open library '...\xrt_core.dll'`. This appears to be an SDK/ORT C++ API initialization issue: the C++ API creates a fresh runner per subgraph, while Python's `onnxruntime.InferenceSession` reuses a single XRT context. - -This branch provides an optional workaround that embeds a Python interpreter and routes VitisAI inference through Python's `onnxruntime.InferenceSession`. Enable it with: - -``` -cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DPYTHON_ONNXRUNTIME=ON -cmake --build cpp/build --config Release -j -``` - -Requirements: -* A Python installation with development headers/libs that matches the Ryzen AI SDK's recommended environment (e.g., the `ryzen-ai-1.7.1` conda env with Python 3.12). CMake uses `CONDA_PREFIX` if set, or you can point it with `Python3_ROOT_DIR`. -* The `onnxruntime` Python package installed in that environment, with a version matching the SDK's bundled ONNX Runtime ABI. -* The Ryzen AI SDK installed (auto-detected as described above). - -The build bakes in the path to the Python interpreter (`KATAGO_PYTHON_EXE_PATH`). At runtime, `katago.exe` initializes Python from that installation and imports `numpy` and `onnxruntime`. - -Deployment/runtime notes: -* The directory containing `katago.exe` should also contain the matching `python312.dll` (or whichever Python version you built against) and the conda `onnxruntime.dll`. This prevents Windows from loading the older `C:\Windows\System32\onnxruntime.dll` (1.17.1), which causes API version mismatch errors such as `TarWriter` failures. -* The conda `...\Lib\site-packages\onnxruntime\capi` directory must be on `PATH` so the VitisAI EP DLLs (`onnxruntime_vitisai_ep.dll`, etc.) are found. -* `PATH` must also include the Ryzen AI SDK's `xrt` and `voe-*-win_amd64` directories. - -Example wrapper (`sabaki_katago.bat`) that keeps these PATH changes process-local: - -```bat -@echo off -setlocal -set PATH=C:\Users\\miniconda3\envs\ryzen-ai-1.7.1;%PATH% -set PATH=C:\Users\\miniconda3\envs\ryzen-ai-1.7.1\Lib\site-packages\onnxruntime\capi;%PATH% -set PATH=C:\Program Files\RyzenAI\1.7.1\xrt;%PATH% -set PATH=C:\Program Files\RyzenAI\1.7.1\voe-4.0-win_amd64;%PATH% -cd /d "C:\Envs\katago-v1.16.5-vitisai1.7.1-windows-x64" -katago.exe gtp -config gtp_npu.cfg -model kata1-zhizi-b40c768nbt-s11272M-d5935M-mish-int8_sdk_ctx.onnx -endlocal -``` - -Caveats: -* The Python C API holds the GIL around bookkeeping calls. `session.run` releases it internally, but multi-threaded throughput has not been fully benchmarked. -* First inference can take 15–30 seconds while the NPU session is created and the model is compiled/cached. -* `katago benchmark` may time out because it creates a second session while the first is still active. This workaround is mainly intended for interactive GTP play. - ## MacOS * TLDR (Metal backend - recommended for most users, hybrid CPU+GPU+Neural Engine for maximum throughput): ``` diff --git a/README.md b/README.md index 7ae39445f2..4ea665e7f5 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,27 @@ # KataGo -- [KataGo](#katago) - - [Overview](#overview) - - [Training History and Research and Docs](#training-history-and-research-and-docs) - - [Where To Download Stuff](#where-to-download-stuff) - - [Setting Up and Running KataGo](#setting-up-and-running-katago) - - [GUIs](#guis) - - [Windows and Linux](#windows-and-linux) - - [MacOS](#macos) - - [OpenCL vs CUDA vs TensorRT vs Eigen vs ONNX](#opencl-vs-cuda-vs-tensorrt-vs-eigen-vs-onnx) - - [How To Use](#how-to-use) - - [ONNX/VitisAI AMD Ryzen AI NPU Quick Start (Windows)](#onnxvitisai-amd-ryzen-ai-npu-quick-start-windows) - - [ONNX/VitisAI AMD NPU Quick Start (Windows)](#onnxvitisai-amd-npu-quick-start-windows) - - [Human-style Play and Analysis](#human-style-play-and-analysis) - - [Other Commands:](#other-commands) - - [Tuning for Performance](#tuning-for-performance) - - [Common Questions and Issues](#common-questions-and-issues) - - [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers) - - [Common Problems](#common-problems) - - [Other Questions](#other-questions) - - [Features for Developers](#features-for-developers) - - [GTP Extensions:](#gtp-extensions) - - [Analysis Engine:](#analysis-engine) - - [Compiling KataGo](#compiling-katago) - - [Source Code Overview:](#source-code-overview) - - [Selfplay Training:](#selfplay-training) - - [Contributors](#contributors) - - [License](#license) ->>>>>>> 4bfca431b2511a9fd6dbb6e66158cb4c2600bd9d - - [Human-style Play and Analysis](#human-style-play-and-analysis) - - [Other Commands:](#other-commands) - - [Tuning for Performance](#tuning-for-performance) - - [Common Questions and Issues](#common-questions-and-issues) - - [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers) - - [Common Problems](#common-problems) - - [Other Questions](#other-questions) - - [Features for Developers](#features-for-developers) - - [GTP Extensions:](#gtp-extensions) - - [Analysis Engine:](#analysis-engine) - - [Compiling KataGo](#compiling-katago) - - [Source Code Overview:](#source-code-overview) - - [Selfplay Training:](#selfplay-training) - - [Contributors](#contributors) - - [License](#license) +* [Overview](#overview) +* [Training History and Research](#training-history-and-research) +* [Where To Download Stuff](#where-to-download-stuff) +* [Setting Up and Running KataGo](#setting-up-and-running-katago) + * [GUIs](#guis) + * [Windows and Linux](#windows-and-linux) + * [MacOS](#macos) + * [OpenCL vs CUDA vs TensorRT vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-eigen) + * [How To Use](#how-to-use) + * [Tuning for Performance](#tuning-for-performance) + * [Common Questions and Issues](#common-questions-and-issues) + * [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers) + * [Common Problems](#common-problems) + * [Other Questions](#other-questions) +* [Features for Developers](#features-for-developers) + * [GTP Extensions](#gtp-extensions) + * [Analysis Engine](#analysis-engine) +* [Compiling KataGo](#compiling-katago) +* [Source Code Overview](#source-code-overview) +* [Selfplay Training](#selfplay-training) +* [Contributors](#contributors) +* [License](#license) ## Overview @@ -106,23 +85,23 @@ The community also provides KataGo packages for [Homebrew](https://brew.sh) on M Use `brew install katago`. The latest config files and networks are installed in KataGo's `share` directory. Find them via `brew list --verbose katago`. A basic way to run katago will be `katago gtp -config $(brew list --verbose katago | grep 'gtp.*\.cfg') -model $(brew list --verbose katago | grep .gz | head -1)`. You should choose the Network according to the release notes here and customize the provided example config as with every other way of installing KataGo. -### OpenCL vs CUDA vs TensorRT vs Eigen vs ONNX -KataGo has five backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), Eigen (CPU), and ONNX (CPU/GPU/NPU via providers). +### OpenCL vs CUDA vs TensorRT vs Eigen +KataGo has four backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), and Eigen (CPU). (On macOS there is also a Metal backend, most easily obtained via homebrew - see above.) + +As of v1.17, KataGo supports transformer neural nets, which are generally much stronger for the same compute cost and which the main training run is switching to. Transformer models are more demanding on the GPU backend than the older convolutional nets, so the backend recommendations below matter more for them - in particular OpenCL is noticeably slower on transformers, and on NVIDIA the CUDNN and TensorRT versions make a large difference. The quick summary is: - * **To easily get something working, try OpenCL if you have any good or decent GPU.** + * **To easily get something working, try OpenCL if you have any good or decent GPU.** Note that it is noticeably slower than the NVIDIA-specific backends, especially for transformer models. * **For often much better performance on NVIDIA GPUs, try TensorRT**, but you may need to install TensorRT from Nvidia. * Use Eigen with AVX2 if you don't have a GPU or if your GPU is too old/weak to work with OpenCL, and you just want a plain CPU KataGo. * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. - * The CUDA backend can work for NVIDIA GPUs with CUDA+CUDNN installed but is likely worse than TensorRT. - * ONNX backend uses ONNX Runtime execution providers (CPU/CUDA/TensorRT/MIGraphX/VitisAI/CoreML). It is useful for AMD Ryzen AI NPU (VitisAI) and raw `.onnx` models. + * The CUDA+CUDNN backend can also work well for NVIDIA GPUs. It has faster startup than TensorRT and is competitive on transformers if using CUDNN >= 9.8.0, though TensorRT 10.16 is often still slightly faster. More in detail: - * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). - * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. On most GPUs, the OpenCL implementation will actually beat NVIDIA's own CUDA/CUDNN at performance. The exception is for top-end NVIDIA GPUs that support FP16 and tensor cores, in which case sometimes one is better and sometimes the other is better. - * TensorRT is similar to CUDA, but only uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs, it should work whenever CUDA does and will usually be faster than CUDA or any other backend. + * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). OpenCL is not as optimized as the NVIDIA-specific backends and will generally be slower, particularly for transformer models. + * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. For older convolutional nets, on many GPUs the OpenCL implementation can match or beat NVIDIA's own CUDA/CUDNN, with the exception of top-end NVIDIA GPUs that support FP16 and tensor cores. For transformer nets, CUDA+CUDNN clearly outperforms OpenCL, but you should use CUDNN >= 9.8.0 if at all possible - the older CUDNN 8.9.7 is a LOT slower on transformer models. Compared to TensorRT, CUDA+CUDNN has faster startup times and is often only slightly slower (and occasionally faster) on transformers. + * TensorRT is similar to CUDA, but uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs it should work whenever CUDA does, and will usually be the fastest backend, though it has much longer startup times on every launch. As of v1.17.0, TensorRT versions older than 10 are no longer supported. For transformer models, recent versions like CUDA 13 + TensorRT 10.16 are best, while older TensorRT versions can be outperformed by CUDA+CUDNN. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. - * ONNX backend uses [ONNX Runtime](https://onnxruntime.ai/). It can use CPU by default, VitisAI for AMD Ryzen AI NPU, CUDA/TensorRT for NVIDIA GPUs, MIGraphX for AMD GPUs, and CoreML on macOS. Multi-device assignment via `onnxDeviceToUseThread*` is mainly for CUDA/TensorRT/MIGraphX providers; VitisAI NPU setups are single-device. For **any** implementation, it's recommended that you also tune the number of threads used if you care about optimal performance, as it can make a factor of 2-3 difference in the speed. See "Tuning for Performance" below. However, if you mostly just want to get it working, then the default untuned settings should also be still reasonable. @@ -156,60 +135,6 @@ path/to/katago.exe gtp -model path/to/.bin.gz path/to/katago.exe gtp -model path/to/.bin.gz -config path/to/gtp_custom.cfg ``` -#### ONNX/VitisAI AMD Ryzen AI NPU Quick Start (Windows) - -The ONNX backend supports AMD's Ryzen AI NPU via the VitisAI execution provider -(`onnxProvider = vitisai`). It loads a standard `.bin.gz` KataGo model **directly** — no conversion -step needed (it can also load a raw `.onnx` file, e.g. via `exportonnx`). See [Compiling.md](Compiling.md) -for installing the Ryzen AI / VitisAI SDK and building against it (CMake auto-detects a Ryzen AI -installation and bakes in a default `vaip_config.json` path when found). - -``` -./katago.exe benchmark -config cpp/configs/gtp_example.cfg -model .bin.gz -override-config onnxProvider=vitisai -./katago.exe gtp -config cpp/configs/gtp_example.cfg -model .bin.gz -override-config onnxProvider=vitisai -``` - -The compiled NPU model is cached (by default under `/vitisaicache`) so the multi-minute -compile cost is only paid once per model. See the `onnxVitisAI*` keys in -[`cpp/configs/gtp_example.cfg`](cpp/configs/gtp_example.cfg) to override the config file path, cache -directory, or CPU-fallback behavior. - -#### ONNX/VitisAI AMD NPU Quick Start (Windows) - -If you want to use ONNX Runtime + VitisAI on an AMD Ryzen AI NPU: - -* Install the AMD Ryzen AI SDK: https://ryzenai.docs.amd.com/ -* Use the `ryzen-ai-` conda environment (or equivalent) with Python's `onnxruntime` package matching the SDK. -* This branch has a `PYTHON_ONNXRUNTIME` build option that embeds Python to work around a RyzenAI 1.7.1 C++ API bug when loading quantized models with many EPContext nodes. - -Build with: -```bash -cmake -S cpp -B cpp/build -G "Visual Studio 18 2026" -A x64 -DUSE_BACKEND=ONNX -DPYTHON_ONNXRUNTIME=ON -cmake --build cpp/build --config Release -j -``` - -At runtime, to avoid Windows loading the wrong `onnxruntime.dll` from `C:\Windows\System32`, deploy `katago.exe` together with the matching `python312.dll` and the conda `onnxruntime.dll`. Also ensure `PATH` includes: -* your conda environment directory, -* `...\Lib\site-packages\onnxruntime\capi`, -* `C:\Program Files\RyzenAI\\xrt`, -* `C:\Program Files\RyzenAI\\voe-*-win_amd64`. - -A `.bat` wrapper is the recommended way to set PATH only for the KataGo process (see [Compiling.md](Compiling.md) for an example). - -Minimal commands: -```bash -# 1) Export .bin/.bin.gz to ONNX (default export size is 19x19) -./katago.exe exportonnx -model .bin.gz -output .onnx - -# 2) Quantize to INT8 for VitisAI NPU (uses AMD quark in the RyzenAI conda env) -python python/quantize_vitisai.py --input .onnx --calibration calib.npz --output -int8.onnx - -# 3) Run GTP for GUI tools -./katago.exe gtp -config cpp/configs/gtp_example.cfg -model -int8.onnx -override-config onnxProvider=vitisai -``` - -First inference may take 15–30 seconds while the NPU compiles/caches the model. `katago benchmark` may time out with this workaround; it is mainly intended for interactive GTP play. - #### Human-style Play and Analysis You can also have KataGo imitate human play if you download the human SL model b18c384nbt-humanv0.bin.gz from https://github.com/lightvector/KataGo/releases/tag/v1.15.0, and run a command like the following, providing both the normal model and the human SL model: diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 0507a9c5c2..fb8bb130fa 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -44,7 +44,7 @@ endif() set(BUILD_DISTRIBUTED 0 CACHE BOOL "Build with http support for contributing to distributed training") set(USE_BACKEND CACHE STRING "Neural net backend") string(TOUPPER "${USE_BACKEND}" USE_BACKEND) -set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN METAL ONNX) +set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN METAL) set(USE_TCMALLOC 0 CACHE BOOL "Use TCMalloc") set(NO_GIT_REVISION 0 CACHE BOOL "Disable embedding the git revision into the compiled exe") @@ -54,111 +54,6 @@ set(USE_BIGGER_BOARDS_EXPENSIVE 0 CACHE BOOL "Allow boards up to size 50. Compil set(USE_CACHE_TENSORRT_PLAN 0 CACHE BOOL "Use TENSORRT plan cache. May use a lot of disk space. Only applies when USE_BACKEND is TENSORRT.") mark_as_advanced(USE_CACHE_TENSORRT_PLAN) -if(WIN32 OR (UNIX AND NOT APPLE)) - set(_katago_auto_fetch_default ON) -else() - set(_katago_auto_fetch_default OFF) -endif() -option(KATAGO_AUTO_FETCH_DEPS "Automatically fetch missing dependencies into build/deps (Windows/Linux use vcpkg)." ${_katago_auto_fetch_default}) -set(KATAGO_DEPS_DIR "${CMAKE_BINARY_DIR}/deps" CACHE PATH "Directory for auto-fetched third-party dependencies") -if(WIN32) - # Static libs (not DLLs), but still linked against the dynamic CRT (matches how katago.exe - # itself is built). Using static libs here avoids a class of heap-corruption crash where a - # dependency (e.g. abseil_dll.dll, a transitive dependency of protobuf) ends up loaded as two - # separate DLL instances at runtime, corrupting the heap during static initialization. - set(_katago_vcpkg_triplet_default "x64-windows-static-md") -elseif(UNIX AND NOT APPLE) - if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$") - set(_katago_vcpkg_triplet_default "arm64-linux") - else() - set(_katago_vcpkg_triplet_default "x64-linux") - endif() -else() - set(_katago_vcpkg_triplet_default "x64-windows") -endif() -set(KATAGO_VCPKG_TRIPLET "${_katago_vcpkg_triplet_default}" CACHE STRING "vcpkg triplet used by KATAGO_AUTO_FETCH_DEPS") -set(KATAGO_VCPKG_ROOT "${KATAGO_DEPS_DIR}/vcpkg" CACHE PATH "Path to local vcpkg clone used by KATAGO_AUTO_FETCH_DEPS") -mark_as_advanced(KATAGO_VCPKG_TRIPLET KATAGO_VCPKG_ROOT) - -function(katago_vcpkg_bootstrap_if_needed) - if(NOT WIN32 AND NOT (UNIX AND NOT APPLE)) - message(FATAL_ERROR "katago_vcpkg_bootstrap_if_needed is only supported on Windows and Linux") - endif() - - if(NOT KATAGO_AUTO_FETCH_DEPS) - message(FATAL_ERROR "KATAGO_AUTO_FETCH_DEPS is OFF, cannot auto-fetch missing dependency") - endif() - - file(MAKE_DIRECTORY "${KATAGO_DEPS_DIR}") - - if(WIN32) - set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg.exe") - else() - set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg") - endif() - - if(NOT EXISTS "${_katago_vcpkg_exe}") - if(NOT EXISTS "${KATAGO_VCPKG_ROOT}/.git") - find_package(Git QUIET) - if(NOT GIT_FOUND) - message(FATAL_ERROR "KATAGO_AUTO_FETCH_DEPS requires git to clone vcpkg") - endif() - message(STATUS "Auto-fetch deps: cloning vcpkg into ${KATAGO_VCPKG_ROOT}") - execute_process( - COMMAND "${GIT_EXECUTABLE}" clone --depth=1 https://github.com/microsoft/vcpkg.git "${KATAGO_VCPKG_ROOT}" - RESULT_VARIABLE _clone_result - OUTPUT_VARIABLE _clone_out - ERROR_VARIABLE _clone_err - ) - if(NOT _clone_result EQUAL 0) - message(FATAL_ERROR "Failed to clone vcpkg.\n${_clone_out}\n${_clone_err}") - endif() - endif() - - message(STATUS "Auto-fetch deps: bootstrapping vcpkg") - if(WIN32) - execute_process( - COMMAND "${KATAGO_VCPKG_ROOT}/bootstrap-vcpkg.bat" -disableMetrics - WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" - RESULT_VARIABLE _bootstrap_result - ) - else() - execute_process( - COMMAND sh "${KATAGO_VCPKG_ROOT}/bootstrap-vcpkg.sh" -disableMetrics - WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" - RESULT_VARIABLE _bootstrap_result - ) - endif() - if(NOT _bootstrap_result EQUAL 0) - message(FATAL_ERROR "Failed to bootstrap vcpkg") - endif() - endif() -endfunction() - -function(katago_vcpkg_install_if_needed package_name) - katago_vcpkg_bootstrap_if_needed() - - if(WIN32) - set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg.exe") - else() - set(_katago_vcpkg_exe "${KATAGO_VCPKG_ROOT}/vcpkg") - endif() - if(NOT EXISTS "${_katago_vcpkg_exe}") - message(FATAL_ERROR "vcpkg executable not found after bootstrap: ${_katago_vcpkg_exe}") - endif() - - set(_spec "${package_name}:${KATAGO_VCPKG_TRIPLET}") - message(STATUS "Auto-fetch deps: ensuring ${_spec} via vcpkg") - execute_process( - COMMAND "${_katago_vcpkg_exe}" install "${_spec}" --disable-metrics - WORKING_DIRECTORY "${KATAGO_VCPKG_ROOT}" - RESULT_VARIABLE _install_result - ) - if(NOT _install_result EQUAL 0) - message(FATAL_ERROR "Failed to install ${_spec} via vcpkg") - endif() -endfunction() - #--------------------------- NEURAL NET BACKEND ------------------------------------------------------------------------ message(STATUS "Building 'katago' executable for GTP engine and other tools.") @@ -269,14 +164,8 @@ elseif(USE_BACKEND STREQUAL "EIGEN") set(NEURALNET_BACKEND_SOURCES neuralnet/eigenbackend.cpp ) -elseif(USE_BACKEND STREQUAL "ONNX") - message(STATUS "-DUSE_BACKEND=ONNX, using ONNX Runtime backend.") - set(NEURALNET_BACKEND_SOURCES - neuralnet/onnxbackend.cpp - neuralnet/onnxmodelbuilder.cpp - ) elseif(USE_BACKEND STREQUAL "") - message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN or -DUSE_BACKEND=ONNX to compile with the respective backend.${ColorReset}") + message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN to compile with the respective backend.${ColorReset}") set(NEURALNET_BACKEND_SOURCES neuralnet/dummybackend.cpp) else() message(FATAL_ERROR "Unrecognized backend: " ${USE_BACKEND}) @@ -441,6 +330,7 @@ add_executable(katago tests/testconfig.cpp tests/testmisc.cpp tests/testnnevalcanary.cpp + tests/testpassalivesuicide.cpp tests/testrules.cpp tests/testscore.cpp tests/testsgf.cpp @@ -464,7 +354,6 @@ add_executable(katago command/analysis.cpp command/benchmark.cpp command/contribute.cpp - command/dumpcalibrationdata.cpp command/evalsgf.cpp command/gatekeeper.cpp command/genbook.cpp @@ -583,7 +472,10 @@ elseif(USE_BACKEND STREQUAL "TENSORRT") if(NOT TENSORRT_ONNXPARSER_LIBRARY) message(FATAL_ERROR "${ColorBoldRed} libnvonnxparser was NOT found in the TensorRT lib dir. ${ColorReset}") endif() - target_link_libraries(katago ${TENSORRT_ONNXPARSER_LIBRARY} ${Protobuf_LIBRARIES}) + # Link the imported target rather than ${Protobuf_LIBRARIES}: when protobuf comes from a + # CMake package config (e.g. vcpkg), the variable can resolve to the DLL itself rather + # than the import lib, and it also omits protobuf's own dependencies such as abseil. + target_link_libraries(katago ${TENSORRT_ONNXPARSER_LIBRARY} protobuf::libprotobuf) elseif(USE_BACKEND STREQUAL "METAL") target_compile_definitions(katago PRIVATE USE_METAL_BACKEND) target_link_libraries(katago KataGoSwift katagocoreml @@ -612,334 +504,6 @@ elseif(USE_BACKEND STREQUAL "OPENCL") link_directories(${OpenCL_LIBRARY}) target_link_libraries(katago ${OpenCL_LIBRARY}) endif() -elseif(USE_BACKEND STREQUAL "ONNX") - target_compile_definitions(katago PRIVATE USE_ONNX_BACKEND) - - # ---- AMD Ryzen AI / VitisAI SDK discovery (Windows) ---- - # Done here, ahead of ONNXRUNTIME_ROOT, so that when a Ryzen AI SDK install is found, its own - # bundled onnxruntime/ package (include+lib+bin, all one matched build) can be preferred as the - # ONNXRUNTIME_ROOT default. This matters: onnxruntime_providers_vitisai.dll / vaiml.dll / - # dyn_bins.dll / onnxruntime_vitisai_ep.dll are NOT independently versioned components -- they're - # part of one cohesive ORT+VitisAI-EP build, and mixing DLLs of the same name from two - # differently-sourced ORT packages (e.g. a separately-downloaded ORT vs. the SDK's own copy) - # produces a runtime ABI mismatch deep in the VitisAI EP's own call chain: session creation and - # even NPU compilation succeed, but actually creating an inference "runner" against the compiled - # model fails (observed as "Failed to create runner: Failed to open library ... xrt_core.dll", - # which is misleading -- the file opens fine standalone; the real cause is a symbol/ABI mismatch - # triggered only once several of the mismatched DLLs are loaded into the same process together). - # Not hardcoded to any particular Ryzen AI SDK version or install path: scans - # %ProgramFiles%\RyzenAI\ for the highest installed version, validated by the - # actual presence of voe-*-win_amd64/vaip_config.json inside it (a bare PATH entry is not a - # reliable signal -- e.g. a stale entry can point at an uninstalled older version). A manual - # override is available via -DRYZENAI_ROOT=... or the RYZENAI_ROOT environment variable. - if(WIN32) - set(RYZENAI_ROOT "" CACHE PATH "Path to an AMD Ryzen AI / VitisAI SDK installation (e.g. C:/Program Files/RyzenAI/1.7.1). Auto-detected if not set.") - if(NOT RYZENAI_ROOT AND DEFINED ENV{RYZENAI_ROOT}) - set(RYZENAI_ROOT "$ENV{RYZENAI_ROOT}") - endif() - if(NOT RYZENAI_ROOT) - set(_ryzenai_search_roots "") - if(DEFINED ENV{ProgramFiles}) - list(APPEND _ryzenai_search_roots "$ENV{ProgramFiles}/RyzenAI") - endif() - if(DEFINED ENV{ProgramW6432}) - list(APPEND _ryzenai_search_roots "$ENV{ProgramW6432}/RyzenAI") - endif() - list(REMOVE_DUPLICATES _ryzenai_search_roots) - foreach(_ryzenai_search_root IN LISTS _ryzenai_search_roots) - file(GLOB _ryzenai_candidate_dirs "${_ryzenai_search_root}/*") - set(_ryzenai_valid_candidates "") - foreach(_ryzenai_candidate IN LISTS _ryzenai_candidate_dirs) - if(IS_DIRECTORY "${_ryzenai_candidate}") - file(GLOB _ryzenai_vaip_configs_probe "${_ryzenai_candidate}/voe-*-win_amd64/vaip_config.json") - if(_ryzenai_vaip_configs_probe) - list(APPEND _ryzenai_valid_candidates "${_ryzenai_candidate}") - endif() - endif() - endforeach() - if(_ryzenai_valid_candidates) - list(SORT _ryzenai_valid_candidates COMPARE NATURAL ORDER DESCENDING) - list(GET _ryzenai_valid_candidates 0 _ryzenai_best) - set(RYZENAI_ROOT "${_ryzenai_best}") - break() - endif() - endforeach() - endif() - if(RYZENAI_ROOT AND IS_DIRECTORY "${RYZENAI_ROOT}") - string(REPLACE "\\" "/" RYZENAI_ROOT "${RYZENAI_ROOT}") - endif() - endif() - - if(WIN32 AND RYZENAI_ROOT AND EXISTS "${RYZENAI_ROOT}/onnxruntime/lib/onnxruntime.lib" AND EXISTS "${RYZENAI_ROOT}/onnxruntime/include/onnxruntime/core/session/onnxruntime_cxx_api.h") - # Prefer the Ryzen AI SDK's own bundled ONNX Runtime + VitisAI EP build over a separately - # prepared cpp/external/onnxruntime-win-x64-vitisai package -- see comment above. - set(_onnx_default_root "${RYZENAI_ROOT}/onnxruntime") - elseif(WIN32) - set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-win-x64-vitisai") - elseif(UNIX AND NOT APPLE) - set(_onnx_default_root "${CMAKE_CURRENT_SOURCE_DIR}/external/onnxruntime-linux-x64-openvino") - else() - set(_onnx_default_root "") - endif() - set(ONNXRUNTIME_ROOT "${_onnx_default_root}" CACHE PATH "Path to ONNX Runtime package root") - - if(NOT IS_DIRECTORY "${ONNXRUNTIME_ROOT}") - message(FATAL_ERROR "ONNXRUNTIME_ROOT does not exist: ${ONNXRUNTIME_ROOT}") - endif() - - # Package layouts vary: some ship headers directly under include/ (e.g. the openvino package), - # some nest them one level deeper under include/onnxruntime/ (e.g. the standalone vitisai - # package), and the Ryzen AI SDK's own bundled copy nests them two levels deeper under - # include/onnxruntime/core/session/. - if(EXISTS "${ONNXRUNTIME_ROOT}/include/onnxruntime_cxx_api.h") - set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include") - elseif(EXISTS "${ONNXRUNTIME_ROOT}/include/onnxruntime/onnxruntime_cxx_api.h") - set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include/onnxruntime") - elseif(EXISTS "${ONNXRUNTIME_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_api.h") - set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include/onnxruntime/core/session") - else() - set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_ROOT}/include") - endif() - if(NOT IS_DIRECTORY "${ONNXRUNTIME_INCLUDE_DIR}") - message(FATAL_ERROR "ONNX Runtime include directory not found: ${ONNXRUNTIME_INCLUDE_DIR}") - endif() - target_include_directories(katago SYSTEM PRIVATE "${ONNXRUNTIME_INCLUDE_DIR}") - - if(WIN32) - set(ONNXRUNTIME_LIB "${ONNXRUNTIME_ROOT}/lib/onnxruntime.lib") - # Package layouts vary: some ship runtime DLLs under lib/ (e.g. the openvino package), others - # under bin/ (e.g. the vitisai package) -- glob both. - file(GLOB ONNXRUNTIME_DLLS "${ONNXRUNTIME_ROOT}/lib/*.dll" "${ONNXRUNTIME_ROOT}/bin/*.dll") - else() - find_library(ONNXRUNTIME_LIB onnxruntime HINTS "${ONNXRUNTIME_ROOT}/lib" "${ONNXRUNTIME_ROOT}") - endif() - if(NOT EXISTS "${ONNXRUNTIME_LIB}" AND NOT ONNXRUNTIME_LIB) - message(FATAL_ERROR "Could not find onnxruntime library under ${ONNXRUNTIME_ROOT}") - endif() - target_link_libraries(katago ${ONNXRUNTIME_LIB}) - - # ---- Optional: embedded Python onnxruntime path for VitisAI ---- - # The RyzenAI 1.7.1 SDK's VitisAI EP works through Python's onnxruntime binding but fails - # when the model is loaded via the public C/C++ API (Ort::Session). Allow users to opt into - # embedding a Python interpreter and using onnxruntime.InferenceSession directly for the - # VitisAI provider. Requires Python development headers/library and a numpy/onnxruntime - # environment that can reach the VitisAI provider (e.g. the ryzen-ai conda env). - if(WIN32) - set(PYTHON_ONNXRUNTIME OFF CACHE BOOL "Embed Python and route VitisAI inference through Python's onnxruntime") - if(PYTHON_ONNXRUNTIME) - if(DEFINED ENV{CONDA_PREFIX}) - set(Python3_ROOT_DIR "$ENV{CONDA_PREFIX}") - endif() - find_package(Python3 COMPONENTS Interpreter Development REQUIRED) - if(Python3_FOUND) - target_compile_definitions(katago PRIVATE ENABLE_PYTHON_ONNXRUNTIME) - # Pass the Python interpreter path into the binary so Py_SetProgramName can point the - # embedded interpreter at the correct stdlib / site-packages (e.g. the ryzen-ai conda env). - target_compile_definitions(katago PRIVATE KATAGO_PYTHON_EXE_PATH="${Python3_EXECUTABLE}") - target_include_directories(katago SYSTEM PRIVATE ${Python3_INCLUDE_DIRS}) - target_link_libraries(katago ${Python3_LIBRARIES}) - message(STATUS "Python embedded onnxruntime enabled (VitisAI Python path): ${Python3_EXECUTABLE}") - else() - message(FATAL_ERROR "PYTHON_ONNXRUNTIME requested but Python3 development files were not found. Set CONDA_PREFIX or Python3_ROOT_DIR.") - endif() - endif() - endif() - - # Required by onnxmodelbuilder.cpp for building ONNX graphs from .bin.gz. - # These are intentionally configurable because package layouts vary. - set(ONNX_INCLUDE_DIR "" CACHE PATH "Directory containing onnx/onnx-ml.pb.h (required for .bin.gz -> ONNX conversion)") - set(ONNX_PROTO_LIB "" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)") - set(PROTOBUF_INCLUDE_DIR "" CACHE PATH "Directory containing google/protobuf/message.h (required for .bin.gz -> ONNX conversion)") - set(PROTOBUF_LIB "" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)") - set(ONNX_PROTO_TARGET "" CACHE STRING "Imported CMake target for onnx_proto (optional, preferred over ONNX_PROTO_LIB)") - set(PROTOBUF_TARGET "" CACHE STRING "Imported CMake target for protobuf (optional, preferred over PROTOBUF_LIB)") - mark_as_advanced(CLEAR ONNX_INCLUDE_DIR ONNX_PROTO_LIB PROTOBUF_INCLUDE_DIR PROTOBUF_LIB) - - # Backward compatibility with older cache variable name. - if(NOT PROTOBUF_LIB AND PROTOBUF_LITE_LIB) - set(PROTOBUF_LIB "${PROTOBUF_LITE_LIB}") - endif() - - if(KATAGO_AUTO_FETCH_DEPS) - set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") - endif() - - if(KATAGO_AUTO_FETCH_DEPS) - set(_need_onnx_proto_deps FALSE) - if(NOT ONNX_INCLUDE_DIR OR NOT ONNX_PROTO_LIB OR NOT PROTOBUF_INCLUDE_DIR OR NOT PROTOBUF_LIB) - set(_need_onnx_proto_deps TRUE) - endif() - if(_need_onnx_proto_deps) - katago_vcpkg_install_if_needed("onnx") - katago_vcpkg_install_if_needed("protobuf") - set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") - if(EXISTS "${_katago_vcpkg_installed_root}/include/onnx/onnx-ml.pb.h") - set(ONNX_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Directory containing onnx/onnx-ml.pb.h (required for .bin.gz -> ONNX conversion)" FORCE) - endif() - find_library(_katago_onnx_proto_lib NAMES onnx_proto HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) - if(_katago_onnx_proto_lib) - set(ONNX_PROTO_LIB "${_katago_onnx_proto_lib}" CACHE FILEPATH "Path to onnx_proto library (required for .bin.gz -> ONNX conversion)" FORCE) - endif() - if(EXISTS "${_katago_vcpkg_installed_root}/include/google/protobuf/message.h") - set(PROTOBUF_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Directory containing google/protobuf/message.h (required for .bin.gz -> ONNX conversion)" FORCE) - endif() - find_library(_katago_protobuf_lib NAMES protobuf-lite libprotobuf-lite protobuf libprotobuf HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) - if(_katago_protobuf_lib) - set(PROTOBUF_LIB "${_katago_protobuf_lib}" CACHE FILEPATH "Path to protobuf library (protobuf-lite or libprotobuf, required for .bin.gz -> ONNX conversion)" FORCE) - endif() - endif() - endif() - - # Prefer config-mode packages (vcpkg provides these) so transitive dependencies - # like absl/utf8_range are linked automatically. - if(_katago_vcpkg_installed_root) - list(APPEND CMAKE_PREFIX_PATH "${_katago_vcpkg_installed_root}") - endif() - if(NOT ONNX_PROTO_TARGET) - find_package(ONNX CONFIG QUIET) - if(TARGET ONNX::onnx_proto) - set(ONNX_PROTO_TARGET "ONNX::onnx_proto") - endif() - endif() - if(NOT PROTOBUF_TARGET) - if(_katago_vcpkg_installed_root AND EXISTS "${_katago_vcpkg_installed_root}/share/protobuf/protobuf-config.cmake") - set(protobuf_DIR "${_katago_vcpkg_installed_root}/share/protobuf") - endif() - find_package(protobuf CONFIG QUIET) - if(NOT TARGET protobuf::libprotobuf AND NOT TARGET protobuf::libprotobuf-lite) - find_package(Protobuf CONFIG QUIET) - endif() - if(TARGET protobuf::libprotobuf) - set(PROTOBUF_TARGET "protobuf::libprotobuf") - elseif(TARGET protobuf::libprotobuf-lite) - set(PROTOBUF_TARGET "protobuf::libprotobuf-lite") - endif() - endif() - - if(NOT ONNX_INCLUDE_DIR) - find_path(ONNX_INCLUDE_DIR onnx/onnx-ml.pb.h) - endif() - if(NOT ONNX_PROTO_LIB AND NOT ONNX_PROTO_TARGET) - find_library(ONNX_PROTO_LIB onnx_proto) - endif() - if(NOT PROTOBUF_INCLUDE_DIR) - find_path(PROTOBUF_INCLUDE_DIR google/protobuf/message.h) - endif() - if(NOT PROTOBUF_LIB AND NOT PROTOBUF_TARGET) - find_library(PROTOBUF_LIB libprotobuf protobuf protobuf-lite protobuf-lite32) - endif() - - if(NOT ONNX_INCLUDE_DIR OR NOT PROTOBUF_INCLUDE_DIR OR (NOT ONNX_PROTO_TARGET AND NOT ONNX_PROTO_LIB) OR (NOT PROTOBUF_TARGET AND NOT PROTOBUF_LIB)) - message(FATAL_ERROR - "ONNX backend requires ONNX protobuf dependencies for .bin.gz model conversion. " - "Set ONNX_INCLUDE_DIR (contains onnx/onnx-ml.pb.h), ONNX_PROTO_LIB, PROTOBUF_INCLUDE_DIR, and PROTOBUF_LIB.") - endif() - target_include_directories(katago SYSTEM PRIVATE "${ONNX_INCLUDE_DIR}") - target_include_directories(katago SYSTEM PRIVATE "${PROTOBUF_INCLUDE_DIR}") - if(ONNX_PROTO_TARGET) - target_link_libraries(katago ${ONNX_PROTO_TARGET}) - else() - target_link_libraries(katago ${ONNX_PROTO_LIB}) - endif() - if(PROTOBUF_TARGET) - target_link_libraries(katago ${PROTOBUF_TARGET}) - else() - target_link_libraries(katago ${PROTOBUF_LIB}) - endif() - - if(WIN32 AND ONNXRUNTIME_DLLS) - foreach(_onnxruntime_dll IN LISTS ONNXRUNTIME_DLLS) - add_custom_command(TARGET katago POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${_onnxruntime_dll}" - $ - ) - endforeach() - endif() - - # ---- AMD Ryzen AI / VitisAI EP runtime deployment (Windows) ---- - # RYZENAI_ROOT was already located above (ahead of ONNXRUNTIME_ROOT). This section copies the - # remaining pieces needed at runtime: vaip_config.json, xclbins, XRT, and the handful of VitisAI - # deployment DLLs not already part of RYZENAI_ROOT/onnxruntime/bin (which, when used as - # ONNXRUNTIME_ROOT, is already fully copied by the ONNXRUNTIME_DLLS loop above -- see the ABI - # matching rationale in the RYZENAI_ROOT detection comment above). - if(WIN32 AND RYZENAI_ROOT AND IS_DIRECTORY "${RYZENAI_ROOT}") - file(GLOB _ryzenai_voe_dirs "${RYZENAI_ROOT}/voe-*-win_amd64") - set(_ryzenai_vaip_config "") - set(_ryzenai_xclbins_dir "") - if(_ryzenai_voe_dirs) - list(SORT _ryzenai_voe_dirs COMPARE NATURAL ORDER DESCENDING) - list(GET _ryzenai_voe_dirs 0 _ryzenai_voe_dir) - if(EXISTS "${_ryzenai_voe_dir}/vaip_config.json") - set(_ryzenai_vaip_config "${_ryzenai_voe_dir}/vaip_config.json") - endif() - if(IS_DIRECTORY "${_ryzenai_voe_dir}/xclbins") - set(_ryzenai_xclbins_dir "${_ryzenai_voe_dir}/xclbins") - endif() - endif() - - if(_ryzenai_vaip_config) - message(STATUS "VitisAI: found Ryzen AI installation at ${RYZENAI_ROOT}, vaip_config.json = ${_ryzenai_vaip_config}") - # Baked in only as a fallback default (see ComputeContext's vitisaiConfigFile init in - # onnxbackend.cpp); always overridable at runtime via the onnxVitisAIConfigFile config key, - # so copying the exe to a machine with a different Ryzen AI install layout doesn't break -- - # it just requires setting that key. - target_compile_definitions(katago PRIVATE "KATAGO_VITISAI_DEFAULT_CONFIG_FILE=\"${_ryzenai_vaip_config}\"") - - add_custom_command(TARGET katago POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${_ryzenai_vaip_config}" $ - ) - if(_ryzenai_xclbins_dir) - add_custom_command(TARGET katago POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - "${_ryzenai_xclbins_dir}" $/xclbins - ) - endif() - - # XRT (NPU device driver userspace lib). Not ORT/VitisAI-EP-versioned, so no ABI concern - # sourcing this from RYZENAI_ROOT/xrt regardless of where ONNXRUNTIME_ROOT points. - if(EXISTS "${RYZENAI_ROOT}/xrt/xrt_coreutil.dll") - add_custom_command(TARGET katago POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${RYZENAI_ROOT}/xrt/xrt_coreutil.dll" $ - ) - endif() - - # Remaining VitisAI deployment DLLs that RYZENAI_ROOT/onnxruntime/bin does not ship (as of - # SDK 1.7.1: flexmlrt.dll, onnx_custom_ops.dll, ryzen_mm.dll, ryzenai_onnx_utils.dll). Prefer - # them from RYZENAI_ROOT/onnxruntime/bin first in case a future SDK version adds them there - # (keeping the whole set ABI-matched), falling back to RYZENAI_ROOT/deployment otherwise -- - # these four are lower-level utility/custom-op libraries outside the tightly-coupled - # onnxruntime.dll <-> onnxruntime_providers_vitisai.dll <-> onnxruntime_vitisai_ep.dll <-> - # vaiml.dll chain, so sourcing them from deployment/ alongside an onnxruntime/bin-derived - # ONNXRUNTIME_ROOT is not expected to reintroduce the ABI mismatch that motivated this change. - set(_ryzenai_extra_dlls - flexmlrt.dll - onnx_custom_ops.dll - ryzen_mm.dll - ryzenai_onnx_utils.dll - ) - foreach(_ryzenai_dll_name IN LISTS _ryzenai_extra_dlls) - set(_ryzenai_dll_src "") - if(EXISTS "${RYZENAI_ROOT}/onnxruntime/bin/${_ryzenai_dll_name}") - set(_ryzenai_dll_src "${RYZENAI_ROOT}/onnxruntime/bin/${_ryzenai_dll_name}") - elseif(EXISTS "${RYZENAI_ROOT}/deployment/${_ryzenai_dll_name}") - set(_ryzenai_dll_src "${RYZENAI_ROOT}/deployment/${_ryzenai_dll_name}") - endif() - if(_ryzenai_dll_src) - add_custom_command(TARGET katago POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${_ryzenai_dll_src}" $ - ) - endif() - endforeach() - else() - message(STATUS "VitisAI: Ryzen AI installation found at ${RYZENAI_ROOT} but no voe-*-win_amd64/vaip_config.json inside it -- onnxProvider=vitisai will require onnxVitisAIConfigFile to be set manually in your config") - endif() - elseif(WIN32) - message(STATUS "VitisAI: no Ryzen AI / VitisAI SDK installation auto-detected (set -DRYZENAI_ROOT=... to override) -- onnxProvider=vitisai will require onnxVitisAIConfigFile to be set manually in your config") - endif() elseif(USE_BACKEND STREQUAL "EIGEN") target_compile_definitions(katago PRIVATE USE_EIGEN_BACKEND) # Allow EIGEN3_INCLUDE_DIRS as a manual override (for users who downloaded @@ -981,25 +545,6 @@ if(NO_GIT_REVISION AND (NOT BUILD_DISTRIBUTED)) target_compile_definitions(katago PRIVATE NO_GIT_REVISION) endif() -if(KATAGO_AUTO_FETCH_DEPS) - set(_need_zlib_deps FALSE) - if(NOT ZLIB_INCLUDE_DIR OR NOT ZLIB_LIBRARY) - set(_need_zlib_deps TRUE) - endif() - if(_need_zlib_deps) - katago_vcpkg_install_if_needed("zlib") - set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") - if(EXISTS "${_katago_vcpkg_installed_root}/include/zlib.h") - set(ZLIB_INCLUDE_DIR "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zlib.h and other header files" FORCE) - endif() - # "zs" is vcpkg's name for the static zlib lib (as opposed to "zlib"/"z" for the DLL import lib). - find_library(_katago_zlib_lib NAMES zlib z zs HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) - if(_katago_zlib_lib) - set(ZLIB_LIBRARY "${_katago_zlib_lib}" CACHE FILEPATH "Path to 'libz.so' on Linux or 'libz.lib' on Windows" FORCE) - endif() - endif() -endif() - find_package(ZLIB) if(ZLIB_FOUND) include_directories(${ZLIB_INCLUDE_DIRS}) @@ -1011,45 +556,15 @@ else() message(SEND_ERROR "${ColorBoldRed}zlib was not found, if zlib is actually installed but not being found you can set ZLIB_INCLUDE_DIR to the directory with zlib.h and other headers, and ZLIB_LIBRARY to the compiled library 'libz.so' on Linux or 'libz.lib' on Windows. On the command line, this is -DZLIB_INCLUDE_DIR=... and -DZLIB_LIBRARY=... ${ColorReset}") endif(ZLIB_FOUND) -if(KATAGO_AUTO_FETCH_DEPS) - set(_need_libzip_deps FALSE) - if((NOT LIBZIP_LIBRARY) OR (NOT LIBZIP_INCLUDE_DIR_ZIP) OR (NOT LIBZIP_INCLUDE_DIR_ZIPCONF)) - set(_need_libzip_deps TRUE) - endif() - if(_need_libzip_deps) - # libzip's vcpkg port pulls in bzip2 as a dependency (needed for the BZip2 compression - # method); since we link against the raw .lib below rather than via vcpkg's CMake config - # (which would propagate transitive link deps automatically), bz2 must also be located - # and linked explicitly, or the final link fails with unresolved BZ2_bz* symbols. - katago_vcpkg_install_if_needed("libzip") - set(_katago_vcpkg_installed_root "${KATAGO_VCPKG_ROOT}/installed/${KATAGO_VCPKG_TRIPLET}") - if(EXISTS "${_katago_vcpkg_installed_root}/include/zip.h") - set(LIBZIP_INCLUDE_DIR_ZIP "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zip.h and other header files" FORCE) - endif() - if(EXISTS "${_katago_vcpkg_installed_root}/include/zipconf.h") - set(LIBZIP_INCLUDE_DIR_ZIPCONF "${_katago_vcpkg_installed_root}/include" CACHE PATH "Path to directory with zipconf.h and other header files" FORCE) - endif() - find_library(_katago_libzip_lib NAMES zip HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) - find_library(_katago_bz2_lib NAMES bz2 HINTS "${_katago_vcpkg_installed_root}/lib" "${_katago_vcpkg_installed_root}/debug/lib" NO_DEFAULT_PATH) - if(_katago_libzip_lib) - if(_katago_bz2_lib) - set(LIBZIP_LIBRARY "${_katago_libzip_lib};${_katago_bz2_lib}" CACHE FILEPATH "Path to 'libzip.so' on Linux or 'libzip.lib' or 'zip.lib' on Windows" FORCE) - else() - set(LIBZIP_LIBRARY "${_katago_libzip_lib}" CACHE FILEPATH "Path to 'libzip.so' on Linux or 'libzip.lib' or 'zip.lib' on Windows" FORCE) - endif() - endif() - endif() -endif() - find_library(LIBZIP_LIBRARY NAMES zip) find_path(LIBZIP_INCLUDE_DIR_ZIP NAMES zip.h) find_path(LIBZIP_INCLUDE_DIR_ZIPCONF NAMES zipconf.h) if((NOT LIBZIP_LIBRARY) OR (NOT LIBZIP_INCLUDE_DIR_ZIP) OR (NOT LIBZIP_INCLUDE_DIR_ZIPCONF)) if(BUILD_DISTRIBUTED) - message(SEND_ERROR "${ColorBoldRed}WARNING: BUILD_DISTRIBUTED was requested but libzip library was NOT found. KataGo needs this for writing training data so libzip is required. On Linux, install through your normal package manager. On Windows, set LIBZIP_INCLUDE_DIR_ZIP to the directory that includes zip.h and other files, and LIBZIP_INCLUDE_DIR_ZIPCONF to the directory that includes zipconf.h and other files, and LIBZIP_LIBRARY to the libzip.lib or zip.lib file, or enable KATAGO_AUTO_FETCH_DEPS=ON to auto-install via vcpkg. ${ColorReset}") + message(SEND_ERROR "${ColorBoldRed}WARNING: BUILD_DISTRIBUTED was requested but libzip library was NOT found. KataGo needs this for writing training data so libzip is required. On Linux, install through your normal package manager. On Windows, set LIBZIP_INCLUDE_DIR_ZIP to the directory that includes zip.h and other files, and LIBZIP_INCLUDE_DIR_ZIPCONF to the directory that includes zipconf.h and other files, and LIBZIP_LIBRARY to the libzip.lib or zip.lib file. ${ColorReset}") endif() target_compile_definitions(katago PRIVATE NO_LIBZIP) - message(WARNING "${ColorBoldRed}WARNING: libzip library was NOT found. KataGo should still work for GTP/matches/analysis if everything else is good, but selfplay for writing training data will not be possible. Enable KATAGO_AUTO_FETCH_DEPS=ON to auto-install libzip via vcpkg.${ColorReset}") + message(WARNING "${ColorBoldRed}WARNING: libzip library was NOT found. KataGo should still work for GTP/matches/analysis if everything else is good, but selfplay for writing training data will not be possible.${ColorReset}") set(LIBZIP_INCLUDE_DIR_ZIP ${LIBZIP_INCLUDE_DIR_ZIP} CACHE PATH "Path to directory with zip.h and other header files") set(LIBZIP_INCLUDE_DIR_ZIPCONF ${LIBZIP_INCLUDE_DIR_ZIPCONF} CACHE PATH "Path to directory with zipconf.h and other header files") set(LIBZIP_LIBRARY ${LIBZIP_LIBRARY} CACHE FILEPATH "Path to 'libzip.so' on Linux or 'libzip.lib' or 'zip.lib' on Windows") @@ -1084,7 +599,7 @@ if (WIN32) # handles both x86 and x64 target_compile_definitions(katago PRIVATE LITTLE_ENDIAN=1234) target_compile_definitions(katago PRIVATE BIG_ENDIAN=4321) # core/rand.cpp uses winsock for a gethostname - target_link_libraries(katago ws2_32 ole32) + target_link_libraries(katago ws2_32) if (MINGW) message(STATUS "Setting up build for mingw.") if(USE_BACKEND STREQUAL "CUDA" OR USE_BACKEND STREQUAL "TENSORRT") @@ -1118,6 +633,16 @@ if(MSVC) # things. They might be useful in some cases, but also are noisy. target_compile_definitions(katago PRIVATE _CRT_SECURE_NO_WARNINGS) + # MSVC toolset 14.40+ (VS 2022 17.10 and later, including VS 2026) made std::mutex's + # constructor constexpr, so mutexes are zero-initialized at compile time instead of being + # initialized at runtime via _Mtx_init_in_situ. If the process then loads a copy of + # msvcp140.dll older than 14.40 (outdated VC++ redistributable, or a stale msvcp140.dll + # sitting next to the exe or shipped by a GUI frontend, which takes precedence over the + # system one), the old _Mtx_lock misreads the zero-initialized mutex and crashes on the + # first lock. This define restores the old runtime initialization, which is compatible + # with both old and new runtimes. See https://github.com/microsoft/STL/issues/4978 + target_compile_definitions(katago PRIVATE _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) + if(USE_AVX2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2 -D__FMA__") target_compile_definitions(katago PRIVATE USE_AVX2) diff --git a/cpp/README.md b/cpp/README.md index dabcef5b53..1f5d8d21fc 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -9,14 +9,13 @@ Summary of source folders, in approximate dependency order, from lowest level to * `board.{cpp,h}` - Raw board implementation, without move history. Helper functions for Benson's algorithm and ladder search. * `boardhistory.{cpp,h}` - Datastructure that does include move history - handles superko, passing, game end, final scoring, komi, handicap detection, etc. * `graphhash.{cpp,h}` - History-sensitive hash used for [monte-carlo graph search](https://github.com/lightvector/KataGo/blob/master/docs/GraphSearch.md). -* `neuralnet` - Neural net GPU implementation and interface. Contains OpenCL, CUDA, TensorRT, Metal, Eigen, and ONNX backends along with common interfaces and model data structures. +* `neuralnet` - Neural net GPU implementation and interface. Contains OpenCL, CUDA, Eigen, TensorRT backends along with common interfaces and model data structures. * `desc.{cpp,h}` - Data structure holding neural net structure and weights. * `modelversion.{cpp,h}` - Enumerates the various versions of neural net features and models. * `nninputs.{cpp,h}` - Implements the input features for the neural net. * `sgfmetadata.{cpp,h}` - Implements the input features for the [HumanSL neural net](https://github.com/lightvector/KataGo/blob/master/docs/Analysis_Engine.md#human-sl-analysis-guide), for conditioning on various SGF metadata about human players from training data. * `nninterface.h` - Common interface that is implemented by every low-level neural net backend. - * `{cuda,opencl,eigen,trt,metal,onnx,dummy}backend.cpp` - Various backends. - * `onnxmodelbuilder.{cpp,h}` - Builds ONNX graphs from KataGo model weights for ONNX Runtime. + * `{cuda,opencl,eigen,trt,dummy}backend.cpp` - Various backends. * `nneval.{cpp,h}` - Top-level handle to the neural net used by the rest of the engine, implements thread-safe batching of queries. * `search` - The main search engine. * `timecontrols.cpp` - Basic handling of a few possible time controls. diff --git a/cpp/book/book.cpp b/cpp/book/book.cpp index 4a0fe135e0..298509cb92 100644 --- a/cpp/book/book.cpp +++ b/cpp/book/book.cpp @@ -145,7 +145,8 @@ void BookHash::getHashAndSymmetry(const BoardHistory& hist, int repBound, BookHa for(int symmetry = 0; symmetry < numSymmetries; symmetry++) { boardsBySym[symmetry] = SymmetryHelpers::getSymBoard(hist.initialBoard,symmetry); - histsBySym[symmetry] = BoardHistory(boardsBySym[symmetry], hist.initialPla, hist.rules, hist.initialEncorePhase); + //Replay and hash under the same pass-alive computation mode as the history we're hashing. + histsBySym[symmetry] = BoardHistory(boardsBySym[symmetry], hist.initialPla, hist.rules, hist.initialEncorePhase, hist.alwaysComputePassAliveUnderSuicideRules); accums[symmetry] = Hash128(); } @@ -860,12 +861,14 @@ Book::Book( const Rules& r, Player p, int rb, + bool alwaysPassAliveSuicide, BookParams bp ) : bookVersion(bversion), initialBoard(b), initialRules(r), initialPla(p), repBound(rb), + alwaysComputePassAliveUnderSuicideRules(alwaysPassAliveSuicide), params(bp), initialSymmetry(0), root(nullptr), @@ -873,6 +876,14 @@ Book::Book( nodeIdxMapsByHash(nullptr), nextVisitedDoneValue(1) { + //Older binaries silently mis-hash flagged books rather than erroring, so flagged books must use + //a version those binaries reject. See comment on LATEST_BOOK_VERSION. + if(alwaysComputePassAliveUnderSuicideRules && bookVersion < 3) + throw StringError( + "Books with alwaysComputePassAliveUnderSuicideRules=true require book version >= 3, got version " + + Global::intToString(bookVersion) + ); + nodeIdxMapsByHash = new std::map[NUM_HASH_BUCKETS]; BookHash rootHash; @@ -880,7 +891,7 @@ Book::Book( vector rootSymmetries; int initialEncorePhase = 0; - BoardHistory initialHist(initialBoard, initialPla, initialRules, initialEncorePhase); + BoardHistory initialHist(initialBoard, initialPla, initialRules, initialEncorePhase, alwaysComputePassAliveUnderSuicideRules); BookHash::getHashAndSymmetry(initialHist, repBound, rootHash, symmetryToAlign, rootSymmetries, bookVersion); initialSymmetry = symmetryToAlign; @@ -900,7 +911,7 @@ BoardHistory Book::getInitialHist() const { } BoardHistory Book::getInitialHist(int symmetry) const { int initialEncorePhase = 0; - return BoardHistory(SymmetryHelpers::getSymBoard(initialBoard,symmetry), initialPla, initialRules, initialEncorePhase); + return BoardHistory(SymmetryHelpers::getSymBoard(initialBoard,symmetry), initialPla, initialRules, initialEncorePhase, alwaysComputePassAliveUnderSuicideRules); } size_t Book::size() const { @@ -2990,7 +3001,15 @@ void Book::saveToFile(const string& fileName) const { string tmpFileName = fileName + ".tmp"; std::ofstream out; FileUtils::open(out, tmpFileName); + saveToStream(out); + out.close(); + + // Just in case, avoid any possible racing for file system + std::this_thread::sleep_for(std::chrono::duration(1)); + FileUtils::rename(tmpFileName,fileName); +} +void Book::saveToStream(std::ostream& out) const { { json paramsDump; paramsDump["version"] = bookVersion; @@ -2998,6 +3017,7 @@ void Book::saveToFile(const string& fileName) const { paramsDump["initialRules"] = initialRules.toJson(); paramsDump["initialPla"] = PlayerIO::playerToString(initialPla); paramsDump["repBound"] = repBound; + paramsDump["alwaysComputePassAliveUnderSuicideRules"] = alwaysComputePassAliveUnderSuicideRules; paramsDump["errorFactor"] = params.errorFactor; paramsDump["costPerMove"] = params.costPerMove; paramsDump["costPerUCBWinLossLoss"] = params.costPerUCBWinLossLoss; @@ -3125,16 +3145,41 @@ void Book::saveToFile(const string& fileName) const { out << nodeData << "\n"; } out << std::flush; - out.close(); +} - // Just in case, avoid any possible racing for file system - std::this_thread::sleep_for(std::chrono::duration(1)); - FileUtils::rename(tmpFileName,fileName); +bool Book::readAlwaysComputePassAliveUnderSuicideRulesOfFileHeader(const std::string& fileName) { + std::ifstream in; + FileUtils::open(in, fileName); + try { + return readAlwaysComputePassAliveUnderSuicideRulesOfHeader(in); + } + catch(const std::exception& e) { + throw IOError("When parsing book file " + fileName + ": " + e.what()); + } +} + +bool Book::readAlwaysComputePassAliveUnderSuicideRulesOfHeader(std::istream& in) { + std::string line; + getline(in,line); + if(!in) + throw IOError("Could not load initial metadata line from book data"); + json params = json::parse(line); + if(params.contains("alwaysComputePassAliveUnderSuicideRules")) + return params["alwaysComputePassAliveUnderSuicideRules"].get(); + return false; } Book* Book::loadFromFile(const std::string& fileName, int numThreadsForRecompute) { std::ifstream in; FileUtils::open(in, fileName); + return loadFromStreamHelper(in, numThreadsForRecompute, "book file " + fileName); +} + +Book* Book::loadFromStream(std::istream& in, int numThreadsForRecompute) { + return loadFromStreamHelper(in, numThreadsForRecompute, "book data"); +} + +Book* Book::loadFromStreamHelper(std::istream& in, int numThreadsForRecompute, const std::string& sourceDesc) { std::string line; Book* ret = NULL; try { @@ -3151,7 +3196,7 @@ Book* Book::loadFromFile(const std::string& fileName, int numThreadsForRecompute json params = json::parse(line); assertContains(params,"version"); int bookVersion = params["version"].get(); - if(bookVersion != 1 && bookVersion != 2) + if(bookVersion != 1 && bookVersion != 2 && bookVersion != 3) throw IOError("Unsupported book version: " + Global::intToString(bookVersion)); assertContains(params,"initialBoard"); @@ -3194,12 +3239,17 @@ Book* Book::loadFromFile(const std::string& fileName, int numThreadsForRecompute bookParams.visitsScaleLeaves = params.contains("visitsScaleLeaves") ? params["visitsScaleLeaves"].get() : 1.0; bookParams.sharpScoreOutlierCap = params.contains("sharpScoreOutlierCap") ? params["sharpScoreOutlierCap"].get() : 10000.0; + //Absent in older book files = false + bool alwaysComputePassAliveUnderSuicideRules = + params.contains("alwaysComputePassAliveUnderSuicideRules") ? params["alwaysComputePassAliveUnderSuicideRules"].get() : false; + book = std::make_unique( bookVersion, initialBoard, initialRules, initialPla, repBound, + alwaysComputePassAliveUnderSuicideRules, bookParams ); @@ -3338,7 +3388,7 @@ Book* Book::loadFromFile(const std::string& fileName, int numThreadsForRecompute ret = book.release(); } catch(const std::exception& e) { - throw IOError("When parsing book file " + fileName + ": " + e.what() + "\nFurthest line read was:\n" + line.substr(0,10000)); + throw IOError("When parsing " + sourceDesc + ": " + e.what() + "\nFurthest line read was:\n" + line.substr(0,10000)); } return ret; } diff --git a/cpp/book/book.h b/cpp/book/book.h index 0165648f87..d4d0633684 100644 --- a/cpp/book/book.h +++ b/cpp/book/book.h @@ -363,6 +363,9 @@ class Book { const Rules initialRules; const Player initialPla; const int repBound; + //Whether all histories and hashes of this book compute pass-alive area as if multi-stone suicide + //were legal regardless of the actual suicide rule. Recorded in the book file (absent = false). + const bool alwaysComputePassAliveUnderSuicideRules; private: BookParams params; @@ -384,11 +387,22 @@ class Book { const Rules& rules, Player initialPla, int repBound, + bool alwaysComputePassAliveUnderSuicideRules, BookParams params ); ~Book(); - static constexpr int LATEST_BOOK_VERSION = 2; + //Reads just the metadata header of a saved book file to get its recorded pass-alive computation + //mode without loading the whole book. Absent key (older book files) = false. + static bool readAlwaysComputePassAliveUnderSuicideRulesOfFileHeader(const std::string& fileName); + static bool readAlwaysComputePassAliveUnderSuicideRulesOfHeader(std::istream& in); + + //Version 3 is identical to version 2 in format and hashing, except that it may record + //alwaysComputePassAliveUnderSuicideRules=true. Flagged books require version >= 3 so that older + //binaries reject them cleanly ("Unsupported book version") instead of silently mis-hashing them + //into a disconnected mess. All new books are written as version 3, so new book files require + //this version of KataGo or later to load, whether flagged or not. + static constexpr int LATEST_BOOK_VERSION = 3; Book(const Book&) = delete; Book& operator=(const Book&) = delete; @@ -485,9 +499,12 @@ class Book { ); void saveToFile(const std::string& fileName) const; + void saveToStream(std::ostream& out) const; static Book* loadFromFile(const std::string& fileName, int numThreadsForRecompute=1); + static Book* loadFromStream(std::istream& in, int numThreadsForRecompute=1); private: + static Book* loadFromStreamHelper(std::istream& in, int numThreadsForRecompute, const std::string& sourceDesc); int64_t getIdx(const BookHash& hash) const; BookNode* get(const BookHash& hash); const BookNode* get(const BookHash& hash) const; diff --git a/cpp/command/analysis.cpp b/cpp/command/analysis.cpp index f202d0a20f..9a6e1f035f 100644 --- a/cpp/command/analysis.cpp +++ b/cpp/command/analysis.cpp @@ -912,9 +912,9 @@ int MainCmds::analysis(const vector& args) { if(input.find("komi") != input.end()) { double komi; - static_assert(Rules::MIN_USER_KOMI == -150.0f, ""); - static_assert(Rules::MAX_USER_KOMI == 150.0f, ""); - const char* msg = "Must be a integer or half-integer from -150.0 to 150.0"; + static_assert(Rules::MIN_USER_KOMI == -400.0f, ""); + static_assert(Rules::MAX_USER_KOMI == 400.0f, ""); + const char* msg = "Must be a integer or half-integer from -400.0 to 400.0"; bool suc = parseDouble(input, "komi", komi, Rules::MIN_USER_KOMI, Rules::MAX_USER_KOMI, msg); if(!suc) continue; @@ -1076,12 +1076,14 @@ int MainCmds::analysis(const vector& args) { reportErrorForId(rbase.id, field, string("Must be a list of dicts with subfields 'player', 'moves', 'untilDepth'")); continue; } - if(hasAllowMoves && avoidParamsList.size() > 1) { - reportErrorForId(rbase.id, field, string("Currently allowMoves only allows one entry")); + if(hasAllowMoves && avoidParamsList.size() > 2) { + reportErrorForId(rbase.id, field, string("Currently allowMoves only allows at most one entry per player")); continue; } bool failed = false; + bool gotAllowMovesBlack = false; + bool gotAllowMovesWhite = false; for(size_t i = 0; i& args) { suc = parseInteger(avoidParams, "untilDepth", untilDepth, 1, 1000000000, "Must be a positive integer"); if(!suc) { failed = true; break; } + //For allowMoves, at most one entry per player is permitted. Two entries for the same player would be + //ambiguous/incorrect since the std::fill below for the second entry would wipe out the first entry's allowed locs. + //Two entries for different players are fine since they write to separate per-player vectors. + if(hasAllowMoves) { + bool& gotAllowMoves = avoidPla == P_BLACK ? gotAllowMovesBlack : gotAllowMovesWhite; + if(gotAllowMoves) { + reportErrorForId(rbase.id, field, string("Cannot specify allowMoves more than once for the same player")); + failed = true; break; + } + gotAllowMoves = true; + } + vector& avoidMoveUntilByLoc = avoidPla == P_BLACK ? rbase.avoidMoveUntilByLocBlack : rbase.avoidMoveUntilByLocWhite; avoidMoveUntilByLoc.resize(Board::MAX_ARR_SIZE); if(hasAllowMoves) { @@ -1144,7 +1158,10 @@ int MainCmds::analysis(const vector& args) { } Player nextPla = initialPlayer; - BoardHistory hist(board,nextPla,rules,0); + //Keep this request's history consistent with the pass-alive computation mode that the search + //for this request will resolve to. (The search would re-stamp its own copy anyway, but this keeps + //any adjudication done during request setup/replay consistent with it.) + BoardHistory hist(board,nextPla,rules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(rbase.params, nnEval)); hist.setAssumeMultipleStartingBlackMovesAreHandicap(assumeMultipleStartingBlackMovesAreHandicap); if(warnUnusedFields) { diff --git a/cpp/command/benchmark.cpp b/cpp/command/benchmark.cpp index 43427a0dda..89ecd1bb19 100644 --- a/cpp/command/benchmark.cpp +++ b/cpp/command/benchmark.cpp @@ -266,21 +266,6 @@ int MainCmds::benchmark(const vector& args) { #endif #ifdef USE_EIGEN_BACKEND cout << "You are currently using the Eigen (CPU) version of KataGo. Due to having no GPU, it may be slow." << endl; -#endif -#ifdef USE_ONNX_BACKEND - string onnxProvider = cfg.contains("onnxProvider") ? cfg.getString("onnxProvider") : "cpu"; - string onnxProviderLower = Global::toLower(onnxProvider); - cout << "You are currently using the ONNX Runtime version of KataGo." << endl; - cout << "Your GTP config is currently set to onnxProvider = " << onnxProvider << endl; - if(onnxProviderLower == "openvino") { - string deviceType = cfg.contains("onnxOpenVINODeviceType") ? cfg.getString("onnxOpenVINODeviceType") : "CPU"; - cout << "OpenVINO device type = " << deviceType << endl; - cout << "For Intel NPU, typically set onnxOpenVINODeviceType = NPU." << endl; - cout << "OpenVINO/NPU usually uses a single device; onnxDeviceToUseThread* is typically for cuda/trt/migraphx providers." << endl; - } - else if(onnxProviderLower == "cuda" || onnxProviderLower == "tensorrt" || onnxProviderLower == "migraphx") { - cout << "For ONNX Runtime multi-GPU, use numNNServerThreadsPerModel + onnxDeviceToUseThreadX." << endl; - } #endif cout << endl; cout << "Your GTP config is currently set to use numSearchThreads = " << params.numThreads << endl; @@ -322,7 +307,7 @@ int MainCmds::benchmark(const vector& args) { static void warmStartNNEval(const CompactSgf& sgf, Logger& logger, const SearchParams& params, NNEvaluator* nnEval, Rand& seedRand) { Board board(sgf.xSize,sgf.ySize); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,Rules(),0); + BoardHistory hist(board,nextPla,Rules(),0,false); SearchParams thisParams = params; thisParams.numThreads = 1; thisParams.maxVisits = 5; @@ -647,9 +632,6 @@ int MainCmds::genconfig(const vector& args, const string& firstCommand) int configNNCacheSizePowerOfTwo = 20; int configNNMutexPoolSizePowerOfTwo = 16; int configNumSearchThreads = 6; -#ifdef USE_ONNX_BACKEND - string configOnnxProvider = "openvino"; -#endif cout << endl; cout << "=========================================================================" << endl; @@ -775,72 +757,30 @@ int MainCmds::genconfig(const vector& args, const string& firstCommand) }); } -#ifdef USE_ONNX_BACKEND - { - cout << endl; - string prompt = - "Select ONNX Runtime execution provider in the generated config\n" - "(cpu, openvino, cuda, tensorrt, migraphx, coreml), default openvino:\n"; - promptAndParseInput(prompt, [&](const string& line) { - string provider = Global::toLower(Global::trim(line)); - if(provider == "") - provider = "openvino"; - if( - provider != "cpu" && - provider != "openvino" && - provider != "cuda" && - provider != "tensorrt" && - provider != "migraphx" && - provider != "coreml" - ) - throw StringError("Must be one of: cpu, openvino, cuda, tensorrt, migraphx, coreml"); - configOnnxProvider = provider; - }); - } -#endif - cout << endl; cout << "=========================================================================" << endl; cout << "GPUS AND RAM" << endl; #ifndef USE_EIGEN_BACKEND { - bool askForDeviceIdxs = true; -#ifdef USE_ONNX_BACKEND - bool onnxProviderSupportsThreadDeviceMap = - configOnnxProvider == "cuda" || - configOnnxProvider == "tensorrt" || - configOnnxProvider == "migraphx"; - askForDeviceIdxs = onnxProviderSupportsThreadDeviceMap; -#endif - if(askForDeviceIdxs) { - cout << endl; - cout << "Finding available GPU-like devices..." << endl; - NeuralNet::printDevices(); - cout << endl; + cout << endl; + cout << "Finding available GPU-like devices..." << endl; + NeuralNet::printDevices(); + cout << endl; - string prompt = - "Specify devices/GPUs to use (for example \"0,1,2\" to use devices 0, 1, and 2). Leave blank for a default SINGLE-GPU config:\n"; - promptAndParseInput(prompt, [&](const string& line) { - vector pieces = Global::split(line,','); - configDeviceIdxs.clear(); - for(size_t i = 0; i 10000) - throw StringError("Invalid device idx: " + Global::intToString(idx)); - configDeviceIdxs.push_back(idx); - } - }); - } -#ifdef USE_ONNX_BACKEND - else { - cout << endl; - cout << "onnxProvider = " << configOnnxProvider << " selected." << endl; - cout << "Skipping per-thread multi-device mapping (mainly used by cuda/tensorrt/migraphx providers)." << endl; - configDeviceIdxs.clear(); - } -#endif + string prompt = + "Specify devices/GPUs to use (for example \"0,1,2\" to use devices 0, 1, and 2). Leave blank for a default SINGLE-GPU config:\n"; + promptAndParseInput(prompt, [&](const string& line) { + vector pieces = Global::split(line,','); + configDeviceIdxs.clear(); + for(size_t i = 0; i 10000) + throw StringError("Invalid device idx: " + Global::intToString(idx)); + configDeviceIdxs.push_back(idx); + } + }); } #endif @@ -917,9 +857,6 @@ int MainCmds::genconfig(const vector& args, const string& firstCommand) configNNCacheSizePowerOfTwo, configNNMutexPoolSizePowerOfTwo, configNumSearchThreads -#ifdef USE_ONNX_BACKEND - ,configOnnxProvider -#endif ); }; updateConfigContents(); diff --git a/cpp/command/dumpcalibrationdata.cpp b/cpp/command/dumpcalibrationdata.cpp deleted file mode 100644 index 6ef78d9a63..0000000000 --- a/cpp/command/dumpcalibrationdata.cpp +++ /dev/null @@ -1,257 +0,0 @@ -#include "../core/global.h" -#include "../core/fileutils.h" -#include "../core/rand.h" -#include "../dataio/sgf.h" -#include "../dataio/files.h" -#include "../dataio/numpywrite.h" -#include "../neuralnet/nninputs.h" -#include "../neuralnet/nninterface.h" -#include "../neuralnet/modelversion.h" -#include "../command/commandline.h" -#include "../main.h" - -using namespace std; - -// Dumps a calibration dataset (NN input feature tensors, sampled from real games) for offline -// post-training static quantization of an exported .onnx model -- e.g. via AMD's amd-quark -// (quark.onnx), to produce an INT8 QDQ model that the VitisAI EP can actually accelerate on NPU -// (the VitisAI EP falls back to CPU for FP32 ops, so quantization is a prerequisite for NPU -// offload, not an optimization). See Compiling.md's ONNX/VitisAI section. -// -// Deliberately reuses NNInputs::fillRowV7 -- the exact same feature-encoding code path used at -// real inference time -- rather than any separate/reimplemented extraction logic, so calibration -// data is guaranteed to match what the network actually sees at inference. Does NOT load any -// neural net compute backend (GPU/NPU/CPU session) -- feature extraction only depends on the -// model's channel counts (from ModelDesc, no session needed), not on a working backend. This -// keeps the tool fast and usable on any machine, independent of any particular execution -// provider's availability or quirks. -int MainCmds::dumpcalibrationdata(const vector& args) { - Board::initHash(); - - string modelFile; - vector sgfFilesFromCmdline; - vector sgfDirs; - vector sgfsDirs; - string outputFile; - int nnXLen; - int nnYLen; - int positionsPerGame; - int maxPositions; - string randSeed; - - try { - KataGoCommandLine cmd( - "Dump a calibration dataset of NN input tensors (spatial+global features) sampled from sgf " - "games, for offline INT8 quantization of an exported ONNX model (e.g. via AMD's amd-quark, " - "for the VitisAI/NPU execution provider). Does not require a GPU/NPU or a config file -- " - "purely extracts board features from the model's channel counts." - ); - cmd.addModelFileArg(); - - TCLAP::MultiArg sgfArg("","sgf","Sgf file",false,"SGF"); - TCLAP::MultiArg sgfDirArg("","sgfdir","Directory of sgf files",false,"DIR"); - TCLAP::MultiArg sgfsDirArg("","sgfsdir","Directory of sgfs (multi-game-per-file) files",false,"DIR"); - TCLAP::ValueArg outputArg("o","output","Output npz file path",true,string(),"FILE"); - TCLAP::ValueArg xLenArg("x","xlen","Board x size baked into calibration tensors",false,19,"N"); - TCLAP::ValueArg yLenArg("y","ylen","Board y size baked into calibration tensors",false,19,"N"); - TCLAP::ValueArg positionsPerGameArg( - "","positions-per-game","How many positions to sample per game, evenly spaced across its move range",false,8,"N" - ); - TCLAP::ValueArg maxPositionsArg("","max-positions","Stop after collecting this many total positions",false,2000,"N"); - TCLAP::ValueArg randSeedArg("","rand-seed","Random seed for shuffling game order",false,string(),"SEED"); - - cmd.add(sgfArg); - cmd.add(sgfDirArg); - cmd.add(sgfsDirArg); - cmd.add(outputArg); - cmd.add(xLenArg); - cmd.add(yLenArg); - cmd.add(positionsPerGameArg); - cmd.add(maxPositionsArg); - cmd.add(randSeedArg); - cmd.parseArgs(args); - - modelFile = cmd.getModelFile(); - sgfFilesFromCmdline = sgfArg.getValue(); - sgfDirs = sgfDirArg.getValue(); - sgfsDirs = sgfsDirArg.getValue(); - outputFile = outputArg.getValue(); - nnXLen = xLenArg.getValue(); - nnYLen = yLenArg.getValue(); - positionsPerGame = positionsPerGameArg.getValue(); - maxPositions = maxPositionsArg.getValue(); - randSeed = randSeedArg.getValue(); - } - catch(TCLAP::ArgException& e) { - cerr << "Error: " << e.error() << " for argument " << e.argId() << endl; - return 1; - } - - if(nnXLen < 2 || nnXLen > NNPos::MAX_BOARD_LEN || nnYLen < 2 || nnYLen > NNPos::MAX_BOARD_LEN) - throw StringError("Invalid board size for dumpcalibrationdata"); - if(positionsPerGame <= 0) - throw StringError("positions-per-game must be positive"); - if(maxPositions <= 0) - throw StringError("max-positions must be positive"); - if(randSeed.size() <= 0) - randSeed = Global::uint64ToString(Rand().nextUInt64()); - - // Load just the model's channel-count metadata -- no compute backend/session is created. - const string expectedSha256 = ""; - std::unique_ptr loadedModel( - NeuralNet::loadModelFile(modelFile, expectedSha256), - NeuralNet::freeLoadedModel - ); - const ModelDesc& modelDesc = NeuralNet::getModelDesc(loadedModel.get()); - int numSpatialFeatures = modelDesc.numInputChannels; - int numGlobalFeatures = modelDesc.numInputGlobalChannels; - if(numSpatialFeatures != NNInputs::NUM_FEATURES_SPATIAL_V7 || numGlobalFeatures != NNInputs::NUM_FEATURES_GLOBAL_V7) { - throw StringError( - "dumpcalibrationdata only supports the current V7 feature set (spatial=" + - Global::intToString(NNInputs::NUM_FEATURES_SPATIAL_V7) + ", global=" + - Global::intToString(NNInputs::NUM_FEATURES_GLOBAL_V7) + "), but the model reports spatial=" + - Global::intToString(numSpatialFeatures) + " global=" + Global::intToString(numGlobalFeatures) - ); - } - if(modelDesc.numInputMetaChannels > 0) { - cerr << "Warning: model has " << modelDesc.numInputMetaChannels - << " metadata input channels; dumpcalibrationdata does not populate these (left as zero)." << endl; - } - - // Collect sgf files -------------------------------------------------------- - vector sgfFiles; - FileHelpers::collectSgfsFromDirsOrFiles(sgfDirs,sgfFiles); - for(const string& s: sgfFilesFromCmdline) - sgfFiles.push_back(s); - - vector sgfsFiles; - FileHelpers::collectMultiSgfsFromDirsOrFiles(sgfsDirs,sgfsFiles); - - if(sgfFiles.size() <= 0 && sgfsFiles.size() <= 0) - throw StringError("No sgf files specified or found (use -sgf, -sgfdir, and/or -sgfsdir)"); - - vector> compactSgfs; - for(const string& f : sgfFiles) { - try { - compactSgfs.push_back(CompactSgf::loadFile(f)); - } - catch(const std::exception& e) { - cerr << "Warning: skipping sgf that failed to load: " << f << " (" << e.what() << ")" << endl; - } - } - for(const string& f : sgfsFiles) { - vector> sgfs; - try { - sgfs = Sgf::loadSgfsFile(f); - } - catch(const std::exception& e) { - cerr << "Warning: skipping sgfs file that failed to load: " << f << " (" << e.what() << ")" << endl; - continue; - } - for(auto& sgf : sgfs) { - try { - compactSgfs.push_back(std::unique_ptr(new CompactSgf(std::move(*sgf)))); - } - catch(const std::exception& e) { - cerr << "Warning: skipping one game within " << f << " that failed to compact (" << e.what() << ")" << endl; - } - } - } - - if(compactSgfs.size() <= 0) - throw StringError("No sgf games successfully loaded"); - - cout << "Loaded " << compactSgfs.size() << " games." << endl; - - // Shuffle game order deterministically so a max-positions cutoff doesn't bias toward - // whatever happens to sort first (e.g. alphabetically-early filenames). - Rand rand(randSeed); - rand.shuffle(compactSgfs); - - // Sample positions ----------------------------------------------------------- - int64_t maxRows = (int64_t)maxPositions; - NumpyBuffer binaryInputNCHW(std::vector({maxRows,(int64_t)numSpatialFeatures,(int64_t)nnYLen,(int64_t)nnXLen})); - NumpyBuffer globalInputNC(std::vector({maxRows,(int64_t)numGlobalFeatures})); - - int64_t numRowsWritten = 0; - int numGamesUsed = 0; - MiscNNInputParams nnInputParams; - const bool inputsUseNHWC = false; - - for(size_t gameIdx = 0; gameIdx < compactSgfs.size() && numRowsWritten < maxRows; gameIdx++) { - CompactSgf* sgf = compactSgfs[gameIdx].get(); - int64_t numMoves = (int64_t)sgf->moves.size(); - if(numMoves <= 0) - continue; - if(sgf->xSize != nnXLen || sgf->ySize != nnYLen) - continue; // Skip games whose board size doesn't match the requested calibration board size - - Rules initialRules; - try { - initialRules = sgf->getRulesOrWarn( - Rules::getTrompTaylorish(), - [](const string& msg) { (void)msg; } // Suppress per-game rules warnings; too noisy over many games. - ); - } - catch(const std::exception& e) { - cerr << "Warning: skipping game with unparseable rules: " << e.what() << endl; - continue; - } - - bool usedAnyPositionThisGame = false; - for(int i = 0; i < positionsPerGame && numRowsWritten < maxRows; i++) { - // Evenly space sampled move numbers across the game, skewed away from move 0 (near-empty - // boards contribute little to calibration) and away from the very last move. - int64_t moveNum = (numMoves * (int64_t)(i+1)) / (positionsPerGame + 1); - if(moveNum < 0) moveNum = 0; - if(moveNum > numMoves) moveNum = numMoves; - - Board board; - Player nextPla; - BoardHistory hist; - bool ok = true; - try { - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); - sgf->playMovesTolerant(board, nextPla, hist, moveNum, false); - } - catch(const std::exception&) { - ok = false; // Skip this position (e.g. an illegal move somewhere in the replay) - } - if(!ok) - continue; - - float* spatialRow = binaryInputNCHW.data + numRowsWritten * (int64_t)numSpatialFeatures * nnXLen * nnYLen; - float* globalRow = globalInputNC.data + numRowsWritten * (int64_t)numGlobalFeatures; - NNInputs::fillRowV7(board, hist, nextPla, nnInputParams, nnXLen, nnYLen, inputsUseNHWC, spatialRow, globalRow); - - numRowsWritten++; - usedAnyPositionThisGame = true; - } - if(usedAnyPositionThisGame) { - numGamesUsed++; - if(numGamesUsed % 200 == 0) - cout << "..." << numRowsWritten << " positions collected from " << numGamesUsed << " games" << endl; - } - } - - if(numRowsWritten <= 0) - throw StringError("Collected zero calibration positions (check board size matches your sgfs, and that games have moves)"); - - cout << "Collected " << numRowsWritten << " calibration positions from " << numGamesUsed << " games." << endl; - - uint64_t spatialBytes = binaryInputNCHW.prepareHeaderWithNumRows(numRowsWritten); - uint64_t globalBytes = globalInputNC.prepareHeaderWithNumRows(numRowsWritten); - - ZipFile zipFile(outputFile); - zipFile.writeBuffer("binaryInputNCHW", binaryInputNCHW.dataIncludingHeader, spatialBytes); - zipFile.writeBuffer("globalInputNC", globalInputNC.dataIncludingHeader, globalBytes); - zipFile.close(); - - cout << "Wrote " << numRowsWritten << " rows to " << outputFile << endl; - cout << " binaryInputNCHW shape: [" << numRowsWritten << ", " << numSpatialFeatures << ", " << nnYLen << ", " << nnXLen << "]" << endl; - cout << " globalInputNC shape: [" << numRowsWritten << ", " << numGlobalFeatures << "]" << endl; - cout << "Note: channel 0 of binaryInputNCHW is the on-board mask (per KataGo convention), matching" << endl; - cout << "the InputSpatial tensor consumed by the exported ONNX graph (see exportonnx)." << endl; - - return 0; -} diff --git a/cpp/command/evalsgf.cpp b/cpp/command/evalsgf.cpp index 0e8812012c..d7d019b88e 100644 --- a/cpp/command/evalsgf.cpp +++ b/cpp/command/evalsgf.cpp @@ -184,8 +184,11 @@ int MainCmds::evalsgf(const vector& args) { Player nextPla; BoardHistory hist; - auto setUpBoardUsingRules = [&board,&nextPla,&hist,overrideKomi,&sgf,&extraMoves](const Rules& initialRules, int moveNum) { - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + //Set for real after the neural net is loaded, from the params and the model's declaration. + bool alwaysComputePassAliveUnderSuicideRules = false; + auto setUpBoardUsingRules = [&board,&nextPla,&hist,overrideKomi,&sgf,&extraMoves,&alwaysComputePassAliveUnderSuicideRules](const Rules& initialRules, int moveNum) { + //Set up before replaying moves so any adjudication during replay is consistent with the searches. + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, alwaysComputePassAliveUnderSuicideRules); vector& moves = sgf->moves; if(!isnan(overrideKomi)) { @@ -287,6 +290,8 @@ int MainCmds::evalsgf(const vector& args) { } logger.write("Loaded neural net"); + alwaysComputePassAliveUnderSuicideRules = Search::resolveAlwaysComputePassAliveUnderSuicideRules(params, nnEval); + { bool rulesWereSupported; Rules supportedRules = nnEval->getSupportedRules(initialRules,rulesWereSupported); @@ -373,7 +378,11 @@ int MainCmds::evalsgf(const vector& args) { buf.result->debugPrint(cout,board); if(humanEval != NULL) { - humanEval->evaluate(board,hist,nextPla,nnInputParams,buf,skipCache,includeOwnerMap); + //Featurize per the human model's own resolution, which may differ from the main model's. + MiscNNInputParams humanNNInputParams = nnInputParams; + humanNNInputParams.passAliveSuicideRulesOverride = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(params, humanEval) ? 1 : 0; + humanEval->evaluate(board,hist,nextPla,humanNNInputParams,buf,skipCache,includeOwnerMap); buf.result->debugPrint(cout,board); } continue; diff --git a/cpp/command/genbook.cpp b/cpp/command/genbook.cpp index f907942610..213eb3f1d4 100644 --- a/cpp/command/genbook.cpp +++ b/cpp/command/genbook.cpp @@ -181,6 +181,7 @@ static void maybeParseBonusFile( int boardSizeY, const Rules& rules, int repBound, + bool alwaysComputePassAliveUnderSuicideRules, double bonusFileScale, Logger& logger, std::map& bonusByHash, @@ -205,7 +206,8 @@ static void maybeParseBonusFile( comments.find("BRANCH") != string::npos ) ) { - BoardHistory hist(sgfHist.initialBoard, sgfHist.initialPla, rules, sgfHist.initialEncorePhase); + //Replay and hash under the book's pass-alive computation mode so hashes match book nodes. + BoardHistory hist(sgfHist.initialBoard, sgfHist.initialPla, rules, sgfHist.initialEncorePhase, alwaysComputePassAliveUnderSuicideRules); Board board = hist.initialBoard; for(size_t i = 0; i& args) { Rules rules = Setup::loadSingleRules(cfg,loadKomiFromCfg); const bool hasHumanModel = humanModelFile != ""; - const SearchParams params = Setup::loadSingleParams(cfg,Setup::SETUP_FOR_GTP,hasHumanModel); + //Not const - alwaysComputePassAliveUnderSuicideRules is forced below to match the book. + SearchParams params = Setup::loadSingleParams(cfg,Setup::SETUP_FOR_GTP,hasHumanModel); const int boardSizeX = cfg.getInt("boardSizeX",2,Board::MAX_LEN); const int boardSizeY = cfg.getInt("boardSizeY",2,Board::MAX_LEN); @@ -432,23 +435,8 @@ int MainCmds::genbook(const vector& args) { bonusInitialBoard = Board(boardSizeX,boardSizeY); bonusInitialPla = P_BLACK; - for(const std::string& bonusFile: bonusFiles) { - maybeParseBonusFile( - bonusFile, - boardSizeX, - boardSizeY, - rules, - repBound, - bonusFileScale, - logger, - bonusByHash, - expandBonusByHash, - visitsRequiredByHash, - branchRequiredByHash, - bonusInitialBoard, - bonusInitialPla - ); - } + //Bonus sgf files are parsed further below, after the pass-alive computation mode for this run is + //known, since the book hashes they produce depend on it. for(const std::string& hashBonusFile: hashBonusFiles) { maybeParseHashBonusFile( hashBonusFile, @@ -491,6 +479,44 @@ int MainCmds::genbook(const vector& args) { if(humanEval != NULL) policyEvaluator = humanEval; + //Determine the pass-alive computation mode governing this run. A preexisting book's recorded value + //takes precedence; a new book records the resolution of the config param against the model. All + //searches, evals, and book hashes in this run are then forced to be consistent with it. + bool bookFileExists; + { + std::ifstream infile; + bookFileExists = FileUtils::tryOpen(infile,bookFile); + } + const bool bookPassAliveUnderSuicideRules = + bookFileExists ? + Book::readAlwaysComputePassAliveUnderSuicideRulesOfFileHeader(bookFile) : + Search::resolveAlwaysComputePassAliveUnderSuicideRules(params, nnEval); + if(Search::resolveAlwaysComputePassAliveUnderSuicideRules(params, nnEval) != bookPassAliveUnderSuicideRules) + logger.write( + "Note: preexisting book was made with alwaysComputePassAliveUnderSuicideRules=" + + Global::boolToString(bookPassAliveUnderSuicideRules) + ", forcing that value for all searches in this run" + ); + params.alwaysComputePassAliveUnderSuicideRules = bookPassAliveUnderSuicideRules ? enabled_t::True : enabled_t::False; + + for(const std::string& bonusFile: bonusFiles) { + maybeParseBonusFile( + bonusFile, + boardSizeX, + boardSizeY, + rules, + repBound, + bookPassAliveUnderSuicideRules, + bonusFileScale, + logger, + bonusByHash, + expandBonusByHash, + visitsRequiredByHash, + branchRequiredByHash, + bonusInitialBoard, + bonusInitialPla + ); + } + vector searches; for(int i = 0; i& args) { MakeDir::make(htmlDir); Book* book; - bool bookFileExists; - { - std::ifstream infile; - bookFileExists = FileUtils::tryOpen(infile,bookFile); - } if(bookFileExists) { book = Book::loadFromFile(bookFile,numBookThreads); + testAssert(book->alwaysComputePassAliveUnderSuicideRules == bookPassAliveUnderSuicideRules); if( boardSizeX != book->getInitialHist().getRecentBoard(0).x_size || boardSizeY != book->getInitialHist().getRecentBoard(0).y_size || @@ -592,6 +614,7 @@ int MainCmds::genbook(const vector& args) { rules, bonusInitialPla, repBound, + bookPassAliveUnderSuicideRules, cfgParams ); logger.write("Creating new book at " + bookFile); @@ -1629,6 +1652,8 @@ int MainCmds::writebook(const vector& args) { boardSizeY, rules, repBound, + //Bonus hashes must be computed under the book's recorded pass-alive computation mode. + Book::readAlwaysComputePassAliveUnderSuicideRulesOfFileHeader(bookFile), bonusFileScale, logger, bonusByHash, @@ -2143,9 +2168,10 @@ int MainCmds::comparebooks(const vector& args) { book1->initialBoard.x_size != book2->initialBoard.x_size || book1->initialBoard.y_size != book2->initialBoard.y_size || book1->repBound != book2->repBound || - book1->initialRules != book2->initialRules + book1->initialRules != book2->initialRules || + book1->alwaysComputePassAliveUnderSuicideRules != book2->alwaysComputePassAliveUnderSuicideRules ) { - logger.write("ERROR: Books have different board sizes, rep bounds, or rules"); + logger.write("ERROR: Books have different board sizes, rep bounds, rules, or pass-alive computation modes"); delete book1; delete book2; return 1; diff --git a/cpp/command/gtp.cpp b/cpp/command/gtp.cpp index fbf143d756..934de87087 100644 --- a/cpp/command/gtp.cpp +++ b/cpp/command/gtp.cpp @@ -556,7 +556,7 @@ struct GTPEngine { Board board(boardXSize,boardYSize); Player pla = P_BLACK; - BoardHistory hist(board,pla,currentRules,0); + BoardHistory hist(board,pla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); vector newMoveHistory; setPositionAndRules(pla,board,hist,board,pla,newMoveHistory); clearStatsForNewGame(); @@ -589,7 +589,7 @@ struct GTPEngine { int newYSize = bot->getRootBoard().y_size; Board board(newXSize,newYSize); Player pla = P_BLACK; - BoardHistory hist(board,pla,currentRules,0); + BoardHistory hist(board,pla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); vector newMoveHistory; setPositionAndRules(pla,board,hist,board,pla,newMoveHistory); clearStatsForNewGame(); @@ -611,7 +611,7 @@ struct GTPEngine { } } Player pla = P_BLACK; - BoardHistory hist(board,pla,currentRules,0); + BoardHistory hist(board,pla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); hist.setInitialTurnNumber(board.numStonesOnBoard()); //Heuristic to guess at what turn this is vector newMoveHistory; setPositionAndRules(pla,board,hist,board,pla,newMoveHistory); @@ -649,7 +649,7 @@ struct GTPEngine { vector moveHistoryCopy = moveHistory; Board undoneBoard = initialBoard; - BoardHistory undoneHist(undoneBoard,initialPla,currentRules,0); + BoardHistory undoneHist(undoneBoard,initialPla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); undoneHist.setInitialTurnNumber(bot->getRootHist().initialTurnNumber); vector emptyMoveHistory; setPositionAndRules(initialPla,undoneBoard,undoneHist,initialBoard,initialPla,emptyMoveHistory); @@ -678,7 +678,7 @@ struct GTPEngine { vector moveHistoryCopy = moveHistory; Board board = initialBoard; - BoardHistory hist(board,initialPla,newRules,0); + BoardHistory hist(board,initialPla,newRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); hist.setInitialTurnNumber(bot->getRootHist().initialTurnNumber); vector emptyMoveHistory; setPositionAndRules(initialPla,board,hist,initialBoard,initialPla,emptyMoveHistory); @@ -699,6 +699,30 @@ struct GTPEngine { return true; } + //Re-replay the current game from the beginning under the currently resolved + //alwaysComputePassAliveUnderSuicideRules mode. Used when a runtime params change (kata-set-param) + //flips that mode - the bot's own rootHistory gets re-stamped by setParams, but re-stamping + //deliberately does not re-adjudicate game state recorded under the old mode (e.g. an + //automatically detected game end), whereas replaying recomputes everything as if the engine had + //been using the new mode all along. This also keeps the state consistent with what a later + //rebuild-and-replay (undo, kata-set-rules) would produce. + void rereplayGameForPassAliveModeChange() { + testAssert(bot->getRootHist().rules == currentRules); + vector moveHistoryCopy = moveHistory; + + Board board = initialBoard; + BoardHistory hist(board,initialPla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); + hist.setInitialTurnNumber(bot->getRootHist().initialTurnNumber); + vector emptyMoveHistory; + setPositionAndRules(initialPla,board,hist,initialBoard,initialPla,emptyMoveHistory); + + for(int i = 0; iponder(lastSearchFactor); } @@ -1325,7 +1349,7 @@ struct GTPEngine { testAssert(bot->getRootHist().rules == currentRules); Player pla = P_BLACK; - BoardHistory hist(board,pla,currentRules,0); + BoardHistory hist(board,pla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); //Also switch the initial player, expecting white should be next. hist.clear(board,P_WHITE,currentRules,0); @@ -1366,7 +1390,7 @@ struct GTPEngine { Board board(xSize,ySize); Player pla = P_BLACK; - BoardHistory hist(board,pla,currentRules,0); + BoardHistory hist(board,pla,currentRules,0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(genmoveParams,nnEval)); double extraBlackTemperature = 0.25; PlayUtils::playExtraBlack(bot->getSearchStopAndWait(), n, board, hist, extraBlackTemperature, rand); //Also switch the initial player, expecting white should be next. @@ -1593,7 +1617,7 @@ struct GTPEngine { return Global::trim(policyStr + "\n" + wlStr + "\n" + leadStr); } - string rawNN(int whichSymmetry, double policyOptimism, bool useHumanModel) { + string rawNN(int whichSymmetry, double policyOptimism, bool useHumanModel, Player nextPla) { NNEvaluator* nnEvalToUse = useHumanModel ? humanEval : nnEval; if(nnEvalToUse == NULL) return ""; @@ -1603,7 +1627,13 @@ struct GTPEngine { if(whichSymmetry == NNInputs::SYMMETRY_ALL || whichSymmetry == symmetry) { Board board = bot->getRootBoard(); BoardHistory hist = bot->getRootHist(); - Player nextPla = bot->getRootPla(); + //If evaluating from a player other than the one naturally to move, rebuild the history so that player + //is to move (mirrors how the analysis engine handles a player switch). The NN evaluator asserts that + //nextPla matches the history's presumed next mover. This resets ko/pass history for the position. + if(nextPla != hist.presumedNextMovePla) { + board.clearSimpleKoLoc(); + hist.clear(board,nextPla,hist.rules,hist.encorePhase); + } MiscNNInputParams nnInputParams; nnInputParams.playoutDoublingAdvantage = @@ -1611,6 +1641,11 @@ struct GTPEngine { analysisParams.playoutDoublingAdvantage : -analysisParams.playoutDoublingAdvantage; nnInputParams.symmetry = symmetry; nnInputParams.policyOptimism = policyOptimism; + //When evaluating the human model, featurize per its own resolution (which may differ from the + //main search's mode carried by the history), matching how in-search human evals featurize. + if(useHumanModel) + nnInputParams.passAliveSuicideRulesOverride = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(analysisParams, humanEval) ? 1 : 0; NNResultBuf buf; bool skipCache = true; bool includeOwnerMap = true; @@ -1891,6 +1926,71 @@ static GTPEngine::AnalyzeArgs parseAnalyzeCommand( return args; } +//Parse args for kata-raw-nn / kata-raw-human-nn: an optional leading player color ("b"/"w"/"black"/"white"), +//a required symmetry ("all" or an index 0-7), and (if allowOptimism) an optional trailing policy optimism value +//in [0,1]. This is positional and mirrors the optional-player convention used by the analyze commands (see +//parseAnalyzeCommand): a color, if present, must come first, and the optimism, if present, must come last. +//'pla' and 'policyOptimism' should be pre-filled with defaults; each is overwritten only if its argument is given. +//Returns false and fills 'error' on any missing, extra, or unparseable argument. +//Note: only "b"/"w"/"black"/"white" parse as a player (see PlayerIO::tryParsePlayer). An integer never parses as a +//player, so a bare symmetry index such as "kata-raw-nn 3" is unambiguously the symmetry, exactly as before. +static bool parseRawNNArgs( + const vector& pieces, + bool allowOptimism, + Player& pla, + int& whichSymmetry, + double& policyOptimism, + string& error +) { + size_t idx = 0; + + //Optional leading player color. + Player parsedPla; + if(idx < pieces.size() && PlayerIO::tryParsePlayer(Global::trim(Global::toLower(pieces[idx])),parsedPla)) { + pla = parsedPla; + idx += 1; + } + + //Required symmetry. + if(idx >= pieces.size()) { + error = "Expected a symmetry argument 'all' or index [0-7]"; + return false; + } + { + string s = Global::trim(Global::toLower(pieces[idx])); + int parsedSym; + if(s == "all") + whichSymmetry = NNInputs::SYMMETRY_ALL; + else if(Global::tryStringToInt(s,parsedSym) && parsedSym >= 0 && parsedSym <= SymmetryHelpers::NUM_SYMMETRIES-1) + whichSymmetry = parsedSym; + else { + error = "Expected a symmetry argument 'all' or index [0-7] but got '" + pieces[idx] + "'"; + return false; + } + idx += 1; + } + + //Optional trailing policy optimism in [0,1]. + if(allowOptimism && idx < pieces.size()) { + double parsedOpt; + if(Global::tryStringToDouble(pieces[idx],parsedOpt) && !isnan(parsedOpt) && parsedOpt >= 0.0 && parsedOpt <= 1.0) { + policyOptimism = parsedOpt; + idx += 1; + } + else { + error = "Expected an optimism value in [0,1] but got '" + pieces[idx] + "'"; + return false; + } + } + + //No further arguments allowed. + if(idx < pieces.size()) { + error = "Unexpected extra argument '" + pieces[idx] + "'"; + return false; + } + return true; +} + int MainCmds::gtp(const vector& args) { Board::initHash(); @@ -2649,8 +2749,15 @@ int MainCmds::gtp(const vector& args) { SearchParams::failIfParamsDifferOnUnchangeableParameter(initialGenmoveParams,genmoveParams); SearchParams::failIfParamsDifferOnUnchangeableParameter(initialAnalysisParams,analysisParams); + bool oldPassAliveMode = Search::resolveAlwaysComputePassAliveUnderSuicideRules(engine->getGenmoveParams(),engine->nnEval); engine->setGenmoveParamsIfChanged(genmoveParams); engine->setAnalysisParamsIfChanged(analysisParams); + //If the params change flipped the resolved pass-alive computation mode, re-replay the game + //so all recorded game state is recomputed under the new mode (re-stamping alone does not + //re-adjudicate). Done after both param sets are updated so the replay runs under the new mode. + bool newPassAliveMode = Search::resolveAlwaysComputePassAliveUnderSuicideRules(engine->getGenmoveParams(),engine->nnEval); + if(newPassAliveMode != oldPassAliveMode) + engine->rereplayGameForPassAliveModeChange(); staticPDATakesPrecedence = cfg.contains("playoutDoublingAdvantage") && !cfg.contains("dynamicPlayoutDoublingAdvantageCapPerOppLead"); engine->staticPDATakesPrecedence = staticPDATakesPrecedence; allowResignation = desiredAllowResignation; @@ -3204,7 +3311,7 @@ int MainCmds::gtp(const vector& args) { else { maybeSaveAvoidPatterns(false); Player pla = P_WHITE; - BoardHistory hist(board,pla,engine->getCurrentRules(),0); + BoardHistory hist(board,pla,engine->getCurrentRules(),0,Search::resolveAlwaysComputePassAliveUnderSuicideRules(engine->getGenmoveParams(),engine->nnEval)); hist.setInitialTurnNumber(board.numStonesOnBoard()); //Should give more accurate temperaure and time control behavior vector newMoveHistory; engine->setPositionAndRules(pla,board,hist,board,pla,newMoveHistory); @@ -3359,7 +3466,13 @@ int MainCmds::gtp(const vector& args) { } } - sgf->setupInitialBoardAndHist(sgfRules, sgfInitialBoard, sgfInitialNextPla, sgfInitialHist); + //Set up with the pass-alive computation mode the bot will be using BEFORE replaying the + //moves, so that any game-end adjudication happening during the replay matches what the + //same moves would give if entered via play commands on the bot's own history. + sgf->setupInitialBoardAndHist( + sgfRules, sgfInitialBoard, sgfInitialNextPla, sgfInitialHist, + Search::resolveAlwaysComputePassAliveUnderSuicideRules(engine->getGenmoveParams(), engine->nnEval) + ); sgfInitialHist.setInitialTurnNumber(sgfInitialBoard.numStonesOnBoard()); //Should give more accurate temperaure and time control behavior sgfBoard = sgfInitialBoard; sgfNextPla = sgfInitialNextPla; @@ -3456,50 +3569,29 @@ int MainCmds::gtp(const vector& args) { else if(command == "kata-raw-nn") { int whichSymmetry = NNInputs::SYMMETRY_ALL; - bool parsed = false; - if(pieces.size() == 1 || pieces.size() == 2) { - string s = Global::trim(Global::toLower(pieces[0])); - if(s == "all") - parsed = true; - else if(Global::tryStringToInt(s,whichSymmetry) && whichSymmetry >= 0 && whichSymmetry <= SymmetryHelpers::NUM_SYMMETRIES-1) - parsed = true; - } + Player pla = engine->bot->getRootPla(); + double policyOptimism = engine->getGenmoveParams().rootPolicyOptimism; + string error; + bool parsed = parseRawNNArgs(pieces, true, pla, whichSymmetry, policyOptimism, error); if(!parsed) { responseIsError = true; - response = "Expected one argument 'all' or symmetry index [0-7] for kata-raw-nn but got '" + Global::concat(pieces," ") + "'"; + response = error + " for kata-raw-nn (expected an optional color, a symmetry 'all' or index [0-7], and an optional optimism [0-1])"; } else { - double policyOptimism = engine->getGenmoveParams().rootPolicyOptimism; - if(pieces.size() == 2) { - parsed = false; - if(Global::tryStringToDouble(pieces[0],policyOptimism) && isnan(policyOptimism) && policyOptimism >= 0.0 && policyOptimism <= 1.0) { - parsed = true; - } - } - if(!parsed) { - responseIsError = true; - response = "Expected double from 0 to 1 for optimism but got '" + Global::concat(pieces," ") + "'"; - } - else { - const bool useHumanModel = false; - response = engine->rawNN(whichSymmetry, policyOptimism, useHumanModel); - } + const bool useHumanModel = false; + response = engine->rawNN(whichSymmetry, policyOptimism, useHumanModel, pla); } } else if(command == "kata-raw-human-nn") { int whichSymmetry = NNInputs::SYMMETRY_ALL; - bool parsed = false; - if(pieces.size() == 1) { - string s = Global::trim(Global::toLower(pieces[0])); - if(s == "all") - parsed = true; - else if(Global::tryStringToInt(s,whichSymmetry) && whichSymmetry >= 0 && whichSymmetry <= SymmetryHelpers::NUM_SYMMETRIES-1) - parsed = true; - } + Player pla = engine->bot->getRootPla(); + double policyOptimism = engine->getGenmoveParams().rootPolicyOptimism; + string error; + bool parsed = parseRawNNArgs(pieces, false, pla, whichSymmetry, policyOptimism, error); if(!parsed) { responseIsError = true; - response = "Expected one argument 'all' or symmetry index [0-7] for kata-raw-human-nn but got '" + Global::concat(pieces," ") + "'"; + response = error + " for kata-raw-human-nn (expected an optional color followed by a symmetry 'all' or index [0-7])"; } else { if(engine->humanEval == NULL) { @@ -3511,9 +3603,8 @@ int MainCmds::gtp(const vector& args) { response = "Cannot run kata-raw-human-nn, humanSLProfile parameter was not set"; } else { - double policyOptimism = engine->getGenmoveParams().rootPolicyOptimism; const bool useHumanModel = true; - response = engine->rawNN(whichSymmetry, policyOptimism, useHumanModel); + response = engine->rawNN(whichSymmetry, policyOptimism, useHumanModel, pla); } } } diff --git a/cpp/command/misc.cpp b/cpp/command/misc.cpp index e73acf9c55..49a2b72e18 100644 --- a/cpp/command/misc.cpp +++ b/cpp/command/misc.cpp @@ -13,21 +13,26 @@ #include "../program/setup.h" #include "../program/playutils.h" #include "../program/play.h" -#include "../neuralnet/nninterface.h" -#ifdef USE_ONNX_BACKEND -#include "../neuralnet/onnxmodelbuilder.h" -#endif #include "../command/commandline.h" #include "../tests/tests.h" #include "../main.h" +#include #include #include #include -#include +#include +#include using namespace std; +static std::atomic sigReceived(false); +static void signalHandler(int signal) +{ + if(signal == SIGINT || signal == SIGTERM) + sigReceived.store(true); +} + int MainCmds::printclockinfo(const vector& args) { (void)args; #ifdef OS_IS_WINDOWS @@ -40,73 +45,6 @@ int MainCmds::printclockinfo(const vector& args) { return 0; } -int MainCmds::exportonnx(const vector& args) { -#ifndef USE_ONNX_BACKEND - (void)args; - cerr << "exportonnx is only available in ONNX backend builds (USE_BACKEND=ONNX)." << endl; - return 1; -#else - string modelFile; - string outputFile; - int nnXLen; - int nnYLen; - bool emitFusedMishOp; - try { - KataGoCommandLine cmd("Export KataGo .bin/.bin.gz model to ONNX file."); - cmd.addModelFileArg(); - TCLAP::ValueArg outputArg("o","output","Output ONNX file path",true,string(),"FILE"); - TCLAP::ValueArg xLenArg("x","xlen","Board x size baked into exported model",false,19,"N"); - TCLAP::ValueArg yLenArg("y","ylen","Board y size baked into exported model",false,19,"N"); - TCLAP::SwitchArg emitFusedMishOpArg( - "","emitFusedMishOp", - "Emit KataGo's Mish activation as a single native ONNX Mish node instead of the decomposed " - "Softplus+Tanh+Mul. Off by default (matches what TensorRT's nvonnxparser and the live ONNX " - "backends are tested against). Turn this on when exporting for external quantizers targeting " - "AMD VitisAI/Ryzen AI NPU: its DPU compiler recognizes the fused Mish op for XINT8 " - "quantization but not the decomposed Softplus primitive, so without this flag the exported " - "graph's Conv/activation layers fail to fuse into NPU-executable subgraphs.", - false - ); - cmd.add(outputArg); - cmd.add(xLenArg); - cmd.add(yLenArg); - cmd.add(emitFusedMishOpArg); - cmd.parseArgs(args); - - modelFile = cmd.getModelFile(); - outputFile = outputArg.getValue(); - nnXLen = xLenArg.getValue(); - nnYLen = yLenArg.getValue(); - emitFusedMishOp = emitFusedMishOpArg.getValue(); - } - catch(TCLAP::ArgException& e) { - cerr << "Error: " << e.error() << " for argument " << e.argId() << endl; - return 1; - } - - if(nnXLen < 2 || nnXLen > NNPos::MAX_BOARD_LEN || nnYLen < 2 || nnYLen > NNPos::MAX_BOARD_LEN) - throw StringError("Invalid board size for exportonnx"); - - const string expectedSha256 = ""; - std::unique_ptr loadedModel( - NeuralNet::loadModelFile(modelFile, expectedSha256), - NeuralNet::freeLoadedModel - ); - const ModelDesc& modelDesc = NeuralNet::getModelDesc(loadedModel.get()); - OnnxModelBuilder::Result onnxResult = - OnnxModelBuilder::build(modelDesc, nnXLen, nnYLen, /*requireExactNNLen=*/false, /*transformerNHWC=*/false, nullptr, emitFusedMishOp); - string onnxBytes = std::move(onnxResult.serializedModel); - - ofstream out; - FileUtils::open(out, outputFile, std::ios::binary | std::ios::out); - out.write(onnxBytes.data(), onnxBytes.size()); - out.close(); - - cout << "Exported ONNX model to " << outputFile << " (" << onnxBytes.size() << " bytes)" << endl; - return 0; -#endif -} - int MainCmds::sampleinitializations(const vector& args) { Board::initHash(); ScoreValue::initTables(); @@ -284,7 +222,9 @@ int MainCmds::evalrandominits(const vector& args) { Board board(19,19); Player pla = P_BLACK; Rules rules = Rules::parseRules("japanese"); - BoardHistory hist(board,pla,rules,0); + //Keep pass-alive computations (e.g. endGameIfAllPassAlive below) consistent with how the bot's + //own searches are performing them. + BoardHistory hist(board,pla,rules,0,evalBot->getRootHist().alwaysComputePassAliveUnderSuicideRules); int numInitialMovesToPlay = (int)gameRand.nextUInt(200); double temperature = 1.0; for(int i = 0; i& args) { Player pla; BoardHistory hist; Rules initialRules; - sgfObj->setupInitialBoardAndHist(initialRules, board, pla, hist); + sgfObj->setupInitialBoardAndHist(initialRules, board, pla, hist, bot->getRootHist().alwaysComputePassAliveUnderSuicideRules); for(int i = 0; i < turnIdx; i++) { Loc moveLoc = sgfObj->moves[i].loc; @@ -473,3 +413,245 @@ int MainCmds::searchentropyanalysis(const vector& args) { ScoreValue::freeTables(); return 0; } + +//One CSV row per recorded turn of the game, containing the stats that drive surprise-based selection of +//positions (policy surprise, value surprise) along with the per-game and per-turn covariates needed to +//analyze what they vary with. +static void writeSurpriseStatsRows(ostream& out, int64_t gameIdx, const FinishedGameData& data) { + size_t numMoves = data.targetWeightByTurn.size(); + testAssert(data.hasFullData); + testAssert(data.policySurpriseByTurn.size() == numMoves); + testAssert(data.policyEntropyByTurn.size() == numMoves); + testAssert(data.searchEntropyByTurn.size() == numMoves); + testAssert(data.valueSurpriseByTurn.size() == numMoves); + testAssert(data.wasCheapSearchByTurn.size() == numMoves); + testAssert(data.nnRawStatsByTurn.size() == numMoves); + testAssert(data.policyTargetsByTurn.size() == numMoves); + testAssert(data.reanalysisByTurn.size() == numMoves); + testAssert(data.whiteValueTargetsByTurn.size() == numMoves + 1); + + //Last entry of the value targets is the actual game outcome. + const ValueTargets& outcome = data.whiteValueTargetsByTurn[numMoves]; + double pdaWhite = + data.playoutDoublingAdvantagePla == P_WHITE ? data.playoutDoublingAdvantage : + data.playoutDoublingAdvantagePla == P_BLACK ? -data.playoutDoublingAdvantage : 0.0; + //Turn number of the first recorded turn, counting handicap/policy-init/fork setup moves and any initial + //turn number offset of positions begun from sgfs, so that turn number is comparable across game modes. + int64_t startTurnIdx = data.startHist.initialTurnNumber + (int64_t)data.startHist.moveHistory.size(); + + for(size_t t = 0; t& args) { + Board::initHash(); + ScoreValue::initTables(); + + ConfigParser cfg; + string modelFile; + string outputFile; + int64_t numGamesTotal; + bool reanalyzeAll; + try { + KataGoCommandLine cmd("Run selfplay games with a fixed model and dump per-position policy and value surprise stats to csv"); + cmd.addConfigFileArg("","selfplay config file"); + cmd.addModelFileArg(); + cmd.addOverrideConfigArg(); + + TCLAP::ValueArg outputArg("","output","Csv file to write one row per recorded turn to",true,string(),"FILE"); + TCLAP::ValueArg numGamesArg("","num-games","Number of games to run",true,0,"N"); + TCLAP::SwitchArg reanalyzeAllArg("","reanalyze-all","Instead of disabling reanalysis, reanalyze every cheap-search position, so each such row records both the cheap search's (before) and the full search's (after) surprise stats"); + cmd.add(outputArg); + cmd.add(numGamesArg); + cmd.add(reanalyzeAllArg); + cmd.parseArgs(args); + outputFile = outputArg.getValue(); + numGamesTotal = numGamesArg.getValue(); + reanalyzeAll = reanalyzeAllArg.getValue(); + if(numGamesTotal <= 0) + throw StringError("-num-games must be positive"); + + cmd.getConfig(cfg); + modelFile = cmd.getModelFile(); + } + catch (TCLAP::ArgException &e) { + cerr << "Error: " << e.error() << " for argument " << e.argId() << endl; + return 1; + } + + Rand seedRand; + + const bool logToStdoutDefault = true; + Logger logger(&cfg, logToStdoutDefault); + logger.write("Selfplay surprise stats dump"); + logger.write("Model: " + modelFile); + + const int numGameThreads = cfg.getInt("numGameThreads",1,16384); + const string gameSeedBase = Global::uint64ToHexString(seedRand.nextUInt64()); + + const SearchParams baseParams = Setup::loadSingleParams(cfg,Setup::SETUP_FOR_OTHER); + const bool isDistributed = false; + PlaySettings playSettings = PlaySettings::loadForSelfplay(cfg, isDistributed); + if(reanalyzeAll) { + //Reanalyze every cheap-search position, so that every cheap-search row records both the cheap search's + //surprise stats (the ones that would drive reanalysis selection, preserved as origPolicySurprise and + //origValueSurprise) and the full search's stats, without any selection bias in which positions get both. + //Note that the post-reanalysis value surprise of a turn also absorbs the value changes of other reanalyzed + //turns after it, via the smoothed forward-outcome track, so unlike policy surprise it is not a pure + //cheap-vs-full comparison of this turn's search alone. + logger.write("Reanalyzing all cheap-search positions to record before and after surprise stats"); + playSettings.useReanalyze = true; + playSettings.reanalyzeProp = 1.0; + } + else { + //Force no reanalysis, so that every turn's recorded stats are those of the search the game actually played + //with - exactly the stats that would drive reanalysis selection - rather than partly overwritten by + //reanalysis searches. + if(playSettings.useReanalyze && playSettings.reanalyzeProp > 0.0) + logger.write("Config has reanalyzeProp > 0, forcing it to 0 so that recorded stats are the pre-reanalysis ones"); + playSettings.reanalyzeProp = 0.0; + } + + GameRunner* gameRunner = new GameRunner(cfg, playSettings, logger); + + const int minBoardXSizeUsed = gameRunner->getGameInitializer()->getMinBoardXSize(); + const int minBoardYSizeUsed = gameRunner->getGameInitializer()->getMinBoardYSize(); + const int maxBoardXSizeUsed = gameRunner->getGameInitializer()->getMaxBoardXSize(); + const int maxBoardYSizeUsed = gameRunner->getGameInitializer()->getMaxBoardYSize(); + + Setup::initializeSession(cfg); + NNEvaluator* nnEval; + { + const int expectedConcurrentEvals = cfg.getInt("numSearchThreads") * numGameThreads; + const bool defaultRequireExactNNLen = minBoardXSizeUsed == maxBoardXSizeUsed && minBoardYSizeUsed == maxBoardYSizeUsed; + const int defaultMaxBatchSize = -1; + const bool disableFP16 = false; + const string expectedSha256 = ""; + nnEval = Setup::initializeNNEvaluator( + modelFile,modelFile,expectedSha256,cfg,logger,seedRand,expectedConcurrentEvals, + maxBoardXSizeUsed,maxBoardYSizeUsed,defaultMaxBatchSize,defaultRequireExactNNLen,disableFP16, + Setup::SETUP_FOR_OTHER + ); + } + logger.write("Loaded neural net"); + + cfg.warnUnusedKeys(cerr,&logger); + + ofstream out; + FileUtils::open(out,outputFile); + out.precision(9); + out << "gameIdx,gameHash,xSize,ySize,komi,pdaWhite,numExtraBlack,mode,hitTurnLimit,gameNumMoves" + << ",outcomeWhiteWin,outcomeWhiteLoss,outcomeWhiteNoResult,outcomeWhiteScore" + << ",turnIdx,turnAfterStart,wasCheapSearch,unreducedNumVisits,targetWeight" + << ",policySurprise,valueSurprise,policyEntropy,searchEntropy" + << ",rawNNWhiteWinLoss,rawNNWhiteScoreMean,mctsWhiteWin,mctsWhiteLoss,mctsWhiteNoResult,mctsWhiteScore" + << ",wasReanalyzed,origPolicySurprise,origValueSurprise,origNumVisits" + << "\n"; + + if(!std::atomic_is_lock_free(&sigReceived)) + throw StringError("sigReceived is not lock free, signal-quitting mechanism will NOT work!"); + std::signal(SIGINT, signalHandler); + std::signal(SIGTERM, signalHandler); + + std::mutex writeMutex; + std::atomic numGamesStarted(0); + int64_t numGamesWritten = 0; + ForkData* forkData = new ForkData(); + + auto gameLoop = [ + &gameRunner,&logger,&numGamesStarted,&forkData,numGamesTotal,&baseParams,&gameSeedBase, + &nnEval,&writeMutex,&out,&numGamesWritten + ](int threadIdx) { + (void)threadIdx; + auto shouldStopFunc = []() noexcept { + return sigReceived.load(); + }; + Rand thisLoopSeedRand; + while(true) { + if(sigReceived.load()) + break; + int64_t gameIdx = numGamesStarted.fetch_add(1,std::memory_order_acq_rel); + if(gameIdx >= numGamesTotal) + break; + + MatchPairer::BotSpec botSpec; + botSpec.botIdx = 0; + botSpec.botName = nnEval->getModelName(); + botSpec.nnEval = nnEval; + botSpec.baseParams = baseParams; + + string seed = gameSeedBase + ":" + Global::uint64ToHexString(thisLoopSeedRand.nextUInt64()); + FinishedGameData* gameData = gameRunner->runGame( + seed, botSpec, botSpec, forkData, NULL, logger, + shouldStopFunc, nullptr, nullptr, nullptr, nullptr + ); + //Happens when interrupted by the signal handler mid-game + if(gameData == NULL) + break; + + { + std::lock_guard lock(writeMutex); + writeSurpriseStatsRows(out, gameIdx, *gameData); + out.flush(); + numGamesWritten += 1; + logger.write( + "Finished game " + Global::int64ToString(gameIdx) + " (" + + Global::int64ToString(numGamesWritten) + "/" + Global::int64ToString(numGamesTotal) + " written)" + ); + } + delete gameData; + } + }; + + vector threads; + for(int i = 0; i& args) { Tests::runBoardAreaTests(); Tests::runRulesTests(); + Tests::runPassAliveSuicideModeTests(); Tests::runBoardUndoTest(); Tests::runBoardHandicapTest(); @@ -78,6 +79,7 @@ int MainCmds::runoutputtests(const vector& args) { Tests::runNNInputsV3V4Tests(); Tests::runNNLessSearchTests(); Tests::runTrainingWriteTests(); + Tests::runPassAliveSuicideGameTests(); Tests::runTimeControlsTests(); Tests::runScoreTests(); Tests::runNNSymmetryTests(); @@ -543,7 +545,7 @@ int MainCmds::runbeginsearchspeedtest(const vector& args) { Player nextPla = P_BLACK; rules.komi = 6.5; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); bot->setPosition(nextPla,board,hist); @@ -667,7 +669,7 @@ int MainCmds::runownershipspeedtest(const vector& args) { Player nextPla = P_BLACK; rules.komi = 7.0; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); bot->setPosition(nextPla,board,hist); bot->setAlwaysIncludeOwnerMap(true); diff --git a/cpp/command/sandbox.cpp b/cpp/command/sandbox.cpp index 4b82a57189..a8dbc358c5 100644 --- a/cpp/command/sandbox.cpp +++ b/cpp/command/sandbox.cpp @@ -197,7 +197,7 @@ using namespace std; #include #include -#include "onnx/onnx_pb.h" +#include "onnx.pb.h" namespace { // Minimal TensorRT logger for the smoke test. diff --git a/cpp/command/selfplay.cpp b/cpp/command/selfplay.cpp index 50ffe3129a..cea2cf20b6 100644 --- a/cpp/command/selfplay.cpp +++ b/cpp/command/selfplay.cpp @@ -3,6 +3,7 @@ #include "../core/fileutils.h" #include "../core/makedir.h" #include "../core/config_parser.h" +#include "../core/timer.h" #include "../dataio/sgf.h" #include "../dataio/trainingwrite.h" #include "../dataio/loadmodel.h" @@ -128,6 +129,9 @@ int MainCmds::selfplay(const vector& args) { if(!logger.isLoggingToStdout()) cout << "Loaded all config stuff, starting self play" << endl; + //Time the whole self-play run for reporting overall computational throughput. + ClockTimer selfplayTimer; + if(!std::atomic_is_lock_free(&shouldStop)) throw StringError("shouldStop is not lock free, signal-quitting mechanism for terminating matches will NOT work!"); std::signal(SIGINT, signalHandler); @@ -380,6 +384,10 @@ int MainCmds::selfplay(const vector& args) { //At this point, nothing else except possibly data write loops are running, within the selfplay manager. delete manager; + //Overall self-play totals (per-model NN/data/moves breakdowns are logged above by the manager). + logger.write("Total games: " + Global::int64ToString(numGamesStarted.load(std::memory_order_relaxed))); + logger.write("Total selfplay runtime (seconds): " + Global::doubleToString(selfplayTimer.getSeconds())); + //Delete and clean up everything else NeuralNet::globalCleanup(); delete forkData; diff --git a/cpp/command/startposes.cpp b/cpp/command/startposes.cpp index d082998de8..d79a323ecd 100644 --- a/cpp/command/startposes.cpp +++ b/cpp/command/startposes.cpp @@ -440,7 +440,8 @@ int MainCmds::samplesgfs(const vector& args) { Player nextPla; BoardHistory hist; Rules rules = compactSgf.getRulesOrFailAllowUnspecified(Rules::getSimpleTerritory()); - compactSgf.setupInitialBoardAndHist(rules, board, nextPla, hist); + //Featurize per the model's own declaration (no user-level search params in this mode). + compactSgf.setupInitialBoardAndHist(rules, board, nextPla, hist, valueFluctuationNNEval->modelPreferPassAliveUnderSuicideRules()); if(valueFluctuationMakeKomiFair) { Rand rand; @@ -1393,7 +1394,8 @@ int MainCmds::dataminesgfs(const vector& args) { Board board; Player nextPla; BoardHistory hist; - sgf.setupInitialBoardAndHist(rules, board, nextPla, hist); + //Keep pass-alive computations and featurization consistent with how the search performs them. + sgf.setupInitialBoardAndHist(rules, board, nextPla, hist, search->getRootHist().alwaysComputePassAliveUnderSuicideRules); if(!gameInit->isAllowedBSize(board.x_size,board.y_size)) { numFilteredSgfs.fetch_add(1); return; @@ -1687,7 +1689,8 @@ int MainCmds::dataminesgfs(const vector& args) { //Now play the rest of the moves out, except the last, which we keep as the potential hintloc int encorePhase = 0; Player pla = sample.nextPla; - BoardHistory hist(board,pla,rules,encorePhase); + //Keep pass-alive computations and featurization consistent with how the search performs them. + BoardHistory hist(board,pla,rules,encorePhase,search->getRootHist().alwaysComputePassAliveUnderSuicideRules); int numSampleMoves = (int)sample.moves.size(); for(int i = 0; i& args) { for(const Rules& rules: rulesToUse) { Player nextPla; BoardHistory histBefore; - bool suc = priorPosSample.tryGetCurrentBoardHistory(rules,nextPla,histBefore); + //Featurize per the model's own declaration (this command has no search params to consult). + bool suc = priorPosSample.tryGetCurrentBoardHistory(rules,nextPla,histBefore,nnEval->modelPreferPassAliveUnderSuicideRules()); if(!suc) { logger.write("WARNING: unable to get current history for pos, skipping: " + Sgf::PositionSample::toJsonLine(priorPosSample)); continue; diff --git a/cpp/command/writetrainingdata.cpp b/cpp/command/writetrainingdata.cpp index 3ee88be3a4..cfca0b31ac 100644 --- a/cpp/command/writetrainingdata.cpp +++ b/cpp/command/writetrainingdata.cpp @@ -721,6 +721,11 @@ int MainCmds::writetrainingdata(const vector& args) { string searchRandSeed = Global::uint64ToString(seedRand.nextUInt64()); SearchParams params = SearchParams::basicDecentParams(); + //Pass-alive computation mode, applied uniformly to game replay/adjudication, featurization, + //training targets, and the searches below. Auto resolves to the model's declared preference. + if(cfg.contains("alwaysComputePassAliveUnderSuicideRules")) + params.alwaysComputePassAliveUnderSuicideRules = cfg.getEnabled("alwaysComputePassAliveUnderSuicideRules"); + const bool alwaysComputePassAliveUnderSuicideRules = Search::resolveAlwaysComputePassAliveUnderSuicideRules(params, nnEval); params.maxVisits = maxVisits; params.chosenMoveTemperatureEarly = 0.1; params.chosenMoveTemperature = 0.1; @@ -1377,7 +1382,9 @@ int MainCmds::writetrainingdata(const vector& args) { Player nextPla; BoardHistory hist; try { - sgf->setupInitialBoardAndHist(rules, board, nextPla, hist); + //Set up before replaying so game replay/adjudication, featurization, and targets are all uniform + //with each other and with the searches (whose setPosition resolves to the same value from params). + sgf->setupInitialBoardAndHist(rules, board, nextPla, hist, alwaysComputePassAliveUnderSuicideRules); } catch(const StringError& e) { logger.write("Bad initial setup in sgf " + fileName + " " + e.what()); @@ -2098,7 +2105,7 @@ int MainCmds::writetrainingdata(const vector& args) { // Ownership stuff! hasOwnershipTargets = true; hists[hists.size()-1].endAndScoreGameNow(board,finalOwnership); - board.calculateArea(finalFullArea, true, true, true, hist.rules.multiStoneSuicideLegal); + board.calculateArea(finalFullArea, true, true, true, hist.suicideLegalForPassAlive()); NNInputs::fillScoring(board,finalOwnership,hist.rules.taxRule == Rules::TAX_ALL,finalWhiteScoring); // Make sure KataGo didn't leave huge unscored regions due to passing weirdness, and make sure the scoring agrees with diff --git a/cpp/configs/analysis_example.cfg b/cpp/configs/analysis_example.cfg index d78378990d..4aed2f4f85 100644 --- a/cpp/configs/analysis_example.cfg +++ b/cpp/configs/analysis_example.cfg @@ -179,6 +179,10 @@ nnRandomize = true # TENSORRT GPU settings-------------------------------------- # These only apply when using the TENSORRT version of KataGo. +# Transformer trunks use NHWC by default, which is normally faster. Set this to false only after benchmarking +# the particular GPU and TensorRT version if you think NCHW is faster. +# trtTransformerNHWC = true + # IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 # trtDeviceToUse = 0 @@ -219,7 +223,9 @@ nnRandomize = true # cudaUseNHWC = auto -# Metal GPU settings-------------------------------------- +# ------------------------------ +# Metal GPU settings +# ------------------------------ # These only apply when using the METAL version of KataGo. # Metal backend dispatch is configured via numNNServerThreadsPerModel and metalDeviceToUseThread. @@ -255,31 +261,6 @@ nnRandomize = true # metalUseFP16 = true -# ROCm GPU settings-------------------------------------- -# These only apply when using the ROCm version of KataGo. - -# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 -# rocmDeviceToUse = 0 - -# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 - -# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 -# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 - -# You can probably guess the pattern if you have four, five, etc. GPUs. - -# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you -# want to try to force a particular behavior though you can uncomment these lines and change them -# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using -# FP16 but you think it should. -# rocmUseFP16 = auto -# ROCm does not support NHWC, so this is always false. - - # OpenCL-specific GPU settings-------------------------------------- # These only apply when using the OpenCL version of KataGo. @@ -314,34 +295,6 @@ nnRandomize = true # openclUseFP16 = auto -# ONNX Runtime settings-------------------------------------- -# These only apply when using the ONNX version of KataGo. - -# Execution provider: cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only) -# onnxProvider = openvino - -# Multi-device assignment is mainly for onnxProvider = cuda / tensorrt / migraphx: -# onnxDeviceToUse = 0 -# onnxDeviceToUseThread0 = 0 -# onnxDeviceToUseThread1 = 1 - -# OpenVINO EP options for Intel NPU (typically single device): -# onnxOpenVINODeviceType = NPU -# onnxOpenVINODeviceId = 0 -# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build -# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache - -# Optional overrides for raw .onnx I/O tensor names and model version: -# onnxInputSpatial = input_spatial -# onnxInputGlobal = input_global -# onnxInputMeta = input_meta -# onnxOutputPolicy = out_policy -# onnxOutputValue = out_value -# onnxOutputMiscvalue = out_miscvalue -# onnxOutputOwnership = out_ownership -# onnxModelVersion = 15 - - # Eigen-specific settings-------------------------------------- # These only apply when using the Eigen (pure CPU) version of KataGo. diff --git a/cpp/configs/contribute_example.cfg b/cpp/configs/contribute_example.cfg index ecaac3057e..6ca039f112 100644 --- a/cpp/configs/contribute_example.cfg +++ b/cpp/configs/contribute_example.cfg @@ -83,8 +83,9 @@ watchOngoingGameInFileName = watchgame.txt # cudaUseNHWC = auto -# Metal GPU settings-------------------------------------- - +# ------------------------------ +# Metal GPU settings +# ------------------------------ # These only apply when using the METAL version of KataGo. # For one Metal instance: KataGo will automatically use the default device. @@ -98,31 +99,6 @@ watchOngoingGameInFileName = watchgame.txt # The pattern continues for additional Metal instances. -# ROCm GPU settings-------------------------------------- -# These only apply when using the ROCm version of KataGo. - -# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 -# rocmDeviceToUse = 0 - -# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 - -# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 -# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 - -# You can probably guess the pattern if you have four, five, etc. GPUs. - -# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you -# want to try to force a particular behavior though you can uncomment these lines and change them -# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using -# FP16 but you think it should. -# rocmUseFP16 = auto -# ROCm does not support NHWC, so this is always false. - - # OpenCL GPU settings-------------------------------------- # These only apply when using the OpenCL version of KataGo. @@ -157,34 +133,6 @@ watchOngoingGameInFileName = watchgame.txt # openclUseFP16 = auto -# ONNX Runtime settings-------------------------------------- -# These only apply when using the ONNX version of KataGo. - -# Execution provider: cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only) -# onnxProvider = openvino - -# Multi-device assignment (for onnxProvider = cuda / tensorrt / migraphx): -# onnxDeviceToUse = 0 -# onnxDeviceToUseThread0 = 0 -# onnxDeviceToUseThread1 = 1 - -# OpenVINO EP options for Intel NPU (typically single device): -# onnxOpenVINODeviceType = NPU -# onnxOpenVINODeviceId = 0 -# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build -# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache - -# Optional overrides for raw .onnx I/O tensor names and model version: -# onnxInputSpatial = input_spatial -# onnxInputGlobal = input_global -# onnxInputMeta = input_meta -# onnxOutputPolicy = out_policy -# onnxOutputValue = out_value -# onnxOutputMiscvalue = out_miscvalue -# onnxOutputOwnership = out_ownership -# onnxModelVersion = 15 - - # Eigen-specific settings-------------------------------------- # These only apply when using the Eigen (pure CPU) version of KataGo. diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index d3ee64a823..7c3a8f8341 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -410,6 +410,10 @@ searchFactorWhenWinningThreshold = 0.95 # ------------------------------ # These only apply when using the TENSORRT version of KataGo. +# Transformer trunks use NHWC by default, which is normally faster. Set this to false only after benchmarking +# the particular GPU and TensorRT version if you think NCHW is faster. +# trtTransformerNHWC = true + # For one GPU: optionally uncomment this option and change if the GPU to # use is not device 0. # trtDeviceToUse = 0 @@ -458,9 +462,9 @@ searchFactorWhenWinningThreshold = 0.95 # "auto" (default) uses the GEMM only in FP16, where it is slightly faster. # cudaUse1x1Matmul = auto - -# Metal GPU settings-------------------------------------- - +# ------------------------------ +# Metal GPU settings +# ------------------------------ # These only apply when using the METAL version of KataGo. # Metal backend dispatch is configured via numNNServerThreadsPerModel and metalDeviceToUseThread. @@ -495,32 +499,6 @@ searchFactorWhenWinningThreshold = 0.95 # inference but much slower than the GPU path. # metalUseFP16 = true - -# ROCm GPU settings-------------------------------------- -# These only apply when using the ROCm version of KataGo. - -# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 -# rocmDeviceToUse = 0 - -# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 - -# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 -# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 - -# You can probably guess the pattern if you have four, five, etc. GPUs. - -# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you -# want to try to force a particular behavior though you can uncomment these lines and change them -# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using -# FP16 but you think it should. -# rocmUseFP16 = auto -# ROCm does not support NHWC, so this is always false. - - # ------------------------------ # OpenCL GPU settings # ------------------------------ @@ -568,69 +546,6 @@ searchFactorWhenWinningThreshold = 0.95 # Default: numSearchThreads # numEigenThreadsPerModel = X -# ------------------------------ -# ONNX backend settings -# ------------------------------ -# These only apply when using the ONNX version of KataGo (USE_BACKEND=ONNX). This backend reuses -# the same ONNX graph emitter as the TensorRT backend, so its .bin.gz model support and IO protocol -# are identical to TensorRT; only the runtime differs. It also supports loading a raw .onnx file -# directly (see onnxInput*/onnxOutput* below). - -# Execution provider. One of: -# cpu (default), cuda, tensorrt, migraphx, vitisai, coreml (macOS only). -# Use "vitisai" for AMD Ryzen AI NPU. -# onnxProvider = cpu - -# Provider-specific device selection (mostly for cuda / tensorrt / migraphx). -# onnxDeviceToUse = 0 -# onnxDeviceToUseThread0 = 0 -# onnxDeviceToUseThread1 = 1 - -# NOTE: the ONNX backend does not support the global useFP16 flag used by other backends. Setting -# "useFP16 = true" fails with an error, since ONNX Runtime execution providers decide inference -# precision themselves. Leave useFP16 unset/auto. - -# Skip the scale8 FP16-range workaround (default false = apply it). scale8 keeps convnet -# activations 8x smaller so they stay inside typical FP16 execution-provider ranges; the cost is -# MISH_SCALE8 subgraphs that can block fused-Mish optimizations on some providers. Keep off/default; -# set true only for FP32 precision or workloads where FP16 overflow is not a practical risk. Forced -# to false for -contribute (distributed selfplay) regardless of this setting, since contributed -# training data must never contain FP16-overflow NaNs. -# onnxSkipScale8 = false - -# Run the trunk block stack channel-last (NHWC) for transformer models. Default true (NHWC, -# matching the TensorRT backend). Only takes effect for models with transformer blocks; convnets -# ignore this. -# onnxTransformerNHWC = true - -# VitisAI EP options (only used when onnxProvider = vitisai; AMD Ryzen AI / VitisAI NPU): -# Path to vaip_config.json, shipped with the AMD Ryzen AI SDK. A default is baked in at build time -# if a Ryzen AI installation was auto-detected; otherwise this is required. -# onnxVitisAIConfigFile = C:\\Program Files\\RyzenAI\\\\voe-...\\vaip_config.json -# Cache directory for the compiled NPU model, so the (slow, minutes-long) compile only happens -# once per model instead of on every process launch. Defaults to a "vitisaicache" subdir of -# katagodata (homeDataDir) if unset. -# onnxVitisAICacheDir = C:\\temp\\katago_vitisai_cache -# Fail hard at session-creation time if any graph node can't run on the NPU, instead of silently -# falling back to CPU for that node (default true). -# onnxVitisAIDisableCPUFallback = true - -# Override input/output tensor names -- only needed for raw .onnx models using non-default names. -# Defaults match the names emitted by KataGo's ONNX graph builder (also used by the TensorRT -# backend's ONNX path). -# onnxInputMask = InputMask -# onnxInputSpatial = InputSpatial -# onnxInputGlobal = InputGlobal -# onnxInputMeta = InputMeta -# onnxOutputPolicyPass = OutputPolicyPass -# onnxOutputPolicy = OutputPolicy -# onnxOutputValue = OutputValue -# onnxOutputMiscvalue = OutputScoreValue -# onnxOutputOwnership = OutputOwnership - -# Override auto-detected model version for raw .onnx model files. -# onnxModelVersion = 15 - # =========================================================================== # Root move selection and biases # =========================================================================== diff --git a/cpp/configs/match_example.cfg b/cpp/configs/match_example.cfg index 11b271ef08..7e5b4fc09f 100644 --- a/cpp/configs/match_example.cfg +++ b/cpp/configs/match_example.cfg @@ -156,8 +156,9 @@ numNNServerThreadsPerModel = 1 # cudaUseNHWC = auto -# Metal GPU settings-------------------------------------- - +# ------------------------------ +# Metal GPU settings +# ------------------------------ # These only apply when using the METAL version of KataGo. # For one Metal instance: KataGo will automatically use the default device. @@ -171,31 +172,6 @@ numNNServerThreadsPerModel = 1 # The pattern continues for additional Metal instances. -# ROCm GPU settings-------------------------------------- -# These only apply when using the ROCm version of KataGo. - -# IF USING ONE GPU: optionally uncomment and change this if the GPU you want to use turns out to be not device 0 -# rocmDeviceToUse = 0 - -# IF USING TWO GPUS: Uncomment these two lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 - -# IF USING THREE GPUS: Uncomment these three lines (AND set numNNServerThreadsPerModel above): -# rocmDeviceToUseThread0 = 0 # change this if the first GPU you want to use turns out to be not device 0 -# rocmDeviceToUseThread1 = 1 # change this if the second GPU you want to use turns out to be not device 1 -# rocmDeviceToUseThread2 = 2 # change this if the third GPU you want to use turns out to be not device 2 - -# You can probably guess the pattern if you have four, five, etc. GPUs. - -# KataGo will automatically use FP16 or not based on the compute capability of your AMD GPU. If you -# want to try to force a particular behavior though you can uncomment these lines and change them -# to "true" or "false". E.g. it's using FP16 but on your card that's giving an error, or it's not using -# FP16 but you think it should. -# rocmUseFP16 = auto -# ROCm does not support NHWC, so this is always false. - - # OpenCL GPU settings-------------------------------------- # These only apply when using OpenCL as the backend for inference. # (For GTP, we only ever have one model, when playing matches, we might have more than one, see match_example.cfg) @@ -214,36 +190,6 @@ numNNServerThreadsPerModel = 1 # openclUseFP16 = auto -# ONNX Runtime settings-------------------------------------- -# These only apply when using the ONNX version of KataGo. - -# Execution provider: cpu (default), openvino, cuda, tensorrt, migraphx, coreml(macOS only) -# onnxProvider = openvino - -# Multi-device assignment is mainly for onnxProvider = cuda / tensorrt / migraphx: -# onnxDeviceToUse = 0 -# onnxDeviceToUseModel0 = 0 -# onnxDeviceToUseModel1 = 1 -# onnxDeviceToUseModel0Thread0 = 0 -# onnxDeviceToUseModel0Thread1 = 1 - -# OpenVINO EP options for Intel NPU (typically single device): -# onnxOpenVINODeviceType = NPU -# onnxOpenVINODeviceId = 0 -# onnxOpenVINOEnableNPUFastCompile = true # may be ignored if unsupported by your ORT/OpenVINO build -# onnxOpenVINOCacheDir = C:\\temp\\katago_ov_cache - -# Optional overrides for raw .onnx I/O tensor names and model version: -# onnxInputSpatial = input_spatial -# onnxInputGlobal = input_global -# onnxInputMeta = input_meta -# onnxOutputPolicy = out_policy -# onnxOutputValue = out_value -# onnxOutputMiscvalue = out_miscvalue -# onnxOutputOwnership = out_ownership -# onnxModelVersion = 15 - - # Eigen-specific settings-------------------------------------- # These only apply when using the Eigen (pure CPU) version of KataGo. diff --git a/cpp/dataio/loadmodel.cpp b/cpp/dataio/loadmodel.cpp index 8cb02b3eff..7a78b44460 100644 --- a/cpp/dataio/loadmodel.cpp +++ b/cpp/dataio/loadmodel.cpp @@ -20,34 +20,30 @@ std::time_t to_time_t(TP tp) static const vector ACCEPTABLE_MODEL_SUFFIXES { ".bin.gz", ".bin", - ".onnx", "model.txt.gz", "model.txt" }; static const vector GENERIC_MODEL_NAMES { "model.bin.gz", "model.bin", - "model.onnx", "model.txt.gz", - "model.txt", + "model.txt" "Model.bin.gz", "Model.bin", - "Model.onnx", "Model.txt.gz", - "Model.txt", + "Model.txt" "MODEL.bin.gz", "MODEL.bin", - "MODEL.onnx", "MODEL.txt.gz", - "MODEL.txt", + "MODEL.txt" "model.ckpt", - "Model.ckpt", + "Model.ckpt" "MODEL.ckpt", "model.checkpoint", - "Model.checkpoint", + "Model.checkpoint" "MODEL.checkpoint", "model", - "Model", + "Model" "MODEL", }; @@ -119,8 +115,7 @@ void LoadModel::deleteModelsOlderThan(const string& modelsDir, Logger& logger, c if(Global::isSuffix(filePathStr,".bin.gz") || Global::isSuffix(filePathStr,".txt.gz") || Global::isSuffix(filePathStr,".bin") || - Global::isSuffix(filePathStr,".txt") || - Global::isSuffix(filePathStr,".onnx")) { + Global::isSuffix(filePathStr,".txt")) { time_t thisTime = to_time_t(gfs::last_write_time(filePath)); if(thisTime < time) { pathsToRemove.push_back(filePath); diff --git a/cpp/dataio/sgf.cpp b/cpp/dataio/sgf.cpp index ae601d68cd..8f36432cfb 100644 --- a/cpp/dataio/sgf.cpp +++ b/cpp/dataio/sgf.cpp @@ -786,7 +786,7 @@ void Sgf::iterAllUniquePositions( Rules rules = Rules::getTrompTaylorish(); rules.koRule = Rules::KO_SITUATIONAL; rules.multiStoneSuicideLegal = true; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PositionSample sampleBuf; std::vector> variationTraceNodesBranch; @@ -814,7 +814,7 @@ void Sgf::iterAllPositions( Rules rules = Rules::getTrompTaylorish(); rules.koRule = Rules::KO_SITUATIONAL; rules.multiStoneSuicideLegal = true; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PositionSample sampleBuf; std::vector> variationTraceNodesBranch; @@ -1276,10 +1276,11 @@ Sgf::PositionSample Sgf::PositionSample::previousPosition(double newWeight) cons return other; } -bool Sgf::PositionSample::tryGetCurrentBoardHistory(const Rules& rules, Player& nextPlaToMove, BoardHistory& hist) const { +bool Sgf::PositionSample::tryGetCurrentBoardHistory(const Rules& rules, Player& nextPlaToMove, BoardHistory& hist, bool alwaysComputePassAliveUnderSuicideRules) const { int encorePhase = 0; Player pla = nextPla; Board boardCopy = board; + hist.setAlwaysComputePassAliveUnderSuicideRules(alwaysComputePassAliveUnderSuicideRules); hist.clear(boardCopy,pla,rules,encorePhase); int numSampleMoves = (int)moves.size(); for(int i = 0; ipolicyTargetsByTurn.size()) { + bool wasReanalyzed = + turnAfterStart < gameData->reanalysisByTurn.size() && gameData->reanalysisByTurn[turnAfterStart].wasReanalyzed; char visitsBuf[32]; - sprintf(visitsBuf,"%d",(int)(gameData->policyTargetsByTurn[turnAfterStart].unreducedNumVisits)); if(comment.length() > 0) comment += " "; - comment += "v="; - comment += visitsBuf; + if(wasReanalyzed) { + //The move was chosen by the original cheap search, whose visits we report as v=, but the recorded + //targets and stats come from the post-game reanalysis search, whose visits we report as rv=. + sprintf(visitsBuf,"%d",(int)(gameData->reanalysisByTurn[turnAfterStart].originalNumVisits)); + comment += "v="; + comment += visitsBuf; + sprintf(visitsBuf,"%d",(int)(gameData->policyTargetsByTurn[turnAfterStart].unreducedNumVisits)); + comment += " rv="; + comment += visitsBuf; + } + else { + sprintf(visitsBuf,"%d",(int)(gameData->policyTargetsByTurn[turnAfterStart].unreducedNumVisits)); + comment += "v="; + comment += visitsBuf; + } } if(turnAfterStart < gameData->targetWeightByTurnUnrounded.size()) { char weightBuf[32]; diff --git a/cpp/dataio/sgf.h b/cpp/dataio/sgf.h index 2cd845bbcd..acfc3d9f63 100644 --- a/cpp/dataio/sgf.h +++ b/cpp/dataio/sgf.h @@ -132,7 +132,7 @@ struct Sgf { Sgf::PositionSample previousPosition(double newWeight) const; bool hasPreviousPositions(int numPrevious) const; - bool tryGetCurrentBoardHistory(const Rules& rules, Player& nextPlaToMove, BoardHistory& hist) const; + bool tryGetCurrentBoardHistory(const Rules& rules, Player& nextPlaToMove, BoardHistory& hist, bool alwaysComputePassAliveUnderSuicideRules) const; int64_t getCurrentTurnNumber() const; @@ -247,12 +247,12 @@ struct CompactSgf { Rules getRulesOrFailAllowUnspecified(const Rules& defaultRules) const; Rules getRulesOrWarn(const Rules& defaultRules, const std::function& f) const; - void setupInitialBoardAndHist(const Rules& initialRules, Board& board, Player& nextPla, BoardHistory& hist) const; + void setupInitialBoardAndHist(const Rules& initialRules, Board& board, Player& nextPla, BoardHistory& hist, bool alwaysComputePassAliveUnderSuicideRules) const; void playMovesAssumeLegal(Board& board, Player& nextPla, BoardHistory& hist, int64_t turnIdx) const; - void setupBoardAndHistAssumeLegal(const Rules& initialRules, Board& board, Player& nextPla, BoardHistory& hist, int64_t turnIdx) const; + void setupBoardAndHistAssumeLegal(const Rules& initialRules, Board& board, Player& nextPla, BoardHistory& hist, int64_t turnIdx, bool alwaysComputePassAliveUnderSuicideRules) const; //These throw a StringError upon illegal move. void playMovesTolerant(Board& board, Player& nextPla, BoardHistory& hist, int64_t turnIdx, bool preventEncore) const; - void setupBoardAndHistTolerant(const Rules& initialRules, Board& board, Player& nextPla, BoardHistory& hist, int64_t turnIdx, bool preventEncore) const; + void setupBoardAndHistTolerant(const Rules& initialRules, Board& board, Player& nextPla, BoardHistory& hist, int64_t turnIdx, bool preventEncore, bool alwaysComputePassAliveUnderSuicideRules) const; }; namespace WriteSgf { diff --git a/cpp/dataio/trainingwrite.cpp b/cpp/dataio/trainingwrite.cpp index 66e8f95c1a..56e55d6ee1 100644 --- a/cpp/dataio/trainingwrite.cpp +++ b/cpp/dataio/trainingwrite.cpp @@ -90,6 +90,7 @@ FinishedGameData::FinishedGameData() whiteValueTargetsByTurn(), whiteQValueTargetsByTurn(), nnRawStatsByTurn(), + reanalysisByTurn(), finalFullArea(NULL), finalOwnership(NULL), finalSekiAreas(NULL), @@ -186,6 +187,17 @@ void FinishedGameData::printDebug(ostream& out) const { for(int i = 0; i 7) @@ -674,9 +687,25 @@ void TrainingWriteBuffers::addRow( rowGlobal[62] = (!isSidePosition && actualGameEndHist.isGameFinished && !hitTurnLimit) ? 1.0f : 0.0f; //Version - rowGlobal[63] = 2.0f; + rowGlobal[63] = 3.0f; + + //Reanalysis info - whether this position originally got only a cheap search and was redone with a full + //search after the game, and if so, the original cheap search's surprise stats that drove its selection + //and its visit count. + rowGlobal[64] = reanalysisData.wasReanalyzed ? 1.0f : 0.0f; + rowGlobal[65] = reanalysisData.wasReanalyzed ? reanalysisData.selectionPolicySurprise : 0.0f; + rowGlobal[66] = reanalysisData.wasReanalyzed ? reanalysisData.selectionValueSurprise : 0.0f; + rowGlobal[67] = reanalysisData.wasReanalyzed ? (float)reanalysisData.originalNumVisits : 0.0f; + + //Whether pass-alive areas for this game's adjudication and featurization were being computed as if + //multi-stone suicide were always legal regardless of the actual suicide rule. + rowGlobal[68] = hist.alwaysComputePassAliveUnderSuicideRules ? 1.0f : 0.0f; + + //Unused + for(int i = 69; i<80; i++) + rowGlobal[i] = 0.0f; - testAssert(64 == GLOBAL_TARGET_NUM_CHANNELS); + testAssert(80 == GLOBAL_TARGET_NUM_CHANNELS); int scoreDistrLen = posArea*2 + NNPos::EXTRA_SCORE_DISTR_RADIUS*2; int scoreDistrMid = posArea + NNPos::EXTRA_SCORE_DISTR_RADIUS; @@ -1027,6 +1056,9 @@ bool TrainingDataWriter::isEmpty() const { int64_t TrainingDataWriter::numRowsInBuffer() const { return writeBuffers->curRows; } +int64_t TrainingDataWriter::numRowsWritten() const { + return rowCount.load(std::memory_order_relaxed); +} void TrainingDataWriter::writeAndClearIfFull() { if(writeBuffers->curRows >= writeBuffers->maxRows || (isFirstFile && writeBuffers->curRows >= firstFileMaxRows)) { @@ -1076,6 +1108,7 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { testAssert(data.whiteValueTargetsByTurn.size() == numMoves+1); testAssert(data.whiteQValueTargetsByTurn.size() == numMoves); testAssert(data.nnRawStatsByTurn.size() == numMoves); + testAssert(data.reanalysisByTurn.size() == numMoves || data.reanalysisByTurn.size() == 0); //Some sanity checks { @@ -1140,17 +1173,35 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { float tdValueTargetWeight = 1.0f; float leadTargetWeightFactor = 1.0f; + ReanalysisData reanalysisData; + if(turnAfterStart < data.reanalysisByTurn.size()) + reanalysisData = data.reanalysisByTurn[turnAfterStart]; + int numNeuralNetsBehindLatest = 0; - for(int i = 0; iturnIdx > turnIdx) { - numNeuralNetsBehindLatest = (int)data.changedNeuralNets.size()-i; - break; + if(reanalysisData.wasReanalyzed) { + //Reanalysis searches happen after the game ends, so they use the net as of their creation rather than the net at this turn. + numNeuralNetsBehindLatest = (int)data.changedNeuralNets.size() - reanalysisData.numNeuralNetChangesSoFar; + } + else { + for(int i = 0; iturnIdx > turnIdx) { + numNeuralNetsBehindLatest = (int)data.changedNeuralNets.size()-i; + break; + } } } + //If this position was reanalyzed and we're not using outcome targets for reanalyzed positions, then skip + //the targets derived from the final board and the actual game continuation (ownership, final score, + //future board positions, and the next-move policy target, which comes from the next turn's search along + //the continuation the reanalysis search may not prefer). The value targets are still computed from the + //game's value target array as normal - the entry at this turn is the reanalysis search's values, and + //later turns and past positions read that array too. + bool skipOutcomeDerivedTargets = reanalysisData.wasReanalyzed && !reanalysisData.usedOutcomeTargets; + while(targetWeight > 0.0) { if(targetWeight >= 1.0 || rand.nextBool(targetWeight)) { - if(debugOut == NULL || rowCount % debugOnlyWriteEvery == 0) { + if(debugOut == NULL || rowCount.load(std::memory_order_relaxed) % debugOnlyWriteEvery == 0) { writeBuffers->addRow( board,hist,nextPlayer, data.startHist, @@ -1159,7 +1210,7 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { (float)data.trainingWeight, unreducedNumVisits, policyTarget0, - policyTarget1, + skipOutcomeDerivedTargets ? NULL : policyTarget1, data.policySurpriseByTurn[turnAfterStart], data.policyEntropyByTurn[turnAfterStart], data.searchEntropyByTurn[turnAfterStart], @@ -1170,11 +1221,11 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { tdValueTargetWeight, leadTargetWeightFactor, data.nnRawStatsByTurn[turnAfterStart], - &(data.endHist.getRecentBoard(0)), - data.finalFullArea, - data.finalOwnership, - data.finalWhiteScoring, - &posHistForFutureBoards, + skipOutcomeDerivedTargets ? NULL : &(data.endHist.getRecentBoard(0)), + skipOutcomeDerivedTargets ? NULL : data.finalFullArea, + skipOutcomeDerivedTargets ? NULL : data.finalOwnership, + skipOutcomeDerivedTargets ? NULL : data.finalWhiteScoring, + skipOutcomeDerivedTargets ? NULL : &posHistForFutureBoards, isSidePosition, numNeuralNetsBehindLatest, data.drawEquivalentWinsForWhite, @@ -1186,11 +1237,12 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { data.numExtraBlack, data.mode, NULL, - rand + rand, + reanalysisData ); writeAndClearIfFull(); } - rowCount++; + rowCount.fetch_add(1, std::memory_order_relaxed); } targetWeight -= 1.0; } @@ -1212,7 +1264,7 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { double targetWeight = sp->targetWeight; while(targetWeight > 0.0) { if(targetWeight >= 1.0 || rand.nextBool(targetWeight)) { - if(debugOut == NULL || rowCount % debugOnlyWriteEvery == 0) { + if(debugOut == NULL || rowCount.load(std::memory_order_relaxed) % debugOnlyWriteEvery == 0) { int turnIdx = (int)sp->hist.moveHistory.size(); testAssert(turnIdx >= data.startHist.moveHistory.size()); @@ -1263,7 +1315,7 @@ void TrainingDataWriter::writeGame(const FinishedGameData& data) { ); writeAndClearIfFull(); } - rowCount++; + rowCount.fetch_add(1, std::memory_order_relaxed); } targetWeight -= 1.0; } diff --git a/cpp/dataio/trainingwrite.h b/cpp/dataio/trainingwrite.h index 253c132580..9fc0993269 100644 --- a/cpp/dataio/trainingwrite.h +++ b/cpp/dataio/trainingwrite.h @@ -1,6 +1,8 @@ #ifndef DATAIO_TRAINING_WRITE_H_ #define DATAIO_TRAINING_WRITE_H_ +#include + #include "../dataio/numpywrite.h" #include "../neuralnet/nninputs.h" #include "../neuralnet/sgfmetadata.h" @@ -38,6 +40,25 @@ struct NNRawStats { double policyEntropy; }; +//Info about the post-game reanalysis (full re-search) of a position that originally got only a cheap search. +struct ReanalysisData { + bool wasReanalyzed = false; + //If false, the targets derived from the final board and the actual game continuation (ownership, final + //score, future board positions, and the next-move policy target) are not recorded for this row. The value + //targets always come from the game's value target array, whose entry at this turn is the reanalysis + //search's values but whose later entries and final outcome still reflect the actual game. + bool usedOutcomeTargets = true; + //The policy surprise and value surprise of the original cheap search on this turn, which are the stats + //that drove the probability of this position being selected for reanalysis. The value surprise is computed + //by whichever definition was configured (see PlaySettings::useSearchValueSurprise). + float selectionPolicySurprise = 0.0f; + float selectionValueSurprise = 0.0f; + //The number of visits of the original cheap search, whose recorded targets were replaced. + int64_t originalNumVisits = 0; + //Number of neural net changes this game before this reanalysis search was performed. + int numNeuralNetChangesSoFar = 0; +}; + //A side position that was searched off the main line of the game, to give some data about an alternative move. struct SidePosition { Board board; @@ -103,6 +124,14 @@ struct FinishedGameData { std::vector whiteValueTargetsByTurn; //Except this one, we may have some of std::vector whiteQValueTargetsByTurn; std::vector nnRawStatsByTurn; + std::vector reanalysisByTurn; //May be empty if no reanalysis was configured + //Statistical info, not used for training targets. The value surprise of each turn as used for surprise-based + //data weighting (if reanalysis happened, recomputed afterward, so reanalyzed turns reflect the reanalysis + //search rather than the value surprise that drove their selection), and whether each turn's search during + //the game was a cheap search. + std::vector valueSurpriseByTurn; + std::vector wasCheapSearchByTurn; + Color* finalFullArea; Color* finalOwnership; bool* finalSekiAreas; @@ -222,8 +251,17 @@ struct TrainingWriteBuffers { //C59: Policy prior entropy //C60: Number of visits in the search generating this row, prior to any reduction. //C61: Number of bonus points the player to move will get onward from this point in the game. Reliable only if C27 and/or C62 (V2 and later), otherwise may make no sense. - //C62: V1: unused. V2: 1 if the game was finished and not a side position. - //C63: Data format version, currently always equals 2. + //C62: V1: unused. V2 and later: 1 if the game was finished and not a side position. + //C63: Data format version, currently always equals 3. Version 2 data had only 64 channels, ending here. + + //C64: 1 if this position originally got only a cheap search during the game and was reanalyzed with a full search + //after the game ended, generating this row. 0 for ordinary full-search rows and side position rows. + //C65: If C64, the policy surprise of the original cheap search (the reanalysis search's own policy surprise is in C30). + //C66: If C64, the value surprise of the original cheap search, by whichever value surprise definition was + //configured (see PlaySettings::useSearchValueSurprise). Both C65 and C66 are the stats that drove the + //probability of this position being selected for reanalysis, recorded for statistical purposes. + //C67: If C64, the number of visits of the original cheap search (the reanalysis search's visits are in C60). + //C68-79: Unused, zero-filled. NumpyBuffer globalTargetsNC; @@ -301,7 +339,8 @@ struct TrainingWriteBuffers { int numExtraBlack, int mode, SGFMetadata* sgfMeta, - Rand& rand + Rand& rand, + const ReanalysisData& reanalysisData = ReanalysisData() ); void writeToZipFile(const std::string& fileName); @@ -322,6 +361,9 @@ class TrainingDataWriter { bool isEmpty() const; int64_t numRowsInBuffer() const; + // Cumulative training rows added by this writer, including rows still in the buffer not yet flushed to file. + // Safe to call concurrently from other threads (e.g. for stats logging). + int64_t numRowsWritten() const; private: std::string outputDir; @@ -331,7 +373,9 @@ class TrainingDataWriter { std::ostream* debugOut; int debugOnlyWriteEvery; - int64_t rowCount; + // Atomic only so that numRowsWritten() can be read for stats from other threads; + // all mutation happens on the single thread using this writer. + std::atomic rowCount; bool isFirstFile; int firstFileMaxRows; diff --git a/cpp/external/katagocoreml/include/katagocoreml/KataGoConverter.hpp b/cpp/external/katagocoreml/include/katagocoreml/KataGoConverter.hpp index aea2c7def6..9f5d3b7282 100644 --- a/cpp/external/katagocoreml/include/katagocoreml/KataGoConverter.hpp +++ b/cpp/external/katagocoreml/include/katagocoreml/KataGoConverter.hpp @@ -42,6 +42,11 @@ class KataGoConverter { return version >= MIN_SUPPORTED_VERSION && version <= MAX_SUPPORTED_VERSION; } + /// True if converting with compute_precision="FLOAT16" would nonetheless build the model + /// fully in FP32 (narrow transformer trunks are demoted for accuracy). Lets callers report + /// the effective precision without performing a conversion. + static bool wouldBuildFullyFp32(int trunk_num_channels, bool has_transformer_blocks); + /// Get library version string static std::string getVersion() { return "1.1.0"; diff --git a/cpp/external/katagocoreml/src/Converter.cpp b/cpp/external/katagocoreml/src/Converter.cpp index cb6ca80d90..377ecaff73 100644 --- a/cpp/external/katagocoreml/src/Converter.cpp +++ b/cpp/external/katagocoreml/src/Converter.cpp @@ -29,9 +29,12 @@ void KataGoConverter::convert(const std::string& input_path, throw std::invalid_argument("max_batch_size must be >= min_batch_size or <= 0 for unlimited"); } - // Parse KataGo model - KataGoParser parser(input_path); - KataGoModelDesc model = parser.parse(); + // Parse KataGo model (parser + its decompressed buffer freed at end of scope) + KataGoModelDesc model; + { + KataGoParser parser(input_path); + model = parser.parse(); + } // Determine if using FP16 precision bool use_fp16 = (options.compute_precision == "FLOAT16"); @@ -52,12 +55,19 @@ void KataGoConverter::convert(const std::string& input_path, options.use_fp16_io); auto program = builder.build(); - // Get weights from builder - auto weights = builder.getWeights(); - std::vector weights_copy(weights.begin(), weights.end()); + // Serialize directly from the builder's weight views (no copy). + std::vector& weights = builder.getWeightsMutable(); // Update options with model metadata for serialization ConversionOptions final_options = options; + + // The builder may have demoted a narrow transformer trunk to full FP32; propagate the + // effective precision so the serialized Model description declares I/O dtypes matching + // the actual MIL function, and so the compute_precision metadata does not lie. + final_options.use_fp16_io = builder.getEffectiveUseFp16IO(); + if (use_fp16 && !builder.getEffectiveUseFp16()) { + final_options.compute_precision = "FLOAT32"; + } final_options.model_version = model.model_version; final_options.meta_encoder_version = model.meta_encoder_version; final_options.num_input_meta_channels = model.num_input_meta_channels; @@ -82,7 +92,11 @@ void KataGoConverter::convert(const std::string& input_path, // Serialize to .mlpackage CoreMLSerializer serializer(final_options.specification_version); - serializer.serialize(program.get(), weights_copy, output_path, final_options); + serializer.serialize(program.get(), weights, output_path, final_options); +} + +bool KataGoConverter::wouldBuildFullyFp32(int trunk_num_channels, bool has_transformer_blocks) { + return MILBuilder::wouldBuildFullyFp32(trunk_num_channels, has_transformer_blocks); } ModelInfo KataGoConverter::getModelInfo(const std::string& input_path) { diff --git a/cpp/external/katagocoreml/src/builder/MILBuilder.cpp b/cpp/external/katagocoreml/src/builder/MILBuilder.cpp index db0c6c4b1d..9540e54942 100644 --- a/cpp/external/katagocoreml/src/builder/MILBuilder.cpp +++ b/cpp/external/katagocoreml/src/builder/MILBuilder.cpp @@ -4,12 +4,46 @@ #include "MILBuilder.hpp" #include "MILBlob/Fp16.hpp" #include +#include // Include generated protobuf headers #include "MIL.pb.h" namespace katagocoreml { +namespace { +// RAII: set a dtype slot to FLOAT32 for the current scope and restore it on exit. Used to emit a +// sub-region of ops in FP32 inside an otherwise-FP16 model. +struct ScopedFp32 { + CoreML::Specification::MILSpec::DataType& slot; + CoreML::Specification::MILSpec::DataType saved; + explicit ScopedFp32(CoreML::Specification::MILSpec::DataType& s) + : slot(s), saved(s) { s = CoreML::Specification::MILSpec::DataType::FLOAT32; } + ~ScopedFp32() { slot = saved; } + ScopedFp32(const ScopedFp32&) = delete; + ScopedFp32& operator=(const ScopedFp32&) = delete; +}; + +// True if any block in this list is a transformer (attention/FFN), recursing into nested-bottleneck +// blocks (which can themselves contain transformer blocks). Used to scope the off-ANE FP32 +// escalations to transformer trunks only. +bool blocksContainTransformer(const std::vector& blocks) { + for (const auto& entry : blocks) { + if (entry.block_kind == TRANSFORMER_ATTENTION_BLOCK_KIND || + entry.block_kind == TRANSFORMER_FFN_BLOCK_KIND) { + return true; + } + if (entry.block_kind == NESTED_BOTTLENECK_BLOCK_KIND) { + const auto& nbt = std::get(*entry.block); + if (blocksContainTransformer(nbt.blocks)) { + return true; + } + } + } + return false; +} +} // namespace + MILBuilder::MILBuilder(const KataGoModelDesc& model, int board_x_size, int board_y_size, @@ -30,7 +64,41 @@ MILBuilder::MILBuilder(const KataGoModelDesc& model, ? CoreML::Specification::MILSpec::DataType::FLOAT16 : CoreML::Specification::MILSpec::DataType::FLOAT32) , m_ops(board_x_size, board_y_size, optimize_identity_mask) - , m_var_counter(0) {} + , m_var_counter(0) { + // Precision in FP16 mode. The ANE's datapath is FP16 at op granularity: reductions use a wide + // (FP32-class) accumulator, but every op's inputs and stored outputs round to FP16, so a chain of + // ops re-rounds at each boundary and cancellation-heavy chains (notably the attention softmax + // chain, measured ~10x worse policyKLDiv than with an FP32 attention core) lose precision that a + // wide accumulator alone cannot save. FP32 type annotations are not implemented by the ANE, so + // any FP32 op runs OFF the ANE (on CPU/GPU), breaking the ANE pipeline -- FP32 escalation is a + // per-op trade of accuracy against ANE residency (measured ~1.8x eval slowdown for escalating the + // attention core on b11c768). These off-ANE FP32 escalations are applied ONLY to transformer + // trunks, whose attention/RMSNorm ops widen the activation range and deepen the rounding chains. + // Plain convnets stay PURE FP16 on the ANE -- the long-standing pre-tier path, verified to pass + // testgpuerror (b18c384nbt, b28c512nbt) and ~2.6x faster than forcing their per-block global + // pooling and convs to FP32 (measured: the per-block pooling round-trips, not the convs, dominate + // the slowdown). For transformers: + // - Trunks below 320ch build FULLY in FP32: b4c256 on the partial tier failed testgpuerror + // policyKLDiv at 19x19 (max 1.77x over; FP32 convs at 256 did not fix it, an FP32 attention + // core did but is not worth the ANE slowdown for wide models). Off-ANE but cheap since + // narrow; equals the FP32 reference. Weights stored FP32 (per-weight serialization). + // - Trunks at/above 320ch use partial FP32: q/k/v projections, FFN matmuls, pooling, norm + // cores, convs, and the pooled head layers (addLinearOp: value head v2/v3/sv3, policy + // gpool-to-pass, metadata encoder - measured ~25-60% better value-metric errors at ~2% + // cost). The attention core (scores/softmax/attn@V, gated by ATTENTION_CORE_FP32), the + // per-head output-projection matmuls, and spatial elementwise ops stay FP16 on the ANE + // (b10c384/b15c512/b11c768 pass with >=2.7x headroom on every metric). + const int trunkChannels = model.trunk.trunk_num_channels; + const bool hasTransformer = blocksContainTransformer(model.trunk.blocks); + const bool full_fp32 = use_fp16 && hasTransformer && trunkChannels < FULL_FP32_MAX_TRUNK_CHANNELS; + if (full_fp32) { + m_use_fp16 = false; + m_use_fp16_io = false; + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + } + m_nonspatial_fp32 = m_use_fp16 && hasTransformer; + m_conv_fp32 = m_use_fp16 && hasTransformer && trunkChannels >= CONV_FP32_MIN_TRUNK_CHANNELS; +} void MILBuilder::setBatchDimension(CoreML::Specification::MILSpec::TensorType* tensor_type) { auto* dim = tensor_type->add_dimensions(); @@ -212,9 +280,30 @@ void MILBuilder::addConstOp(CoreML::Specification::MILSpec::Block* block, const std::string& name, const std::vector& data, const std::vector& shape) { - // Register weight for blob storage - m_ops.registerWeight(name, data, shape); + // Register weight for blob storage (non-owning view into the model). Mark FP32 storage when this + // const is declared FP32 (e.g. inside an FP32 sub-region of an otherwise-FP16 model) so storage + // matches the declared type. + m_ops.registerWeight(name, data, shape, + m_weight_dtype == CoreML::Specification::MILSpec::DataType::FLOAT32); + emitConstOp(block, name, shape); +} + +void MILBuilder::addOwnedConstOp(CoreML::Specification::MILSpec::Block* block, + const std::string& name, + std::vector&& data, + const std::vector& shape) { + // Register derived/owned weight. Mirror addConstOp's per-weight FP32 marking: emitConstOp + // declares this const's dtype as m_weight_dtype, so the stored bytes must follow the same flag + // or BNNS rejects the model ("Metadata data type does not match requested type") when a derived + // const lands in an FP32 sub-region of an FP16 model. + const bool is_fp32 = (m_weight_dtype == CoreML::Specification::MILSpec::DataType::FLOAT32); + m_ops.registerOwnedWeight(name, std::move(data), shape, is_fp32); + emitConstOp(block, name, shape); +} +void MILBuilder::emitConstOp(CoreML::Specification::MILSpec::Block* block, + const std::string& name, + const std::vector& shape) { // Add const operation auto* op = block->add_operations(); op->set_type("const"); @@ -328,7 +417,11 @@ void MILBuilder::addFloatScalarConstOp(CoreML::Specification::MILSpec::Block* bl val_type->set_datatype(m_weight_dtype); val_type->set_rank(0); - if (m_use_fp16) { + // Key the storage format off the DECLARED dtype (m_weight_dtype), not the global m_use_fp16: + // a temporarily-flipped FP32 sub-region (m_weight_dtype=FLOAT32 while m_use_fp16 stays true) + // must store FP32 floats, or CoreML rejects the model ("storage and type have different number + // of elements"). For all non-flipped calls m_weight_dtype tracks m_use_fp16, so this is a no-op. + if (m_weight_dtype == CoreML::Specification::MILSpec::DataType::FLOAT16) { // For FP16, use bytes storage with FP16 representation MILBlob::Fp16 fp16_val = MILBlob::Fp16::FromFloat(value); std::string bytes_data(reinterpret_cast(&fp16_val.bytes), sizeof(fp16_val.bytes)); @@ -426,6 +519,68 @@ void MILBuilder::addCastOp(CoreML::Specification::MILSpec::Block* block, } } +std::string MILBuilder::castFixed(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const std::string& dtype, + const std::vector& dims) { + std::string out = genVarName(input + "_cast"); + std::string dtName = out + "_dt"; + { + auto* op = block->add_operations(); + op->set_type("const"); + auto& na = (*op->mutable_attributes())["name"]; + na.mutable_type()->mutable_tensortype()->set_datatype(CoreML::Specification::MILSpec::DataType::STRING); + na.mutable_immediatevalue()->mutable_tensor()->mutable_strings()->add_values(dtName); + auto& va = (*op->mutable_attributes())["val"]; + va.mutable_type()->mutable_tensortype()->set_datatype(CoreML::Specification::MILSpec::DataType::STRING); + va.mutable_immediatevalue()->mutable_tensor()->mutable_strings()->add_values(dtype); + auto* o = op->add_outputs(); + o->set_name(dtName); + o->mutable_type()->mutable_tensortype()->set_datatype(CoreML::Specification::MILSpec::DataType::STRING); + } + auto* op = block->add_operations(); + op->set_type("cast"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(input); + (*op->mutable_inputs())["dtype"].add_arguments()->set_name(dtName); + auto* o = op->add_outputs(); + o->set_name(out); + auto* tt = o->mutable_type()->mutable_tensortype(); + tt->set_datatype(dtype == "fp32" ? CoreML::Specification::MILSpec::DataType::FLOAT32 + : CoreML::Specification::MILSpec::DataType::FLOAT16); + tt->set_rank(static_cast(dims.size())); + for (int64_t d : dims) { + if (d < 0) tt->add_dimensions()->mutable_unknown()->set_variadic(false); + else tt->add_dimensions()->mutable_constant()->set_size(d); + } + return out; +} + +void MILBuilder::addGlobalPoolingFp32(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const std::string& mask, + int channels, + const std::string& output, + bool valueVariant) { + auto pool = [&](const std::string& in, const std::string& msk, const std::string& out) { + if (valueVariant) addGlobalPoolingValueOps(block, in, msk, channels, out); + else addGlobalPoolingOps(block, in, msk, channels, out); + }; + // Non-spatial per KataGo's FP16 convention -> FP32 (the FP16 spatial sum over H*W loses too much + // precision at larger board sizes). No addConstOp in the pooling, so flipping m_weight_dtype is + // safe. Cast input/mask up, pool in FP32, cast the [N, channels*3] features back to FP16. + if (!m_nonspatial_fp32) { + pool(input, mask, output); + return; + } + std::string in32 = castFixed(block, input, "fp32", {-1, channels, m_board_y_size, m_board_x_size}); + std::string mask32 = m_optimize_identity_mask + ? mask + : castFixed(block, mask, "fp32", {-1, 1, m_board_y_size, m_board_x_size}); + std::string out32 = genVarName(output + "_f32"); + { ScopedFp32 g(m_weight_dtype); pool(in32, mask32, out32); } + addCastOp(block, out32, output, "fp16", {-1, channels * 3}); +} + void MILBuilder::addConvOp(CoreML::Specification::MILSpec::Block* block, const std::string& input, const ConvLayerDesc& layer, @@ -566,6 +721,21 @@ void MILBuilder::addConvOp(CoreML::Specification::MILSpec::Block* block, tt->add_dimensions()->mutable_constant()->set_size(4); } + // Channel-gated FP32 convs. The ANE accumulates FP16 convs in FP16, which loses too much + // precision for WIDE trunks and fails testgpuerror at large board sizes (validated: 384ch + // fails, <=256ch is fine FP16-on-ANE). For wide trunks (>= threshold) run convs in FP32 (weights + // cast up at runtime, stored fp16). FP32 convs can't run on the fp16-only ANE, so only the wide + // models that actually need it pay that off-ANE cost; narrow models keep convs on the ANE. + const bool convFp32 = m_conv_fp32; + std::string convX = input, convW = weight_name, convOut = output; + auto savedConvDtype = m_weight_dtype; + if (convFp32) { + convX = castFixed(block, input, "fp32", {-1, layer.in_channels, m_board_y_size, m_board_x_size}); + convW = castFixed(block, weight_name, "fp32", layer.getWeightShape()); + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + convOut = output + "_cf32"; + } + // Add conv operation referencing all const parameters auto* op = block->add_operations(); op->set_type("conv"); @@ -577,12 +747,12 @@ void MILBuilder::addConvOp(CoreML::Specification::MILSpec::Block* block, inputs["pad"].add_arguments()->set_name(pad_name); inputs["pad_type"].add_arguments()->set_name(pad_type_name); inputs["strides"].add_arguments()->set_name(strides_name); - inputs["weight"].add_arguments()->set_name(weight_name); - inputs["x"].add_arguments()->set_name(input); + inputs["weight"].add_arguments()->set_name(convW); + inputs["x"].add_arguments()->set_name(convX); // Output with dimensions [batch, out_channels, height, width] auto* out = op->add_outputs(); - out->set_name(output); + out->set_name(convOut); auto* out_type = out->mutable_type()->mutable_tensortype(); out_type->set_datatype(m_weight_dtype); out_type->set_rank(4); @@ -590,6 +760,11 @@ void MILBuilder::addConvOp(CoreML::Specification::MILSpec::Block* block, out_type->add_dimensions()->mutable_constant()->set_size(layer.out_channels); out_type->add_dimensions()->mutable_constant()->set_size(m_board_y_size); out_type->add_dimensions()->mutable_constant()->set_size(m_board_x_size); + + if (convFp32) { + m_weight_dtype = savedConvDtype; + addCastOp(block, convOut, output, "fp16", {-1, layer.out_channels, m_board_y_size, m_board_x_size}); + } } // Helper: Set output tensor type with 4D shape [batch, C, H, W] @@ -732,6 +907,63 @@ void MILBuilder::addBatchNormActivationOps(CoreML::Specification::MILSpec::Block setTensorOutput4D(op, output, bn.num_channels, m_board_y_size, m_board_x_size); } else if (act.activation_type == ActivationType::Mish) { addMishOps(block, bn_output, output, 4, bn.num_channels); + } else if (act.activation_type == ActivationType::Silu) { + addSiluOps(block, bn_output, output, 4, bn.num_channels); + } +} + +void MILBuilder::addSiluOps(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const std::string& output, + int rank, + int channels) { + // SiLU / Swish: x * sigmoid(x) + auto setOutputType = [this, rank, channels](CoreML::Specification::MILSpec::Operation* op, const std::string& name) { + auto* out = op->add_outputs(); + out->set_name(name); + auto* out_type = out->mutable_type()->mutable_tensortype(); + out_type->set_datatype(m_weight_dtype); + out_type->set_rank(rank); + setBatchDimension(out_type); + out_type->add_dimensions()->mutable_constant()->set_size(channels); + if (rank == 4) { + out_type->add_dimensions()->mutable_constant()->set_size(m_board_y_size); + out_type->add_dimensions()->mutable_constant()->set_size(m_board_x_size); + } + }; + + std::string sig = output + "_sigmoid"; + { + auto* op = block->add_operations(); + op->set_type("sigmoid"); + auto& inputs = *op->mutable_inputs(); + inputs["x"].add_arguments()->set_name(input); + setOutputType(op, sig); + } + { + auto* op = block->add_operations(); + op->set_type("mul"); + auto& inputs = *op->mutable_inputs(); + inputs["x"].add_arguments()->set_name(input); + inputs["y"].add_arguments()->set_name(sig); + setOutputType(op, output); + } +} + +void MILBuilder::setShape(CoreML::Specification::MILSpec::Operation* op, + const std::string& name, + const std::vector& dims) { + auto* out = op->add_outputs(); + out->set_name(name); + auto* t = out->mutable_type()->mutable_tensortype(); + t->set_datatype(m_weight_dtype); + t->set_rank(static_cast(dims.size())); + for (int64_t d : dims) { + auto* dim = t->add_dimensions(); + if (d < 0) + dim->mutable_unknown()->set_variadic(false); + else + dim->mutable_constant()->set_size(d); } } @@ -887,23 +1119,38 @@ void MILBuilder::addMatMulOp(CoreML::Specification::MILSpec::Block* block, CoreML::Specification::MILSpec::DataType::BOOL); } + // Non-spatial matmul in FP32 (KataGo FP16 convention; weights cast up at runtime, stored fp16). + std::string mmIn = input, mmW = weight_name, mmOut = output; + auto savedMmDtype = m_weight_dtype; + if (m_nonspatial_fp32) { + mmIn = castFixed(block, input, "fp32", {-1, layer.in_channels}); + mmW = castFixed(block, weight_name, "fp32", layer.getWeightShape()); + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + mmOut = output + "_mmf32"; + } + // Add matmul operation auto* op = block->add_operations(); op->set_type("matmul"); auto& inputs = *op->mutable_inputs(); inputs["transpose_x"].add_arguments()->set_name(transpose_x_name); inputs["transpose_y"].add_arguments()->set_name(transpose_y_name); - inputs["x"].add_arguments()->set_name(input); - inputs["y"].add_arguments()->set_name(weight_name); + inputs["x"].add_arguments()->set_name(mmIn); + inputs["y"].add_arguments()->set_name(mmW); // Output with 2D shape [batch, out_channels] auto* out = op->add_outputs(); - out->set_name(output); + out->set_name(mmOut); auto* out_type = out->mutable_type()->mutable_tensortype(); out_type->set_datatype(m_weight_dtype); out_type->set_rank(2); setBatchDimension(out_type); out_type->add_dimensions()->mutable_constant()->set_size(layer.out_channels); + + if (m_nonspatial_fp32) { + m_weight_dtype = savedMmDtype; + addCastOp(block, mmOut, output, "fp16", {-1, layer.out_channels}); + } } void MILBuilder::addMatBiasOp(CoreML::Specification::MILSpec::Block* block, @@ -937,16 +1184,84 @@ void MILBuilder::addLinearOp(CoreML::Specification::MILSpec::Block* block, const MatMulLayerDesc& matmul, const MatBiasLayerDesc& bias, const std::string& output) { - // Create const operations for weight and bias (matching Python's linear op structure) - // Core ML linear expects weights in [out_channels, in_channels] format - // KataGo matmul stores weights in [in_channels, out_channels] format - // We need to transpose the weights to match Python's fuse_matmul_weight_bias pass std::string weight_name = output + "_weight_0"; std::string bias_name = output + "_bias_0"; - - // Transpose weights from [in_channels, out_channels] to [out_channels, in_channels] const int in_ch = matmul.in_channels; const int out_ch = matmul.out_channels; + + if (m_nonspatial_fp32) { + // FP32 escalation for the partial-FP32 tier. MIL `linear` requires const weight/bias, so + // the runtime-cast trick cannot apply to it; rewrite as matmul+add, which accept cast + // inputs. These layers (value head v2/v3/sv3, policy gpool-to-pass, metadata encoder) + // reduce pooled features directly into the engine's final outputs (value, lead, score), + // and are tiny relative to the trunk, so the off-ANE FP32 cost is negligible. Weights and + // bias are simply stored FP32 (per-weight serialization handles the mixed dtypes). + const auto savedDtype = m_weight_dtype; + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + // KataGo's [in_channels, out_channels] row-major layout is used untransposed by matmul. + addConstOp(block, weight_name, matmul.weights, + {static_cast(in_ch), static_cast(out_ch)}); + addConstOp(block, bias_name, bias.weights, {static_cast(bias.num_channels)}); + + std::string x32 = castFixed(block, input, "fp32", {-1, in_ch}); + + std::string txName = output + "_tx", tyName = output + "_ty"; + addBoolScalarConstOp(block, txName, false); + addBoolScalarConstOp(block, tyName, false); + std::string mm32 = genVarName(output + "_mm32"); + { + auto* op = block->add_operations(); + op->set_type("matmul"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x32); + (*op->mutable_inputs())["y"].add_arguments()->set_name(weight_name); + (*op->mutable_inputs())["transpose_x"].add_arguments()->set_name(txName); + (*op->mutable_inputs())["transpose_y"].add_arguments()->set_name(tyName); + setShape(op, mm32, {-1, out_ch}); + } + std::string add32 = genVarName(output + "_add32"); + { + auto* op = block->add_operations(); + op->set_type("add"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(mm32); + (*op->mutable_inputs())["y"].add_arguments()->set_name(bias_name); + setShape(op, add32, {-1, out_ch}); + } + m_weight_dtype = savedDtype; + + // Cast back to the ambient dtype under the exact output name callers expect. + { + std::string dtName = output + "_dt"; + auto* cop = block->add_operations(); + cop->set_type("const"); + auto& na = (*cop->mutable_attributes())["name"]; + na.mutable_type()->mutable_tensortype()->set_datatype(CoreML::Specification::MILSpec::DataType::STRING); + na.mutable_immediatevalue()->mutable_tensor()->mutable_strings()->add_values(dtName); + auto& va = (*cop->mutable_attributes())["val"]; + va.mutable_type()->mutable_tensortype()->set_datatype(CoreML::Specification::MILSpec::DataType::STRING); + va.mutable_immediatevalue()->mutable_tensor()->mutable_strings()->add_values("fp16"); + auto* co = cop->add_outputs(); + co->set_name(dtName); + co->mutable_type()->mutable_tensortype()->set_datatype(CoreML::Specification::MILSpec::DataType::STRING); + + auto* op = block->add_operations(); + op->set_type("cast"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(add32); + (*op->mutable_inputs())["dtype"].add_arguments()->set_name(dtName); + auto* out = op->add_outputs(); + out->set_name(output); + auto* out_type = out->mutable_type()->mutable_tensortype(); + out_type->set_datatype(CoreML::Specification::MILSpec::DataType::FLOAT16); + out_type->set_rank(2); + setBatchDimension(out_type); + out_type->add_dimensions()->mutable_constant()->set_size(out_ch); + } + return; + } + + // Create const operations for weight and bias (matching Python's linear op structure) + // Core ML linear expects weights in [out_channels, in_channels] format + // KataGo matmul stores weights in [in_channels, out_channels] format + // We need to transpose the weights to match Python's fuse_matmul_weight_bias pass std::vector transposed_weights(matmul.weights.size()); for (int i = 0; i < in_ch; ++i) { for (int j = 0; j < out_ch; ++j) { @@ -958,13 +1273,12 @@ void MILBuilder::addLinearOp(CoreML::Specification::MILSpec::Block* block, // Add transposed weight constant with shape [out_channels, in_channels] std::vector transposed_shape = {static_cast(out_ch), static_cast(in_ch)}; - addConstOp(block, weight_name, transposed_weights, transposed_shape); + addOwnedConstOp(block, weight_name, std::move(transposed_weights), transposed_shape); // Add bias constant std::vector bias_shape = {static_cast(bias.num_channels)}; addConstOp(block, bias_name, bias.weights, bias_shape); - // Add linear operation auto* op = block->add_operations(); op->set_type("linear"); auto& inputs = *op->mutable_inputs(); @@ -1637,6 +1951,667 @@ void MILBuilder::addGlobalPoolingValueOps(CoreML::Specification::MILSpec::Block* // Network Component Builders // ============================================================================ +// --------------------------------------------------------------------------- +// Transformer blocks (MIL). Layout is NCHW [B, C, H, W]; spatial positions +// (H*W, ordered y*W+x) are treated as the attention sequence. RoPE is applied +// via a fixed pair-rotation matmul plus host-precomputed cos/sin tables, which +// keeps every tensor rank <= 4 (ANE-friendly). +// --------------------------------------------------------------------------- + +std::string MILBuilder::addTransformerRMSNorm(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const TransformerRMSNormDesc& desc, + const std::string& mask, + const std::string& prefix) { + const int C = desc.num_channels; + const int H = m_board_y_size, W = m_board_x_size; + auto emit2 = [&](const std::string& type, const std::string& x, const std::string& y, + const std::string& out, const std::vector& dims) { + auto* op = block->add_operations(); + op->set_type(type); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["y"].add_arguments()->set_name(y); + setShape(op, out, dims); + }; + + // RMSNorm reduction core: square -> mean over channels -> rsqrt. In FP16 mode compute this + // core in FP32 (cast input up, flip the working dtype so the core's op outputs + eps scalar are + // FP32, then cast 1/rms back down). The FP16 channel reduction loses too much precision on the + // ANE; only this core is FP32 - the scaling/weight/mask below stay FP16. No addConstOp lives in + // the flipped window, so weight serialization is unaffected. + auto savedDtype = m_weight_dtype; + std::string sqSrc = input; + if (m_use_fp16) { + sqSrc = genVarName(prefix + "_in32"); + addCastOp(block, input, sqSrc, "fp32", {-1, C, H, W}); + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + } + std::string sq = genVarName(prefix + "_sq"); + emit2("mul", sqSrc, sqSrc, sq, {-1, C, H, W}); + // meanSq = reduce_mean(sq, axes=[1]) over channels. reduce_mean (not reduce_sum) is used so + // the accumulator stays ~O(activation^2) instead of summing hundreds of channels, which can + // overflow FP16 (and the FP16 accumulation on ANE) for large activations. + std::string meanSq = genVarName(prefix + "_meansq"); + { + std::string axesName = meanSq + "_axes"; + std::string keepName = meanSq + "_keep"; + addIntArrayConstOp(block, axesName, {1}); + addBoolScalarConstOp(block, keepName, true); + auto* op = block->add_operations(); + op->set_type("reduce_mean"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(sq); + (*op->mutable_inputs())["axes"].add_arguments()->set_name(axesName); + (*op->mutable_inputs())["keep_dims"].add_arguments()->set_name(keepName); + setShape(op, meanSq, {-1, 1, H, W}); + } + // MIL rsqrt computes 1/sqrt(x + epsilon); supply epsilon directly. + std::string epsName = prefix + "_eps"; + addFloatScalarConstOp(block, epsName, desc.epsilon); + std::string invCore = genVarName(prefix + "_inv"); + { + auto* op = block->add_operations(); + op->set_type("rsqrt"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(meanSq); + (*op->mutable_inputs())["epsilon"].add_arguments()->set_name(epsName); + setShape(op, invCore, {-1, 1, H, W}); + } + std::string inv = invCore; + if (m_use_fp16) { + m_weight_dtype = savedDtype; + inv = genVarName(prefix + "_inv16"); + addCastOp(block, invCore, inv, "fp16", {-1, 1, H, W}); + } + std::string normalized = genVarName(prefix + "_norm"); + emit2("mul", input, inv, normalized, {-1, C, H, W}); + std::string weightName = prefix + "_weight"; + addConstOp(block, weightName, desc.weight, {1, static_cast(C), 1, 1}); + std::string scaled = genVarName(prefix + "_scaled"); + emit2("mul", normalized, weightName, scaled, {-1, C, H, W}); + std::string out = genVarName(prefix + "_out"); + emit2("mul", scaled, mask, out, {-1, C, H, W}); + return out; +} + +std::string MILBuilder::addTrunkRMSNorm(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const RMSNormLayerDesc& desc, + const ActivationLayerDesc& act, + const std::string& mask, + const std::string& prefix) { + const int C = desc.num_channels; + const int H = m_board_y_size, W = m_board_x_size; + auto emit2 = [&](const std::string& type, const std::string& x, const std::string& y, + const std::string& out, const std::vector& dims) { + auto* op = block->add_operations(); + op->set_type(type); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["y"].add_arguments()->set_name(y); + setShape(op, out, dims); + }; + auto reduceSum = [&](const std::string& x, const std::string& out, const std::vector& axes, + const std::vector& dims) { + std::string axesName = out + "_axes"; + std::string keepName = out + "_keep"; + addIntArrayConstOp(block, axesName, axes); + addBoolScalarConstOp(block, keepName, true); + auto* op = block->add_operations(); + op->set_type("reduce_sum"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["axes"].add_arguments()->set_name(axesName); + (*op->mutable_inputs())["keep_dims"].add_arguments()->set_name(keepName); + setShape(op, out, dims); + }; + + // Variance core (mask -> square -> reduce -> rsqrt) in FP32 when in FP16 mode. The trunk-tip + // norm in particular reduces over many elements and loses too much precision in FP16 on the + // ANE; compute the core in FP32 and cast 1/rms back to FP16. Only the core is FP32 - gamma/beta, + // the activation and the final mask below stay FP16. No addConstOp lives in the flipped window. + auto savedDtype = m_weight_dtype; + std::string tinput = input; + std::string tmask = mask; + if (m_use_fp16) { + tinput = genVarName(prefix + "_in32"); + addCastOp(block, input, tinput, "fp32", {-1, C, H, W}); + tmask = genVarName(prefix + "_mask32"); + addCastOp(block, mask, tmask, "fp32", {-1, 1, H, W}); + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + } + std::string masked = genVarName(prefix + "_premask"); + emit2("mul", tinput, tmask, masked, {-1, C, H, W}); + std::string sq = genVarName(prefix + "_sq"); + emit2("mul", masked, masked, sq, {-1, C, H, W}); + + std::string meanSq; + std::vector denomDims; + if (desc.spatial) { + // Mean of squares over valid positions and channels. A reduce_sum over C*H*W elements + // overflows FP16 (e.g. trunk tip with large activations on ANE -> inf -> rsqrt 0 -> + // collapse). Instead take reduce_mean over all of C,H,W (masked positions are zero) and + // rescale by totalPositions/validCount to restrict the mean to valid positions. + std::string meanAll = genVarName(prefix + "_meanall"); + { + std::string axesName = meanAll + "_axes", keepName = meanAll + "_keep"; + addIntArrayConstOp(block, axesName, {1, 2, 3}); + addBoolScalarConstOp(block, keepName, true); + auto* op = block->add_operations(); + op->set_type("reduce_mean"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(sq); + (*op->mutable_inputs())["axes"].add_arguments()->set_name(axesName); + (*op->mutable_inputs())["keep_dims"].add_arguments()->set_name(keepName); + setShape(op, meanAll, {-1, 1, 1, 1}); + } + std::string count = genVarName(prefix + "_count"); + reduceSum(tmask, count, {1, 2, 3}, {-1, 1, 1, 1}); // valid positions (<= H*W, no overflow) + std::string totalPosName = prefix + "_totalpos"; + addFloatScalarConstOp(block, totalPosName, static_cast(H * W)); + std::string scaleF = genVarName(prefix + "_scalef"); + emit2("real_div", totalPosName, count, scaleF, {-1, 1, 1, 1}); // totalPos / validCount + meanSq = genVarName(prefix + "_meansq"); + emit2("mul", meanAll, scaleF, meanSq, {-1, 1, 1, 1}); + denomDims = {-1, 1, 1, 1}; + } else { + meanSq = genVarName(prefix + "_meansq"); + std::string axesName = meanSq + "_axes"; + std::string keepName = meanSq + "_keep"; + addIntArrayConstOp(block, axesName, {1}); + addBoolScalarConstOp(block, keepName, true); + auto* op = block->add_operations(); + op->set_type("reduce_mean"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(sq); + (*op->mutable_inputs())["axes"].add_arguments()->set_name(axesName); + (*op->mutable_inputs())["keep_dims"].add_arguments()->set_name(keepName); + setShape(op, meanSq, {-1, 1, H, W}); + denomDims = {-1, 1, H, W}; + } + + // MIL rsqrt computes 1/sqrt(x + epsilon); supply epsilon directly. + std::string epsName = prefix + "_eps"; + addFloatScalarConstOp(block, epsName, desc.epsilon); + std::string invCore = genVarName(prefix + "_inv"); + { + auto* op = block->add_operations(); + op->set_type("rsqrt"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(meanSq); + (*op->mutable_inputs())["epsilon"].add_arguments()->set_name(epsName); + setShape(op, invCore, denomDims); + } + std::string inv = invCore; + if (m_use_fp16) { + m_weight_dtype = savedDtype; + inv = genVarName(prefix + "_inv16"); + addCastOp(block, invCore, inv, "fp16", denomDims); + } + std::string normalized = genVarName(prefix + "_norm"); + emit2("mul", input, inv, normalized, {-1, C, H, W}); + std::string gammaName = prefix + "_gamma"; + std::string betaName = prefix + "_beta"; + addConstOp(block, gammaName, desc.gamma, {1, static_cast(C), 1, 1}); + addConstOp(block, betaName, desc.beta, {1, static_cast(C), 1, 1}); + std::string scaled = genVarName(prefix + "_scaled"); + emit2("mul", normalized, gammaName, scaled, {-1, C, H, W}); + std::string biased = genVarName(prefix + "_biased"); + emit2("add", scaled, betaName, biased, {-1, C, H, W}); + + std::string activated; + if (act.activation_type == ActivationType::Silu) { + activated = genVarName(prefix + "_act"); + addSiluOps(block, biased, activated, 4, C); + } else if (act.activation_type == ActivationType::Mish) { + activated = genVarName(prefix + "_act"); + addMishOps(block, biased, activated, 4, C); + } else if (act.activation_type == ActivationType::ReLU) { + activated = genVarName(prefix + "_act"); + auto* op = block->add_operations(); + op->set_type("relu"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(biased); + setShape(op, activated, {-1, C, H, W}); + } else { + activated = biased; + } + std::string out = genVarName(prefix + "_out"); + emit2("mul", activated, mask, out, {-1, C, H, W}); + return out; +} + +std::string MILBuilder::buildTransformerAttentionBlock(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const TransformerAttentionBlockDesc& desc, + const std::string& mask, + const std::string& prefix) { + const int C = desc.q_proj.in_channels; + const int H = m_board_y_size, W = m_board_x_size; + const int seq = H * W; + const int numHeads = desc.num_heads, numKVHeads = desc.num_kv_heads; + const int qHeadDim = desc.q_head_dim, vHeadDim = desc.v_head_dim; + const int qTotal = numHeads * qHeadDim, kTotal = numKVHeads * qHeadDim, vTotal = numKVHeads * vHeadDim; + + auto reshape = [&](const std::string& in, const std::string& out, const std::vector& shapeVals, + const std::vector& dims) { + std::string shapeName = out + "_shape"; + addIntArrayConstOp(block, shapeName, shapeVals); + auto* op = block->add_operations(); + op->set_type("reshape"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(in); + (*op->mutable_inputs())["shape"].add_arguments()->set_name(shapeName); + setShape(op, out, dims); + }; + auto transpose = [&](const std::string& in, const std::string& out, const std::vector& perm, + const std::vector& dims) { + std::string permName = out + "_perm"; + addIntArrayConstOp(block, permName, perm); + auto* op = block->add_operations(); + op->set_type("transpose"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(in); + (*op->mutable_inputs())["perm"].add_arguments()->set_name(permName); + setShape(op, out, dims); + }; + auto matmul = [&](const std::string& x, const std::string& y, const std::string& out, + const std::vector& dims, bool transX, bool transY) { + std::string txName = out + "_tx", tyName = out + "_ty"; + addBoolScalarConstOp(block, txName, transX); + addBoolScalarConstOp(block, tyName, transY); + auto* op = block->add_operations(); + op->set_type("matmul"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["y"].add_arguments()->set_name(y); + (*op->mutable_inputs())["transpose_x"].add_arguments()->set_name(txName); + (*op->mutable_inputs())["transpose_y"].add_arguments()->set_name(tyName); + setShape(op, out, dims); + }; + auto binary = [&](const std::string& type, const std::string& x, const std::string& y, + const std::string& out, const std::vector& dims) { + auto* op = block->add_operations(); + op->set_type(type); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["y"].add_arguments()->set_name(y); + setShape(op, out, dims); + }; + + std::string normed = addTransformerRMSNorm(block, input, desc.pre_ln, mask, prefix + "_ln"); + std::string nhwc = genVarName(prefix + "_nhwc"); + transpose(normed, nhwc, {0, 2, 3, 1}, {-1, H, W, C}); + std::string x2d = genVarName(prefix + "_x2d"); + reshape(nhwc, x2d, {-1, C}, {-1, C}); + // Q/K/V projection matmuls in FP32 (non-spatial, per KataGo's FP16 convention): they reduce over + // C channels and the ANE's FP16 accumulation loses too much precision for wide models. Weights + // stay fp16-stored (cast up at runtime); output cast back to FP16 for the FP16 head reshapes. + auto proj = [&](const MatMulLayerDesc& w, const std::string& nm, int total) { + std::string wName = nm + "_w"; + addConstOp(block, wName, w.weights, w.getWeightShape()); + std::string out = genVarName(nm); + if (m_nonspatial_fp32) { + std::string x32 = castFixed(block, x2d, "fp32", {-1, C}); + std::string w32 = castFixed(block, wName, "fp32", w.getWeightShape()); + auto sd = m_weight_dtype; + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + std::string o32 = genVarName(nm + "_f32"); + matmul(x32, w32, o32, {-1, total}, false, false); + m_weight_dtype = sd; + out = castFixed(block, o32, "fp16", {-1, total}); + } else { + matmul(x2d, wName, out, {-1, total}, false, false); + } + return out; + }; + std::string q2d = proj(desc.q_proj, prefix + "_q", qTotal); + std::string k2d = proj(desc.k_proj, prefix + "_k", kTotal); + std::string v2d = proj(desc.v_proj, prefix + "_v", vTotal); + auto toHeads = [&](const std::string& in2d, const std::string& nm, int nh, int hd) { + std::string r = genVarName(nm + "_r"); + reshape(in2d, r, {-1, seq, nh, hd}, {-1, seq, nh, hd}); + std::string t = genVarName(nm + "_t"); + transpose(r, t, {0, 2, 1, 3}, {-1, nh, seq, hd}); + return t; + }; + std::string qh = toHeads(q2d, prefix + "_qh", numHeads, qHeadDim); + std::string kh = toHeads(k2d, prefix + "_kh", numKVHeads, qHeadDim); + std::string vh = toHeads(v2d, prefix + "_vh", numKVHeads, vHeadDim); + + if (desc.use_rope) { + const int numPairs = qHeadDim / 2; + const int numPairsPerDim = numPairs / 2; + const int dimHalf = qHeadDim / 2; + auto applyRope = [&](const std::string& x, int nh, const std::string& tag) { + std::vector cosFull(static_cast(nh) * seq * qHeadDim, 0.0f); + std::vector sinFull(static_cast(nh) * seq * qHeadDim, 0.0f); + for (int h = 0; h < nh; h++) { + int kvh = (h * numKVHeads) / nh; + for (int xy = 0; xy < seq; xy++) { + int y = xy / W; + int x = xy % W; + for (int p = 0; p < numPairs; p++) { + float angle = 0.0f; + if (desc.learnable_rope) { + float fx = desc.rope_freqs[(kvh * numPairs + p) * 2 + 0]; + float fy = desc.rope_freqs[(kvh * numPairs + p) * 2 + 1]; + angle = static_cast(x) * fx + static_cast(y) * fy; + } else { + if (p < numPairsPerDim) { + float freq = 1.0f / std::pow(desc.rope_theta, static_cast(2 * p) / dimHalf); + angle = static_cast(y) * freq; + } else { + int pAdj = p - numPairsPerDim; + float freq = 1.0f / std::pow(desc.rope_theta, static_cast(2 * pAdj) / dimHalf); + angle = static_cast(x) * freq; + } + } + float c = std::cos(angle), s = std::sin(angle); + size_t base = (static_cast(h) * seq + xy) * qHeadDim + 2 * p; + cosFull[base] = c; cosFull[base + 1] = c; + sinFull[base] = s; sinFull[base + 1] = s; + } + } + } + std::vector R(static_cast(qHeadDim) * qHeadDim, 0.0f); + for (int p = 0; p < numPairs; p++) { + R[(2 * p) * qHeadDim + (2 * p + 1)] = 1.0f; + R[(2 * p + 1) * qHeadDim + (2 * p)] = -1.0f; + } + std::string cosName = prefix + "_" + tag + "_cos"; + std::string sinName = prefix + "_" + tag + "_sin"; + std::string rName = prefix + "_" + tag + "_R"; + // cosFull/sinFull/R are locals computed here, so register them as OWNED consts: the + // WeightEntry holds a non-owning FloatView and serialization runs after this lambda + // returns, so a non-owning addConstOp would dangle. + addOwnedConstOp(block, cosName, std::move(cosFull), {1, nh, seq, qHeadDim}); + addOwnedConstOp(block, sinName, std::move(sinFull), {1, nh, seq, qHeadDim}); + // Rank-4 [1,1,qd,qd] so matmul batch dims broadcast cleanly against [B,nh,seq,qd]. + addOwnedConstOp(block, rName, std::move(R), {1, 1, qHeadDim, qHeadDim}); + std::string rotated = genVarName(prefix + "_" + tag + "_rot"); + matmul(x, rName, rotated, {-1, nh, seq, qHeadDim}, false, false); + std::string xc = genVarName(prefix + "_" + tag + "_xc"); + binary("mul", x, cosName, xc, {-1, nh, seq, qHeadDim}); + std::string rs = genVarName(prefix + "_" + tag + "_rs"); + binary("mul", rotated, sinName, rs, {-1, nh, seq, qHeadDim}); + std::string out = genVarName(prefix + "_" + tag + "_rope"); + binary("add", xc, rs, out, {-1, nh, seq, qHeadDim}); + return out; + }; + qh = applyRope(qh, numHeads, "q"); + kh = applyRope(kh, numKVHeads, "k"); + } + + // GQA: when numKVHeads < numHeads, repeat each KV head groupSize times along the head + // axis (axis 1) so query head h consumes kv head (h / groupSize). RoPE has already been + // applied above to the unexpanded kh (kh = applyRope(kh, numKVHeads, "k")), mirroring the + // GPU path (metallayers.swift repeatKVHeads runs AFTER applyRope). We slice each KV head + // and concat its copies consecutively, so the resulting head index is kv*groupSize + g; + // query head h then maps to kv = h/groupSize == (h*numKVHeads)/numHeads (exact divisor, + // the same formula the qh RoPE table uses) == Eigen's kvh = h/kvGroupSize. slice_by_size + + // concat (not reshape+broadcast) avoids the dynamic -1 batch broadcast pitfall, same as the + // GPU code. The repeat is required so the scores (qh@kh^T) and attnOut (attn@vh) matmuls see + // matching [B,numHeads,...] batch dims instead of numHeads vs numKVHeads (no broadcast). + if (numKVHeads != numHeads) { + const int groupSize = numHeads / numKVHeads; + auto repeatKVHeads = [&](const std::string& x, const std::string& tag, int headDim) { + std::vector parts; + parts.reserve(static_cast(numKVHeads) * groupSize); + for (int kv = 0; kv < numKVHeads; kv++) { + for (int g = 0; g < groupSize; g++) { + std::string part = genVarName(prefix + "_" + tag + "_slc"); + std::string beginName = part + "_begin", sizeName = part + "_size"; + addIntArrayConstOp(block, beginName, {0, kv, 0, 0}); + addIntArrayConstOp(block, sizeName, {-1, 1, seq, headDim}); + auto* sop = block->add_operations(); + sop->set_type("slice_by_size"); + (*sop->mutable_inputs())["x"].add_arguments()->set_name(x); + (*sop->mutable_inputs())["begin"].add_arguments()->set_name(beginName); + (*sop->mutable_inputs())["size"].add_arguments()->set_name(sizeName); + setShape(sop, part, {-1, 1, seq, headDim}); + parts.push_back(part); + } + } + std::string out = genVarName(prefix + "_" + tag + "_exp"); + std::string axisName = out + "_axis", interleaveName = out + "_interleave"; + addIntScalarConstOp(block, axisName, 1); + addBoolScalarConstOp(block, interleaveName, false); + auto* cop = block->add_operations(); + cop->set_type("concat"); + auto& cin = *cop->mutable_inputs(); + for (const std::string& part : parts) + cin["values"].add_arguments()->set_name(part); + cin["axis"].add_arguments()->set_name(axisName); + cin["interleave"].add_arguments()->set_name(interleaveName); + setShape(cop, out, {-1, numHeads, seq, headDim}); + return out; + }; + kh = repeatKVHeads(kh, "khrep", qHeadDim); + vh = repeatKVHeads(vh, "vhrep", vHeadDim); + } + + // mask [B,1,H,W] -> [B,1,1,seq] directly (contiguous reshape; H,W already trailing so the + // row-major flatten gives seq index xy=y*W+x). No transpose -> avoids the reshape-after- + // transpose issue, and is also correct for non-full boards. Computed in the ambient dtype + // (FP16 in FP16 mode) since the mask tensor is FP16; cast up below if the core runs FP32. + std::string maskSeq = genVarName(prefix + "_mseq"); + reshape(mask, maskSeq, {-1, 1, 1, seq}, {-1, 1, 1, seq}); + std::string oneName = prefix + "_one"; + addFloatScalarConstOp(block, oneName, 1.0f); + std::string mm1 = genVarName(prefix + "_mm1"); + binary("sub", maskSeq, oneName, mm1, {-1, 1, 1, seq}); + // Use an FP16-safe magnitude: 1e9 overflows FP16 to +inf, and for valid keys + // (maskSeq-1 == 0) the product 0 * inf becomes NaN, poisoning the whole softmax. + // 3e4 is exactly representable in FP16 (a multiple of the local ulp of 16), stays well + // below the FP16 max of 65504 even after summing with any plausible score, and + // exp(score - 3e4) underflows to exactly 0 - while leaving ~3x more headroom than + // 1e4 against unusually large valid scores. + std::string bigName = prefix + "_big"; + addFloatScalarConstOp(block, bigName, 3.0e4f); + std::string keyBias = genVarName(prefix + "_kb"); + binary("mul", mm1, bigName, keyBias, {-1, 1, 1, seq}); + + // Optional FP32 escalation of the scores/softmax/attn@V chain, gated by + // ATTENTION_CORE_FP32 (currently off; see MILBuilder.hpp for the measured tradeoffs). + // When enabled it must cover the whole chain contiguously: escalating the softmax ALONE + // was measured to regress accuracy and speed, because an isolated off-ANE fp32 island + // makes the partitioner relocate the neighboring seq-x-seq matmuls off the ANE in FP16, + // losing its wide accumulator. + const bool attnCoreFp32 = m_nonspatial_fp32 && ATTENTION_CORE_FP32; + std::string qhc = attnCoreFp32 ? castFixed(block, qh, "fp32", {-1, numHeads, seq, qHeadDim}) : qh; + std::string khc = attnCoreFp32 ? castFixed(block, kh, "fp32", {-1, numHeads, seq, qHeadDim}) : kh; + std::string vhc = attnCoreFp32 ? castFixed(block, vh, "fp32", {-1, numHeads, seq, vHeadDim}) : vh; + std::string keyBiasC = attnCoreFp32 ? castFixed(block, keyBias, "fp32", {-1, 1, 1, seq}) : keyBias; + const auto savedCoreDtype = m_weight_dtype; + if (attnCoreFp32) + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + + std::string scores = genVarName(prefix + "_scores"); + matmul(qhc, khc, scores, {-1, numHeads, seq, seq}, false, true); + std::string scaleName = prefix + "_scale"; + addFloatScalarConstOp(block, scaleName, 1.0f / std::sqrt(static_cast(qHeadDim))); + std::string scaled = genVarName(prefix + "_sc"); + binary("mul", scores, scaleName, scaled, {-1, numHeads, seq, seq}); + std::string scoresMasked = genVarName(prefix + "_scm"); + binary("add", scaled, keyBiasC, scoresMasked, {-1, numHeads, seq, seq}); + + std::string attn = genVarName(prefix + "_attn"); + { + std::string axisName = attn + "_axis"; + addIntScalarConstOp(block, axisName, 3); + auto* op = block->add_operations(); + op->set_type("softmax"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(scoresMasked); + (*op->mutable_inputs())["axis"].add_arguments()->set_name(axisName); + setShape(op, attn, {-1, numHeads, seq, seq}); + } + + std::string attnOut = genVarName(prefix + "_ao"); + matmul(attn, vhc, attnOut, {-1, numHeads, seq, vHeadDim}, false, false); + if (attnCoreFp32) { + m_weight_dtype = savedCoreDtype; + attnOut = castFixed(block, attnOut, "fp16", {-1, numHeads, seq, vHeadDim}); + } + + // Output projection, done per-head as a workaround: merging [head,dim]->channels via + // transpose({0,2,1,3}) followed by reshape was observed to scramble the data on this + // specific pattern (root cause not isolated - note the transpose+reshape at this + // function's INPUT works fine, so it is not a general CoreML rule; possibly a fusion or + // layout bug for this rank-4 permutation feeding a trailing-dim merge). Instead slice + // each head from attnOut (head is the contiguous axis 1), reshape (leading-merge only), + // matmul its weight slice, and sum. + // out[b,s,c] = sum_h sum_d attnOut[b,h,s,d] * outProj.weights[(h*vHeadDim+d)*outC + c] + const int outC = desc.out_proj.out_channels; + std::string proj2d; + for (int h = 0; h < numHeads; h++) { + std::string aoh = genVarName(prefix + "_aoh"); + { + std::string beginName = aoh + "_begin", sizeName = aoh + "_size"; + addIntArrayConstOp(block, beginName, {0, h, 0, 0}); + addIntArrayConstOp(block, sizeName, {-1, 1, seq, vHeadDim}); + auto* op = block->add_operations(); + op->set_type("slice_by_size"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(attnOut); + (*op->mutable_inputs())["begin"].add_arguments()->set_name(beginName); + (*op->mutable_inputs())["size"].add_arguments()->set_name(sizeName); + setShape(op, aoh, {-1, 1, seq, vHeadDim}); + } + std::string aoh2d = genVarName(prefix + "_aoh2d"); + reshape(aoh, aoh2d, {-1, vHeadDim}, {-1, vHeadDim}); // [B*seq, vHeadDim] + std::string wh = prefix + "_ow" + std::to_string(h); + std::vector whData(static_cast(vHeadDim) * outC); + for (int d = 0; d < vHeadDim; d++) + for (int c = 0; c < outC; c++) + whData[d * outC + c] = desc.out_proj.weights[static_cast(h * vHeadDim + d) * outC + c]; + // whData is a per-head local slice; register OWNED so its FloatView stays valid until + // serialization (a non-owning addConstOp would dangle after this loop iteration). + addOwnedConstOp(block, wh, std::move(whData), {vHeadDim, outC}); + std::string contrib = genVarName(prefix + "_contrib"); + matmul(aoh2d, wh, contrib, {-1, outC}, false, false); + if (h == 0) { + proj2d = contrib; + } else { + std::string acc = genVarName(prefix + "_acc"); + binary("add", proj2d, contrib, acc, {-1, outC}); + proj2d = acc; + } + } + std::string projNHWC = genVarName(prefix + "_pnhwc"); + reshape(proj2d, projNHWC, {-1, H, W, C}, {-1, H, W, C}); + std::string projNCHW = genVarName(prefix + "_pnchw"); + transpose(projNHWC, projNCHW, {0, 3, 1, 2}, {-1, C, H, W}); + std::string maskedOut = genVarName(prefix + "_masked"); + binary("mul", projNCHW, mask, maskedOut, {-1, C, H, W}); + std::string out = genVarName(prefix + "_out"); + binary("add", input, maskedOut, out, {-1, C, H, W}); + return out; +} + +std::string MILBuilder::buildTransformerFFNBlock(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const TransformerFFNBlockDesc& desc, + const std::string& mask, + const std::string& prefix) { + const int C = desc.num_channels; + const int ffn = desc.ffn_channels; + const int H = m_board_y_size, W = m_board_x_size; + + if (!desc.use_swiglu) { + throw std::runtime_error(desc.name + ": non-SwiGLU transformer FFN not supported in CoreML backend"); + } + + auto reshape = [&](const std::string& in, const std::string& out, const std::vector& shapeVals, + const std::vector& dims) { + std::string shapeName = out + "_shape"; + addIntArrayConstOp(block, shapeName, shapeVals); + auto* op = block->add_operations(); + op->set_type("reshape"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(in); + (*op->mutable_inputs())["shape"].add_arguments()->set_name(shapeName); + setShape(op, out, dims); + }; + auto transpose = [&](const std::string& in, const std::string& out, const std::vector& perm, + const std::vector& dims) { + std::string permName = out + "_perm"; + addIntArrayConstOp(block, permName, perm); + auto* op = block->add_operations(); + op->set_type("transpose"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(in); + (*op->mutable_inputs())["perm"].add_arguments()->set_name(permName); + setShape(op, out, dims); + }; + auto matmul = [&](const std::string& x, const std::string& y, const std::string& out, + const std::vector& dims) { + std::string txName = out + "_tx", tyName = out + "_ty"; + addBoolScalarConstOp(block, txName, false); + addBoolScalarConstOp(block, tyName, false); + auto* op = block->add_operations(); + op->set_type("matmul"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["y"].add_arguments()->set_name(y); + (*op->mutable_inputs())["transpose_x"].add_arguments()->set_name(txName); + (*op->mutable_inputs())["transpose_y"].add_arguments()->set_name(tyName); + setShape(op, out, dims); + }; + auto binary = [&](const std::string& type, const std::string& x, const std::string& y, + const std::string& out, const std::vector& dims) { + auto* op = block->add_operations(); + op->set_type(type); + (*op->mutable_inputs())["x"].add_arguments()->set_name(x); + (*op->mutable_inputs())["y"].add_arguments()->set_name(y); + setShape(op, out, dims); + }; + + std::string normed = addTransformerRMSNorm(block, input, desc.pre_ln, mask, prefix + "_ln"); + std::string nhwc = genVarName(prefix + "_nhwc"); + transpose(normed, nhwc, {0, 2, 3, 1}, {-1, H, W, C}); + std::string x2d = genVarName(prefix + "_x2d"); + reshape(nhwc, x2d, {-1, C}, {-1, C}); + + // FFN matmuls in FP32 (weights cast up at runtime, stored fp16) — KataGo's FP16 convention is + // spatial(convs)=FP16, non-spatial(matmuls)=FP32 (see openclbackend.cpp). The ANE accumulates + // FP16 matmuls in FP16, which loses too much precision over C/ffn; run them in FP32 instead. + std::string w1 = prefix + "_w1"; + addConstOp(block, w1, desc.linear1.weights, desc.linear1.getWeightShape()); + std::string wg = prefix + "_wg"; + addConstOp(block, wg, desc.linear_gate.weights, desc.linear_gate.getWeightShape()); + std::string w2 = prefix + "_w2"; + addConstOp(block, w2, desc.linear2.weights, desc.linear2.getWeightShape()); + + auto savedDtype = m_weight_dtype; + std::string mx2d = x2d, mw1 = w1, mwg = wg, mw2 = w2; + if (m_nonspatial_fp32) { + mx2d = castFixed(block, x2d, "fp32", {-1, C}); + mw1 = castFixed(block, w1, "fp32", desc.linear1.getWeightShape()); + mwg = castFixed(block, wg, "fp32", desc.linear_gate.getWeightShape()); + mw2 = castFixed(block, w2, "fp32", desc.linear2.getWeightShape()); + m_weight_dtype = CoreML::Specification::MILSpec::DataType::FLOAT32; + } + std::string a = genVarName(prefix + "_a"); + matmul(mx2d, mw1, a, {-1, ffn}); + std::string g = genVarName(prefix + "_g"); + matmul(mx2d, mwg, g, {-1, ffn}); + + std::string sig = genVarName(prefix + "_sig"); + { + auto* op = block->add_operations(); + op->set_type("sigmoid"); + (*op->mutable_inputs())["x"].add_arguments()->set_name(a); + setShape(op, sig, {-1, ffn}); + } + std::string siluA = genVarName(prefix + "_silu"); + binary("mul", a, sig, siluA, {-1, ffn}); + std::string h = genVarName(prefix + "_h"); + binary("mul", siluA, g, h, {-1, ffn}); + + std::string oCore = genVarName(prefix + "_o"); + matmul(h, mw2, oCore, {-1, C}); + std::string o = oCore; + if (m_nonspatial_fp32) { + m_weight_dtype = savedDtype; + o = castFixed(block, oCore, "fp16", {-1, C}); + } + + std::string oNHWC = genVarName(prefix + "_onhwc"); + reshape(o, oNHWC, {-1, H, W, C}, {-1, H, W, C}); + std::string oNCHW = genVarName(prefix + "_onchw"); + transpose(oNHWC, oNCHW, {0, 3, 1, 2}, {-1, C, H, W}); + std::string maskedOut = genVarName(prefix + "_masked"); + binary("mul", oNCHW, mask, maskedOut, {-1, C, H, W}); + std::string out = genVarName(prefix + "_out"); + binary("add", input, maskedOut, out, {-1, C, H, W}); + return out; +} + std::string MILBuilder::buildTrunk(CoreML::Specification::MILSpec::Block* block, const std::string& spatial_input, const std::string& global_input, @@ -1747,12 +2722,23 @@ std::string MILBuilder::buildTrunk(CoreML::Specification::MILSpec::Block* block, } else if (entry.block_kind == NESTED_BOTTLENECK_BLOCK_KIND) { const auto& block_desc = std::get(*entry.block); x = buildNestedBottleneckBlock(block, x, block_desc, mask, prefix); + } else if (entry.block_kind == TRANSFORMER_ATTENTION_BLOCK_KIND) { + const auto& block_desc = std::get(*entry.block); + x = buildTransformerAttentionBlock(block, x, block_desc, mask, prefix); + } else if (entry.block_kind == TRANSFORMER_FFN_BLOCK_KIND) { + const auto& block_desc = std::get(*entry.block); + x = buildTransformerFFNBlock(block, x, block_desc, mask, prefix); } } // Trunk tip - std::string trunk_out = genVarName("trunk_tip"); - addBatchNormActivationOps(block, x, trunk.trunk_tip_bn, trunk.trunk_tip_activation, mask, trunk_out); + std::string trunk_out; + if (trunk.trunk_norm_kind == TRUNK_NORM_KIND_STANDARD) { + trunk_out = genVarName("trunk_tip"); + addBatchNormActivationOps(block, x, trunk.trunk_tip_bn, trunk.trunk_tip_activation, mask, trunk_out); + } else { + trunk_out = addTrunkRMSNorm(block, x, trunk.trunk_tip_rms_norm, trunk.trunk_tip_activation, mask, "trunk_tip_rms"); + } return trunk_out; } @@ -1814,9 +2800,11 @@ std::string MILBuilder::buildGlobalPoolingResidualBlock(CoreML::Specification::M std::string gpool_bn_out = genVarName(prefix + "_gpool_bn"); addBatchNormActivationOps(block, gpool_conv_out, block_desc.gpool_bn, block_desc.gpool_activation, mask, gpool_bn_out); - // Global pooling + // Global pooling (FP32 when m_nonspatial_fp32 -- see addGlobalPoolingFp32). Feeds a bias back + // into the whole trunk, so the FP16 spatial sum must not lose precision for wide trunks. std::string gpool_features = genVarName(prefix + "_gpool_features"); - addGlobalPoolingOps(block, gpool_bn_out, mask, block_desc.gpool_conv.out_channels, gpool_features); + addGlobalPoolingFp32(block, gpool_bn_out, mask, block_desc.gpool_conv.out_channels, gpool_features, + /*valueVariant=*/false); // Project to bias std::string gpool_bias = genVarName(prefix + "_gpool_bias"); @@ -1898,6 +2886,12 @@ std::string MILBuilder::buildNestedBottleneckBlock(CoreML::Specification::MILSpe } else if (entry.block_kind == GLOBAL_POOLING_BLOCK_KIND) { const auto& nested = std::get(*entry.block); x = buildGlobalPoolingResidualBlock(block, x, nested, mask, nested_prefix); + } else if (entry.block_kind == TRANSFORMER_ATTENTION_BLOCK_KIND) { + const auto& nested = std::get(*entry.block); + x = buildTransformerAttentionBlock(block, x, nested, mask, nested_prefix); + } else if (entry.block_kind == TRANSFORMER_FFN_BLOCK_KIND) { + const auto& nested = std::get(*entry.block); + x = buildTransformerFFNBlock(block, x, nested, mask, nested_prefix); } } @@ -1942,9 +2936,9 @@ void MILBuilder::buildPolicyHead(CoreML::Specification::MILSpec::Block* block, std::string g1 = genVarName("policy_g1"); addBatchNormActivationOps(block, g1_conv, ph.g1_bn, ph.g1_activation, mask, g1); - // Global pooling on G1 + // Global pooling on G1 (FP32 when m_nonspatial_fp32; feeds the policy bias / policyKLDiv). std::string g1_pooled = genVarName("policy_g1_pool"); - addGlobalPoolingOps(block, g1, mask, ph.g1_conv.out_channels, g1_pooled); + addGlobalPoolingFp32(block, g1, mask, ph.g1_conv.out_channels, g1_pooled, /*valueVariant=*/false); // Project to spatial bias std::string gpool_bias = genVarName("policy_gpool_bias"); @@ -2002,6 +2996,8 @@ void MILBuilder::buildPolicyHead(CoreML::Specification::MILSpec::Block* block, setTensorOutput2D(op, pass_activated, ph.gpool_to_pass_mul.out_channels); } else if (ph.pass_activation->activation_type == ActivationType::Mish) { addMishOps(block, pass_biased, pass_activated, 2, ph.gpool_to_pass_mul.out_channels); + } else if (ph.pass_activation->activation_type == ActivationType::Silu) { + addSiluOps(block, pass_biased, pass_activated, 2, ph.gpool_to_pass_mul.out_channels); } else { pass_activated = pass_biased; } @@ -2032,9 +3028,9 @@ void MILBuilder::buildValueHead(CoreML::Specification::MILSpec::Block* block, std::string v1 = genVarName("value_v1"); addBatchNormActivationOps(block, v1_conv, vh.v1_bn, vh.v1_activation, mask, v1); - // Global pooling (value head version) + // Global pooling (value head version; FP32 when m_nonspatial_fp32). std::string v1_pooled = genVarName("value_v1_pool"); - addGlobalPoolingValueOps(block, v1, mask, vh.v1_conv.out_channels, v1_pooled); + addGlobalPoolingFp32(block, v1, mask, vh.v1_conv.out_channels, v1_pooled, /*valueVariant=*/true); // V2: linear + activation (fused matmul+bias -> linear) std::string v2_bias = genVarName("value_v2_bias"); @@ -2049,6 +3045,8 @@ void MILBuilder::buildValueHead(CoreML::Specification::MILSpec::Block* block, setTensorOutput2D(op, v2, vh.v2_mul.out_channels); } else if (vh.v2_activation.activation_type == ActivationType::Mish) { addMishOps(block, v2_bias, v2, 2, vh.v2_mul.out_channels); + } else if (vh.v2_activation.activation_type == ActivationType::Silu) { + addSiluOps(block, v2_bias, v2, 2, vh.v2_mul.out_channels); } else { v2 = v2_bias; } @@ -2085,6 +3083,8 @@ std::string MILBuilder::buildSGFMetadataEncoder(CoreML::Specification::MILSpec:: setTensorOutput2D(op, act1, encoder.mul1.out_channels); } else if (encoder.act1.activation_type == ActivationType::Mish) { addMishOps(block, bias1, act1, 2, encoder.mul1.out_channels); + } else if (encoder.act1.activation_type == ActivationType::Silu) { + addSiluOps(block, bias1, act1, 2, encoder.mul1.out_channels); } else { // Identity activation - create identity op to preserve type information auto* op = block->add_operations(); @@ -2107,6 +3107,8 @@ std::string MILBuilder::buildSGFMetadataEncoder(CoreML::Specification::MILSpec:: setTensorOutput2D(op, act2, encoder.mul2.out_channels); } else if (encoder.act2.activation_type == ActivationType::Mish) { addMishOps(block, bias2, act2, 2, encoder.mul2.out_channels); + } else if (encoder.act2.activation_type == ActivationType::Silu) { + addSiluOps(block, bias2, act2, 2, encoder.mul2.out_channels); } else { // Identity activation - create identity op to preserve type information auto* op = block->add_operations(); diff --git a/cpp/external/katagocoreml/src/builder/MILBuilder.hpp b/cpp/external/katagocoreml/src/builder/MILBuilder.hpp index 042f9fc167..992f393a0b 100644 --- a/cpp/external/katagocoreml/src/builder/MILBuilder.hpp +++ b/cpp/external/katagocoreml/src/builder/MILBuilder.hpp @@ -29,13 +29,27 @@ class MILBuilder { /// @return Unique pointer to MIL Program protobuf std::unique_ptr build(); - /// Get weight entries for blob serialization - const std::vector& getWeights() const { return m_ops.getWeights(); } + /// Get weight entries for blob serialization (mutable; serialization sets blob_offset) + std::vector& getWeightsMutable() { return m_ops.getWeightsMutable(); } /// Get board dimensions int getBoardXSize() const { return m_board_x_size; } int getBoardYSize() const { return m_board_y_size; } + /// Effective precision flags after construction. The constructor may demote a narrow + /// transformer trunk to full FP32 (see the precision-tier comment in the .cpp); callers + /// serializing the model must use these, not the requested options, so the declared + /// Model-description I/O dtype and metadata match the actual MIL program dtypes. + bool getEffectiveUseFp16() const { return m_use_fp16; } + bool getEffectiveUseFp16IO() const { return m_use_fp16_io; } + + /// True if converting a model with this trunk width / transformer-ness would be demoted to + /// fully-FP32 compute even when FP16 is requested (see the precision-tier comment in the + /// .cpp). Exposed so callers can report effective precision without performing a conversion. + static bool wouldBuildFullyFp32(int trunk_num_channels, bool has_transformer_blocks) { + return has_transformer_blocks && trunk_num_channels < FULL_FP32_MAX_TRUNK_CHANNELS; + } + private: const KataGoModelDesc& m_model; int m_board_x_size; @@ -43,6 +57,28 @@ class MILBuilder { bool m_optimize_identity_mask; bool m_use_fp16; bool m_use_fp16_io; + // FP32-in-FP16-mode escalations all run off the FP16-only ANE, so they apply ONLY to transformer + // trunks (attention widens activation range, overflowing FP16 conv/matmul/pooling accumulation). + // Plain convnets run pure FP16 on the ANE -- the long-standing pre-tier path, verified to pass + // testgpuerror (b18c384nbt) and ~2.3x faster than forcing their per-block global pooling to FP32. + // For transformers: trunks below FULL_FP32_MAX_TRUNK_CHANNELS build fully FP32; at/above it they + // use non-spatial FP32 (matmuls + pooling) plus conv FP32 (>= CONV_FP32_MIN_TRUNK_CHANNELS). + // The two constants are currently equal, so there is no partial-tier band with FP16 convs; they + // are kept separate in case the boundaries ever need to diverge again. See the constructor + // comment in the .cpp for the measurements behind these values. RMSNorm reductions: FP32 when + // m_use_fp16. + static constexpr int CONV_FP32_MIN_TRUNK_CHANNELS = 320; // transformer convs run FP32 at/above this width + static constexpr int FULL_FP32_MAX_TRUNK_CHANNELS = 320; // transformer trunks below this build fully FP32 + // Escalate the attention scores/softmax/attn@V chain to FP32 in the partial tier. Measured on + // an M2 (b11c768, testgpuerror -quick, baseline 308s): fixes the worst observed fp16 margins + // (b10c384 rect leadError max 0.73x of limit -> 0.35x; ~10x better policyKLDiv) but costs + // ~1.7-2.3x eval time, because ANE<->CPU boundary transitions dominate, not FLOPs. Off by + // default: all current models pass with margin without it. If accuracy is ever preferred over + // ANE throughput, enable this (softmax-only escalation is NOT a valid cheaper substitute; it + // measured slower AND less accurate - see buildTransformerAttentionBlock). + static constexpr bool ATTENTION_CORE_FP32 = false; + bool m_nonspatial_fp32 = false; // = m_use_fp16 && hasTransformer (matmuls + global pooling) + bool m_conv_fp32 = false; // = m_use_fp16 && hasTransformer && trunk_channels >= CONV_FP32_MIN_... int m_min_batch_size; int m_max_batch_size; CoreML::Specification::MILSpec::DataType m_weight_dtype; @@ -80,6 +116,24 @@ class MILBuilder { const std::vector& data, const std::vector& shape); + // addConstOp registers a NON-OWNING view into `data` (see WeightEntry), so the + // backing storage must outlive serialization. Binding a temporary here would + // dangle. Deleted so such calls fail to compile; use addOwnedConstOp for + // derived/temporary tensors that KataGoOps should own instead. + void addConstOp(CoreML::Specification::MILSpec::Block* block, + const std::string& name, + std::vector&& data, + const std::vector& shape) = delete; + + void addOwnedConstOp(CoreML::Specification::MILSpec::Block* block, + const std::string& name, + std::vector&& data, + const std::vector& shape); + + void emitConstOp(CoreML::Specification::MILSpec::Block* block, + const std::string& name, + const std::vector& shape); + void addIntArrayConstOp(CoreML::Specification::MILSpec::Block* block, const std::string& name, const std::vector& values); @@ -102,6 +156,23 @@ class MILBuilder { const std::string& dtype, const std::vector& shape); + // Cast to a tensor with FULLY-specified dims (no forced batch dim like addCastOp). Use for + // weight tensors (fixed [in,out] dims) when running an otherwise-FP16 op in FP32. Returns the + // new tensor name. dims use -1 for an unknown/batch dim, >=0 for a constant dim. + std::string castFixed(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const std::string& dtype, + const std::vector& dims); + + // Emit global pooling, running it in FP32 when m_nonspatial_fp32 (cast input/mask up, pool, + // cast the pooled features back to FP16). valueVariant selects the value-head pooling variant. + void addGlobalPoolingFp32(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const std::string& mask, + int channels, + const std::string& output, + bool valueVariant); + void addConvOp(CoreML::Specification::MILSpec::Block* block, const std::string& input, const ConvLayerDesc& layer, @@ -120,6 +191,44 @@ class MILBuilder { int rank, int channels); + void addSiluOps(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const std::string& output, + int rank, + int channels); + + // Generic output-shape setter: dims with -1 entries become unknown/dynamic dimensions. + void setShape(CoreML::Specification::MILSpec::Operation* op, + const std::string& name, + const std::vector& dims); + + // Lightweight transformer RMSNorm (weight only, per-position over channels). NCHW in/out. + std::string addTransformerRMSNorm(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const TransformerRMSNormDesc& desc, + const std::string& mask, + const std::string& prefix); + + // Full RMSNorm at trunk tip: gamma/beta, spatial or per-position, fused activation. NCHW in/out. + std::string addTrunkRMSNorm(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const RMSNormLayerDesc& desc, + const ActivationLayerDesc& act, + const std::string& mask, + const std::string& prefix); + + std::string buildTransformerAttentionBlock(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const TransformerAttentionBlockDesc& block_desc, + const std::string& mask, + const std::string& prefix); + + std::string buildTransformerFFNBlock(CoreML::Specification::MILSpec::Block* block, + const std::string& input, + const TransformerFFNBlockDesc& block_desc, + const std::string& mask, + const std::string& prefix); + void addGlobalPoolingOps(CoreML::Specification::MILSpec::Block* block, const std::string& input, const std::string& mask, diff --git a/cpp/external/katagocoreml/src/builder/Operations.cpp b/cpp/external/katagocoreml/src/builder/Operations.cpp index c0c0362924..e863649434 100644 --- a/cpp/external/katagocoreml/src/builder/Operations.cpp +++ b/cpp/external/katagocoreml/src/builder/Operations.cpp @@ -14,12 +14,30 @@ KataGoOps::KataGoOps(int board_x_size, int board_y_size, bool optimize_identity_ std::string KataGoOps::registerWeight(const std::string& name, const std::vector& data, - const std::vector& shape) { + const std::vector& shape, + bool is_fp32) { WeightEntry entry; entry.name = name; - entry.data = data; + entry.data = FloatView{data.data(), data.size()}; entry.shape = shape; entry.blob_offset = 0; // Will be set during serialization + entry.is_fp32 = is_fp32; + m_weights.push_back(std::move(entry)); + return name; +} + +std::string KataGoOps::registerOwnedWeight(const std::string& name, + std::vector&& data, + const std::vector& shape, + bool is_fp32) { + m_owned.push_back(std::move(data)); + const std::vector& stored = m_owned.back(); + WeightEntry entry; + entry.name = name; + entry.data = FloatView{stored.data(), stored.size()}; + entry.shape = shape; + entry.blob_offset = 0; + entry.is_fp32 = is_fp32; m_weights.push_back(std::move(entry)); return name; } diff --git a/cpp/external/katagocoreml/src/builder/Operations.hpp b/cpp/external/katagocoreml/src/builder/Operations.hpp index 3fc72ad885..5e207f056b 100644 --- a/cpp/external/katagocoreml/src/builder/Operations.hpp +++ b/cpp/external/katagocoreml/src/builder/Operations.hpp @@ -5,17 +5,33 @@ #include "../types/KataGoTypes.hpp" #include +#include #include #include namespace katagocoreml { -/// Weight entry for blob file storage +/// Minimal non-owning view over a contiguous float buffer. KataGo-local on +/// purpose: keeps the MILBlob dependency out of this header (conversion to +/// MILBlob::Util::Span happens only at the serializer boundary). +struct FloatView { + const float* ptr = nullptr; + size_t len = 0; + const float* data() const { return ptr; } + size_t size() const { return len; } + bool empty() const { return len == 0; } + float operator[](size_t i) const { return ptr[i]; } +}; + +/// Weight entry for blob file storage. `data` is a NON-OWNING view into the live +/// KataGoModelDesc (or into KataGoOps::m_owned for derived tensors). struct WeightEntry { std::string name; - std::vector data; + FloatView data; // non-owning view (replaces raw ptr + count) std::vector shape; uint64_t blob_offset = 0; // Set during serialization + bool is_fp32 = false; // Store as FP32 (set when the const was declared FP32, e.g. inside an + // FP32 sub-region of an otherwise-FP16 model). Else stored per global mode. }; /// Precomputed constants for identity mask optimization @@ -51,16 +67,37 @@ class KataGoOps { /// Get precomputed mask constants const MaskConstants& getMaskConstants() const { return m_mask_constants; } - /// Register a weight tensor and return its reference name + /// Register a weight that lives in the model (stored as a non-owning view). + /// is_fp32 marks it for FP32 storage. std::string registerWeight(const std::string& name, const std::vector& data, - const std::vector& shape); + const std::vector& shape, + bool is_fp32 = false); + + /// The stored WeightEntry is a non-owning view into `data`, so a temporary + /// would leave it dangling. Deleted to reject such calls at compile time; + /// use registerOwnedWeight for tensors KataGoOps should own. The defaulted + /// is_fp32 mirrors the live overload so rvalue calls with OR without an + /// explicit is_fp32 both resolve here (and fail) instead of silently + /// binding the temporary to the const& overload. + std::string registerWeight(const std::string& name, + std::vector&& data, + const std::vector& shape, + bool is_fp32 = false) = delete; + + /// Register a derived/temporary weight; KataGoOps takes ownership so the + /// view stays valid through serialization. is_fp32 marks it for FP32 storage + /// (mirrors registerWeight) so the stored dtype matches the declared const dtype. + std::string registerOwnedWeight(const std::string& name, + std::vector&& data, + const std::vector& shape, + bool is_fp32 = false); - /// Get all registered weights - const std::vector& getWeights() const { return m_weights; } + /// Get all registered weights (mutable; serialization sets blob_offset) + std::vector& getWeightsMutable() { return m_weights; } - /// Clear all registered weights - void clearWeights() { m_weights.clear(); } + /// Clear all registered weights (and their owned backing buffers) + void clearWeights() { m_weights.clear(); m_owned.clear(); } /// Generate unique operation name std::string genOpName(const std::string& prefix); @@ -71,6 +108,7 @@ class KataGoOps { bool m_optimize_identity_mask; MaskConstants m_mask_constants; std::vector m_weights; + std::deque> m_owned; int m_op_counter = 0; }; diff --git a/cpp/external/katagocoreml/src/parser/KataGoParser.cpp b/cpp/external/katagocoreml/src/parser/KataGoParser.cpp index 68f1a0e56f..79f832ba46 100644 --- a/cpp/external/katagocoreml/src/parser/KataGoParser.cpp +++ b/cpp/external/katagocoreml/src/parser/KataGoParser.cpp @@ -5,12 +5,23 @@ #include #include #include -#include +#include #include #include namespace katagocoreml { +namespace { +// Cross-field dimension consistency check, mirroring desc.cpp's pattern of named errors. +// Takes int64_t so callers can pass products like numChannels*3 without signed-int overflow UB. +void checkDimsEqual(const std::string& name, const char* aDesc, int64_t a, const char* bDesc, int64_t b) { + if (a != b) { + throw std::runtime_error(name + ": " + aDesc + " (" + std::to_string(a) + ") != " + + bDesc + " (" + std::to_string(b) + ")"); + } +} +} // namespace + // ============================================================================ // Constructor // ============================================================================ @@ -30,54 +41,51 @@ bool KataGoParser::isVersionSupported(int version) { } // ============================================================================ -// File Loading +// Stream Primitives // ============================================================================ -void KataGoParser::loadFile() { - // Check if gzip compressed - bool is_gzip = false; - if (m_model_path.size() >= 3) { - std::string ext = m_model_path.substr(m_model_path.size() - 3); - is_gzip = (ext == ".gz"); +bool KataGoParser::refill() { + if(!m_gz) return false; + int n = gzread(m_gz.get(), m_refill.data(), (unsigned)m_refill.size()); + if(n < 0) { + int errnum; + const char* errmsg = gzerror(m_gz.get(), &errnum); + throw std::runtime_error("Error reading gzip stream: " + std::string(errmsg)); } + if(n == 0) { + // gzread reports some stream problems as a 0-byte read at EOF rather than + // a negative return - notably a missing/truncated gzip trailer surfaces as + // Z_BUF_ERROR "unexpected end of file" - so an EOF must still be checked + // via gzerror before being treated as a clean end of stream. + int errnum = Z_OK; + const char* errmsg = gzerror(m_gz.get(), &errnum); + if(errnum != Z_OK) + throw std::runtime_error("Error reading gzip stream: " + std::string(errmsg)); + } + m_refillPos = 0; + m_refillLen = (size_t)n; + return n > 0; +} - if (is_gzip) { - // Read gzipped file - gzFile gz = gzopen(m_model_path.c_str(), "rb"); - if (!gz) { - throw std::runtime_error("Cannot open gzip file: " + m_model_path); - } - - // Read in chunks - m_buffer.clear(); - std::vector chunk(1024 * 1024); // 1MB chunks - int bytes_read; - while ((bytes_read = gzread(gz, chunk.data(), static_cast(chunk.size()))) > 0) { - m_buffer.insert(m_buffer.end(), chunk.begin(), chunk.begin() + bytes_read); - } - - if (bytes_read < 0) { - int errnum; - const char* errmsg = gzerror(gz, &errnum); - gzclose(gz); - throw std::runtime_error("Error reading gzip file: " + std::string(errmsg)); - } - - gzclose(gz); - } else { - // Read regular file - std::ifstream file(m_model_path, std::ios::binary | std::ios::ate); - if (!file) { - throw std::runtime_error("Cannot open file: " + m_model_path); - } - - std::streamsize size = file.tellg(); - file.seekg(0, std::ios::beg); +int KataGoParser::peekByte() { + if(m_refillPos >= m_refillLen) { + if(!refill()) return -1; + } + return (int)m_refill[m_refillPos]; +} - m_buffer.resize(static_cast(size)); - if (!file.read(reinterpret_cast(m_buffer.data()), size)) { - throw std::runtime_error("Error reading file: " + m_model_path); +void KataGoParser::readExact(uint8_t* dst, size_t n, const std::string& name) { + size_t got = 0; + while(got < n) { + if(m_refillPos >= m_refillLen) { + if(!refill()) + throw std::runtime_error(name + ": unexpected EOF in binary block"); } + size_t avail = m_refillLen - m_refillPos; + size_t take = std::min(avail, n - got); + std::memcpy(dst + got, m_refill.data() + m_refillPos, take); + m_refillPos += take; + got += take; } } @@ -86,16 +94,29 @@ void KataGoParser::loadFile() { // ============================================================================ KataGoModelDesc KataGoParser::parse() { - loadFile(); - m_pos = 0; - - // Detect if binary format (check for @BIN@ marker) - const std::string bin_marker = "@BIN@"; - auto it = std::search(m_buffer.begin(), m_buffer.end(), - bin_marker.begin(), bin_marker.end()); - m_binary_floats = (it != m_buffer.end()); + // Allocate the refill buffer first; if this throws, no handle has been opened. + m_refill.resize(1024 * 1024); + m_gz.reset(gzopen(m_model_path.c_str(), "rb")); + if(!m_gz) + throw std::runtime_error("Cannot open file: " + m_model_path); + m_refillPos = 0; + m_refillLen = 0; + m_formatDetected = false; // decided at first readFloats + m_binary_floats = true; + // ~GzHandle closes the file on normal return OR exception — no try/catch needed. + KataGoModelDesc model = parseModel(); + + // Drain to end-of-stream so zlib verifies the gzip integrity trailer (CRC32 + + // length). Streaming reads stop at the last byte the model needs, but zlib only + // checks the trailer when the stream is read through EOF — without this, a + // truncated or tail-corrupted .gz would convert "successfully". (The old + // buffer-the-whole-file loader read to EOF and got this check implicitly; + // refill() throws on the gzread error that a bad trailer produces.) + do { + m_refillPos = m_refillLen; + } while(refill()); - return parseModel(); + return model; } // ============================================================================ @@ -103,24 +124,20 @@ KataGoModelDesc KataGoParser::parse() { // ============================================================================ void KataGoParser::skipWhitespace() { - while (m_pos < m_buffer.size()) { - char c = static_cast(m_buffer[m_pos]); - if (c != ' ' && c != '\t' && c != '\n' && c != '\r') { - break; - } - m_pos++; + int c; + while((c = peekByte()) >= 0) { + if(c != ' ' && c != '\t' && c != '\n' && c != '\r') break; + m_refillPos++; } } void KataGoParser::readUntilWhitespace(std::string& out) { out.clear(); - while (m_pos < m_buffer.size()) { - char c = static_cast(m_buffer[m_pos]); - if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { - break; - } - out += c; - m_pos++; + int c; + while((c = peekByte()) >= 0) { + if(c == ' ' || c == '\t' || c == '\n' || c == '\r') break; + out += (char)c; + m_refillPos++; } } @@ -133,12 +150,24 @@ std::string KataGoParser::readString() { int KataGoParser::readInt() { std::string token = readString(); - return std::stoi(token); + try { + return std::stoi(token); + } catch (const std::exception&) { + throw std::runtime_error( + "model file parse error: expected integer, got \"" + token + "\"" + + (token.empty() ? " (unexpected end of file?)" : "")); + } } float KataGoParser::readFloat() { std::string token = readString(); - return std::stof(token); + try { + return std::stof(token); + } catch (const std::exception&) { + throw std::runtime_error( + "model file parse error: expected float, got \"" + token + "\"" + + (token.empty() ? " (unexpected end of file?)" : "")); + } } bool KataGoParser::readBool() { @@ -146,38 +175,44 @@ bool KataGoParser::readBool() { } std::vector KataGoParser::readFloats(size_t count, const std::string& name) { - std::vector floats(count); + // Grow the output only as bytes actually arrive from the stream, never by trusting + // `count` up front: dimensions are attacker-controlled, and a crafted header (a few + // KB gzipped) declaring e.g. 10^11 weights would otherwise commit hundreds of GB of + // zero-initialized memory before the first read could fail. With incremental growth, + // peak memory is bounded by the actual decompressed data, and a short file fails in + // readExact/readFloat with a clean EOF error instead. + std::vector floats; + skipWhitespace(); + + // KataGo model files are uniformly text OR uniformly binary, so detecting the + // format once at the first weight block (binary blocks start with '@BIN@') + // is valid for all subsequent blocks. + if(!m_formatDetected) { + m_binary_floats = (peekByte() == '@'); + m_formatDetected = true; + } - if (!m_binary_floats) { + // Floats per growth step (4 MB); also caps the initial reserve. + constexpr size_t CHUNK_FLOATS = size_t(1) << 20; + + if(!m_binary_floats) { // Text format - for (size_t i = 0; i < count; i++) { - floats[i] = readFloat(); - } + floats.reserve(std::min(count, CHUNK_FLOATS)); + for(size_t i = 0; i < count; i++) + floats.push_back(readFloat()); } else { - // Binary format - find @BIN@ marker - while (m_pos < m_buffer.size()) { - if (m_buffer[m_pos] == '@') { - break; - } - m_pos++; - } - - // Check for @BIN@ header - if (m_pos + 5 > m_buffer.size() || - std::memcmp(&m_buffer[m_pos], "@BIN@", 5) != 0) { + // Binary: consume the "@BIN@" marker, then read count*4 raw bytes. + char marker[5]; + readExact(reinterpret_cast(marker), 5, name); + if(std::memcmp(marker, "@BIN@", 5) != 0) throw std::runtime_error(name + ": expected @BIN@ marker for binary float block"); - } - m_pos += 5; - // Read binary floats (little-endian) - size_t num_bytes = count * 4; - if (m_pos + num_bytes > m_buffer.size()) { - throw std::runtime_error(name + ": not enough bytes for " + std::to_string(count) + " floats"); + while(floats.size() < count) { + size_t take = std::min(CHUNK_FLOATS, count - floats.size()); + size_t done = floats.size(); + floats.resize(done + take); + readExact(reinterpret_cast(floats.data() + done), take * 4, name); } - - // Copy as little-endian float32 - std::memcpy(floats.data(), &m_buffer[m_pos], num_bytes); - m_pos += num_bytes; } // Reject NaN/Inf weights: corrupted or otherwise invalid models would @@ -223,9 +258,21 @@ ConvLayerDesc KataGoParser::parseConvLayer() { std::to_string(layer.conv_x_size)); } - // Read weights in file order: [y, x, ic, oc] - size_t num_weights = static_cast(layer.conv_y_size) * layer.conv_x_size * - layer.in_channels * layer.out_channels; + // Read weights in file order: [y, x, ic, oc]. Multiply with an overflow check: four + // attacker-controlled 31-bit ints can wrap a 64-bit product, and a wrapped-small + // num_weights would pass the readFloats bounds check while the transpose loops below + // still iterate the full unwrapped ranges, indexing far out of bounds. + auto checkedMul = [&layer](size_t a, size_t b) { + if (b != 0 && a > std::numeric_limits::max() / b) { + throw std::runtime_error(layer.name + ": conv weight count overflows"); + } + return a * b; + }; + size_t num_weights = checkedMul( + checkedMul( + checkedMul(static_cast(layer.conv_y_size), static_cast(layer.conv_x_size)), + static_cast(layer.in_channels)), + static_cast(layer.out_channels)); std::vector weights_flat = readFloats(num_weights, layer.name); // Transpose from [y, x, ic, oc] to [oc, ic, y, x] @@ -271,9 +318,10 @@ BatchNormLayerDesc KataGoParser::parseBatchNormLayer() { std::to_string(layer.num_channels)); } // epsilon == 0 with variance == 0 would divide by zero in the merged-scale - // formula below and produce Inf weights. Match master desc.cpp's check. - if (layer.epsilon <= 0.0f) { - throw std::runtime_error(layer.name + ": batchnorm epsilon must be > 0, got " + + // formula below and produce Inf weights. Written NaN-safe and finite-checked + // (stof accepts "nan"/"inf" tokens, and NaN passes a `<= 0` comparison). + if (!(layer.epsilon > 0.0f) || !std::isfinite(layer.epsilon)) { + throw std::runtime_error(layer.name + ": batchnorm epsilon must be positive and finite, got " + std::to_string(layer.epsilon)); } @@ -315,6 +363,8 @@ ActivationLayerDesc KataGoParser::parseActivationLayer(int model_version) { layer.activation_type = ActivationType::ReLU; } else if (activation_str == "ACTIVATION_MISH") { layer.activation_type = ActivationType::Mish; + } else if (activation_str == "ACTIVATION_SILU") { + layer.activation_type = ActivationType::Silu; } else { throw std::runtime_error("Unknown activation type: " + activation_str); } @@ -332,6 +382,13 @@ MatMulLayerDesc KataGoParser::parseMatMulLayer() { layer.in_channels = readInt(); layer.out_channels = readInt(); + // Matches desc.cpp; a negative count would wrap the size_t product below. + if (layer.in_channels < 1 || layer.out_channels < 1) { + throw std::runtime_error(layer.name + ": matmul channels must be positive, got in=" + + std::to_string(layer.in_channels) + " out=" + + std::to_string(layer.out_channels)); + } + // Weights in [ic, oc] order size_t num_weights = static_cast(layer.in_channels) * layer.out_channels; layer.weights = readFloats(num_weights, layer.name); @@ -343,6 +400,10 @@ MatBiasLayerDesc KataGoParser::parseMatBiasLayer() { MatBiasLayerDesc layer; layer.name = readString(); layer.num_channels = readInt(); + if (layer.num_channels < 1) { + throw std::runtime_error(layer.name + ": matbias numChannels must be >= 1, got " + + std::to_string(layer.num_channels)); + } layer.weights = readFloats(layer.num_channels, layer.name); return layer; @@ -362,6 +423,14 @@ ResidualBlockDesc KataGoParser::parseResidualBlock(int model_version) { block.mid_activation = parseActivationLayer(model_version); block.final_conv = parseConvLayer(); + // Internal cross-checks, matching desc.cpp. + checkDimsEqual(block.name, "preBN.numChannels", block.pre_bn.num_channels, + "regularConv.inChannels", block.regular_conv.in_channels); + checkDimsEqual(block.name, "midBN.numChannels", block.mid_bn.num_channels, + "regularConv.outChannels", block.regular_conv.out_channels); + checkDimsEqual(block.name, "midBN.numChannels", block.mid_bn.num_channels, + "finalConv.inChannels", block.final_conv.in_channels); + return block; } @@ -380,6 +449,22 @@ GlobalPoolingResidualBlockDesc KataGoParser::parseGlobalPoolingResidualBlock(int block.mid_activation = parseActivationLayer(model_version); block.final_conv = parseConvLayer(); + // Internal cross-checks, matching desc.cpp. + checkDimsEqual(block.name, "preBN.numChannels", block.pre_bn.num_channels, + "regularConv.inChannels", block.regular_conv.in_channels); + checkDimsEqual(block.name, "preBN.numChannels", block.pre_bn.num_channels, + "gpoolConv.inChannels", block.gpool_conv.in_channels); + checkDimsEqual(block.name, "gpoolBN.numChannels", block.gpool_bn.num_channels, + "gpoolConv.outChannels", block.gpool_conv.out_channels); + checkDimsEqual(block.name, "gpoolBN.numChannels * 3", (int64_t)block.gpool_bn.num_channels * 3, + "gpoolToBiasMul.inChannels", block.gpool_to_bias_mul.in_channels); + checkDimsEqual(block.name, "midBN.numChannels", block.mid_bn.num_channels, + "regularConv.outChannels", block.regular_conv.out_channels); + checkDimsEqual(block.name, "midBN.numChannels", block.mid_bn.num_channels, + "gpoolToBiasMul.outChannels", block.gpool_to_bias_mul.out_channels); + checkDimsEqual(block.name, "midBN.numChannels", block.mid_bn.num_channels, + "finalConv.inChannels", block.final_conv.in_channels); + return block; } @@ -387,6 +472,10 @@ NestedBottleneckResidualBlockDesc KataGoParser::parseNestedBottleneckBlock(int m NestedBottleneckResidualBlockDesc block; block.name = readString(); block.num_blocks = readInt(); + if (block.num_blocks < 1) { + throw std::runtime_error(block.name + ": nested bottleneck res block num blocks must be positive, got " + + std::to_string(block.num_blocks)); + } block.pre_bn = parseBatchNormLayer(); block.pre_activation = parseActivationLayer(model_version); @@ -398,6 +487,14 @@ NestedBottleneckResidualBlockDesc KataGoParser::parseNestedBottleneckBlock(int m block.post_activation = parseActivationLayer(model_version); block.post_conv = parseConvLayer(); + // Internal cross-checks, matching desc.cpp. + checkDimsEqual(block.name, "preBN.numChannels", block.pre_bn.num_channels, + "preConv.inChannels", block.pre_conv.in_channels); + checkDimsEqual(block.name, "postBN.numChannels", block.post_bn.num_channels, + "preConv.outChannels", block.pre_conv.out_channels); + checkDimsEqual(block.name, "postBN.numChannels", block.post_bn.num_channels, + "postConv.inChannels", block.post_conv.in_channels); + return block; } @@ -420,6 +517,152 @@ static void checkBlockChannels(const std::string& block_name, const std::string& } } +TransformerRMSNormDesc KataGoParser::parseTransformerRMSNorm() { + TransformerRMSNormDesc layer; + layer.name = readString(); + layer.num_channels = readInt(); + layer.epsilon = readFloat(); + if (layer.num_channels < 1) { + throw std::runtime_error(layer.name + ": transformer rmsnorm numChannels must be >= 1"); + } + // Matches desc.cpp; epsilon <= 0 makes rsqrt(0+0)=inf at masked-off positions and NaN + // then propagates silently through the whole net. Written NaN-safe (!(x > 0) catches NaN). + if (!(layer.epsilon > 0.0f) || layer.epsilon > 1.0f) { + throw std::runtime_error(layer.name + ": transformer rmsnorm epsilon is not positive or is too large"); + } + layer.weight = readFloats(layer.num_channels, layer.name + "/weight"); + return layer; +} + +RMSNormLayerDesc KataGoParser::parseRMSNormLayer() { + RMSNormLayerDesc layer; + layer.name = readString(); + layer.num_channels = readInt(); + layer.epsilon = readFloat(); + layer.spatial = (readInt() != 0); + layer.cgroup_size = readInt(); + if (layer.num_channels < 1) { + throw std::runtime_error(layer.name + ": rmsnorm numChannels must be >= 1"); + } + if (layer.cgroup_size != 0) { + throw std::runtime_error(layer.name + ": grouped spatial RMSNorm is not supported"); + } + // Matches desc.cpp (see parseTransformerRMSNorm for rationale; NaN-safe form). + if (!(layer.epsilon > 0.0f) || layer.epsilon > 1.0f) { + throw std::runtime_error(layer.name + ": rmsnorm epsilon is not positive or is too large"); + } + layer.gamma = readFloats(layer.num_channels, layer.name + "/gamma"); + layer.beta = readFloats(layer.num_channels, layer.name + "/beta"); + return layer; +} + +TransformerAttentionBlockDesc KataGoParser::parseTransformerAttentionBlock(int model_version) { + TransformerAttentionBlockDesc block; + block.name = readString(); + block.num_heads = readInt(); + block.num_kv_heads = readInt(); + block.q_head_dim = readInt(); + block.v_head_dim = readInt(); + block.use_rope = (readInt() != 0); + block.learnable_rope = (readInt() != 0); + + if (block.num_heads < 1 || block.num_kv_heads < 1 || (block.num_heads % block.num_kv_heads != 0)) { + throw std::runtime_error(block.name + ": invalid numHeads/numKVHeads"); + } + if (block.q_head_dim < 1 || block.v_head_dim < 1) { + throw std::runtime_error(block.name + ": head dims must be positive"); + } + if (block.use_rope && (block.q_head_dim % 2 != 0)) { + throw std::runtime_error(block.name + ": qHeadDim must be even when RoPE is used"); + } + + block.pre_ln = parseTransformerRMSNorm(); + block.q_proj = parseMatMulLayer(); + block.k_proj = parseMatMulLayer(); + block.v_proj = parseMatMulLayer(); + block.out_proj = parseMatMulLayer(); + + // Cross-check projection dims against the header, matching desc.cpp. The MIL builder + // slices out_proj.weights assuming in_channels == numHeads*vHeadDim, so without the + // out_proj check a malformed file causes a heap out-of-bounds read in the converter; + // the others would only surface as cryptic CoreML shape errors. + if (block.q_proj.out_channels != (int64_t)block.num_heads * block.q_head_dim) { + throw std::runtime_error(block.name + ": qProj.outChannels (" + std::to_string(block.q_proj.out_channels) + + ") != numHeads*qHeadDim (" + std::to_string((int64_t)block.num_heads * block.q_head_dim) + ")"); + } + if (block.k_proj.out_channels != (int64_t)block.num_kv_heads * block.q_head_dim) { + throw std::runtime_error(block.name + ": kProj.outChannels (" + std::to_string(block.k_proj.out_channels) + + ") != numKVHeads*qHeadDim (" + std::to_string((int64_t)block.num_kv_heads * block.q_head_dim) + ")"); + } + if (block.v_proj.out_channels != (int64_t)block.num_kv_heads * block.v_head_dim) { + throw std::runtime_error(block.name + ": vProj.outChannels (" + std::to_string(block.v_proj.out_channels) + + ") != numKVHeads*vHeadDim (" + std::to_string((int64_t)block.num_kv_heads * block.v_head_dim) + ")"); + } + if (block.out_proj.in_channels != (int64_t)block.num_heads * block.v_head_dim) { + throw std::runtime_error(block.name + ": outProj.inChannels (" + std::to_string(block.out_proj.in_channels) + + ") != numHeads*vHeadDim (" + std::to_string((int64_t)block.num_heads * block.v_head_dim) + ")"); + } + + if (block.use_rope) { + if (block.learnable_rope) { + readString(); // ropeFreqs name + block.rope_num_kv_heads = readInt(); + block.rope_num_pairs = readInt(); + int rope_dim2 = readInt(); + if (block.rope_num_kv_heads != block.num_kv_heads || + block.rope_num_pairs != block.q_head_dim / 2 || rope_dim2 != 2) { + throw std::runtime_error(block.name + ": invalid learnable rope header"); + } + block.rope_freqs = readFloats( + static_cast(block.rope_num_kv_heads) * block.rope_num_pairs * 2, + block.name + "/rope_freqs"); + } else { + readString(); // ropeTheta name + block.rope_theta = readFloat(); + // Matches desc.cpp; theta <= 0 (or NaN/inf, which readFloat accepts for scalars) + // would silently bake NaN/garbage RoPE tables into a structurally valid model. + if (!(block.rope_theta > 0.0f) || !std::isfinite(block.rope_theta)) { + throw std::runtime_error(block.name + ": rope theta must be positive and finite"); + } + } + } + return block; +} + +TransformerFFNBlockDesc KataGoParser::parseTransformerFFNBlock(int model_version) { + TransformerFFNBlockDesc block; + block.name = readString(); + block.num_channels = readInt(); + block.ffn_channels = readInt(); + block.use_swiglu = (readInt() != 0); + if (block.num_channels < 1 || block.ffn_channels < 1) { + throw std::runtime_error(block.name + ": transformer ffn channels must be positive"); + } + block.pre_ln = parseTransformerRMSNorm(); + block.linear1 = parseMatMulLayer(); + if (block.use_swiglu) { + block.linear_gate = parseMatMulLayer(); + } + block.linear2 = parseMatMulLayer(); + + // Cross-check layer dims against the header, matching desc.cpp; mismatches would + // otherwise surface as cryptic CoreML shape errors at compile/load time. + if (block.linear1.in_channels != block.num_channels || block.linear1.out_channels != block.ffn_channels) { + throw std::runtime_error(block.name + ": linear1 dims (" + std::to_string(block.linear1.in_channels) + + "->" + std::to_string(block.linear1.out_channels) + ") do not match numChannels->ffnChannels"); + } + if (block.use_swiglu && + (block.linear_gate.in_channels != block.num_channels || block.linear_gate.out_channels != block.ffn_channels)) { + throw std::runtime_error(block.name + ": linearGate dims (" + std::to_string(block.linear_gate.in_channels) + + "->" + std::to_string(block.linear_gate.out_channels) + ") do not match numChannels->ffnChannels"); + } + if (block.linear2.in_channels != block.ffn_channels || block.linear2.out_channels != block.num_channels) { + throw std::runtime_error(block.name + ": linear2 dims (" + std::to_string(block.linear2.in_channels) + + "->" + std::to_string(block.linear2.out_channels) + ") do not match ffnChannels->numChannels"); + } + return block; +} + std::vector KataGoParser::parseBlockStack(int model_version, int num_blocks, int trunk_num_channels) { std::vector blocks; blocks.reserve(num_blocks); @@ -449,6 +692,27 @@ std::vector KataGoParser::parseBlockStack(int model_version, int num desc.pre_bn.num_channels, desc.post_conv.out_channels, trunk_num_channels); entry.block = std::make_shared(std::move(desc)); + } else if (block_kind_name == "transformer_attention_block") { + entry.block_kind = TRANSFORMER_ATTENTION_BLOCK_KIND; + auto desc = parseTransformerAttentionBlock(model_version); + // Matches desc.cpp's trunk-channel cross-checks for transformer blocks. + if (desc.q_proj.in_channels != trunk_num_channels) { + throw std::runtime_error(desc.name + ": qProj.inChannels (" + std::to_string(desc.q_proj.in_channels) + + ") != trunkNumChannels (" + std::to_string(trunk_num_channels) + ")"); + } + if (desc.out_proj.out_channels != trunk_num_channels) { + throw std::runtime_error(desc.name + ": outProj.outChannels (" + std::to_string(desc.out_proj.out_channels) + + ") != trunkNumChannels (" + std::to_string(trunk_num_channels) + ")"); + } + entry.block = std::make_shared(std::move(desc)); + } else if (block_kind_name == "transformer_ffn_block") { + entry.block_kind = TRANSFORMER_FFN_BLOCK_KIND; + auto desc = parseTransformerFFNBlock(model_version); + if (desc.num_channels != trunk_num_channels) { + throw std::runtime_error(desc.name + ": numChannels (" + std::to_string(desc.num_channels) + + ") != trunkNumChannels (" + std::to_string(trunk_num_channels) + ")"); + } + entry.block = std::make_shared(std::move(desc)); } else { throw std::runtime_error("Unknown block kind: " + block_kind_name); } @@ -469,6 +733,14 @@ SGFMetadataEncoderDesc KataGoParser::parseSGFMetadataEncoder(int model_version, encoder.meta_encoder_version = meta_encoder_version; encoder.num_input_meta_channels = readInt(); + // desc.cpp validates the declared count against NNModelVersion::getNumInputMetaChannels; + // for the only supported metaEncoderVersion (1) that is 192, which parseModel also hardcodes. + if (meta_encoder_version == 1 && encoder.num_input_meta_channels != 192) { + throw std::runtime_error(encoder.name + ": numInputMetaChannels (" + + std::to_string(encoder.num_input_meta_channels) + + ") != 192 expected for metaEncoderVersion 1"); + } + encoder.mul1 = parseMatMulLayer(); encoder.bias1 = parseMatBiasLayer(); encoder.act1 = parseActivationLayer(model_version); @@ -477,6 +749,16 @@ SGFMetadataEncoderDesc KataGoParser::parseSGFMetadataEncoder(int model_version, encoder.act2 = parseActivationLayer(model_version); encoder.mul3 = parseMatMulLayer(); + // Internal cross-checks, matching desc.cpp. + checkDimsEqual(encoder.name, "mul1.outChannels", encoder.mul1.out_channels, + "bias1.numChannels", encoder.bias1.num_channels); + checkDimsEqual(encoder.name, "mul2.inChannels", encoder.mul2.in_channels, + "mul1.outChannels", encoder.mul1.out_channels); + checkDimsEqual(encoder.name, "mul2.outChannels", encoder.mul2.out_channels, + "bias2.numChannels", encoder.bias2.num_channels); + checkDimsEqual(encoder.name, "mul3.inChannels", encoder.mul3.in_channels, + "mul2.outChannels", encoder.mul2.out_channels); + return encoder; } @@ -506,20 +788,21 @@ TrunkDesc KataGoParser::parseTrunk(int model_version, int meta_encoder_version) } // Version >= 15 writes the trunk norm kind followed by 5 unused int parameters. - // This CoreML parser only supports the standard trunk norm kind (0 = BatchNorm/BiasMask); - // RMSNorm (used by transformer/rmsnorm models, kind != 0) is not implemented here, so reject it - // defensively rather than silently parsing it as standard norm and producing wrong outputs. + // Unlike upstream's CoreML parser (which rejects any non-standard norm), this fork + // implements RMSNorm, so we capture the kind here instead of throwing. The 5 trailing + // ints are reserved and still expected to be zero. if (model_version >= 15) { - int trunk_norm_kind = readInt(); - if (trunk_norm_kind != 0) { - throw std::runtime_error(trunk.name + ": unsupported trunk norm kind " + - std::to_string(trunk_norm_kind) + - " (this CoreML parser only supports standard trunk norm, not RMSNorm)"); + trunk.trunk_norm_kind = readInt(); + if (trunk.trunk_norm_kind != TRUNK_NORM_KIND_STANDARD && + trunk.trunk_norm_kind != TRUNK_NORM_KIND_RMSNORM) { + throw std::runtime_error(trunk.name + ": unknown/unsupported trunk norm kind " + + std::to_string(trunk.trunk_norm_kind)); } for (int i = 0; i < 5; i++) { int unused = readInt(); if (unused != 0) { throw std::runtime_error(trunk.name + ": unknown/unsupported trunk option " + + std::string(1, static_cast('B' + i)) + ": " + std::to_string(unused)); } } @@ -561,14 +844,24 @@ TrunkDesc KataGoParser::parseTrunk(int model_version, int meta_encoder_version) // Parse residual blocks trunk.blocks = parseBlockStack(model_version, trunk.num_blocks, trunk.trunk_num_channels); - trunk.trunk_tip_bn = parseBatchNormLayer(); - trunk.trunk_tip_activation = parseActivationLayer(model_version); - if (trunk.trunk_tip_bn.num_channels != trunk.trunk_num_channels) { - throw std::runtime_error(trunk.name + ": trunkTipBN.numChannels (" + - std::to_string(trunk.trunk_tip_bn.num_channels) + - ") != trunkNumChannels (" + - std::to_string(trunk.trunk_num_channels) + ")"); + if (trunk.trunk_norm_kind == TRUNK_NORM_KIND_STANDARD) { + trunk.trunk_tip_bn = parseBatchNormLayer(); + if (trunk.trunk_tip_bn.num_channels != trunk.trunk_num_channels) { + throw std::runtime_error(trunk.name + ": trunkTipBN.numChannels (" + + std::to_string(trunk.trunk_tip_bn.num_channels) + + ") != trunkNumChannels (" + + std::to_string(trunk.trunk_num_channels) + ")"); + } + } else { + trunk.trunk_tip_rms_norm = parseRMSNormLayer(); + if (trunk.trunk_tip_rms_norm.num_channels != trunk.trunk_num_channels) { + throw std::runtime_error(trunk.name + ": trunkTipRMSNorm.numChannels (" + + std::to_string(trunk.trunk_tip_rms_norm.num_channels) + + ") != trunkNumChannels (" + + std::to_string(trunk.trunk_num_channels) + ")"); + } } + trunk.trunk_tip_activation = parseActivationLayer(model_version); return trunk; } @@ -592,6 +885,7 @@ PolicyHeadDesc KataGoParser::parsePolicyHead(int model_version) { int unused = readInt(); if (unused != 0) { throw std::runtime_error(head.name + ": unknown/unsupported policy option " + + std::string(1, static_cast('A' + i)) + ": " + std::to_string(unused)); } } @@ -625,6 +919,38 @@ PolicyHeadDesc KataGoParser::parsePolicyHead(int model_version) { head.policy_out_channels = 1; } + // Internal cross-checks, matching desc.cpp. In particular p2Conv.outChannels must equal + // policy_out_channels: parseModel reports num_policy_channels from the latter while the MIL + // graph emits p2Conv's actual width, so a mismatch would mean the consumer reads the policy + // buffer with the wrong channel count (silent wrong output) rather than a load error. + checkDimsEqual(head.name, "p1Conv.outChannels", head.p1_conv.out_channels, + "p1BN.numChannels", head.p1_bn.num_channels); + checkDimsEqual(head.name, "g1Conv.outChannels", head.g1_conv.out_channels, + "g1BN.numChannels", head.g1_bn.num_channels); + checkDimsEqual(head.name, "gpoolToBiasMul.inChannels", head.gpool_to_bias_mul.in_channels, + "g1BN.numChannels * 3", (int64_t)head.g1_bn.num_channels * 3); + checkDimsEqual(head.name, "gpoolToBiasMul.outChannels", head.gpool_to_bias_mul.out_channels, + "p1BN.numChannels", head.p1_bn.num_channels); + checkDimsEqual(head.name, "p2Conv.inChannels", head.p2_conv.in_channels, + "p1BN.numChannels", head.p1_bn.num_channels); + checkDimsEqual(head.name, "gpoolToPassMul.inChannels", head.gpool_to_pass_mul.in_channels, + "g1BN.numChannels * 3", (int64_t)head.g1_bn.num_channels * 3); + checkDimsEqual(head.name, "p2Conv.outChannels", head.p2_conv.out_channels, + "policyOutChannels", head.policy_out_channels); + if (model_version >= 15) { + checkDimsEqual(head.name, "gpoolToPassMul.outChannels", head.gpool_to_pass_mul.out_channels, + "gpoolToPassBias.numChannels", head.gpool_to_pass_bias->num_channels); + checkDimsEqual(head.name, "gpoolToPassMul.outChannels", head.gpool_to_pass_mul.out_channels, + "gpoolToPassMul2.inChannels", head.gpool_to_pass_mul2->in_channels); + checkDimsEqual(head.name, "gpoolToPassMul.outChannels", head.gpool_to_pass_mul.out_channels, + "p1Conv.outChannels", head.p1_conv.out_channels); + checkDimsEqual(head.name, "gpoolToPassMul2.outChannels", head.gpool_to_pass_mul2->out_channels, + "policyOutChannels", head.policy_out_channels); + } else { + checkDimsEqual(head.name, "gpoolToPassMul.outChannels", head.gpool_to_pass_mul.out_channels, + "policyOutChannels", head.policy_out_channels); + } + return head; } @@ -639,6 +965,7 @@ ValueHeadDesc KataGoParser::parseValueHead(int model_version) { int unused = readInt(); if (unused != 0) { throw std::runtime_error(head.name + ": unknown/unsupported value option " + + std::string(1, static_cast('A' + i)) + ": " + std::to_string(unused)); } } @@ -656,6 +983,30 @@ ValueHeadDesc KataGoParser::parseValueHead(int model_version) { head.sv3_bias = parseMatBiasLayer(); head.v_ownership_conv = parseConvLayer(); + // Internal cross-checks, matching desc.cpp (only v8+ branches: older versions are + // rejected by isVersionSupported). v3Mul/sv3Mul/vOwnershipConv widths must match the + // counts parseModel hardcodes, since the MIL graph emits the actual layer widths. + checkDimsEqual(head.name, "v1Conv.outChannels", head.v1_conv.out_channels, + "v1BN.numChannels", head.v1_bn.num_channels); + checkDimsEqual(head.name, "v2Mul.inChannels", head.v2_mul.in_channels, + "v1BN.numChannels * 3", (int64_t)head.v1_bn.num_channels * 3); + checkDimsEqual(head.name, "v2Mul.outChannels", head.v2_mul.out_channels, + "v2Bias.numChannels", head.v2_bias.num_channels); + checkDimsEqual(head.name, "v2Mul.outChannels", head.v2_mul.out_channels, + "v3Mul.inChannels", head.v3_mul.in_channels); + checkDimsEqual(head.name, "v3Mul.outChannels", head.v3_mul.out_channels, "3", 3); + checkDimsEqual(head.name, "v3Bias.numChannels", head.v3_bias.num_channels, "3", 3); + checkDimsEqual(head.name, "sv3Mul.inChannels", head.sv3_mul.in_channels, + "v2Mul.outChannels", head.v2_mul.out_channels); + const int expected_sv = (model_version >= 9) ? 6 : 4; + checkDimsEqual(head.name, "sv3Mul.outChannels", head.sv3_mul.out_channels, + "expected scoreValueChannels", expected_sv); + checkDimsEqual(head.name, "sv3Bias.numChannels", head.sv3_bias.num_channels, + "expected scoreValueChannels", expected_sv); + checkDimsEqual(head.name, "vOwnershipConv.inChannels", head.v_ownership_conv.in_channels, + "v1Conv.outChannels", head.v1_conv.out_channels); + checkDimsEqual(head.name, "vOwnershipConv.outChannels", head.v_ownership_conv.out_channels, "1", 1); + return head; } @@ -671,9 +1022,15 @@ KataGoModelDesc KataGoParser::parseModel() { model.model_version = readInt(); if (!isVersionSupported(model.model_version)) { + // Note: the main engine (desc.cpp) accepts versions 3+, so a pre-v8 model that loads + // fine on other backends (including Metal's MPSGraph GPU path) still lands here on the + // CoreML/ANE path; say so rather than leaving the user to guess. throw std::runtime_error( - "Only KataGo model versions 8-17 are supported, got version " + - std::to_string(model.model_version)); + "Only KataGo model versions 8-17 are supported by the CoreML/ANE converter, got version " + + std::to_string(model.model_version) + + (model.model_version < 8 + ? ". This older model can still be used with the GPU (MPSGraph) path or other backends." + : ". You may need a newer KataGo version.")); } model.num_input_channels = readInt(); @@ -698,10 +1055,12 @@ KataGoModelDesc KataGoParser::parseModel() { p.variance_time_multiplier = readFloat(); p.shortterm_value_error_multiplier = readFloat(); p.shortterm_score_error_multiplier = readFloat(); + // NaN-safe and finite-checked: these multipliers scale engine outputs, so a NaN/Inf + // here (which stof will happily parse) would silently poison every evaluation. auto checkPositive = [&](const char* field, float v) { - if (v <= 0.0f) { + if (!(v > 0.0f) || !std::isfinite(v)) { throw std::runtime_error(model.name + ": postProcessParams." + field + - " must be > 0, got " + std::to_string(v)); + " must be positive and finite, got " + std::to_string(v)); } }; checkPositive("tdScoreMultiplier", p.td_score_multiplier); @@ -731,9 +1090,16 @@ KataGoModelDesc KataGoParser::parseModel() { std::to_string(model.meta_encoder_version) + " not implemented; you may need a newer KataGo version"); } - // Read unused params + // Read reserved params (model options B..H). desc.cpp rejects any nonzero value so + // future format features fail loudly instead of silently producing wrong output; + // mirror that here (the trunk/policy/value reserved ints below are already checked). for (int i = 0; i < 7; i++) { - readInt(); + int unused = readInt(); + if (unused != 0) { + throw std::runtime_error(model.name + ": unknown/unsupported model option " + + std::string(1, static_cast('B' + i)) + ": " + + std::to_string(unused)); + } } if (model.meta_encoder_version > 0) { @@ -762,6 +1128,14 @@ KataGoModelDesc KataGoParser::parseModel() { std::to_string(model.trunk.initial_matmul.in_channels) + ")"); } + // Head-input-vs-trunk cross-checks, matching desc.cpp. + checkDimsEqual(model.name, "policyHead.p1Conv.inChannels", model.policy_head.p1_conv.in_channels, + "trunkNumChannels", model.trunk.trunk_num_channels); + checkDimsEqual(model.name, "policyHead.g1Conv.inChannels", model.policy_head.g1_conv.in_channels, + "trunkNumChannels", model.trunk.trunk_num_channels); + checkDimsEqual(model.name, "valueHead.v1Conv.inChannels", model.value_head.v1_conv.in_channels, + "trunkNumChannels", model.trunk.trunk_num_channels); + // Determine output channel counts model.num_policy_channels = model.policy_head.policy_out_channels; model.num_value_channels = 3; // win, loss, noresult diff --git a/cpp/external/katagocoreml/src/parser/KataGoParser.hpp b/cpp/external/katagocoreml/src/parser/KataGoParser.hpp index a7d9f161c0..7ed423fac9 100644 --- a/cpp/external/katagocoreml/src/parser/KataGoParser.hpp +++ b/cpp/external/katagocoreml/src/parser/KataGoParser.hpp @@ -5,8 +5,11 @@ #include "../types/KataGoTypes.hpp" #include +#include #include +#include #include +#include namespace katagocoreml { @@ -14,7 +17,11 @@ namespace katagocoreml { /// Supports versions 8-17 models in binary format (.bin, .bin.gz). class KataGoParser { public: - /// Supported KataGo model versions + /// Supported KataGo model versions. The floor of 8 is deliberate (v3-7 predate the .bin + /// format; they still work via the GPU/MPSGraph path, which parses with desc.cpp). The + /// ceiling must be kept in lockstep with NNModelVersion::latestModelVersionImplemented in + /// cpp/neuralnet/modelversion.cpp whenever a new model version is added, or new models will + /// load on every other backend but fail CoreML/ANE conversion. static constexpr std::array SUPPORTED_VERSIONS = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; /// Constructor @@ -31,9 +38,23 @@ class KataGoParser { private: std::string m_model_path; - std::vector m_buffer; - size_t m_pos = 0; + // Custom-deleter unique_ptr owns the gzFile so it closes on every exit path + // (normal return, exception, or bad_alloc) without manual try/catch. + struct GzCloser { + void operator()(gzFile f) const noexcept { if(f) gzclose(f); } + }; + using GzHandle = std::unique_ptr, GzCloser>; + GzHandle m_gz; + std::vector m_refill; // bounded refill buffer (~1 MB) + size_t m_refillPos = 0; // read cursor within m_refill + size_t m_refillLen = 0; // valid bytes in m_refill bool m_binary_floats = true; + bool m_formatDetected = false; + + // Stream primitives + bool refill(); // returns false at EOF + int peekByte(); // -1 at EOF + void readExact(uint8_t* dst, size_t n, const std::string& name); // Low-level reading functions void readUntilWhitespace(std::string& out); @@ -50,11 +71,15 @@ class KataGoParser { ActivationLayerDesc parseActivationLayer(int model_version); MatMulLayerDesc parseMatMulLayer(); MatBiasLayerDesc parseMatBiasLayer(); + TransformerRMSNormDesc parseTransformerRMSNorm(); + RMSNormLayerDesc parseRMSNormLayer(); // Block parsing functions ResidualBlockDesc parseResidualBlock(int model_version); GlobalPoolingResidualBlockDesc parseGlobalPoolingResidualBlock(int model_version); NestedBottleneckResidualBlockDesc parseNestedBottleneckBlock(int model_version, int trunk_num_channels); + TransformerAttentionBlockDesc parseTransformerAttentionBlock(int model_version); + TransformerFFNBlockDesc parseTransformerFFNBlock(int model_version); std::vector parseBlockStack(int model_version, int num_blocks, int trunk_num_channels); // Component parsing functions @@ -65,9 +90,6 @@ class KataGoParser { // Main model parsing KataGoModelDesc parseModel(); - - // Helper to load file (handles gzip) - void loadFile(); }; } // namespace katagocoreml diff --git a/cpp/external/katagocoreml/src/serializer/CoreMLSerializer.cpp b/cpp/external/katagocoreml/src/serializer/CoreMLSerializer.cpp index f271f5526f..155c374d94 100644 --- a/cpp/external/katagocoreml/src/serializer/CoreMLSerializer.cpp +++ b/cpp/external/katagocoreml/src/serializer/CoreMLSerializer.cpp @@ -8,13 +8,45 @@ #include "Model.pb.h" #include "FeatureTypes.pb.h" #include "ModelPackage.hpp" +#include +#include #include #include #include #include +#include +#include +#include namespace katagocoreml { +namespace { +// Scratch dirs must be unique per call: the temp directory is machine-shared, so +// a fixed name lets two concurrently-converting katago processes clobber each +// other's spec/weights mid-package. mkdtemp (rather than a pid/counter name) +// also makes the path unpredictable and guarantees the directory is freshly +// created - a pre-existing path (stale leftover or another user's symlink) +// fails instead of being silently reused. +std::filesystem::path makeUniqueTempDir(const std::string& tag) { + std::string tmpl = + (std::filesystem::temp_directory_path() / ("katagocoreml_" + tag + "_XXXXXX")).string(); + if (mkdtemp(tmpl.data()) == nullptr) { + throw std::runtime_error("Failed to create temp dir " + tmpl + ": " + std::strerror(errno)); + } + return std::filesystem::path(tmpl); +} + +// Removes the temp dir on scope exit, so failed conversions (disk full, bad +// model spec, package errors) don't strand weight blobs in the shared temp dir. +struct TempDirGuard { + std::filesystem::path dir; + ~TempDirGuard() { + std::error_code ec; + std::filesystem::remove_all(dir, ec); // best-effort; never throws in a destructor + } +}; +} // namespace + CoreMLSerializer::CoreMLSerializer(int spec_version) : m_spec_version(spec_version) {} @@ -22,9 +54,9 @@ void CoreMLSerializer::serialize(CoreML::Specification::MILSpec::Program* progra std::vector& weights, const std::string& output_path, const ConversionOptions& options) { - // Create temporary directory for weights - std::filesystem::path temp_dir = std::filesystem::temp_directory_path() / "katagocoreml_weights"; - std::filesystem::create_directories(temp_dir); + // Create temporary directory for weights (removed by the guard on all paths) + std::filesystem::path temp_dir = makeUniqueTempDir("weights"); + TempDirGuard temp_dir_guard{temp_dir}; std::string weights_dir = temp_dir.string(); // Determine if using FP16 precision @@ -42,9 +74,6 @@ void CoreMLSerializer::serialize(CoreML::Specification::MILSpec::Program* progra // Create .mlpackage createPackage(output_path, model.get(), weights_dir); - - // Cleanup temp directory - std::filesystem::remove_all(temp_dir); } std::unique_ptr CoreMLSerializer::createModelSpec( @@ -223,15 +252,29 @@ void CoreMLSerializer::createPackage(const std::string& output_path, // Create package using MPL::ModelPackage MPL::ModelPackage package(output_path, true, false); - // Serialize model spec to temp file - std::filesystem::path temp_spec = std::filesystem::temp_directory_path() / "model.mlmodel"; + // Serialize model spec to temp file (dir removed by the guard on all paths) + std::filesystem::path temp_spec_dir = makeUniqueTempDir("spec"); + TempDirGuard temp_spec_guard{temp_spec_dir}; + std::filesystem::path temp_spec = temp_spec_dir / "model.mlmodel"; { std::ofstream out(temp_spec, std::ios::binary); if (!out) { throw std::runtime_error("Failed to create temp model file"); } - if (!model->SerializeToOstream(&out)) { - throw std::runtime_error("Failed to serialize model spec"); + { + google::protobuf::io::OstreamOutputStream zos(&out); + google::protobuf::io::CodedOutputStream cos(&zos); + cos.SetSerializationDeterministic(true); + if (!model->SerializeToCodedStream(&cos)) { + throw std::runtime_error("Failed to serialize model spec"); + } + } + // SerializeToCodedStream catches write errors during serialization, but the + // final buffer is flushed at close; a disk-full there would otherwise hand a + // silently-truncated spec to the package. + out.close(); + if (!out) { + throw std::runtime_error("Failed to write temp model file (disk full?)"); } } @@ -241,8 +284,6 @@ void CoreMLSerializer::createPackage(const std::string& output_path, // Add weights package.addItem(weights_dir, "weights", "com.apple.CoreML", "Model Weights"); - // Cleanup temp file - std::filesystem::remove(temp_spec); } void CoreMLSerializer::updateBlobOffsets(CoreML::Specification::MILSpec::Program* program, diff --git a/cpp/external/katagocoreml/src/serializer/WeightSerializer.cpp b/cpp/external/katagocoreml/src/serializer/WeightSerializer.cpp index 2ac23a3dab..69d590609d 100644 --- a/cpp/external/katagocoreml/src/serializer/WeightSerializer.cpp +++ b/cpp/external/katagocoreml/src/serializer/WeightSerializer.cpp @@ -15,20 +15,25 @@ size_t WeightSerializer::serialize(std::vector& weights, size_t total_bytes = 0; for (auto& entry : weights) { - if (use_fp16) { + const size_t count = entry.data.size(); + // Per-weight precision: store FP16 only when the global mode is FP16 AND this weight was not + // declared FP32 (entry.is_fp32 marks consts inside an FP32 sub-region of an FP16 model), so + // stored bytes stay consistent with each const's declared dtype. + const bool store_fp16 = use_fp16 && !entry.is_fp32; + if (store_fp16) { // Convert FP32 weights to FP16 - std::vector fp16_data(entry.data.size()); - for (size_t i = 0; i < entry.data.size(); ++i) { + std::vector fp16_data(count); + for (size_t i = 0; i < count; ++i) { fp16_data[i] = MILBlob::Fp16::FromFloat(entry.data[i]); } MILBlob::Util::Span span(fp16_data.data(), fp16_data.size()); entry.blob_offset = writer.WriteData(span); - total_bytes += entry.data.size() * sizeof(MILBlob::Fp16); + total_bytes += count * sizeof(MILBlob::Fp16); } else { - // Write FP32 weights - MILBlob::Util::Span span(entry.data.data(), entry.data.size()); + // Write FP32 weights — convert the KataGo-local view to a MILBlob span here. + MILBlob::Util::Span span(entry.data.data(), count); entry.blob_offset = writer.WriteData(span); - total_bytes += entry.data.size() * sizeof(float); + total_bytes += count * sizeof(float); } } diff --git a/cpp/external/katagocoreml/src/types/KataGoTypes.hpp b/cpp/external/katagocoreml/src/types/KataGoTypes.hpp index 147541a399..1074ad4198 100644 --- a/cpp/external/katagocoreml/src/types/KataGoTypes.hpp +++ b/cpp/external/katagocoreml/src/types/KataGoTypes.hpp @@ -20,10 +20,15 @@ namespace katagocoreml { enum class ActivationType : int { Identity = 0, ReLU = 1, - Mish = 2 + Mish = 2, + Silu = 3 // MISH_SCALE8 = 12 is internal optimization, treated as Mish }; +/// Trunk normalization kind (matching KataGo's desc.h) +constexpr int TRUNK_NORM_KIND_STANDARD = 0; +constexpr int TRUNK_NORM_KIND_RMSNORM = 1; + // ============================================================================ // Block Kind Constants // ============================================================================ @@ -32,6 +37,8 @@ enum class ActivationType : int { constexpr int ORDINARY_BLOCK_KIND = 0; constexpr int GLOBAL_POOLING_BLOCK_KIND = 2; constexpr int NESTED_BOTTLENECK_BLOCK_KIND = 3; +constexpr int TRANSFORMER_ATTENTION_BLOCK_KIND = 4; +constexpr int TRANSFORMER_FFN_BLOCK_KIND = 5; // ============================================================================ // Layer Descriptors @@ -99,6 +106,25 @@ struct MatBiasLayerDesc { std::vector weights; // Shape: [num_channels] }; +/// Lightweight RMSNorm used inside transformer blocks (weight only, no bias). +struct TransformerRMSNormDesc { + std::string name; + int num_channels = 0; + float epsilon = 1e-6f; + std::vector weight; // Shape: [num_channels] +}; + +/// Full-featured RMSNorm (gamma/beta, spatial mode) used at the trunk tip. +struct RMSNormLayerDesc { + std::string name; + int num_channels = 0; + float epsilon = 1e-6f; + bool spatial = false; + int cgroup_size = 0; + std::vector gamma; // Shape: [num_channels] + std::vector beta; // Shape: [num_channels] +}; + // ============================================================================ // Block Descriptors // ============================================================================ @@ -107,12 +133,16 @@ struct MatBiasLayerDesc { struct ResidualBlockDesc; struct GlobalPoolingResidualBlockDesc; struct NestedBottleneckResidualBlockDesc; +struct TransformerAttentionBlockDesc; +struct TransformerFFNBlockDesc; /// Block descriptor variant using BlockDesc = std::variant< ResidualBlockDesc, GlobalPoolingResidualBlockDesc, - NestedBottleneckResidualBlockDesc + NestedBottleneckResidualBlockDesc, + TransformerAttentionBlockDesc, + TransformerFFNBlockDesc >; /// Block with its kind @@ -166,6 +196,38 @@ struct NestedBottleneckResidualBlockDesc { ConvLayerDesc post_conv; }; +/// Transformer self-attention block descriptor (pre-norm, multi-head, optional 2D RoPE, GQA). +struct TransformerAttentionBlockDesc { + std::string name; + int num_heads = 0; + int num_kv_heads = 0; + int q_head_dim = 0; + int v_head_dim = 0; + bool use_rope = false; + bool learnable_rope = false; + TransformerRMSNormDesc pre_ln; + MatMulLayerDesc q_proj; + MatMulLayerDesc k_proj; + MatMulLayerDesc v_proj; + MatMulLayerDesc out_proj; + int rope_num_kv_heads = 0; + int rope_num_pairs = 0; + std::vector rope_freqs; // learnable: (num_kv_heads, num_pairs, 2) flattened + float rope_theta = 0.0f; +}; + +/// Transformer feed-forward (SwiGLU) block descriptor. +struct TransformerFFNBlockDesc { + std::string name; + int num_channels = 0; + int ffn_channels = 0; + bool use_swiglu = false; + TransformerRMSNormDesc pre_ln; + MatMulLayerDesc linear1; + MatMulLayerDesc linear_gate; // only used when use_swiglu + MatMulLayerDesc linear2; +}; + // ============================================================================ // SGF Metadata Encoder (v15+) // ============================================================================ @@ -203,7 +265,9 @@ struct TrunkDesc { MatMulLayerDesc initial_matmul; std::optional sgf_metadata_encoder; std::vector blocks; + int trunk_norm_kind = TRUNK_NORM_KIND_STANDARD; BatchNormLayerDesc trunk_tip_bn; + RMSNormLayerDesc trunk_tip_rms_norm; ActivationLayerDesc trunk_tip_activation; }; diff --git a/cpp/game/boardhistory.cpp b/cpp/game/boardhistory.cpp index 0b58dc1d24..44b64871c9 100644 --- a/cpp/game/boardhistory.cpp +++ b/cpp/game/boardhistory.cpp @@ -38,6 +38,7 @@ BoardHistory::BoardHistory() assumeMultipleStartingBlackMovesAreHandicap(false), whiteHasMoved(false), overrideNumHandicapStones(-1), + alwaysComputePassAliveUnderSuicideRules(false), recentBoards(), currentRecentBoardIdx(0), presumedNextMovePla(P_BLACK), @@ -65,7 +66,7 @@ BoardHistory::BoardHistory() BoardHistory::~BoardHistory() {} -BoardHistory::BoardHistory(const Board& board, Player pla, const Rules& r, int ePhase) +BoardHistory::BoardHistory(const Board& board, Player pla, const Rules& r, int ePhase, bool alwaysPassAliveSuicide) :rules(r), moveHistory(), preventEncoreHistory(), @@ -78,6 +79,7 @@ BoardHistory::BoardHistory(const Board& board, Player pla, const Rules& r, int e assumeMultipleStartingBlackMovesAreHandicap(false), whiteHasMoved(false), overrideNumHandicapStones(-1), + alwaysComputePassAliveUnderSuicideRules(alwaysPassAliveSuicide), recentBoards(), currentRecentBoardIdx(0), presumedNextMovePla(pla), @@ -117,6 +119,7 @@ BoardHistory::BoardHistory(const BoardHistory& other) assumeMultipleStartingBlackMovesAreHandicap(other.assumeMultipleStartingBlackMovesAreHandicap), whiteHasMoved(other.whiteHasMoved), overrideNumHandicapStones(other.overrideNumHandicapStones), + alwaysComputePassAliveUnderSuicideRules(other.alwaysComputePassAliveUnderSuicideRules), recentBoards(), currentRecentBoardIdx(other.currentRecentBoardIdx), presumedNextMovePla(other.presumedNextMovePla), @@ -159,6 +162,7 @@ BoardHistory& BoardHistory::operator=(const BoardHistory& other) assumeMultipleStartingBlackMovesAreHandicap = other.assumeMultipleStartingBlackMovesAreHandicap; whiteHasMoved = other.whiteHasMoved; overrideNumHandicapStones = other.overrideNumHandicapStones; + alwaysComputePassAliveUnderSuicideRules = other.alwaysComputePassAliveUnderSuicideRules; std::copy(other.recentBoards, other.recentBoards+NUM_RECENT_BOARDS, recentBoards); currentRecentBoardIdx = other.currentRecentBoardIdx; presumedNextMovePla = other.presumedNextMovePla; @@ -202,6 +206,7 @@ BoardHistory::BoardHistory(BoardHistory&& other) noexcept assumeMultipleStartingBlackMovesAreHandicap(other.assumeMultipleStartingBlackMovesAreHandicap), whiteHasMoved(other.whiteHasMoved), overrideNumHandicapStones(other.overrideNumHandicapStones), + alwaysComputePassAliveUnderSuicideRules(other.alwaysComputePassAliveUnderSuicideRules), recentBoards(), currentRecentBoardIdx(other.currentRecentBoardIdx), presumedNextMovePla(other.presumedNextMovePla), @@ -241,6 +246,7 @@ BoardHistory& BoardHistory::operator=(BoardHistory&& other) noexcept assumeMultipleStartingBlackMovesAreHandicap = other.assumeMultipleStartingBlackMovesAreHandicap; whiteHasMoved = other.whiteHasMoved; overrideNumHandicapStones = other.overrideNumHandicapStones; + alwaysComputePassAliveUnderSuicideRules = other.alwaysComputePassAliveUnderSuicideRules; std::copy(other.recentBoards, other.recentBoards+NUM_RECENT_BOARDS, recentBoards); currentRecentBoardIdx = other.currentRecentBoardIdx; presumedNextMovePla = other.presumedNextMovePla; @@ -285,6 +291,7 @@ void BoardHistory::clear(const Board& board, Player pla, const Rules& r, int ePh assumeMultipleStartingBlackMovesAreHandicap = false; whiteHasMoved = false; overrideNumHandicapStones = -1; + //Deliberately does NOT reset alwaysComputePassAliveUnderSuicideRules - see boardhistory.h. //This makes it so that if we ask for recent boards with a lookback beyond what we have a history for, //we simply return copies of the starting board. @@ -356,7 +363,7 @@ void BoardHistory::clear(const Board& board, Player pla, const Rules& r, int ePh } BoardHistory BoardHistory::copyToInitial() const { - BoardHistory hist(initialBoard, initialPla, rules, initialEncorePhase); + BoardHistory hist(initialBoard, initialPla, rules, initialEncorePhase, alwaysComputePassAliveUnderSuicideRules); hist.setInitialTurnNumber(initialTurnNumber); hist.setAssumeMultipleStartingBlackMovesAreHandicap(assumeMultipleStartingBlackMovesAreHandicap); hist.setOverrideNumHandicapStones(overrideNumHandicapStones); @@ -377,6 +384,14 @@ void BoardHistory::setOverrideNumHandicapStones(int n) { whiteHandicapBonusScore = (float)computeWhiteHandicapBonus(); } +void BoardHistory::setAlwaysComputePassAliveUnderSuicideRules(bool b) { + alwaysComputePassAliveUnderSuicideRules = b; +} + +bool BoardHistory::suicideLegalForPassAlive() const { + return rules.multiStoneSuicideLegal || alwaysComputePassAliveUnderSuicideRules; +} + static int numHandicapStonesOnBoardHelper(const Board& board, int blackNonPassTurnsToStart) { int startBoardNumBlackStones = 0; int startBoardNumWhiteStones = 0; @@ -581,7 +596,7 @@ int BoardHistory::countAreaScoreWhiteMinusBlack(const Board& board, Color area[B bool unsafeBigTerritories = true; board.calculateArea( area, - nonPassAliveStones,safeBigTerritories,unsafeBigTerritories,rules.multiStoneSuicideLegal + nonPassAliveStones,safeBigTerritories,unsafeBigTerritories,suicideLegalForPassAlive() ); } else if(rules.taxRule == Rules::TAX_SEKI || rules.taxRule == Rules::TAX_ALL) { @@ -592,7 +607,7 @@ int BoardHistory::countAreaScoreWhiteMinusBlack(const Board& board, Color area[B area,whiteMinusBlackIndependentLifeRegionCount, keepTerritories, keepStones, - rules.multiStoneSuicideLegal + suicideLegalForPassAlive() ); if(rules.taxRule == Rules::TAX_ALL) score -= 2 * whiteMinusBlackIndependentLifeRegionCount; @@ -634,7 +649,7 @@ int BoardHistory::countTerritoryAreaScoreWhiteMinusBlack(const Board& board, Col area,whiteMinusBlackIndependentLifeRegionCount, keepTerritories, keepStones, - rules.multiStoneSuicideLegal + suicideLegalForPassAlive() ); for(int y = 0; y" #else -#include "program/gitinfo.h" +// Angle-bracket (not quoted) include so this resolves ONLY via the -I search +// paths, where the build dir's freshly-generated program/gitinfo.h lives. A +// quoted include would search main.cpp's own directory first and pick up a +// stale in-source cpp/program/gitinfo.h left over from an in-source build. +#include #endif #include @@ -29,8 +33,6 @@ static void printHelp(const vector& args) { gtp : Runs GTP engine that can be plugged into any standard Go GUI for play/analysis. benchmark : Test speed with different numbers of search threads. genconfig : User-friendly interface to generate a config with rules and automatic performance tuning. -exportonnx : Export KataGo .bin/.bin.gz model to a fixed-size .onnx model. -dumpcalibrationdata : Dump NN input tensors sampled from sgf games, for offline quantization (e.g. for VitisAI/NPU). contribute : Connect to online distributed KataGo training and run perpetually contributing selfplay games. @@ -48,6 +50,7 @@ gatekeeper : Poll directory for new nets and match them against the latest net s ---Testing/debugging subcommands------------- evalsgf : Utility/debug tool, analyze a single position of a game from an SGF file. searchentropyanalysis : Analyze search entropy across test datasets. +selfplaysurprisedump : Run selfplay games with a fixed model and dump per-position policy/value surprise stats to csv. testgpuerror : Print the average error of the neural net between current config and fp32 config. @@ -161,6 +164,8 @@ static int handleSubcommand(const string& subcommand, const vector& args return MainCmds::evalrandominits(subArgs); else if(subcommand == "searchentropyanalysis") return MainCmds::searchentropyanalysis(subArgs); + else if(subcommand == "selfplaysurprisedump") + return MainCmds::selfplaysurprisedump(subArgs); else if(subcommand == "runbeginsearchspeedtest") return MainCmds::runbeginsearchspeedtest(subArgs); else if(subcommand == "runownershipspeedtest") @@ -169,10 +174,6 @@ static int handleSubcommand(const string& subcommand, const vector& args return MainCmds::runsleeptest(subArgs); else if(subcommand == "printclockinfo") return MainCmds::printclockinfo(subArgs); - else if(subcommand == "exportonnx") - return MainCmds::exportonnx(subArgs); - else if(subcommand == "dumpcalibrationdata") - return MainCmds::dumpcalibrationdata(subArgs); else if(subcommand == "sandbox") return MainCmds::sandbox(); else if(subcommand == "version") { @@ -225,11 +226,11 @@ int main(int argc, const char* const* argv) { string Version::getKataGoVersion() { - return string("1.16.5"); + return string("1.17.2"); } string Version::getKataGoVersionForHelp() { - return string("KataGo v1.16.5"); + return string("KataGo v1.17.2"); } string Version::getKataGoVersionFullInfo() { @@ -252,8 +253,6 @@ string Version::getKataGoVersionFullInfo() { out << "Using OpenCL backend" << endl; #elif defined(USE_EIGEN_BACKEND) out << "Using Eigen(CPU) backend" << endl; -#elif defined(USE_ONNX_BACKEND) - out << "Using ONNX backend" << endl; #else out << "Using dummy backend" << endl; #endif @@ -290,8 +289,6 @@ string Version::getGitRevisionWithBackend() { s += "-opencl"; #elif defined(USE_EIGEN_BACKEND) s += "-eigen"; -#elif defined(USE_ONNX_BACKEND) - s += "-onnx"; #else s += "-dummy"; #endif diff --git a/cpp/main.h b/cpp/main.h index 73a6d231b6..f7e3f86249 100644 --- a/cpp/main.h +++ b/cpp/main.h @@ -52,11 +52,10 @@ namespace MainCmds { int genposesfromselfplayinit(const std::vector& args); int printclockinfo(const std::vector& args); - int exportonnx(const std::vector& args); - int dumpcalibrationdata(const std::vector& args); int sampleinitializations(const std::vector& args); int evalrandominits(const std::vector& args); int searchentropyanalysis(const std::vector& args); + int selfplaysurprisedump(const std::vector& args); int sandbox(); } diff --git a/cpp/neuralnet/cudabackend.cpp b/cpp/neuralnet/cudabackend.cpp index a6df159cd9..d9f3f9ee73 100644 --- a/cpp/neuralnet/cudabackend.cpp +++ b/cpp/neuralnet/cudabackend.cpp @@ -63,11 +63,18 @@ void NeuralNet::globalCleanup() { // element at (n, xy, h, d) lives at offset (h*headDim + d) + (n*seqLen + xy) * (numHeads*headDim). // // Masking: when a mask is present, we build a fully-materialized additive attention bias of shape -// [B, 1, S, S] from the [B, S] mask: bias[b,q,k] = (mask[b,k] != 0 ? 0 : -1e4). cudnn does not have +// [B, 1, S, S] from the [B, S] mask: bias[b,q,k] = (mask[b,k] != 0 ? 0 : -3e4). cudnn does not have // plans for the [B,1,1,S] broadcast pattern that would let us avoid this materialization, but the // full bias is correct for arbitrary (non-prefix) masks, which we need to support sub-board games. // The bias is built once per inference (the mask is the same across all 20 attention blocks). // +// The bias tensor dtype MUST match the io dtype (fp16). An fp32 bias with fp16 Q/K/V passes +// validate/check_support/build_plans on cudnn 9.x but silently misexecutes (nonfinite outputs - +// the fused kernel evidently reinterprets the buffer). Since cudnn adds the (converted) bias to the +// fp32 scores and computes the softmax in fp32, the fp16-range-limited -3e4 constant still masks +// exactly (exp underflow) for any model whose genuine logit spread is below ~3e4. +// See cudahelpers.cu for details. +// // When mask is NULL (full-board, requireExactNNLen case), we build a no-bias graph instead, which // avoids both the extra memory and the bias build kernel. @@ -1576,6 +1583,12 @@ struct RMSNormLayer { (void)cudaHandles; testAssert((int)desc->gamma.size() == numChannels); testAssert((int)desc->beta.size() == numChannels); + // The device kernels apply only RELU/MISH/SILU explicitly and treat anything else as + // identity; guard here so an unsupported kind (e.g. MISH_SCALE8, which applyScale8 can + // produce for non-transformer nets) fails loudly instead of silently skipping activation. + if(activation != ACTIVATION_IDENTITY && activation != ACTIVATION_RELU && + activation != ACTIVATION_MISH && activation != ACTIVATION_SILU) + throw StringError(name + ": RMSNorm layer unsupported activation: " + Global::intToString(activation)); CudaUtils::mallocAndCopyToDevice(name, desc->gamma, gammaBuf, useFP16); CudaUtils::mallocAndCopyToDevice(name, desc->beta, betaBuf, useFP16); } diff --git a/cpp/neuralnet/cudahelpers.cu b/cpp/neuralnet/cudahelpers.cu index 00482a973a..3308ef1115 100644 --- a/cpp/neuralnet/cudahelpers.cu +++ b/cpp/neuralnet/cudahelpers.cu @@ -2589,9 +2589,13 @@ void customCudaFlashAttention( //-------------------------------------------------------------------------------------------------------------- // Convert mask [batchSize, seqLen] (0/1) into a fully-materialized additive attention bias of shape // [batchSize, seqLen, seqLen] suitable for cuDNN SDPA's `[B, 1, S, S]` bias input. -// bias[b, q, k] = (mask[b, k] != 0 ? 0 : -1e4). -// Note: the q dim is fully replicated since the mask only depends on k. Using -1e4 (well within FP16 -// max ~65504) avoids -inf-minus-inf NaNs in cuDNN's softmax. +// bias[b, q, k] = (mask[b, k] != 0 ? 0 : -3e4). +// Note: the q dim is fully replicated since the mask only depends on k. +// +// The constant must be a large finite negative to avoid any chance of misbehavior in +// cuDNN's softmax, and it must fit in fp16 (max ~65504) since the bias tensor's dtype must match +// Q/K/V's. We use -3e4, the largest round value that leaves fp16 headroom for the model's own +// logits on top. Measured logit magnitudes on real models as of mid-2026 are < ~500. // // Threading: one thread per (b, q, k). Inner-most (warp) axis = k so we write contiguous bytes per // (b, q) row. Each thread broadcast-reads mask[b, k], so within a warp all 32 lanes read consecutive @@ -2605,7 +2609,7 @@ void maskToAttnBiasFullKernel(const float* mask, float* outBias, int seqLen) { if(k >= seqLen) return; float m = mask[b * seqLen + k]; - outBias[((size_t)b * seqLen + q) * seqLen + k] = (m != 0.0f) ? 0.0f : -1e4f; + outBias[((size_t)b * seqLen + q) * seqLen + k] = (m != 0.0f) ? 0.0f : -3e4f; } __global__ @@ -2617,7 +2621,7 @@ void maskToAttnBiasFullHalfKernel(const half* mask, half* outBias, int seqLen) { if(k >= seqLen) return; float m = __half2float(mask[b * seqLen + k]); - outBias[((size_t)b * seqLen + q) * seqLen + k] = __float2half((m != 0.0f) ? 0.0f : -1e4f); + outBias[((size_t)b * seqLen + q) * seqLen + k] = __float2half((m != 0.0f) ? 0.0f : -3e4f); #endif } diff --git a/cpp/neuralnet/cudahelpers.h b/cpp/neuralnet/cudahelpers.h index cdac3d508c..7f9e07d9e9 100644 --- a/cpp/neuralnet/cudahelpers.h +++ b/cpp/neuralnet/cudahelpers.h @@ -78,10 +78,8 @@ void customCudaApplyRoPELearnableRecompute( //Convert a [batchSize, seqLen] mask (0/1) into a fully-materialized additive attention bias of shape //[batchSize, seqLen, seqLen] suitable for cuDNN SDPA's [B, 1, S, S] bias input: -// bias[b, q, k] = (mask[b, k] != 0 ? 0 : -1e4). -//cuDNN doesn't currently have plans for the [B, 1, 1, S] broadcast-over-q variant for our shape, -//so we materialize the full bias. Using -1e4 (well within FP16 max ~65504) avoids -inf-minus-inf -//NaNs in cuDNN's softmax. +// bias[b, q, k] = (mask[b, k] != 0 ? 0 : -3e4). +//See the comment in cudahelpers.cu for why this bias value for the mask. void customCudaMaskToAttnBiasFull(const float* mask, float* outBias, int batchSize, int seqLen); void customCudaMaskToAttnBiasFull(const half* mask, half* outBias, int batchSize, int seqLen); diff --git a/cpp/neuralnet/desc.cpp b/cpp/neuralnet/desc.cpp index 8141b43666..50b6c50926 100644 --- a/cpp/neuralnet/desc.cpp +++ b/cpp/neuralnet/desc.cpp @@ -197,6 +197,10 @@ void ConvLayerDesc::scaleOutputChannels(const std::vector& scaling) { } } +void ConvLayerDesc::releaseWeights() { + std::vector().swap(weights); +} + //----------------------------------------------------------------------------- BatchNormLayerDesc::BatchNormLayerDesc() : numChannels(0), epsilon(0.001f), hasScale(false), hasBias(false) {} @@ -213,8 +217,8 @@ BatchNormLayerDesc::BatchNormLayerDesc(istream& in, bool binaryFloats) { if(numChannels < 1) throw StringError(name + ": numChannels (" + Global::intToString(numChannels) + ") < 1"); - if(epsilon <= 0) - throw StringError(name + ": epsilon (" + Global::floatToString(epsilon) + ") <= 0"); + if(!(epsilon > 0) || !isfinite(epsilon)) + throw StringError(name + ": epsilon (" + Global::floatToString(epsilon) + ") is not positive and finite"); vector floats; readFloats(in, (size_t)numChannels, binaryFloats, name, floats); @@ -361,6 +365,15 @@ void BatchNormLayerDesc::applyScale8ToReduceActivations() { } } +void BatchNormLayerDesc::releaseWeights() { + std::vector().swap(mean); + std::vector().swap(variance); + std::vector().swap(scale); + std::vector().swap(bias); + std::vector().swap(mergedScale); + std::vector().swap(mergedBias); +} + //----------------------------------------------------------------------------- @@ -493,6 +506,10 @@ void MatMulLayerDesc::scaleOutputChannels(const std::vector& scaling) { } } +void MatMulLayerDesc::releaseWeights() { + std::vector().swap(weights); +} + //----------------------------------------------------------------------------- @@ -538,6 +555,10 @@ void MatBiasLayerDesc::applyScale8ToReduceActivations() { } } +void MatBiasLayerDesc::releaseWeights() { + std::vector().swap(weights); +} + //----------------------------------------------------------------------------- ResidualBlockDesc::ResidualBlockDesc() {} @@ -617,6 +638,13 @@ void ResidualBlockDesc::applyScale8ToReduceActivations() { midActivation.applyScale8ToReduceActivations(); } +void ResidualBlockDesc::releaseWeights() { + preBN.releaseWeights(); + regularConv.releaseWeights(); + midBN.releaseWeights(); + finalConv.releaseWeights(); +} + //----------------------------------------------------------------------------- GlobalPoolingResidualBlockDesc::GlobalPoolingResidualBlockDesc() {} @@ -738,6 +766,16 @@ void GlobalPoolingResidualBlockDesc::applyScale8ToReduceActivations() { midActivation.applyScale8ToReduceActivations(); } +void GlobalPoolingResidualBlockDesc::releaseWeights() { + preBN.releaseWeights(); + regularConv.releaseWeights(); + gpoolConv.releaseWeights(); + gpoolBN.releaseWeights(); + gpoolToBiasMul.releaseWeights(); + midBN.releaseWeights(); + finalConv.releaseWeights(); +} + //----------------------------------------------------------------------------- NestedBottleneckResidualBlockDesc::NestedBottleneckResidualBlockDesc() {} @@ -992,6 +1030,38 @@ void NestedBottleneckResidualBlockDesc::applyScale8ToReduceActivations() { postActivation.applyScale8ToReduceActivations(); } +void NestedBottleneckResidualBlockDesc::releaseWeights() { + preBN.releaseWeights(); + preConv.releaseWeights(); + for(int i = 0; i < blocks.size(); i++) { + if(blocks[i].first == ORDINARY_BLOCK_KIND) { + ResidualBlockDesc* desc = (ResidualBlockDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { + GlobalPoolingResidualBlockDesc* desc = (GlobalPoolingResidualBlockDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { + NestedBottleneckResidualBlockDesc* desc = (NestedBottleneckResidualBlockDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == TRANSFORMER_ATTENTION_BLOCK_KIND) { + TransformerAttentionDesc* desc = (TransformerAttentionDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == TRANSFORMER_FFN_BLOCK_KIND) { + TransformerFFNDesc* desc = (TransformerFFNDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else { + ASSERT_UNREACHABLE; + } + } + postBN.releaseWeights(); + postConv.releaseWeights(); +} + //----------------------------------------------------------------------------- RMSNormLayerDesc::RMSNormLayerDesc() : numChannels(0), epsilon(0), spatial(false), cgroupSize(0) {} @@ -1007,7 +1077,7 @@ RMSNormLayerDesc::RMSNormLayerDesc(istream& in, bool binaryFloats) { if(in.fail()) throw StringError(name + ": rmsnorm layer failed to parse parameters"); - if(epsilon <= 0 || epsilon > 1.0f) + if(!(epsilon > 0) || epsilon > 1.0f) throw StringError(name + ": rmsnorm epsilon (" + Global::doubleToString(epsilon) + ") is not positive or is too large"); if(numChannels < 1) throw StringError(name + ": rmsnorm numChannels (" + Global::intToString(numChannels) + ") < 1"); @@ -1043,6 +1113,11 @@ int64_t RMSNormLayerDesc::getNumParameters() const { return (int64_t)gamma.size() + (int64_t)beta.size(); } +void RMSNormLayerDesc::releaseWeights() { + std::vector().swap(gamma); + std::vector().swap(beta); +} + //----------------------------------------------------------------------------- TransformerRMSNormDesc::TransformerRMSNormDesc() : numChannels(0), epsilon(0) {} @@ -1056,7 +1131,7 @@ TransformerRMSNormDesc::TransformerRMSNormDesc(istream& in, bool binaryFloats) { throw StringError(name + ": transformer rmsnorm failed to parse parameters"); if(numChannels < 1) throw StringError(name + ": transformer rmsnorm numChannels (" + Global::intToString(numChannels) + ") < 1"); - if(epsilon <= 0 || epsilon > 1.0f) + if(!(epsilon > 0) || epsilon > 1.0f) throw StringError(name + ": transformer rmsnorm epsilon (" + Global::doubleToString(epsilon) + ") is not positive or is too large"); vector floats; @@ -1083,6 +1158,10 @@ int64_t TransformerRMSNormDesc::getNumParameters() const { return (int64_t)weight.size(); } +void TransformerRMSNormDesc::releaseWeights() { + std::vector().swap(weight); +} + //----------------------------------------------------------------------------- TransformerAttentionDesc::TransformerAttentionDesc() @@ -1166,8 +1245,8 @@ TransformerAttentionDesc::TransformerAttentionDesc(istream& in, bool binaryFloat in >> ropeTheta; if(in.fail()) throw StringError(name + ": failed to parse rope theta"); - if(ropeTheta <= 0.0f) - throw StringError(name + ": rope theta must be positive"); + if(!(ropeTheta > 0.0f) || !isfinite(ropeTheta)) + throw StringError(name + ": rope theta must be positive and finite"); } } @@ -1209,6 +1288,15 @@ int64_t TransformerAttentionDesc::getNumParameters() const { (int64_t)ropeFreqs.size(); // learnable RoPE frequencies, empty for fixed/no RoPE } +void TransformerAttentionDesc::releaseWeights() { + preLN.releaseWeights(); + qProj.releaseWeights(); + kProj.releaseWeights(); + vProj.releaseWeights(); + outProj.releaseWeights(); + std::vector().swap(ropeFreqs); +} + void TransformerAttentionDesc::computeRopeCosSin(int nnXLen, int nnYLen, int paddedNNXYLen, std::vector& cosTable, std::vector& sinTable) const { if(!useRope) throw StringError("TransformerAttentionDesc::computeRopeCosSin called but useRope is false"); @@ -1344,6 +1432,13 @@ int64_t TransformerFFNDesc::getNumParameters() const { linear2.getNumParameters(); } +void TransformerFFNDesc::releaseWeights() { + preLN.releaseWeights(); + linear1.releaseWeights(); + linearGate.releaseWeights(); + linear2.releaseWeights(); +} + //----------------------------------------------------------------------------- static void parseResidualBlockStack( @@ -1550,6 +1645,14 @@ int64_t SGFMetadataEncoderDesc::getNumParameters() const { mul3.getNumParameters(); } +void SGFMetadataEncoderDesc::releaseWeights() { + mul1.releaseWeights(); + bias1.releaseWeights(); + mul2.releaseWeights(); + bias2.releaseWeights(); + mul3.releaseWeights(); +} + //----------------------------------------------------------------------------- TrunkDesc::TrunkDesc() @@ -1906,6 +2009,40 @@ void TrunkDesc::applyScale8ToReduceActivations() { } } +void TrunkDesc::releaseWeights() { + initialConv.releaseWeights(); + initialMatMul.releaseWeights(); + if(metaEncoderVersion > 0) + sgfMetadataEncoder.releaseWeights(); + for(int i = 0; i < blocks.size(); i++) { + if(blocks[i].first == ORDINARY_BLOCK_KIND) { + ResidualBlockDesc* desc = (ResidualBlockDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == GLOBAL_POOLING_BLOCK_KIND) { + GlobalPoolingResidualBlockDesc* desc = (GlobalPoolingResidualBlockDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == NESTED_BOTTLENECK_BLOCK_KIND) { + NestedBottleneckResidualBlockDesc* desc = (NestedBottleneckResidualBlockDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == TRANSFORMER_ATTENTION_BLOCK_KIND) { + TransformerAttentionDesc* desc = (TransformerAttentionDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else if(blocks[i].first == TRANSFORMER_FFN_BLOCK_KIND) { + TransformerFFNDesc* desc = (TransformerFFNDesc*)blocks[i].second.get(); + desc->releaseWeights(); + } + else { + ASSERT_UNREACHABLE; + } + } + // Whichever trunk tip norm is unused has empty parameter vectors, so releasing both is safe. + trunkTipBN.releaseWeights(); + trunkTipRMSNorm.releaseWeights(); +} //----------------------------------------------------------------------------- @@ -2086,6 +2223,18 @@ void PolicyHeadDesc::applyScale8ToReduceActivations() { passActivation.applyScale8ToReduceActivations(); } +void PolicyHeadDesc::releaseWeights() { + p1Conv.releaseWeights(); + g1Conv.releaseWeights(); + g1BN.releaseWeights(); + gpoolToBiasMul.releaseWeights(); + p1BN.releaseWeights(); + p2Conv.releaseWeights(); + gpoolToPassMul.releaseWeights(); + gpoolToPassBias.releaseWeights(); + gpoolToPassMul2.releaseWeights(); +} + //----------------------------------------------------------------------------- ValueHeadDesc::ValueHeadDesc() : modelVersion(-1) {} @@ -2246,6 +2395,17 @@ void ValueHeadDesc::applyScale8ToReduceActivations() { sv3Bias.applyScale8ToReduceActivations(); } +void ValueHeadDesc::releaseWeights() { + v1Conv.releaseWeights(); + v1BN.releaseWeights(); + v2Mul.releaseWeights(); + v2Bias.releaseWeights(); + v3Mul.releaseWeights(); + v3Bias.releaseWeights(); + sv3Mul.releaseWeights(); + sv3Bias.releaseWeights(); + vOwnershipConv.releaseWeights(); +} //----------------------------------------------------------------------------- @@ -2274,6 +2434,7 @@ ModelDesc::ModelDesc() numScoreValueChannels(0), numOwnershipChannels(0), metaEncoderVersion(0), + preferPassAliveUnderSuicideRules(false), postProcessParams() {} @@ -2317,37 +2478,37 @@ ModelDesc::ModelDesc(istream& in, const string& sha256_, bool binaryFloats) { in >> postProcessParams.tdScoreMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse tdScoreMultiplier"); - if(postProcessParams.tdScoreMultiplier <= 0) + if(!(postProcessParams.tdScoreMultiplier > 0) || !isfinite(postProcessParams.tdScoreMultiplier)) throw StringError(name + ": model tdScoreMultiplier must be positive"); in >> postProcessParams.scoreMeanMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse scoreMeanMultiplier"); - if(postProcessParams.scoreMeanMultiplier <= 0) + if(!(postProcessParams.scoreMeanMultiplier > 0) || !isfinite(postProcessParams.scoreMeanMultiplier)) throw StringError(name + ": model scoreMeanMultiplier must be positive"); in >> postProcessParams.scoreStdevMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse scoreStdevMultiplier"); - if(postProcessParams.scoreStdevMultiplier <= 0) + if(!(postProcessParams.scoreStdevMultiplier > 0) || !isfinite(postProcessParams.scoreStdevMultiplier)) throw StringError(name + ": model scoreStdevMultiplier must be positive"); in >> postProcessParams.leadMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse leadMultiplier"); - if(postProcessParams.leadMultiplier <= 0) + if(!(postProcessParams.leadMultiplier > 0) || !isfinite(postProcessParams.leadMultiplier)) throw StringError(name + ": model leadMultiplier must be positive"); in >> postProcessParams.varianceTimeMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse varianceTimeMultiplier"); - if(postProcessParams.varianceTimeMultiplier <= 0) + if(!(postProcessParams.varianceTimeMultiplier > 0) || !isfinite(postProcessParams.varianceTimeMultiplier)) throw StringError(name + ": model varianceTimeMultiplier must be positive"); in >> postProcessParams.shorttermValueErrorMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse shorttermValueErrorMultiplier"); - if(postProcessParams.shorttermValueErrorMultiplier <= 0) + if(!(postProcessParams.shorttermValueErrorMultiplier > 0) || !isfinite(postProcessParams.shorttermValueErrorMultiplier)) throw StringError(name + ": model shorttermValueErrorMultiplier must be positive"); in >> postProcessParams.shorttermScoreErrorMultiplier; if(in.fail()) throw StringError(name + ": model failed to parse shorttermScoreErrorMultiplier"); - if(postProcessParams.shorttermScoreErrorMultiplier <= 0) + if(!(postProcessParams.shorttermScoreErrorMultiplier > 0) || !isfinite(postProcessParams.shorttermScoreErrorMultiplier)) throw StringError(name + ": model shorttermScoreErrorMultiplier must be positive"); } else { @@ -2374,10 +2535,20 @@ ModelDesc::ModelDesc(istream& in, const string& sha256_, bool binaryFloats) { SGFMetadata::METADATA_INPUT_NUM_CHANNELS)); } + //Whether the model expects pass-alive area features computed as if suicide were always legal. + int preferPassAliveInt = 0; + in >> preferPassAliveInt; + if(preferPassAliveInt == 0) + preferPassAliveUnderSuicideRules = false; + else if(preferPassAliveInt == 1) + preferPassAliveUnderSuicideRules = true; + else + throw StringError(name + ": model preferPassAliveUnderSuicideRules unexpected value: " + Global::intToString(preferPassAliveInt)); + if(in.fail()) + throw StringError(name + ": model failed to parse preferPassAliveUnderSuicideRules"); + int unused = 0; in >> unused; - if(unused != 0) throw StringError(name + ": unknown/unsupported model option B: " + Global::intToString(unused)); - in >> unused; if(unused != 0) throw StringError(name + ": unknown/unsupported model option C: " + Global::intToString(unused)); in >> unused; if(unused != 0) throw StringError(name + ": unknown/unsupported model option D: " + Global::intToString(unused)); @@ -2395,6 +2566,7 @@ ModelDesc::ModelDesc(istream& in, const string& sha256_, bool binaryFloats) { else { metaEncoderVersion = 0; numInputMetaChannels = 0; + preferPassAliveUnderSuicideRules = false; } trunk = TrunkDesc(in, modelVersion, binaryFloats, metaEncoderVersion); @@ -2460,6 +2632,7 @@ ModelDesc& ModelDesc::operator=(ModelDesc&& other) { numScoreValueChannels = other.numScoreValueChannels; numOwnershipChannels = other.numOwnershipChannels; metaEncoderVersion = other.metaEncoderVersion; + preferPassAliveUnderSuicideRules = other.preferPassAliveUnderSuicideRules; postProcessParams = other.postProcessParams; trunk = std::move(other.trunk); policyHead = std::move(other.policyHead); @@ -2562,6 +2735,12 @@ void ModelDesc::applyScale8ToReduceActivations() { postProcessParams.outputScaleMultiplier *= 8.0f; } +void ModelDesc::releaseWeights() { + trunk.releaseWeights(); + policyHead.releaseWeights(); + valueHead.releaseWeights(); +} + struct NonCopyingStreamBuf : public std::streambuf { NonCopyingStreamBuf(string& str) { diff --git a/cpp/neuralnet/desc.h b/cpp/neuralnet/desc.h index 36c5a11d8d..4d5f8c6278 100644 --- a/cpp/neuralnet/desc.h +++ b/cpp/neuralnet/desc.h @@ -36,6 +36,8 @@ struct ConvLayerDesc { int64_t getNumParameters() const; void scaleOutputChannels(const std::vector& scaling); + + void releaseWeights(); }; struct BatchNormLayerDesc { @@ -68,6 +70,8 @@ struct BatchNormLayerDesc { void extractChannelFactorsAbsLtOne(std::vector& channelFactors); void extractChannelFactorsAbsLtOneWithInverses(std::vector& channelFactors, std::vector& invChannelFactors); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct ActivationLayerDesc { @@ -105,6 +109,8 @@ struct MatMulLayerDesc { int64_t getNumParameters() const; void scaleOutputChannels(const std::vector& scaling); + + void releaseWeights(); }; struct MatBiasLayerDesc { @@ -124,6 +130,8 @@ struct MatBiasLayerDesc { int64_t getNumParameters() const; void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct ResidualBlockDesc { @@ -150,6 +158,8 @@ struct ResidualBlockDesc { void transformToReduceActivations(); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct GlobalPoolingResidualBlockDesc { @@ -181,6 +191,8 @@ struct GlobalPoolingResidualBlockDesc { void transformToReduceActivations(); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct NestedBottleneckResidualBlockDesc { @@ -215,6 +227,8 @@ struct NestedBottleneckResidualBlockDesc { void transformToReduceActivations(); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; // Trunk final normalization kind (stored in trunk header) @@ -240,6 +254,7 @@ struct RMSNormLayerDesc { RMSNormLayerDesc& operator=(RMSNormLayerDesc&& other); int64_t getNumParameters() const; + void releaseWeights(); }; // Lightweight RMSNorm used inside transformer blocks (weight only, no bias, no spatial modes) @@ -259,6 +274,7 @@ struct TransformerRMSNormDesc { TransformerRMSNormDesc& operator=(TransformerRMSNormDesc&& other); int64_t getNumParameters() const; + void releaseWeights(); }; struct TransformerAttentionDesc { @@ -294,6 +310,7 @@ struct TransformerAttentionDesc { TransformerAttentionDesc& operator=(TransformerAttentionDesc&& other); int64_t getNumParameters() const; + void releaseWeights(); // Compute cos/sin tables for RoPE given board dimensions. // Output tables are indexed as: @@ -324,6 +341,7 @@ struct TransformerFFNDesc { TransformerFFNDesc& operator=(TransformerFFNDesc&& other); int64_t getNumParameters() const; + void releaseWeights(); }; struct SGFMetadataEncoderDesc { @@ -349,6 +367,7 @@ struct SGFMetadataEncoderDesc { SGFMetadataEncoderDesc& operator=(SGFMetadataEncoderDesc&& other); int64_t getNumParameters() const; + void releaseWeights(); }; @@ -397,6 +416,8 @@ struct TrunkDesc { void transformToReduceActivations(); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct PolicyHeadDesc { @@ -431,6 +452,8 @@ struct PolicyHeadDesc { void transformToReduceActivations(); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct ValueHeadDesc { @@ -463,6 +486,8 @@ struct ValueHeadDesc { void transformToReduceActivations(); void applyScale8ToReduceActivations(); + + void releaseWeights(); }; struct ModelPostProcessParams { @@ -494,6 +519,10 @@ struct ModelDesc { int metaEncoderVersion; + //True if the model expects its pass-alive area input features to be computed as if + //multi-stone suicide were always legal, regardless of the actual suicide rule. + bool preferPassAliveUnderSuicideRules; + ModelPostProcessParams postProcessParams; TrunkDesc trunk; @@ -534,6 +563,11 @@ struct ModelDesc { //Fills supported with true if desiredRules itself was exactly supported, false if some modifications had to be made. Rules getSupportedRules(const Rules& desiredRules, bool& supported) const; + // Frees all weight arrays (conv/matmul/bias/batchnorm), keeping scalar shape + // metadata intact. Safe once weights are no longer needed (e.g. CoreML/ANE + // inference, which reads weights from the compiled .mlmodelc). + void releaseWeights(); + }; #endif // #ifndef DESC_H diff --git a/cpp/neuralnet/eigenbackend.cpp b/cpp/neuralnet/eigenbackend.cpp index 98eac42533..424dbce8b9 100644 --- a/cpp/neuralnet/eigenbackend.cpp +++ b/cpp/neuralnet/eigenbackend.cpp @@ -941,7 +941,23 @@ struct RMSNormLayer { activation(activation_), gamma(desc.gamma), beta(desc.beta) - {} + { + // All activation kinds desc.cpp can produce for a trunk tip are implemented in apply(); + // reject anything else so a future kind fails loudly instead of silently acting as identity. + if(activation != ACTIVATION_IDENTITY && activation != ACTIVATION_RELU && + activation != ACTIVATION_MISH && activation != ACTIVATION_SILU) + throw StringError(name + ": RMSNorm layer unsupported activation: " + Global::intToString(activation)); + } + + inline float applyActivation(float v) const { + if(activation == ACTIVATION_RELU) + return std::max(v, 0.0f); + if(activation == ACTIVATION_MISH) + return v * tanhf(v < 20.0f ? log1pf(expf(v)) : v); + if(activation == ACTIVATION_SILU) + return v / (1.0f + expf(-v)); + return v; + } void apply( CONSTTENSORMAP4* input, @@ -973,9 +989,7 @@ struct RMSNormLayer { float rms = 1.0f / sqrtf(sumSq / (float)numChannels + epsilon); for(int c = 0; c < numChannels; c++) { float v = (*input)(c, w, h, n) * rms * gamma[c] + beta[c]; - if(activation == ACTIVATION_SILU) - v = v / (1.0f + expf(-v)); - (*output)(c, w, h, n) = v; + (*output)(c, w, h, n) = applyActivation(v); } } } @@ -1010,9 +1024,7 @@ struct RMSNormLayer { } for(int c = 0; c < numChannels; c++) { float v = (*input)(c, w, h, n) * rms * gamma[c] + beta[c]; - if(activation == ACTIVATION_SILU) - v = v / (1.0f + expf(-v)); - (*output)(c, w, h, n) = v; + (*output)(c, w, h, n) = applyActivation(v); } } } diff --git a/cpp/neuralnet/metalbackend.cpp b/cpp/neuralnet/metalbackend.cpp index 786ef82901..d13cfa582b 100644 --- a/cpp/neuralnet/metalbackend.cpp +++ b/cpp/neuralnet/metalbackend.cpp @@ -115,10 +115,16 @@ SWBatchNormLayerDesc batchNormLayerDescToSwift(const BatchNormLayerDesc* desc) { int numChannels = desc->numChannels; testAssert(desc->mergedScale.size() == numChannels); testAssert(desc->mergedBias.size() == numChannels); + // A default-constructed desc (e.g. the unused trunkTipBN of an RMSNorm-tip trunk) has empty + // vectors, whose .data() may be null; null in a non-optional Swift pointer parameter is + // undefined, so substitute a valid dummy pointer that is never dereferenced (numChannels == 0). + static float dummy = 0.0f; + float* mergedScale = desc->mergedScale.empty() ? &dummy : (float*)desc->mergedScale.data(); + float* mergedBias = desc->mergedBias.empty() ? &dummy : (float*)desc->mergedBias.data(); return createSWBatchNormLayerDesc( numChannels, - (float*)desc->mergedScale.data(), - (float*)desc->mergedBias.data()); + mergedScale, + mergedBias); } /// Convert an activation layer description from C++ to Swift @@ -129,7 +135,11 @@ ActivationKind activationLayerDescToSwift(const ActivationLayerDesc* desc) { case ACTIVATION_MISH: return ActivationKind::mish(); case ACTIVATION_MISH_SCALE8: - return ActivationKind::identity(); // Metal/CoreML does not use scaled mish + // Only created by applyScale8ToReduceActivations(), which the Metal backend never calls. + // Throw rather than silently treating it as identity if that ever changes. + throw StringError(desc->name + ": ACTIVATION_MISH_SCALE8 is not supported by the Metal backend"); + case ACTIVATION_SILU: + return ActivationKind::silu(); case ACTIVATION_IDENTITY: return ActivationKind::identity(); default: @@ -217,6 +227,63 @@ SWNestedBottleneckResidualBlockDesc nestedBottleneckResidualBlockDescToSwift(con postConv); } +/// Convert a transformer RMSNorm description from C++ to Swift +SWTransformerRMSNormDesc transformerRMSNormDescToSwift(const TransformerRMSNormDesc* desc) { + return createSWTransformerRMSNormDesc( + desc->numChannels, + desc->epsilon, + (float*)desc->weight.data()); +} + +/// Convert a transformer attention block description from C++ to Swift +SWTransformerAttentionBlockDesc transformerAttentionBlockDescToSwift(const TransformerAttentionDesc* desc) { + SWTransformerRMSNormDesc preLN = transformerRMSNormDescToSwift(&desc->preLN); + SWMatMulLayerDesc qProj = matMulLayerDescToSwift(&desc->qProj); + SWMatMulLayerDesc kProj = matMulLayerDescToSwift(&desc->kProj); + SWMatMulLayerDesc vProj = matMulLayerDescToSwift(&desc->vProj); + SWMatMulLayerDesc outProj = matMulLayerDescToSwift(&desc->outProj); + float* ropeFreqs = desc->ropeFreqs.empty() ? nullptr : (float*)desc->ropeFreqs.data(); + + return createSWTransformerAttentionBlockDesc( + desc->numHeads, + desc->numKVHeads, + desc->qHeadDim, + desc->vHeadDim, + desc->useRope, + desc->learnableRope, + preLN, + qProj, + kProj, + vProj, + outProj, + desc->ropeNumKVHeads, + desc->ropeNumPairs, + ropeFreqs, + desc->ropeTheta); +} + +/// Convert a transformer FFN block description from C++ to Swift +SWTransformerFFNBlockDesc transformerFFNBlockDescToSwift(const TransformerFFNDesc* desc) { + // The Metal forward pass (metallayers.swift TransformerFFNBlock) only implements the SwiGLU path + // (SiLU(linear1) * gate); a non-SwiGLU model has no gate weights, so guard here as Eigen and CoreML + // do (eigenbackend.cpp / katagocoreml MILBuilder) instead of crashing on the empty gate descriptor. + if(!desc->useSwiGLU) + throw StringError(desc->name + ": non-SwiGLU transformer FFN not supported in Metal backend"); + SWTransformerRMSNormDesc preLN = transformerRMSNormDescToSwift(&desc->preLN); + SWMatMulLayerDesc linear1 = matMulLayerDescToSwift(&desc->linear1); + SWMatMulLayerDesc linearGate = matMulLayerDescToSwift(&desc->linearGate); + SWMatMulLayerDesc linear2 = matMulLayerDescToSwift(&desc->linear2); + + return createSWTransformerFFNBlockDesc( + desc->numChannels, + desc->ffnChannels, + desc->useSwiGLU, + preLN, + linear1, + linearGate, + linear2); +} + /// Convert residual blocks from C++ to Swift swift::Array residualBlocksToSwift(const vector>& blocks) { auto builder = createBlockDescriptorBuilder(); @@ -230,9 +297,12 @@ swift::Array residualBlocksToSwift(const vector sGFMetadataEncoderDescToSwift(const SG } /// Convert a trunk description from C++ to Swift +SWRMSNormLayerDesc rmsNormLayerDescToSwift(const RMSNormLayerDesc* desc) { + float* gamma = desc->gamma.empty() ? nullptr : (float*)desc->gamma.data(); + float* beta = desc->beta.empty() ? nullptr : (float*)desc->beta.data(); + return createSWRMSNormLayerDesc( + desc->numChannels, + desc->epsilon, + desc->spatial, + gamma, + beta); +} + SWTrunkDesc trunkDescToSwift(const TrunkDesc* trunk) { SWConvLayerDesc initialConv = convLayerDescToSwift(&trunk->initialConv); SWMatMulLayerDesc initialMatMul = matMulLayerDescToSwift(&trunk->initialMatMul); auto sgfMetadataEncoder = sGFMetadataEncoderDescToSwift(&trunk->sgfMetadataEncoder); auto swBlocks = residualBlocksToSwift(trunk->blocks); - if(trunk->trunkNormKind != TRUNK_NORM_KIND_STANDARD) - throw StringError("Trunk RMSNorm is not yet supported by the Metal backend"); SWBatchNormLayerDesc trunkTipBN = batchNormLayerDescToSwift(&trunk->trunkTipBN); + SWRMSNormLayerDesc trunkTipRMSNorm = rmsNormLayerDescToSwift(&trunk->trunkTipRMSNorm); ActivationKind trunkTipActivation = activationLayerDescToSwift(&trunk->trunkTipActivation); return createSWTrunkDesc( @@ -285,7 +365,9 @@ SWTrunkDesc trunkDescToSwift(const TrunkDesc* trunk) { initialMatMul, sgfMetadataEncoder, swBlocks, + trunk->trunkNormKind, trunkTipBN, + trunkTipRMSNorm, trunkTipActivation); } @@ -426,13 +508,27 @@ ComputeContext* NeuralNet::createComputeContext( const LoadedModel* loadedModel, ConfigParser& cfg) { - (void)gpuIdxs; + // Only ANE-only configurations may free the engine's in-memory weights: the + // GPU/MPSGraph path reads them via modelDescToSwift, so freeing is unsafe + // unless no GPU handle can ever be built from this model. + // INVARIANT: gpuIdxs must be the complete (deduplicated) set of device indices + // that will ever be passed as gpuIdxForThisThread to createComputeHandle for + // this context. aneOnly==true frees the in-memory weights, so if any thread + // later used a GPU (MPSGraph) index not represented here, it would read freed + // weights. KataGo derives both from the same gpuIdxByServerThread list, so the + // invariant holds today; preserve it if that wiring ever changes. + bool aneOnly = !gpuIdxs.empty(); + for(int idx : gpuIdxs) { + if(idx != METAL_MUX_ANE) { aneOnly = false; break; } + } (void)logger; (void)homeDataDirOverride; (void)loadedModel; (void)cfg; - return new ComputeContext(nnXLen, nnYLen, useFP16Mode); + ComputeContext* context = new ComputeContext(nnXLen, nnYLen, useFP16Mode); + context->aneOnly = aneOnly; + return context; } void NeuralNet::freeComputeContext(ComputeContext* computeContext) { @@ -459,6 +555,17 @@ static swift::Optional convertAndCreateCoreMLO bool useFP16 = (context->useFP16Mode != enabled_t::False); bool optimizeMask = requireExactNNLen; + // On a confirmed ANE-only run, free the engine's in-memory ModelDesc weight + // arrays. This function converts from loadedModel->modelPath (disk), + // so the in-memory weights are not read here; the GPU/MPSGraph path (which + // DOES read them via modelDescToSwift) is never built when aneOnly is true. + // The whole ComputeHandle ctor runs under computeHandleMutex, so this is not + // racy; releaseWeights() clears only weight vectors, leaving the scalar dims + // read by the ComputeHandle ctor / InputBuffers valid. + if(context->aneOnly) { + const_cast(loadedModel)->modelDesc.releaseWeights(); + } + // Convert model to CoreML format in temp directory string coremlModelPath = CoreMLConversion::convertModelToTemp( loadedModel->modelPath, @@ -515,6 +622,21 @@ static swift::Optional createCoreMLOnlyHandleI return convertAndCreateCoreMLOnlyHandle(context, loadedModel, requireExactNNLen, maxBatchSize, serverThreadIdx); } +// True if any block (recursing into nested bottlenecks) is a transformer block. Used to +// predict the converter's narrow-transformer full-FP32 demotion for precision reporting. +static bool trunkHasTransformerBlocks(const vector>& blocks) { + for(const auto& block : blocks) { + if(block.first == TRANSFORMER_ATTENTION_BLOCK_KIND || block.first == TRANSFORMER_FFN_BLOCK_KIND) + return true; + if(block.first == NESTED_BOTTLENECK_BLOCK_KIND) { + const NestedBottleneckResidualBlockDesc* desc = (const NestedBottleneckResidualBlockDesc*)block.second.get(); + if(trunkHasTransformerBlocks(desc->blocks)) + return true; + } + } + return false; +} + // Helper function to create MPSGraph-only handle for all non-ANE modes static swift::Optional createMPSGraphHandleIfNeeded( ComputeContext* context, @@ -568,7 +690,14 @@ coremlOnlyHandle(createCoreMLOnlyHandleIfNeeded(context, loadedModel, requireExa metaEncoderVersion = modelDesc->metaEncoderVersion; this->inputsUseNHWC = inputsUseNHWC; this->requireExactNNLen = requireExactNNLen; - useFP16 = (context->useFP16Mode != enabled_t::False); + // Report what this handle actually computes with. The MPSGraph (GPU) path builds its graph + // entirely in FP32 regardless of useFP16Mode; the CoreML (ANE) path converts at FP16 EXCEPT + // that the converter demotes narrow transformer trunks to full FP32 for accuracy - query the + // converter's predicate so that case reports FP32 too. If the MPSGraph path is ever switched + // to honor useFP16Mode, update this. + bool aneWouldDemoteToFP32 = katagocoreml::KataGoConverter::wouldBuildFullyFp32( + modelDesc->trunk.trunkNumChannels, trunkHasTransformerBlocks(modelDesc->trunk.blocks)); + useFP16 = (gpuIdx == METAL_MUX_ANE) && (context->useFP16Mode != enabled_t::False) && !aneWouldDemoteToFP32; } ComputeHandle::~ComputeHandle() { @@ -595,6 +724,19 @@ ComputeHandle* NeuralNet::createComputeHandle( " (GPU via MPSGraph) or " + std::to_string(METAL_MUX_ANE) + " (ANE via CoreML)."); } + // Mechanically enforce the aneOnly invariant documented in createComputeContext: + // an aneOnly context may have freed the model's in-memory weights, so building a + // GPU/MPSGraph handle (which reads them via modelDescToSwift) would read freed + // data. This can only trip if a caller changes a thread's device after context + // creation (violating the createComputeContext contract) - fail loudly here + // rather than corrupt silently. + if(context->aneOnly && gpuIdx != METAL_MUX_ANE) { + throw StringError( + "Metal backend: server thread " + std::to_string(serverThreadIdx) + + " requested GPU device " + std::to_string(gpuIdx) + + " on a context created as ANE-only. All thread device indices must be included" + " in the gpuIdxs passed to createComputeContext."); + } ComputeHandle* handle = nullptr; { diff --git a/cpp/neuralnet/metalbackend.h b/cpp/neuralnet/metalbackend.h index b7f751e63c..e77dd18d9b 100644 --- a/cpp/neuralnet/metalbackend.h +++ b/cpp/neuralnet/metalbackend.h @@ -113,6 +113,14 @@ struct ComputeContext { */ MetalComputeContext metalContext; + /** + * @brief True only when every configured device is METAL_MUX_ANE, so no + * MPSGraph (GPU) handle will ever read modelDesc weights. Gates the call to + * ModelDesc::releaseWeights() so a mixed GPU+ANE config can never free live + * weights. + */ + bool aneOnly = false; + /** * @brief Constructs a ComputeContext object. * @param nnX The width of the input tensor. @@ -179,6 +187,18 @@ struct ComputeHandle { */ bool maskIdentityChecked = false; + // Weight-release safety is guaranteed by ComputeContext::aneOnly, NOT by the + // declaration order below: within a single ComputeHandle exactly one handle is + // built (the two paths are mutually exclusive on gpuIdx, enforced by the + // ctor's exactly-one check), and releaseWeights() only ever fires on an + // aneOnly context, where no MPSGraph handle is built for any thread. + // That said, keep mpsGraphOnlyHandle declared before coremlOnlyHandle. C++ + // initializes members in DECLARATION order, so createMPSGraphHandleIfNeeded + // (which reads modelDesc weights via modelDescToSwift) is sequenced before + // createCoreMLOnlyHandleIfNeeded (which may call modelDesc.releaseWeights()). + // This ordering is belt-and-suspenders that preserves the natural read-then- + // release sequence should the aneOnly invariant ever be weakened; don't rely + // on it as the primary guarantee, but don't reorder it either. /** * @brief The MPSGraph-only handle instance from Swift (GPU-only mode). */ diff --git a/cpp/neuralnet/metalbackend.swift b/cpp/neuralnet/metalbackend.swift index 94df967a1a..9952624a90 100644 --- a/cpp/neuralnet/metalbackend.swift +++ b/cpp/neuralnet/metalbackend.swift @@ -570,6 +570,12 @@ public class MPSGraphModelHandle { ownership: UnsafeMutablePointer, batchSize: Int ) { + // Drain the per-call MPS objects (command buffer, the MPSNDArray / MPSGraphTensorData input + // feeds, and the encode result tensors) on every invocation. Without this pool they are + // autoreleased onto the long-lived NN-eval server thread, which never exits during a + // multi-game run (e.g. tunehuman), so they accumulate unboundedly — ~1 GB leaked per game. + // Mirrors the per-inference autoreleasepool in the CoreML apply() above. + autoreleasepool { let channelAxis = InputShape.getChannelAxis() let numInputChannelsNS = input.shape[channelAxis] let numInputGlobalChannelsNS = inputGlobal.shape[channelAxis] @@ -665,6 +671,7 @@ public class MPSGraphModelHandle { readOrDie(valueHead.valueTensor, value, "value") readOrDie(valueHead.scoreValueTensor, scoreValue, "scoreValue") readOrDie(valueHead.ownershipTensor, ownership, "ownership") + } } } diff --git a/cpp/neuralnet/metallayers.swift b/cpp/neuralnet/metallayers.swift index bbd2255bcf..754186522a 100644 --- a/cpp/neuralnet/metallayers.swift +++ b/cpp/neuralnet/metallayers.swift @@ -76,6 +76,11 @@ extension MPSGraph { return mulTensor } + + /// SiLU / Swish activation: x * sigmoid(x). Numerically stable across FP16/FP32. + func silu(tensor: MPSGraphTensor) -> MPSGraphTensor { + return multiplication(tensor, sigmoid(with: tensor, name: nil), name: nil) + } } // MARK: - Input Shape Utilities @@ -358,6 +363,7 @@ public enum ActivationKind { case identity case relu case mish + case silu } /// A struct that represents a description of convolutional layer. @@ -487,6 +493,63 @@ public func createSWMatBiasLayerDesc( weights: weights) } +/// A lightweight RMSNorm description used inside transformer blocks (weight only, no bias). +public struct SWTransformerRMSNormDesc { + let numChannels: NSNumber + let epsilon: Float + let weight: UnsafeMutablePointer + + init(numChannels: NSNumber, epsilon: Float, weight: UnsafeMutablePointer) { + self.numChannels = numChannels + self.epsilon = epsilon + self.weight = weight + } +} + +public func createSWTransformerRMSNormDesc( + numChannels: Int32, + epsilon: Float, + weight: UnsafeMutablePointer +) -> SWTransformerRMSNormDesc { + return SWTransformerRMSNormDesc( + numChannels: numChannels as NSNumber, + epsilon: epsilon, + weight: weight) +} + +/// A full-featured RMSNorm description (gamma/beta, spatial mode), used at the trunk tip. +public struct SWRMSNormLayerDesc { + let numChannels: NSNumber + let epsilon: Float + let spatial: Bool + let gamma: UnsafeMutablePointer? + let beta: UnsafeMutablePointer? + + init(numChannels: NSNumber, epsilon: Float, spatial: Bool, + gamma: UnsafeMutablePointer?, beta: UnsafeMutablePointer?) { + self.numChannels = numChannels + self.epsilon = epsilon + self.spatial = spatial + self.gamma = gamma + self.beta = beta + } +} + +public func createSWRMSNormLayerDesc( + numChannels: Int32, + epsilon: Float, + spatial: Bool, + gamma: UnsafeMutablePointer?, + beta: UnsafeMutablePointer? +) -> SWRMSNormLayerDesc { + return SWRMSNormLayerDesc( + numChannels: numChannels as NSNumber, + epsilon: epsilon, + spatial: spatial, + gamma: gamma, + beta: beta) +} + // MARK: - Core Layers /// A class that represents a convolutional layer using MPSGraph @@ -612,6 +675,8 @@ struct ActivationLayer { resultTensor = graph.reLU(with: sourceTensor, name: nil) case .mish: resultTensor = graph.mish(tensor: sourceTensor) + case .silu: + resultTensor = graph.silu(tensor: sourceTensor) default: resultTensor = sourceTensor } @@ -987,6 +1052,140 @@ public func createSWNestedBottleneckResidualBlockDesc( postConv: postConv) } +public class SWTransformerAttentionBlockDesc: BlockDescriptor { + let numHeads: Int + let numKVHeads: Int + let qHeadDim: Int + let vHeadDim: Int + let useRope: Bool + let learnableRope: Bool + let preLN: SWTransformerRMSNormDesc + let qProj: SWMatMulLayerDesc + let kProj: SWMatMulLayerDesc + let vProj: SWMatMulLayerDesc + let outProj: SWMatMulLayerDesc + let ropeNumKVHeads: Int + let ropeNumPairs: Int + let ropeFreqs: UnsafeMutablePointer? // learnable: (numKVHeads, numPairs, 2) flattened + let ropeTheta: Float + + init( + numHeads: Int, + numKVHeads: Int, + qHeadDim: Int, + vHeadDim: Int, + useRope: Bool, + learnableRope: Bool, + preLN: SWTransformerRMSNormDesc, + qProj: SWMatMulLayerDesc, + kProj: SWMatMulLayerDesc, + vProj: SWMatMulLayerDesc, + outProj: SWMatMulLayerDesc, + ropeNumKVHeads: Int, + ropeNumPairs: Int, + ropeFreqs: UnsafeMutablePointer?, + ropeTheta: Float + ) { + self.numHeads = numHeads + self.numKVHeads = numKVHeads + self.qHeadDim = qHeadDim + self.vHeadDim = vHeadDim + self.useRope = useRope + self.learnableRope = learnableRope + self.preLN = preLN + self.qProj = qProj + self.kProj = kProj + self.vProj = vProj + self.outProj = outProj + self.ropeNumKVHeads = ropeNumKVHeads + self.ropeNumPairs = ropeNumPairs + self.ropeFreqs = ropeFreqs + self.ropeTheta = ropeTheta + } +} + +public func createSWTransformerAttentionBlockDesc( + numHeads: Int32, + numKVHeads: Int32, + qHeadDim: Int32, + vHeadDim: Int32, + useRope: Bool, + learnableRope: Bool, + preLN: SWTransformerRMSNormDesc, + qProj: SWMatMulLayerDesc, + kProj: SWMatMulLayerDesc, + vProj: SWMatMulLayerDesc, + outProj: SWMatMulLayerDesc, + ropeNumKVHeads: Int32, + ropeNumPairs: Int32, + ropeFreqs: UnsafeMutablePointer?, + ropeTheta: Float +) -> SWTransformerAttentionBlockDesc { + return SWTransformerAttentionBlockDesc( + numHeads: Int(numHeads), + numKVHeads: Int(numKVHeads), + qHeadDim: Int(qHeadDim), + vHeadDim: Int(vHeadDim), + useRope: useRope, + learnableRope: learnableRope, + preLN: preLN, + qProj: qProj, + kProj: kProj, + vProj: vProj, + outProj: outProj, + ropeNumKVHeads: Int(ropeNumKVHeads), + ropeNumPairs: Int(ropeNumPairs), + ropeFreqs: ropeFreqs, + ropeTheta: ropeTheta) +} + +public class SWTransformerFFNBlockDesc: BlockDescriptor { + let numChannels: Int + let ffnChannels: Int + let useSwiGLU: Bool + let preLN: SWTransformerRMSNormDesc + let linear1: SWMatMulLayerDesc + let linearGate: SWMatMulLayerDesc + let linear2: SWMatMulLayerDesc + + init( + numChannels: Int, + ffnChannels: Int, + useSwiGLU: Bool, + preLN: SWTransformerRMSNormDesc, + linear1: SWMatMulLayerDesc, + linearGate: SWMatMulLayerDesc, + linear2: SWMatMulLayerDesc + ) { + self.numChannels = numChannels + self.ffnChannels = ffnChannels + self.useSwiGLU = useSwiGLU + self.preLN = preLN + self.linear1 = linear1 + self.linearGate = linearGate + self.linear2 = linear2 + } +} + +public func createSWTransformerFFNBlockDesc( + numChannels: Int32, + ffnChannels: Int32, + useSwiGLU: Bool, + preLN: SWTransformerRMSNormDesc, + linear1: SWMatMulLayerDesc, + linearGate: SWMatMulLayerDesc, + linear2: SWMatMulLayerDesc +) -> SWTransformerFFNBlockDesc { + return SWTransformerFFNBlockDesc( + numChannels: Int(numChannels), + ffnChannels: Int(ffnChannels), + useSwiGLU: useSwiGLU, + preLN: preLN, + linear1: linear1, + linearGate: linearGate, + linear2: linear2) +} + public class BlockDescriptorBuilder { public var blockDescriptors: [BlockDescriptor] = [] @@ -1001,6 +1200,347 @@ public func createBlockDescriptorBuilder() -> BlockDescriptorBuilder { return BlockDescriptorBuilder() } +// MARK: - Transformer Layers + +/// Lightweight RMSNorm used inside transformer blocks (weight only, no bias). +/// Input/output are NCHW [B, C, H, W]. Normalizes across channels per spatial position, +/// scales by per-channel weight, and masks the output. +struct TransformerRMSNormLayer { + let resultTensor: MPSGraphTensor + + init( + graph: MPSGraph, + sourceTensor: MPSGraphTensor, + maskTensor: MPSGraphTensor, + descriptor: SWTransformerRMSNormDesc + ) { + let numChannels = descriptor.numChannels + let dataType = sourceTensor.dataType + + // meanSq over channel axis (1): [B,1,H,W] + let sq = graph.square(with: sourceTensor, name: nil) + let sumSq = graph.reductionSum(with: sq, axis: 1, name: nil) + let invC = graph.constant(1.0 / numChannels.doubleValue, dataType: dataType) + let meanSq = graph.multiplication(sumSq, invC, name: nil) + let epsTensor = graph.constant(Double(descriptor.epsilon), dataType: dataType) + let denom = graph.squareRoot(with: graph.addition(meanSq, epsTensor, name: nil), name: nil) + let normalized = graph.division(sourceTensor, denom, name: nil) + + // scale by per-channel weight [1, C, 1, 1] + // Data-backed constants hold Float32 bytes, so their dataType must stay .float32 even if + // the surrounding graph ever switches to FP16 (a dtype mismatch fails loudly; reinterpreting + // the bytes would silently produce garbage). + let weightShape: [NSNumber] = [1, numChannels, 1, 1] + let weightData = Data(floatsNoCopy: descriptor.weight, shape: weightShape) + let weightTensor = graph.constant(weightData, shape: weightShape, dataType: .float32) + let scaled = graph.multiplication(normalized, weightTensor, name: nil) + + resultTensor = graph.multiplication(scaled, maskTensor, name: nil) + } +} + +/// Full-featured RMSNorm for the trunk tip: gamma/beta, spatial or per-position mode, and a +/// fused activation. Input/output are NCHW [B, C, H, W]. Mirrors the Eigen RMSNormLayer. +struct TrunkRMSNormLayer { + let resultTensor: MPSGraphTensor + + init( + graph: MPSGraph, + sourceTensor: MPSGraphTensor, + maskTensor: MPSGraphTensor, + descriptor: SWRMSNormLayerDesc, + activationKind: ActivationKind + ) { + let dataType = sourceTensor.dataType + let numChannels = descriptor.numChannels + + // Zero invalid positions before accumulating sum of squares. + let masked = graph.multiplication(sourceTensor, maskTensor, name: nil) + let sq = graph.square(with: masked, name: nil) + + let meanSq: MPSGraphTensor + if descriptor.spatial { + // Normalize over channels AND valid spatial positions per batch element. + let sumSq = graph.reductionSum(with: sq, axes: [1, 2, 3], name: nil) // [B,1,1,1] + let count = graph.reductionSum(with: maskTensor, axes: [1, 2, 3], name: nil) // valid positions + let cTensor = graph.constant(numChannels.doubleValue, dataType: dataType) + let totalElts = graph.multiplication(count, cTensor, name: nil) + meanSq = graph.division(sumSq, totalElts, name: nil) + } else { + // Per-position normalization across channels. + let sumSq = graph.reductionSum(with: sq, axes: [1], name: nil) // [B,1,H,W] + let invC = graph.constant(1.0 / numChannels.doubleValue, dataType: dataType) + meanSq = graph.multiplication(sumSq, invC, name: nil) + } + + let epsTensor = graph.constant(Double(descriptor.epsilon), dataType: dataType) + let denom = graph.squareRoot(with: graph.addition(meanSq, epsTensor, name: nil), name: nil) + let normalized = graph.division(sourceTensor, denom, name: nil) + + // Data-backed constants hold Float32 bytes; keep dataType .float32 (see TransformerRMSNormLayer). + let gammaShape: [NSNumber] = [1, numChannels, 1, 1] + let gammaTensor = graph.constant(Data(floatsNoCopy: descriptor.gamma!, shape: gammaShape), shape: gammaShape, dataType: .float32) + let betaTensor = graph.constant(Data(floatsNoCopy: descriptor.beta!, shape: gammaShape), shape: gammaShape, dataType: .float32) + let scaled = graph.addition(graph.multiplication(normalized, gammaTensor, name: nil), betaTensor, name: nil) + + let activated = ActivationLayer(graph: graph, sourceTensor: scaled, activationKind: activationKind).resultTensor + resultTensor = graph.multiplication(activated, maskTensor, name: nil) + } +} + +/// A transformer self-attention block (pre-norm, multi-head, optional 2D RoPE, GQA). +/// Mirrors the Eigen reference: RMSNorm -> Q/K/V projections -> RoPE -> scaled dot-product +/// attention with masked softmax -> output projection -> masked residual. +/// Tensors are NCHW [B, C, H, W]; spatial positions (H*W, ordered y*W+x) are the sequence. +struct TransformerAttentionBlock { + let resultTensor: MPSGraphTensor + + init( + graph: MPSGraph, + sourceTensor: MPSGraphTensor, + maskTensor: MPSGraphTensor, + descriptor: SWTransformerAttentionBlockDesc, + nnXLen: NSNumber, + nnYLen: NSNumber + ) { + let dataType = sourceTensor.dataType + let numHeads = descriptor.numHeads + let numKVHeads = descriptor.numKVHeads + let qHeadDim = descriptor.qHeadDim + let vHeadDim = descriptor.vHeadDim + let nnX = nnXLen.intValue + let nnY = nnYLen.intValue + let seq = nnX * nnY + + // 1. RMSNorm (NCHW) + let normed = TransformerRMSNormLayer( + graph: graph, + sourceTensor: sourceTensor, + maskTensor: maskTensor, + descriptor: descriptor.preLN).resultTensor + + // To NHWC [B,H,W,C] so that reshape [-1, C] groups channels per position. + let normedNHWC = graph.transpose(normed, permutation: [0, 2, 3, 1], name: nil) + + // 2. Q/K/V projections via matmul over channels -> [B*seq, heads*dim] + let q = MatMulLayer(graph: graph, descriptor: descriptor.qProj, sourceTensor: normedNHWC).resultTensor + let k = MatMulLayer(graph: graph, descriptor: descriptor.kProj, sourceTensor: normedNHWC).resultTensor + let v = MatMulLayer(graph: graph, descriptor: descriptor.vProj, sourceTensor: normedNHWC).resultTensor + + // 3. reshape to [B, heads, seq, dim] + var qh = TransformerAttentionBlock.toHeads(graph, q, seq: seq, numHeads: numHeads, headDim: qHeadDim) + var kh = TransformerAttentionBlock.toHeads(graph, k, seq: seq, numHeads: numKVHeads, headDim: qHeadDim) + let vh = TransformerAttentionBlock.toHeads(graph, v, seq: seq, numHeads: numKVHeads, headDim: vHeadDim) + + // 4. RoPE on Q and K + if descriptor.useRope { + let numPairs = qHeadDim / 2 + // Q heads map to KV heads via kvh = h * numKVHeads / numHeads (matches Eigen). + let (qCos, qSin) = TransformerAttentionBlock.makeRopeTables( + graph, descriptor: descriptor, nHeads: numHeads, seq: seq, numPairs: numPairs, + nnX: nnX, nnY: nnY, qHeadDim: qHeadDim, + kvIndexForHead: { h in (h * numKVHeads) / numHeads }) + let (kCos, kSin) = TransformerAttentionBlock.makeRopeTables( + graph, descriptor: descriptor, nHeads: numKVHeads, seq: seq, numPairs: numPairs, + nnX: nnX, nnY: nnY, qHeadDim: qHeadDim, + kvIndexForHead: { h in h }) + qh = TransformerAttentionBlock.applyRope(graph, qh, cosT: qCos, sinT: qSin, + numHeads: numHeads, seq: seq, numPairs: numPairs) + kh = TransformerAttentionBlock.applyRope(graph, kh, cosT: kCos, sinT: kSin, + numHeads: numKVHeads, seq: seq, numPairs: numPairs) + } + + // GQA: if numKVHeads < numHeads, repeat KV heads so they align with query heads. + var khExp = kh + var vhExp = vh + if numKVHeads != numHeads { + let groupSize = numHeads / numKVHeads + khExp = TransformerAttentionBlock.repeatKVHeads(graph, kh, numKVHeads: numKVHeads, groupSize: groupSize) + vhExp = TransformerAttentionBlock.repeatKVHeads(graph, vh, numKVHeads: numKVHeads, groupSize: groupSize) + } + + // 5. scores = scale * Q @ K^T -> [B, heads, seq, seq] + let khT = graph.transpose(khExp, permutation: [0, 1, 3, 2], name: nil) + var scores = graph.matrixMultiplication(primary: qh, secondary: khT, name: nil) + let scale = graph.constant(1.0 / Double(qHeadDim).squareRoot(), dataType: dataType) + scores = graph.multiplication(scores, scale, name: nil) + + // Mask keys: add (maskKey - 1) * BIG so masked key columns get ~ -inf before softmax. + // maskTensor [B,1,H,W] -> [B,1,1,seq]; the flat element order is already b, y, x so a + // direct reshape suffices. + let maskSeq = graph.reshape(maskTensor, shape: [-1, 1, 1, seq as NSNumber], name: nil) + let one = graph.constant(1.0, dataType: dataType) + // This graph is FP32-only, where 1e9 is safe. If this path ever gains an FP16 mode, this + // constant must shrink to an FP16-safe magnitude (e.g. 3e4, as the CoreML MIL builder + // uses): 1e9 overflows FP16 to +inf, and (mask - 1) * inf = 0 * inf = NaN at every + // valid key, poisoning the softmax. The precondition makes that switch fail loudly here. + precondition(dataType == .float32, "attention mask bias magnitude 1e9 is only safe in FP32") + let big = graph.constant(1.0e9, dataType: dataType) + let keyBias = graph.multiplication(graph.subtraction(maskSeq, one, name: nil), big, name: nil) + scores = graph.addition(scores, keyBias, name: nil) + + // 6. softmax over key axis (last) + let attn = graph.softMax(with: scores, axis: 3, name: nil) + + // 7. out = attn @ V -> [B, heads, seq, vHeadDim] + let attnOut = graph.matrixMultiplication(primary: attn, secondary: vhExp, name: nil) + + // 8. back to [B*seq, heads*vHeadDim] + let outHeadsLast = graph.transpose(attnOut, permutation: [0, 2, 1, 3], name: nil) // [B,seq,heads,vHeadDim] + let outFlat = graph.reshape(outHeadsLast, shape: [-1, (numHeads * vHeadDim) as NSNumber], name: nil) + + // 9. output projection -> [B*seq, C] + let proj = MatMulLayer(graph: graph, descriptor: descriptor.outProj, sourceTensor: outFlat).resultTensor + + // 10. reshape to NHWC then NCHW + let outChannels = descriptor.outProj.outChannels + let projNHWC = graph.reshape(proj, shape: [-1, nnYLen, nnXLen, outChannels], name: nil) + let projNCHW = graph.transpose(projNHWC, permutation: [0, 3, 1, 2], name: nil) + + // 11. masked residual + let masked = graph.multiplication(projNCHW, maskTensor, name: nil) + resultTensor = graph.addition(sourceTensor, masked, name: nil) + } + + /// Reshape [B*seq, numHeads*headDim] -> [B, numHeads, seq, headDim]. + static func toHeads(_ graph: MPSGraph, _ x: MPSGraphTensor, seq: Int, numHeads: Int, headDim: Int) -> MPSGraphTensor { + let reshaped = graph.reshape(x, shape: [-1, seq as NSNumber, numHeads as NSNumber, headDim as NSNumber], name: nil) + return graph.transpose(reshaped, permutation: [0, 2, 1, 3], name: nil) + } + + /// Repeat each KV head groupSize times along the head axis: [B,numKVHeads,seq,dim] -> [B,numKVHeads*groupSize,seq,dim]. + static func repeatKVHeads(_ graph: MPSGraph, _ x: MPSGraphTensor, numKVHeads: Int, groupSize: Int) -> MPSGraphTensor { + // Repeat each KV head groupSize times consecutively so query head h uses kv = h / groupSize, + // matching the Eigen reference (kvh = h / kvGroupSize). We slice each KV head and concat the + // copies along the head axis. Note: MPSGraph.broadcast(_:shape:) does NOT infer -1, so a + // reshape+broadcast approach with a dynamic batch dim triggers an NDArray INT_MAX assertion; + // slice+concat is shape-safe with no -1 broadcast. + var heads: [MPSGraphTensor] = [] + heads.reserveCapacity(numKVHeads * groupSize) + for kv in 0.. MPSGraphTensor { + let pairsShape: [NSNumber] = [-1, numHeads as NSNumber, seq as NSNumber, numPairs as NSNumber, 2] + let xPairs = graph.reshape(x, shape: pairsShape, name: nil) + let evenShape: [NSNumber] = [-1, numHeads as NSNumber, seq as NSNumber, numPairs as NSNumber] + let xEven = graph.reshape(graph.sliceTensor(xPairs, dimension: 4, start: 0, length: 1, name: nil), shape: evenShape, name: nil) + let xOdd = graph.reshape(graph.sliceTensor(xPairs, dimension: 4, start: 1, length: 1, name: nil), shape: evenShape, name: nil) + let outEven = graph.subtraction(graph.multiplication(xEven, cosT, name: nil), graph.multiplication(xOdd, sinT, name: nil), name: nil) + let outOdd = graph.addition(graph.multiplication(xEven, sinT, name: nil), graph.multiplication(xOdd, cosT, name: nil), name: nil) + let pairShape5: [NSNumber] = [-1, numHeads as NSNumber, seq as NSNumber, numPairs as NSNumber, 1] + let outEvenE = graph.reshape(outEven, shape: pairShape5, name: nil) + let outOddE = graph.reshape(outOdd, shape: pairShape5, name: nil) + let stacked = graph.concatTensors([outEvenE, outOddE], dimension: 4, name: nil) + return graph.reshape(stacked, shape: [-1, numHeads as NSNumber, seq as NSNumber, (numPairs * 2) as NSNumber], name: nil) + } + + /// Build RoPE cos/sin constant tensors of shape [1, nHeads, seq, numPairs]. + static func makeRopeTables(_ graph: MPSGraph, descriptor: SWTransformerAttentionBlockDesc, + nHeads: Int, seq: Int, numPairs: Int, nnX: Int, nnY: Int, qHeadDim: Int, + kvIndexForHead: (Int) -> Int) -> (MPSGraphTensor, MPSGraphTensor) { + // desc.cpp validates that learnable-rope models always carry frequencies; without this check + // a nil pointer would silently fall through to the fixed-theta branch with theta=0 (NaN tables). + precondition(!descriptor.learnableRope || descriptor.ropeFreqs != nil, + "learnableRope requires ropeFreqs") + let count = nHeads * seq * numPairs + // Managed arrays (freed on return). Unlike the weight constants elsewhere, which point at + // C++-owned descriptor memory and so use floatsNoCopy, these tables have no persistent owner; + // we copy them into the Data below so MPSGraph owns the bytes (avoids a leak / use-after-free). + var cosBuf = [Float32](repeating: 0, count: count) + var sinBuf = [Float32](repeating: 0, count: count) + let numPairsPerDim = numPairs / 2 + let dimHalf = qHeadDim / 2 + for h in 0.. SiLU(linear1)*gate -> linear2 -> masked residual. +struct TransformerFFNBlock { + let resultTensor: MPSGraphTensor + + init( + graph: MPSGraph, + sourceTensor: MPSGraphTensor, + maskTensor: MPSGraphTensor, + descriptor: SWTransformerFFNBlockDesc, + nnXLen: NSNumber, + nnYLen: NSNumber + ) { + let numChannels = descriptor.numChannels + + // The C++ conversion layer throws for non-SwiGLU FFN models; this block only implements + // the SwiGLU path, so fail loudly if that guard is ever bypassed. + precondition(descriptor.useSwiGLU, "non-SwiGLU transformer FFN is not supported") + + // 1. RMSNorm + let normed = TransformerRMSNormLayer( + graph: graph, + sourceTensor: sourceTensor, + maskTensor: maskTensor, + descriptor: descriptor.preLN).resultTensor + let normedNHWC = graph.transpose(normed, permutation: [0, 2, 3, 1], name: nil) + + // 2. linear1 + gate, both [B*seq, ffnChannels] + let a = MatMulLayer(graph: graph, descriptor: descriptor.linear1, sourceTensor: normedNHWC).resultTensor + let gate = MatMulLayer(graph: graph, descriptor: descriptor.linearGate, sourceTensor: normedNHWC).resultTensor + + // 3. SwiGLU: SiLU(a) * gate, SiLU(a) = a * sigmoid(a) + let siluA = graph.multiplication(a, graph.sigmoid(with: a, name: nil), name: nil) + let h = graph.multiplication(siluA, gate, name: nil) + + // 4. linear2 -> [B*seq, numChannels] + let out = MatMulLayer(graph: graph, descriptor: descriptor.linear2, sourceTensor: h).resultTensor + + // 5. reshape to NHWC then NCHW, masked residual + let outNHWC = graph.reshape(out, shape: [-1, nnYLen, nnXLen, numChannels as NSNumber], name: nil) + let outNCHW = graph.transpose(outNHWC, permutation: [0, 3, 1, 2], name: nil) + let masked = graph.multiplication(outNCHW, maskTensor, name: nil) + resultTensor = graph.addition(sourceTensor, masked, name: nil) + } +} + // MARK: - Block Implementations /// A class that represents a Residual Block layer @@ -1241,8 +1781,30 @@ struct BlockStack { optimizeIdentityMask: optimizeIdentityMask) blockInput = ordinary.resultTensor + case let attnDescriptor as SWTransformerAttentionBlockDesc: + let attn = TransformerAttentionBlock( + graph: graph, + sourceTensor: sourceTensor, + maskTensor: maskTensor, + descriptor: attnDescriptor, + nnXLen: nnXLen, + nnYLen: nnYLen) + + blockInput = attn.resultTensor + case let ffnDescriptor as SWTransformerFFNBlockDesc: + let ffn = TransformerFFNBlock( + graph: graph, + sourceTensor: sourceTensor, + maskTensor: maskTensor, + descriptor: ffnDescriptor, + nnXLen: nnXLen, + nnYLen: nnYLen) + + blockInput = ffn.resultTensor default: - blockInput = sourceTensor + // Every BlockDescriptor subclass the C++ conversion layer can enqueue has a case above; + // silently passing the input through would skip a block and corrupt outputs. + fatalError("Unhandled block descriptor type: \(type(of: blockDescriptor))") } return processBlockDescriptors( @@ -1472,6 +2034,10 @@ class SGFMetadataEncoder { // MARK: - Trunk +/// Trunk-tip normalization kind, mirroring desc.h TRUNK_NORM_KIND_* (the value is serialized in the model). +let TRUNK_NORM_KIND_STANDARD = 0 // BatchNorm or BiasMask (existing) +let TRUNK_NORM_KIND_RMSNORM = 1 // RMSNorm + /// A class that describes a trunk for a neural network public class SWTrunkDesc { let version: Int @@ -1483,7 +2049,9 @@ public class SWTrunkDesc { let initialMatMul: SWMatMulLayerDesc let sgfMetadataEncoder: SWSGFMetadataEncoderDesc? let blockDescriptors: [BlockDescriptor] + let trunkNormKind: Int let trunkTipBN: SWBatchNormLayerDesc + let trunkTipRMSNorm: SWRMSNormLayerDesc let trunkTipActivation: ActivationKind init( @@ -1496,7 +2064,9 @@ public class SWTrunkDesc { initialMatMul: SWMatMulLayerDesc, sgfMetadataEncoder: SWSGFMetadataEncoderDesc?, blockDescriptors: [BlockDescriptor], + trunkNormKind: Int, trunkTipBN: SWBatchNormLayerDesc, + trunkTipRMSNorm: SWRMSNormLayerDesc, trunkTipActivation: ActivationKind ) { self.version = version @@ -1508,7 +2078,9 @@ public class SWTrunkDesc { self.initialMatMul = initialMatMul self.sgfMetadataEncoder = sgfMetadataEncoder self.blockDescriptors = blockDescriptors + self.trunkNormKind = trunkNormKind self.trunkTipBN = trunkTipBN + self.trunkTipRMSNorm = trunkTipRMSNorm self.trunkTipActivation = trunkTipActivation } } @@ -1523,7 +2095,9 @@ public func createSWTrunkDesc( initialMatMul: SWMatMulLayerDesc, sgfMetadataEncoder: SWSGFMetadataEncoderDesc?, blockDescriptors: [BlockDescriptor], + trunkNormKind: Int32, trunkTipBN: SWBatchNormLayerDesc, + trunkTipRMSNorm: SWRMSNormLayerDesc, trunkTipActivation: ActivationKind ) -> SWTrunkDesc { return SWTrunkDesc( @@ -1536,7 +2110,9 @@ public func createSWTrunkDesc( initialMatMul: initialMatMul, sgfMetadataEncoder: sgfMetadataEncoder, blockDescriptors: blockDescriptors, + trunkNormKind: Int(trunkNormKind), trunkTipBN: trunkTipBN, + trunkTipRMSNorm: trunkTipRMSNorm, trunkTipActivation: trunkTipActivation) } @@ -1632,21 +2208,33 @@ struct Trunk { nnYLen: nnYLen, optimizeIdentityMask: optimizeIdentityMask) - let trunkTipBN = BatchNormLayer( - graph: graph, - sourceTensor: blocks.resultTensor, - maskTensor: maskTensor, - descriptor: descriptor.trunkTipBN, - nnXLen: nnXLen, - nnYLen: nnYLen, - optimizeIdentityMask: optimizeIdentityMask) + // RMSNorm trunk tip uses a fused activation; standard uses BatchNorm followed by a separate activation. + if descriptor.trunkNormKind == TRUNK_NORM_KIND_RMSNORM { + let trunkTipRMSNorm = TrunkRMSNormLayer( + graph: graph, + sourceTensor: blocks.resultTensor, + maskTensor: maskTensor, + descriptor: descriptor.trunkTipRMSNorm, + activationKind: descriptor.trunkTipActivation) - let trunkTipActivation = ActivationLayer( - graph: graph, - sourceTensor: trunkTipBN.resultTensor, - activationKind: descriptor.trunkTipActivation) + resultTensor = trunkTipRMSNorm.resultTensor + } else { + let trunkTipBN = BatchNormLayer( + graph: graph, + sourceTensor: blocks.resultTensor, + maskTensor: maskTensor, + descriptor: descriptor.trunkTipBN, + nnXLen: nnXLen, + nnYLen: nnYLen, + optimizeIdentityMask: optimizeIdentityMask) + + let trunkTipActivation = ActivationLayer( + graph: graph, + sourceTensor: trunkTipBN.resultTensor, + activationKind: descriptor.trunkTipActivation) - resultTensor = trunkTipActivation.resultTensor + resultTensor = trunkTipActivation.resultTensor + } assert(resultTensor.shape?.count == 4) } diff --git a/cpp/neuralnet/nneval.cpp b/cpp/neuralnet/nneval.cpp index 6e44547c78..881c9fbb67 100644 --- a/cpp/neuralnet/nneval.cpp +++ b/cpp/neuralnet/nneval.cpp @@ -95,6 +95,7 @@ NNEvaluator::NNEvaluator( maxBatchSize(maxBatchSz), m_numRowsProcessed(0), m_numBatchesProcessed(0), + m_numCacheHits(0), bufferMutex(), isKilled(false), numServerThreadsStartingUp(0), @@ -299,6 +300,12 @@ bool NNEvaluator::supportsShorttermError() const { return modelVersion >= 9; } +bool NNEvaluator::modelPreferPassAliveUnderSuicideRules() const { + if(loadedModel == NULL) + return false; + return NeuralNet::getModelDesc(loadedModel).preferPassAliveUnderSuicideRules; +} + bool NNEvaluator::getDoRandomize() const { return currentDoRandomize.load(std::memory_order_acquire); } @@ -329,10 +336,14 @@ uint64_t NNEvaluator::numBatchesProcessed() const { double NNEvaluator::averageProcessedBatchSize() const { return (double)numRowsProcessed() / (double)numBatchesProcessed(); } +uint64_t NNEvaluator::numCacheHits() const { + return m_numCacheHits.load(std::memory_order_relaxed); +} void NNEvaluator::clearStats() { m_numRowsProcessed.store(0); m_numBatchesProcessed.store(0); + m_numCacheHits.store(0); } void NNEvaluator::clearCache() { @@ -359,22 +370,10 @@ static void serveEvals( NNServerBuf* buf = new NNServerBuf(*nnEval,loadedModel); Rand rand(randSeedThisThread); - // An uncaught exception escaping a std::thread's entry function does NOT propagate to any - // try/catch at toplevel on the main thread - it calls std::terminate() directly, which aborts - // the process with no message printed. So catch here instead, print what actually went wrong, - // and then exit - achieving the same "fail fast, nnEval thread dying is fatal" intent as before, - // but with a diagnosable error message instead of a silent abort(). - try { - nnEval->serve(*buf,rand,gpuIdxForThisThread,serverThreadIdx); - } - catch(const std::exception& e) { - cerr << "Uncaught exception in NN eval server thread " << serverThreadIdx << ": " << e.what() << endl; - std::exit(1); - } - catch(...) { - cerr << "Uncaught exception of unknown type in NN eval server thread " << serverThreadIdx << endl; - std::exit(1); - } + // Used to have a try catch around this but actually we're in big trouble if this raises an exception + // and causes possibly the only nnEval thread to die, so actually go ahead and let the exception escape to + // toplevel for easier debugging + nnEval->serve(*buf,rand,gpuIdxForThisThread,serverThreadIdx); delete buf; } @@ -509,7 +508,9 @@ void NNEvaluator::maybeWarmupComputeHandle(ComputeHandle* gpuHandle, int serverT // Empty board of the configured size, default rules/params. Outputs are discarded; we only want // the forward passes to trigger graph compilation for every batch size that will be seen. Board board(nnXLen, nnYLen); - BoardHistory history(board, P_BLACK, Rules::getTrompTaylorish(), 0); + //Featurize the way this model expects (a no-op under Tromp-Taylorish rules, but robust if the + //warmup rules ever change). + BoardHistory history(board, P_BLACK, Rules::getTrompTaylorish(), 0, modelPreferPassAliveUnderSuicideRules()); MiscNNInputParams nnInputParams; SGFMetadata sgfMeta; const SGFMetadata* sgfMetaPtr = NULL; @@ -900,6 +901,7 @@ void NNEvaluator::evaluate( if(nnCacheTable != NULL && !skipCache && nnCacheTable->get(nnHash,buf.result)) { if(!(includeOwnerMap && buf.result->whiteOwnerMap == NULL)) { + m_numCacheHits.fetch_add(1, std::memory_order_relaxed); buf.hasResult = true; return; } diff --git a/cpp/neuralnet/nneval.h b/cpp/neuralnet/nneval.h index 0bbf167c95..b266ff0612 100644 --- a/cpp/neuralnet/nneval.h +++ b/cpp/neuralnet/nneval.h @@ -131,6 +131,11 @@ class NNEvaluator { // Check if the loaded neural net supports shorttermError fields bool supportsShorttermError() const; + // Whether the loaded model declares that it expects pass-alive area input features to be + // computed as if multi-stone suicide were always legal, regardless of the actual suicide rule. + // False if there is no loaded model (e.g. debugSkipNeuralNet). + bool modelPreferPassAliveUnderSuicideRules() const; + // Return the "nearest" supported ruleset to desiredRules by this model. // Fills supported with true if desiredRules itself was exactly supported, false if some modifications had to be made. Rules getSupportedRules(const Rules& desiredRules, bool& supported) const; @@ -204,6 +209,7 @@ class NNEvaluator { uint64_t numRowsProcessed() const; uint64_t numBatchesProcessed() const; double averageProcessedBatchSize() const; + uint64_t numCacheHits() const; void clearStats(); @@ -242,6 +248,7 @@ class NNEvaluator { // Counters for statistics std::atomic m_numRowsProcessed; std::atomic m_numBatchesProcessed; + std::atomic m_numCacheHits; mutable std::mutex bufferMutex; diff --git a/cpp/neuralnet/nninputs.cpp b/cpp/neuralnet/nninputs.cpp index 0eee07901a..8cce96b0a4 100644 --- a/cpp/neuralnet/nninputs.cpp +++ b/cpp/neuralnet/nninputs.cpp @@ -870,7 +870,12 @@ Hash128 NNInputs::getHash( const Board& board, const BoardHistory& hist, Player nextPlayer, const MiscNNInputParams& nnInputParams ) { - Hash128 hash = BoardHistory::getSituationRulesAndKoHash(board, hist, nextPlayer, nnInputParams.drawEquivalentWinsForWhite); + //Hash using the effective pass-alive computation mode for this eval, which is normally hist's own + //but may be overridden per-query (e.g. for a secondary net whose declared featurization differs). + Hash128 hash = BoardHistory::getSituationRulesAndKoHash( + board, hist, nextPlayer, nnInputParams.drawEquivalentWinsForWhite, + nnInputParams.getAlwaysComputePassAliveUnderSuicideRules(hist) + ); //Fold in whether a pass ends this phase. if(hist.passWouldEndPhase(board,nextPlayer)) { @@ -937,6 +942,16 @@ Hash128 NNInputs::getHash( return hash; } +bool MiscNNInputParams::getAlwaysComputePassAliveUnderSuicideRules(const BoardHistory& hist) const { + if(passAliveSuicideRulesOverride >= 0) + return passAliveSuicideRulesOverride != 0; + return hist.alwaysComputePassAliveUnderSuicideRules; +} + +bool MiscNNInputParams::getSuicideLegalForPassAlive(const BoardHistory& hist) const { + return hist.rules.multiStoneSuicideLegal || getAlwaysComputePassAliveUnderSuicideRules(hist); +} + //=========================================================================================== //INPUTSVERSION 3 //=========================================================================================== @@ -1145,7 +1160,7 @@ void NNInputs::fillRowV3( else { ASSERT_UNREACHABLE; } - board.calculateArea(area,nonPassAliveStones,safeBigTerritories,unsafeBigTerritories,hist.rules.multiStoneSuicideLegal); + board.calculateArea(area,nonPassAliveStones,safeBigTerritories,unsafeBigTerritories,nnInputParams.getSuicideLegalForPassAlive(hist)); for(int y = 0; y -#ifdef __APPLE__ -#include -#endif - -#include - -#include -#include -#include -#include - -#ifdef _WIN32 -#include // For CoInitializeEx/CoUninitialize -#endif - -#ifdef ENABLE_PYTHON_ONNXRUNTIME -#include -#endif - -using namespace std; - -//-------------------------------------------------------------- - -// Convert a narrow (ASCII) path string to ONNX Runtime's ORTCHAR_T path type. -static std::basic_string toOrtPath(const string& path) { -#ifdef _WIN32 - return std::basic_string(path.begin(), path.end()); -#else - return path; -#endif -} - -// Extract concrete dimensions from an ONNX TensorShapeProto. Symbolic dimensions -// (e.g. "batch") are treated as unknown and reported as -1. -static vector getOnnxTensorShape(const onnx::TensorShapeProto& shapeProto) { - vector shape; - shape.reserve(shapeProto.dim_size()); - for(const auto& dim : shapeProto.dim()) { - if(dim.has_dim_value()) - shape.push_back(dim.dim_value()); - else - shape.push_back(-1); - } - return shape; -} - -//-------------------------------------------------------------- - -// Auto-detect modelVersion from introspected channel counts. -// -// Detection is based on channel-count heuristics for raw .onnx files where the -// model version is not encoded in the file. The mapping assumes V7 inputs -// (22 spatial + 19 global channels) and distinguishes versions by the number of -// score-value and policy output channels: -// - 4 score-value channels -> version 8 -// - 6 score-value channels, 1 policy channel -> version 10 -// - 6 score-value channels, 2 policy channels -> version 15 -// -// If the heuristic picks the wrong version, set the `onnxModelVersion` config -// key to the correct value (>= 0) to override auto-detection. -static int detectModelVersion( - int numInputChannels, int numInputGlobalChannels, - int numPolicyChannels, int numScoreValueChannels, - int configModelVersion -) { - if(configModelVersion >= 0) - return configModelVersion; - - // inputsVersion 7 -> models 8-16: 22 spatial + 19 global - if(numInputChannels == NNInputs::NUM_FEATURES_SPATIAL_V7 && - numInputGlobalChannels == NNInputs::NUM_FEATURES_GLOBAL_V7) { - if(numScoreValueChannels == 6 && numPolicyChannels == 2) - return 15; - if(numScoreValueChannels == 6 && numPolicyChannels == 1) - return 10; - if(numScoreValueChannels == 4) - return 8; - // Default for V7 inputs - return 15; - } - // Older input versions -- fall back to a reasonable default - return NNModelVersion::defaultModelVersion; -} - -struct LoadedModel { - ModelDesc modelDesc; - bool isRawOnnx; - string rawOnnxBytes; - string rawOnnxFileName; // only valid when isRawOnnx is true - - // One-time scale8 transform (see maybeApplyScale8), only meaningful for the .bin.gz path. All - // server threads share this LoadedModel, so whichever ComputeHandle is created first decides - // for everyone. - mutable std::atomic scale8Resolved; - mutable std::mutex scale8Mutex; - - // Constructor for .bin.gz files - LoadedModel(const string& fileName, const string& expectedSha256, bool rawOnnx) - : isRawOnnx(rawOnnx) - { - scale8Resolved.store(false); - - if(!rawOnnx) { - ModelDesc::loadFromFileMaybeGZipped(fileName, modelDesc, expectedSha256); - return; - } - - rawOnnxFileName = fileName; - - // Read raw .onnx file bytes - { - std::ifstream in(fileName, std::ios::binary | std::ios::ate); - if(!in.good()) - throw StringError("ONNX backend: could not open raw ONNX file: " + fileName); - std::streamsize size = in.tellg(); - if(size < 0) - throw StringError("ONNX backend: could not determine size of ONNX file: " + fileName); - in.seekg(0, std::ios::beg); - rawOnnxBytes.resize(size); - if(!in.read(rawOnnxBytes.data(), size)) - throw StringError("ONNX backend: failed to read raw ONNX file: " + fileName); - } - - // Parse the ONNX ModelProto directly to introspect input/output shapes. This avoids - // creating a temporary CPU-only ONNX Runtime session, which cannot load EP context cache - // models that contain EPContext nodes (the CPU EP has no kernel for them). - onnx::ModelProto modelProto; - if(!modelProto.ParseFromArray(rawOnnxBytes.data(), (int)rawOnnxBytes.size())) - throw StringError("ONNX backend: failed to parse raw ONNX file as ModelProto: " + fileName); - - const onnx::GraphProto& graph = modelProto.graph(); - - // Introspect inputs by name first, falling back to shape-based heuristic - int numInputChannels = 0; - int numInputGlobalChannels = 0; - int numInputMetaChannels = 0; - for(const auto& input : graph.input()) { - string name = input.name(); - if(!input.type().has_tensor_type()) - continue; - auto shape = getOnnxTensorShape(input.type().tensor_type().shape()); - // Name-based matching must be case-insensitive: the graph node names emitted by - // OnnxModelBuilder::build() (and expected by default elsewhere in this file) are - // PascalCase ("InputSpatial", "InputGlobal", "InputMask", "InputMeta"), not lowercase. - string lowerName = name; - for(auto& c : lowerName) c = (char)tolower((unsigned char)c); - if(lowerName.find("mask") != string::npos) { - // The on-board mask is its own single-channel input, not part of the spatial feature - // channel count -- explicitly ignored here so it can't clobber numInputChannels below. - } else if(lowerName.find("spatial") != string::npos) { - if(shape.size() >= 2) - numInputChannels = (int)shape[1]; - } else if(lowerName.find("global") != string::npos) { - if(shape.size() >= 2) - numInputGlobalChannels = (int)shape[1]; - } else if(lowerName.find("meta") != string::npos) { - if(shape.size() >= 2) - numInputMetaChannels = (int)shape[1]; - } else if(shape.size() == 4) { - // Shape-based fallback: [N, C, H, W] -- spatial input - numInputChannels = (int)shape[1]; - } else if(shape.size() == 2) { - // Shape-based fallback: [N, C] -- first 2D is global, second is meta - if(numInputGlobalChannels == 0) - numInputGlobalChannels = (int)shape[1]; - else - numInputMetaChannels = (int)shape[1]; - } else { - cerr << "ONNX backend warning: unrecognized input tensor '" << name - << "' with " << shape.size() << "D shape, ignoring" << "\n"; - } - } - - // Introspect outputs - int numPolicyChannels = 0; - int numValueChannels = 0; - int numScoreValueChannels = 0; - int numOwnershipChannels = 0; - for(const auto& output : graph.output()) { - string name = output.name(); - if(!output.type().has_tensor_type()) - continue; - auto shape = getOnnxTensorShape(output.type().tensor_type().shape()); - - // Case-insensitive for the same reason as the input-side matching above; also match - // "scorevalue" (the actual "OutputScoreValue" node name), not "miscvalue". - string lowerName = name; - for(auto& c : lowerName) c = (char)tolower((unsigned char)c); - if(lowerName.find("policy") != string::npos) { - // Policy: [N, C, H, W] -> dim 1 is policy channels - if(shape.size() >= 2) - numPolicyChannels = (int)shape[1]; - } else if(lowerName.find("scorevalue") != string::npos) { - // ScoreValue (aka MiscValue): [N, numScoreValueChannels] - if(shape.size() >= 2) - numScoreValueChannels = (int)shape[1]; - } else if(lowerName.find("value") != string::npos) { - // Value: [N, 3] - if(shape.size() >= 2) - numValueChannels = (int)shape[1]; - } else if(lowerName.find("ownership") != string::npos) { - // Ownership: [N, 1, H, W] - if(shape.size() >= 2) - numOwnershipChannels = (int)shape[1]; - } - } - - // Populate ModelDesc metadata (weights are in the ONNX graph, not in modelDesc) - modelDesc.numInputChannels = numInputChannels; - modelDesc.numInputGlobalChannels = numInputGlobalChannels; - modelDesc.numInputMetaChannels = numInputMetaChannels; - modelDesc.numPolicyChannels = numPolicyChannels; - modelDesc.numValueChannels = numValueChannels; - modelDesc.numScoreValueChannels = numScoreValueChannels; - modelDesc.numOwnershipChannels = numOwnershipChannels; - - // Extract filename stem as model name - { - size_t lastSlash = fileName.find_last_of("/\\"); - string basename = (lastSlash != string::npos) ? fileName.substr(lastSlash + 1) : fileName; - size_t dotPos = basename.find('.'); - modelDesc.name = (dotPos != string::npos) ? basename.substr(0, dotPos) : basename; - } - - // Model version: auto-detect with possible config override (applied later) - modelDesc.modelVersion = detectModelVersion( - numInputChannels, numInputGlobalChannels, - numPolicyChannels, numScoreValueChannels, - -1 // No config override at load time; applied in createComputeHandle if needed - ); - - // postProcessParams gets default values from its constructor (already set) - - scale8Resolved.store(true); // scale8 only applies to modelDesc weights, which raw .onnx has none of. - } - - // Apply the scale8 FP16-range workaround exactly once per model, unless skipped via - // onnxSkipScale8. Must run before any ComputeHandle builds the ONNX graph from modelDesc. - // No-op for the raw .onnx path (scale8Resolved is already true from the constructor above). - void maybeApplyScale8(bool skip) const { - std::lock_guard lock(scale8Mutex); - if(!scale8Resolved.load()) { - if(!skip) - const_cast(this)->modelDesc.applyScale8ToReduceActivations(); - scale8Resolved.store(true); - } - } - - LoadedModel() = delete; - LoadedModel(const LoadedModel&) = delete; - LoadedModel& operator=(const LoadedModel&) = delete; -}; - -LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { - bool isRawOnnx = Global::isSuffix(file, ".onnx"); - return new LoadedModel(file, expectedSha256, isRawOnnx); -} - -void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { - delete loadedModel; -} - -const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { - return loadedModel->modelDesc; -} - -//-------------------------------------------------------------- - -struct ComputeContext { - Ort::Env env; - int nnXLen; - int nnYLen; - string providerName; - - bool transformerNHWC; // run the trunk block stack channel-last (NHWC) for transformer models - bool skipScale8; // skip the scale8 FP16-range workaround (see createComputeContext) - - // VitisAI (AMD Ryzen AI NPU) EP options. - string vitisaiConfigFile; - string vitisaiCacheDir; - bool vitisaiDisableCPUFallback; - bool vitisaiUsePythonRuntime; - - // ONNX Runtime EP context cache options (VitisAI). See - // https://onnxruntime.ai/docs/execution-providers/EP-Context-Design.html - bool vitisaiUseEpContextCache; - string vitisaiEpContextFilePath; - int vitisaiEpContextEmbedMode; - - // Configurable input/output node names. Defaults match the node names emitted by the shared - // OnnxModelBuilder::build() (see onnxmodelbuilder.cpp) used for .bin.gz -> ONNX conversion, - // which is also what trtbackend.cpp consumes. Raw .onnx models can override these if they use - // different names. - string inputMaskName; - string inputSpatialName; - string inputGlobalName; - string inputMetaName; - string outputPolicyPassName; - string outputPolicyName; - string outputValueName; - string outputMiscvalueName; - string outputOwnershipName; - - // Config override for model version (-1 means auto-detect) - int configModelVersion; - - ComputeContext(int xLen, int yLen, const string& provider) - // TEMP DEBUG: KATAGO_ONNX_VERBOSE_EP_LOG=1 bumps the ORT Env's own logging level to VERBOSE to - // surface ONNX Runtime's node-placement dump (VerifyEachNodeIsAssignedToAnEp). - : env(std::getenv("KATAGO_ONNX_VERBOSE_EP_LOG") != nullptr ? ORT_LOGGING_LEVEL_VERBOSE : ORT_LOGGING_LEVEL_WARNING, "KataGoOnnx"), - nnXLen(xLen), - nnYLen(yLen), - providerName(provider), - transformerNHWC(true), - skipScale8(false), - vitisaiConfigFile( -#ifdef KATAGO_VITISAI_DEFAULT_CONFIG_FILE - KATAGO_VITISAI_DEFAULT_CONFIG_FILE -#endif - ), - vitisaiCacheDir(""), - vitisaiDisableCPUFallback(true), -#ifdef ENABLE_PYTHON_ONNXRUNTIME - // When Python embedding is compiled in, default to the Python onnxruntime path for - // VitisAI. This works around a RyzenAI SDK bug where the native C/C++ API fails to - // create runners for EP context cache models. The user can still opt out by setting - // onnxVitisAIUsePythonRuntime=false in the config. - vitisaiUsePythonRuntime(true), -#else - vitisaiUsePythonRuntime(false), -#endif - vitisaiUseEpContextCache(false), - vitisaiEpContextFilePath(""), - vitisaiEpContextEmbedMode(1), - inputMaskName("InputMask"), - inputSpatialName("InputSpatial"), - inputGlobalName("InputGlobal"), - inputMetaName("InputMeta"), - outputPolicyPassName("OutputPolicyPass"), - outputPolicyName("OutputPolicy"), - outputValueName("OutputValue"), - outputMiscvalueName("OutputScoreValue"), - outputOwnershipName("OutputOwnership"), - configModelVersion(-1) - {} -}; - -//-------------------------------------------------------------- - -#ifdef ENABLE_PYTHON_ONNXRUNTIME -namespace { - -struct PythonOnnxState { - static std::atomic initialized; - static std::mutex initMutex; - static PyObject* npModule; - static PyObject* ortModule; - static PyObject* npFloat32; - static PyObject* npFrombuffer; -}; - -std::atomic PythonOnnxState::initialized{false}; -std::mutex PythonOnnxState::initMutex; -PyObject* PythonOnnxState::npModule = nullptr; -PyObject* PythonOnnxState::ortModule = nullptr; -PyObject* PythonOnnxState::npFloat32 = nullptr; -PyObject* PythonOnnxState::npFrombuffer = nullptr; - -static void pythonPrintError() { - if(PyErr_Occurred()) - PyErr_Print(); -} - -static void ensurePythonInitialized() { - std::lock_guard lock(PythonOnnxState::initMutex); - if(PythonOnnxState::initialized) - return; - -#ifdef KATAGO_PYTHON_EXE_PATH - // Point the embedded interpreter at the Python installation that was detected at build time - // (e.g. the ryzen-ai conda environment). This ensures Python finds its stdlib, site-packages, - // and the onnxruntime package even when katago.exe is launched from a directory that does not - // contain a full Python installation. The buffers must remain valid for the interpreter lifetime. - { - static std::wstring pyExeW; - static std::wstring pyHomeW; - if(pyExeW.empty()) { - const char* pyExe = KATAGO_PYTHON_EXE_PATH; - int wlen = MultiByteToWideChar(CP_UTF8, 0, pyExe, -1, nullptr, 0); - if(wlen > 0) { - pyExeW.resize(wlen); - MultiByteToWideChar(CP_UTF8, 0, pyExe, -1, pyExeW.data(), wlen); - Py_SetProgramName(pyExeW.c_str()); - } - // Derive PYTHONHOME from the directory containing python.exe. - const char* lastSlash = strrchr(pyExe, '/'); - if(!lastSlash) lastSlash = strrchr(pyExe, '\\'); - std::string pyHome(pyExe, lastSlash ? (size_t)(lastSlash - pyExe) : strlen(pyExe)); - wlen = MultiByteToWideChar(CP_UTF8, 0, pyHome.c_str(), -1, nullptr, 0); - if(wlen > 0) { - pyHomeW.resize(wlen); - MultiByteToWideChar(CP_UTF8, 0, pyHome.c_str(), -1, pyHomeW.data(), wlen); - Py_SetPythonHome(pyHomeW.c_str()); - } - } - } -#endif - - Py_Initialize(); - if(!Py_IsInitialized()) - throw StringError("ONNX backend: Py_Initialize failed"); - PythonOnnxState::npModule = PyImport_ImportModule("numpy"); - PythonOnnxState::ortModule = PyImport_ImportModule("onnxruntime"); - if(!PythonOnnxState::npModule || !PythonOnnxState::ortModule) { - pythonPrintError(); - throw StringError("ONNX backend: failed to import numpy or onnxruntime"); - } - PythonOnnxState::npFloat32 = PyObject_GetAttrString(PythonOnnxState::npModule, "float32"); - PythonOnnxState::npFrombuffer = PyObject_GetAttrString(PythonOnnxState::npModule, "frombuffer"); - if(!PythonOnnxState::npFloat32 || !PythonOnnxState::npFrombuffer) { - pythonPrintError(); - throw StringError("ONNX backend: failed to get numpy helpers"); - } - PythonOnnxState::initialized = true; -} - -static PyObject* buildPythonProviderOptions(const ComputeContext* ctx) { - PyObject* opts = PyDict_New(); - PyDict_SetItemString(opts, "config_file", PyUnicode_FromString(ctx->vitisaiConfigFile.c_str())); - return opts; -} - -static PyObject* buildPythonSessionOptions(const ComputeContext* ctx) { - PyObject* cls = PyObject_GetAttrString(PythonOnnxState::ortModule, "SessionOptions"); - PyObject* opts = PyObject_CallObject(cls, nullptr); - PyObject_CallMethod(opts, "__setattr__", "si", "intra_op_num_threads", 1); - Py_DECREF(cls); - return opts; -} - -static PyObject* createPythonSession(const ComputeContext* ctx, const string& modelPath) { - ensurePythonInitialized(); - PyGILState_STATE gil = PyGILState_Ensure(); - PyObject* sessOptions = buildPythonSessionOptions(ctx); - PyObject* providerOpts = buildPythonProviderOptions(ctx); - PyObject* providerOptionsList = PyList_New(1); - PyList_SET_ITEM(providerOptionsList, 0, providerOpts); - PyObject* providersList = PyList_New(1); - PyList_SET_ITEM(providersList, 0, PyUnicode_FromString("VitisAIExecutionProvider")); - PyObject* sessionCls = PyObject_GetAttrString(PythonOnnxState::ortModule, "InferenceSession"); - PyObject* modelPathObj = PyUnicode_FromString(modelPath.c_str()); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "sess_options", sessOptions); - PyDict_SetItemString(kwargs, "providers", providersList); - PyDict_SetItemString(kwargs, "provider_options", providerOptionsList); - PyObject* session = PyObject_Call(sessionCls, PyTuple_Pack(1, modelPathObj), kwargs); - Py_DECREF(sessOptions); Py_DECREF(providersList); Py_DECREF(providerOptionsList); - Py_DECREF(sessionCls); Py_DECREF(modelPathObj); Py_DECREF(kwargs); - if(!session) { - pythonPrintError(); - PyGILState_Release(gil); - throw StringError("ONNX backend: failed to create Python InferenceSession"); - } - PyGILState_Release(gil); - return session; -} - -static PyObject* createPythonSessionFromBytes(const ComputeContext* ctx, const char* data, size_t size) { - ensurePythonInitialized(); - PyGILState_STATE gil = PyGILState_Ensure(); - PyObject* sessOptions = buildPythonSessionOptions(ctx); - PyObject* providerOpts = buildPythonProviderOptions(ctx); - PyObject* providerOptionsList = PyList_New(1); - PyList_SET_ITEM(providerOptionsList, 0, providerOpts); - PyObject* providersList = PyList_New(1); - PyList_SET_ITEM(providersList, 0, PyUnicode_FromString("VitisAIExecutionProvider")); - PyObject* sessionCls = PyObject_GetAttrString(PythonOnnxState::ortModule, "InferenceSession"); - PyObject* modelBytes = PyBytes_FromStringAndSize(data, size); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "sess_options", sessOptions); - PyDict_SetItemString(kwargs, "providers", providersList); - PyDict_SetItemString(kwargs, "provider_options", providerOptionsList); - PyObject* session = PyObject_Call(sessionCls, PyTuple_Pack(1, modelBytes), kwargs); - Py_DECREF(sessOptions); Py_DECREF(providersList); Py_DECREF(providerOptionsList); - Py_DECREF(sessionCls); Py_DECREF(modelBytes); Py_DECREF(kwargs); - if(!session) { - pythonPrintError(); - PyGILState_Release(gil); - throw StringError("ONNX backend: failed to create Python InferenceSession from bytes"); - } - PyGILState_Release(gil); - return session; -} - -// Create a NumPy float32 array (reshaped) that views an existing C++ float buffer. -// The returned object is a new reference; the caller must Py_DECREF it. -static PyObject* numpyArrayFromBuffer(float* data, size_t numFloats, const vector& shape) { - PyObject* memview = PyMemoryView_FromMemory( - reinterpret_cast(data), static_cast(numFloats * sizeof(float)), PyBUF_WRITE); - if(!memview) - return nullptr; - PyObject* arr = PyObject_CallFunctionObjArgs( - PythonOnnxState::npFrombuffer, memview, PythonOnnxState::npFloat32, nullptr); - Py_DECREF(memview); - if(!arr) - return nullptr; - PyObject* shapeTuple = PyTuple_New(shape.size()); - for(size_t i = 0; i < shape.size(); i++) - PyTuple_SET_ITEM(shapeTuple, i, PyLong_FromLongLong(shape[i])); - PyObject* reshaped = PyObject_CallMethod(arr, "reshape", "O", shapeTuple); - Py_DECREF(arr); Py_DECREF(shapeTuple); - return reshaped; -} - -} // namespace -#endif // ENABLE_PYTHON_ONNXRUNTIME - -//-------------------------------------------------------------- - -struct ComputeHandle { - ComputeContext* context; - std::unique_ptr session; - int modelVersion; - -#ifdef ENABLE_PYTHON_ONNXRUNTIME - bool usePythonRuntime; - PyObject* pySession; - std::vector> outputShapes; -#endif - -#ifdef _WIN32 - // COM initialization state for this thread. Some NPU runtime components (XRT/ - // VitisAI) appear to require COM on the thread that creates/runs the session. - HRESULT comInitResult; -#endif - - ~ComputeHandle() { -#ifdef ENABLE_PYTHON_ONNXRUNTIME - if(usePythonRuntime && pySession) { - PyGILState_STATE gil = PyGILState_Ensure(); - Py_DECREF(pySession); - PyGILState_Release(gil); - } -#endif -#ifdef _WIN32 - if(comInitResult == S_OK || comInitResult == S_FALSE) - CoUninitialize(); -#endif - } - int numInputChannels; - int numInputGlobalChannels; - int numPolicyChannels; - int numValueChannels; - int numScoreValueChannels; - int numOwnershipChannels; - int numInputMetaChannels; - int policyResultLen; // H*W+1 - - // Input/output names (stored for session->Run) - vector inputNames; - vector outputNames; - vector inputNamePtrs; - vector outputNamePtrs; - - ComputeHandle(ComputeContext* ctx, const LoadedModel& loadedModel, Logger* logger, int deviceIdxForThread) - : context(ctx), - modelVersion(loadedModel.modelDesc.modelVersion), -#ifdef ENABLE_PYTHON_ONNXRUNTIME - usePythonRuntime(false), - pySession(nullptr), -#endif - numInputChannels(loadedModel.modelDesc.numInputChannels), - numInputGlobalChannels(loadedModel.modelDesc.numInputGlobalChannels), - numPolicyChannels(loadedModel.modelDesc.numPolicyChannels), - numValueChannels(loadedModel.modelDesc.numValueChannels), - numScoreValueChannels(loadedModel.modelDesc.numScoreValueChannels), - numOwnershipChannels(loadedModel.modelDesc.numOwnershipChannels), - numInputMetaChannels(loadedModel.modelDesc.numInputMetaChannels), - policyResultLen(ctx->nnXLen * ctx->nnYLen + 1) -#ifdef _WIN32 - , comInitResult(S_OK) -#endif - { -#ifdef _WIN32 - comInitResult = CoInitializeEx(nullptr, COINIT_MULTITHREADED); -#endif - - // Apply config model version override if set - if(ctx->configModelVersion >= 0) - modelVersion = ctx->configModelVersion; - - const char* onnxData; - size_t onnxSize; - string builtOnnxBytes; - if(loadedModel.isRawOnnx) { - if(logger != NULL) - logger->write("ONNX backend: using raw ONNX model (" + - Global::uint64ToString(loadedModel.rawOnnxBytes.size()) + " bytes)"); - onnxData = loadedModel.rawOnnxBytes.data(); - onnxSize = loadedModel.rawOnnxBytes.size(); - } else { - if(logger != NULL) - logger->write("ONNX backend: building ONNX graph from model weights..."); - OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build( - loadedModel.modelDesc, ctx->nnXLen, ctx->nnYLen, - /*requireExactNNLen=*/false, ctx->transformerNHWC, logger, /*emitFusedMishOp=*/false - ); - builtOnnxBytes = std::move(onnxResult.serializedModel); - if(logger != NULL) - logger->write("ONNX backend: ONNX graph built (" + Global::uint64ToString(builtOnnxBytes.size()) + " bytes)"); - onnxData = builtOnnxBytes.data(); - onnxSize = builtOnnxBytes.size(); - - // Dump the ONNX model to a file when KATAGO_DUMP_ONNX is set (debug aid). - const char* dumpPath = getenv("KATAGO_DUMP_ONNX"); - if(dumpPath != nullptr && dumpPath[0] != '\0') { - ofstream dumpFile(dumpPath, ios::binary); - if(dumpFile.is_open()) { - dumpFile.write(builtOnnxBytes.data(), (streamsize)builtOnnxBytes.size()); - dumpFile.close(); - if(logger != NULL) - logger->write(string("ONNX backend: dumped ONNX model to ") + dumpPath + - " (" + Global::uint64ToString(builtOnnxBytes.size()) + " bytes)"); - } else if(logger != NULL) { - logger->write(string("ONNX backend: WARNING - could not open dump path ") + dumpPath); - } - } - } - - if(logger != NULL) - logger->write("ONNX backend: creating session..."); - - Ort::SessionOptions sessionOpts; - sessionOpts.SetIntraOpNumThreads(1); - - // Select execution provider based on providerName - const string& provider = ctx->providerName; - -#ifdef ENABLE_PYTHON_ONNXRUNTIME - // When Python embedding is compiled in, VitisAI defaults to the Python onnxruntime path - // to work around the RyzenAI 1.7.1 SDK C/C++ API bug. The user can opt out via - // onnxVitisAIUsePythonRuntime=false in the config. - usePythonRuntime = (provider == "vitisai" && ctx->vitisaiUsePythonRuntime); -#endif - - if(provider == "coreml") { -#ifdef __APPLE__ - uint32_t coremlFlags = COREML_FLAG_CREATE_MLPROGRAM; - Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CoreML(sessionOpts, coremlFlags)); - if(logger != NULL) - logger->write("ONNX backend: CoreML execution provider enabled (MLProgram mode)"); -#else - throw StringError("ONNX backend: CoreML is only available on Apple platforms"); -#endif - } else if(provider == "cuda") { - OrtCUDAProviderOptions cudaOpts{}; - cudaOpts.device_id = deviceIdxForThread >= 0 ? deviceIdxForThread : 0; - sessionOpts.AppendExecutionProvider_CUDA(cudaOpts); - if(logger != NULL) - logger->write("ONNX backend: CUDA execution provider enabled, device_id=" + Global::intToString(cudaOpts.device_id)); - } else if(provider == "tensorrt") { - OrtTensorRTProviderOptions trtOpts{}; - trtOpts.device_id = deviceIdxForThread >= 0 ? deviceIdxForThread : 0; - sessionOpts.AppendExecutionProvider_TensorRT(trtOpts); - if(logger != NULL) - logger->write("ONNX backend: TensorRT execution provider enabled, device_id=" + Global::intToString(trtOpts.device_id)); - } else if(provider == "migraphx") { - OrtMIGraphXProviderOptions migraphxOpts{}; - migraphxOpts.device_id = deviceIdxForThread >= 0 ? deviceIdxForThread : 0; - sessionOpts.AppendExecutionProvider_MIGraphX(migraphxOpts); - if(logger != NULL) - logger->write("ONNX backend: MIGraphX execution provider enabled, device_id=" + Global::intToString(migraphxOpts.device_id)); - } else if(provider == "vitisai") { -#ifdef ENABLE_PYTHON_ONNXRUNTIME - if(usePythonRuntime) { - if(logger != NULL) - logger->write("ONNX backend: using Python-embedded onnxruntime path for VitisAI"); - } else -#endif - { - std::unordered_map vitisOpts; - if(!ctx->vitisaiConfigFile.empty()) - vitisOpts["config_file"] = ctx->vitisaiConfigFile; - else - throw StringError( - "ONNX backend: onnxProvider=vitisai requires a VitisAI EP config file (vaip_config.json, " - "shipped with the AMD Ryzen AI / VitisAI SDK). Set 'onnxVitisAIConfigFile' in your config, " - "or rebuild with a locatable Ryzen AI installation so a default gets baked in." - ); - // The VitisAI EP's enable_cache_file_io_in_mem provider option defaults to 1 (in-memory - // only -- nothing is ever written to cache_dir), so it must be explicitly set to 0 to make - // the compiled model actually persist to disk across process launches. Without this, every - // katago.exe launch pays the full NPU compile cost again (can take on the order of minutes). - // For pre-built EP context cache models, leave the cache options at their defaults; the - // compiled context is already embedded in the ONNX model and does not need to be persisted. - bool isContextModel = loadedModel.isRawOnnx && - loadedModel.rawOnnxFileName.find("_ctx.onnx") != string::npos; - if(!isContextModel) { - vitisOpts["cache_dir"] = ctx->vitisaiCacheDir; - vitisOpts["enable_cache_file_io_in_mem"] = "0"; - } - // Use the generic provider-registration path rather than the VitisAI-specific C++ helper. - // The generic path loads the provider by name and also registers any associated custom-op - // libraries (e.g. onnxruntime_vitis_ai_custom_ops.dll), which is required for EP context - // cache models containing EPContext nodes. - sessionOpts.AppendExecutionProvider("VitisAIExecutionProvider", vitisOpts); - if(ctx->vitisaiDisableCPUFallback) { - // Force a hard failure at session-creation time if any node can't be claimed by VitisAI, - // instead of ONNX Runtime silently assigning it to the always-registered CPU EP. Without - // this, "session created successfully" is not evidence that anything actually runs on the - // NPU. Set onnxVitisAIDisableCPUFallback=false to relax this if partial CPU fallback is - // acceptable for your use case. - sessionOpts.AddConfigEntry("session.disable_cpu_ep_fallback", "1"); - } - if(ctx->vitisaiUseEpContextCache) { - // ONNX Runtime EP context cache: ask the VitisAI EP to dump a self-contained context model - // (compiled subgraphs embedded as EPContext nodes). This may avoid per-subgraph repeated - // initialization of the NPU runtime. See https://onnxruntime.ai/docs/execution-providers/EP-Context-Design.html - string ctxFilePath = ctx->vitisaiEpContextFilePath; - if(ctxFilePath.empty()) - ctxFilePath = ctx->vitisaiCacheDir + "/katago_vitisai_ctx.onnx"; - sessionOpts.AddConfigEntry("ep.context_enable", "1"); - sessionOpts.AddConfigEntry("ep.context_file_path", ctxFilePath.c_str()); - sessionOpts.AddConfigEntry("ep.context_embed_mode", Global::intToString(ctx->vitisaiEpContextEmbedMode).c_str()); - if(logger != NULL) { - logger->write( - "ONNX backend: VitisAI EP context cache enabled, context_file_path=" + ctxFilePath + - ", embed_mode=" + Global::intToString(ctx->vitisaiEpContextEmbedMode) - ); - } - } - if(logger != NULL) { - logger->write( - "ONNX backend: VitisAI execution provider enabled, config_file=" + ctx->vitisaiConfigFile + - ", cache_dir=" + ctx->vitisaiCacheDir + - ", disable_cpu_ep_fallback=" + Global::boolToString(ctx->vitisaiDisableCPUFallback) - ); - } - } - } else if(provider == "cpu" || provider.empty()) { - if(logger != NULL) - logger->write("ONNX backend: using CPU execution provider"); - } else { - throw StringError("ONNX backend: unknown onnxProvider '" + provider + "', expected 'cpu', 'coreml', 'cuda', 'tensorrt', 'migraphx', or 'vitisai'"); - } - - // Create session. For raw .onnx files we have the original file path, so prefer loading - // from disk: some EPs (notably VitisAI when consuming an EP context cache model) need the - // model file path to resolve embedded context binaries or to correctly claim EPContext nodes. - // For .bin.gz-derived models we only have in-memory bytes. -#ifdef ENABLE_PYTHON_ONNXRUNTIME - if(usePythonRuntime) { - if(loadedModel.isRawOnnx && !loadedModel.rawOnnxFileName.empty()) { - if(logger != NULL) - logger->write("ONNX backend: creating Python session from file path: " + loadedModel.rawOnnxFileName); - pySession = createPythonSession(ctx, loadedModel.rawOnnxFileName); - } else { - if(logger != NULL) - logger->write("ONNX backend: creating Python session from in-memory bytes"); - pySession = createPythonSessionFromBytes(ctx, onnxData, onnxSize); - } - - // Query input/output names from the Python session and store output shapes. - PyGILState_STATE gil = PyGILState_Ensure(); - PyObject* pyInputs = PyObject_CallMethod(pySession, "get_inputs", nullptr); - if(!pyInputs) { pythonPrintError(); PyGILState_Release(gil); throw StringError("ONNX backend: Python get_inputs failed"); } - Py_ssize_t numInputs = PySequence_Size(pyInputs); - for(Py_ssize_t i = 0; i < numInputs; i++) { - PyObject* inp = PySequence_GetItem(pyInputs, i); - PyObject* nameObj = PyObject_GetAttrString(inp, "name"); - inputNames.push_back(PyUnicode_AsUTF8(nameObj)); - Py_DECREF(nameObj); Py_DECREF(inp); - } - Py_DECREF(pyInputs); - - PyObject* pyOutputs = PyObject_CallMethod(pySession, "get_outputs", nullptr); - if(!pyOutputs) { pythonPrintError(); PyGILState_Release(gil); throw StringError("ONNX backend: Python get_outputs failed"); } - Py_ssize_t numOutputs = PySequence_Size(pyOutputs); - for(Py_ssize_t i = 0; i < numOutputs; i++) { - PyObject* out = PySequence_GetItem(pyOutputs, i); - PyObject* nameObj = PyObject_GetAttrString(out, "name"); - outputNames.push_back(PyUnicode_AsUTF8(nameObj)); - PyObject* shapeObj = PyObject_GetAttrString(out, "shape"); - Py_ssize_t shapeLen = PySequence_Size(shapeObj); - vector shape; - for(Py_ssize_t s = 0; s < shapeLen; s++) { - PyObject* dim = PySequence_GetItem(shapeObj, s); - if(PyLong_Check(dim)) shape.push_back(PyLong_AsLongLong(dim)); - else shape.push_back(-1); // symbolic dimension (batch) - Py_DECREF(dim); - } - outputShapes.push_back(shape); - Py_DECREF(nameObj); Py_DECREF(shapeObj); Py_DECREF(out); - } - Py_DECREF(pyOutputs); - PyGILState_Release(gil); - - for(auto& n : inputNames) inputNamePtrs.push_back(n.c_str()); - for(auto& n : outputNames) outputNamePtrs.push_back(n.c_str()); - - if(logger != NULL) { - logger->write("ONNX backend: Python session created, inputs=" + Global::int64ToString(numInputs) + - " outputs=" + Global::int64ToString(numOutputs)); - // Log which onnxruntime Python package is being used. This is useful for diagnosing - // DLL shadowing: if the directory containing katago.exe also contains an onnxruntime.dll - // (or XRT/VitisAI DLLs) from a different build, the embedded Python path may load the - // wrong one and fail with xrt_core.dll / runner-creation errors. - PyGILState_STATE gil = PyGILState_Ensure(); - PyObject* ortModule = PyImport_ImportModule("onnxruntime"); - if(ortModule) { - PyObject* fileObj = PyObject_GetAttrString(ortModule, "__file__"); - if(fileObj) { - logger->write(string("ONNX backend: Python onnxruntime loaded from: ") + PyUnicode_AsUTF8(fileObj)); - Py_DECREF(fileObj); - } - Py_DECREF(ortModule); - } - PyGILState_Release(gil); - } - } else -#endif - { - if(loadedModel.isRawOnnx && !loadedModel.rawOnnxFileName.empty()) { - if(logger != NULL) - logger->write("ONNX backend: creating session from file path: " + loadedModel.rawOnnxFileName); - session = std::make_unique(ctx->env, toOrtPath(loadedModel.rawOnnxFileName).c_str(), sessionOpts); - } else { - if(logger != NULL) - logger->write("ONNX backend: creating session from in-memory bytes"); - session = std::make_unique(ctx->env, onnxData, onnxSize, sessionOpts); - } - - // Query and store input names - Ort::AllocatorWithDefaultOptions allocator; - size_t numInputs = session->GetInputCount(); - for(size_t i = 0; i < numInputs; i++) { - Ort::AllocatedStringPtr name = session->GetInputNameAllocated(i, allocator); - inputNames.push_back(name.get()); - } - for(auto& n : inputNames) - inputNamePtrs.push_back(n.c_str()); - - // Query and store output names - size_t numOutputs = session->GetOutputCount(); - for(size_t i = 0; i < numOutputs; i++) { - Ort::AllocatedStringPtr name = session->GetOutputNameAllocated(i, allocator); - outputNames.push_back(name.get()); - } - for(auto& n : outputNames) - outputNamePtrs.push_back(n.c_str()); - - if(logger != NULL) - logger->write("ONNX backend: session created, inputs=" + Global::uint64ToString(numInputs) + - " outputs=" + Global::uint64ToString(numOutputs)); - } - } - - ComputeHandle() = delete; - ComputeHandle(const ComputeHandle&) = delete; - ComputeHandle& operator=(const ComputeHandle&) = delete; -}; - -//-------------------------------------------------------------- - -struct InputBuffers { - int maxBatchSize; - - size_t singleInputElts; - size_t singleInputGlobalElts; - size_t singleInputMetaElts; - - vector spatialInput; - vector globalInput; - vector metaInput; - - InputBuffers(const LoadedModel* loadedModel, int maxBatchSz, int nnXLen, int nnYLen) { - const ModelDesc& m = loadedModel->modelDesc; - maxBatchSize = maxBatchSz; - singleInputElts = (size_t)m.numInputChannels * nnXLen * nnYLen; - singleInputGlobalElts = (size_t)m.numInputGlobalChannels; - singleInputMetaElts = (size_t)m.numInputMetaChannels; - spatialInput.resize(singleInputElts * maxBatchSize, 0.0f); - globalInput.resize(singleInputGlobalElts * maxBatchSize, 0.0f); - if(m.numInputMetaChannels > 0) - metaInput.resize(singleInputMetaElts * maxBatchSize, 0.0f); - } - - ~InputBuffers() {} - - InputBuffers() = delete; - InputBuffers(const InputBuffers&) = delete; - InputBuffers& operator=(const InputBuffers&) = delete; -}; - -InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { - return new InputBuffers(loadedModel, maxBatchSize, nnXLen, nnYLen); -} -void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { - delete inputBuffers; -} - -//-------------------------------------------------------------- - -void NeuralNet::globalInitialize() { -} - -void NeuralNet::globalCleanup() { -} - -//-------------------------------------------------------------- - -ComputeContext* NeuralNet::createComputeContext( - const std::vector& gpuIdxs, - Logger* logger, - int nnXLen, - int nnYLen, - const string& homeDataDirOverride, - enabled_t useFP16Mode, - const LoadedModel* loadedModel, - ConfigParser& cfg -) { - (void)gpuIdxs; - (void)loadedModel; - // The emitted ONNX graph is fp32; inference precision is chosen internally by the execution - // provider. KataGo's global useFP16 flag therefore cannot be honored here - fail loudly instead - // of silently ignoring a request. - if(useFP16Mode == enabled_t::True) - throw StringError( - "ONNX backend: the global useFP16 flag is not supported and cannot be honored. " - "Precision is controlled by the execution provider. Leave useFP16 unset or set it to false/auto."); - - string providerName = cfg.contains("onnxProvider") ? Global::toLower(cfg.getString("onnxProvider")) : "cpu"; - - if(logger != NULL) - logger->write("ONNX backend: creating compute context for " + - Global::intToString(nnXLen) + "x" + Global::intToString(nnYLen) + - " with provider '" + providerName + "'"); - - ComputeContext* ctx = new ComputeContext(nnXLen, nnYLen, providerName); - - // Apply configured node names / options, read directly off cfg. - if(cfg.contains("onnxInputMask")) ctx->inputMaskName = cfg.getString("onnxInputMask"); - if(cfg.contains("onnxInputSpatial")) ctx->inputSpatialName = cfg.getString("onnxInputSpatial"); - if(cfg.contains("onnxInputGlobal")) ctx->inputGlobalName = cfg.getString("onnxInputGlobal"); - if(cfg.contains("onnxInputMeta")) ctx->inputMetaName = cfg.getString("onnxInputMeta"); - if(cfg.contains("onnxOutputPolicyPass")) ctx->outputPolicyPassName = cfg.getString("onnxOutputPolicyPass"); - if(cfg.contains("onnxOutputPolicy")) ctx->outputPolicyName = cfg.getString("onnxOutputPolicy"); - if(cfg.contains("onnxOutputValue")) ctx->outputValueName = cfg.getString("onnxOutputValue"); - if(cfg.contains("onnxOutputMiscvalue")) ctx->outputMiscvalueName = cfg.getString("onnxOutputMiscvalue"); - if(cfg.contains("onnxOutputOwnership")) ctx->outputOwnershipName = cfg.getString("onnxOutputOwnership"); - - // Trunk layout for transformer models. Default NHWC (channel-last), matching the TensorRT - // backend's trtTransformerNHWC default; ignored entirely for models without transformer blocks. - ctx->transformerNHWC = cfg.contains("onnxTransformerNHWC") ? cfg.getBool("onnxTransformerNHWC") : true; - - // Skip the scale8 FP16-range workaround (default false = apply it). scale8 keeps convnet - // activations 8x smaller so they stay inside typical FP16 execution-provider ranges; the cost is - // MISH_SCALE8 subgraphs that can block fused-Mish optimizations on some providers. Keep on - // (default); set true only for FP32 precision or workloads where FP16 overflow is not a - // practical risk. - ctx->skipScale8 = cfg.contains("onnxSkipScale8") ? cfg.getBool("onnxSkipScale8") : false; - - if(cfg.contains("onnxVitisAIConfigFile")) ctx->vitisaiConfigFile = cfg.getString("onnxVitisAIConfigFile"); - if(cfg.contains("onnxVitisAICacheDir")) ctx->vitisaiCacheDir = cfg.getString("onnxVitisAICacheDir"); - if(cfg.contains("onnxVitisAIDisableCPUFallback")) - ctx->vitisaiDisableCPUFallback = cfg.getBool("onnxVitisAIDisableCPUFallback"); - if(cfg.contains("onnxVitisAIUsePythonRuntime")) - ctx->vitisaiUsePythonRuntime = cfg.getBool("onnxVitisAIUsePythonRuntime"); - if(cfg.contains("onnxVitisAIUseEpContextCache")) - ctx->vitisaiUseEpContextCache = cfg.getBool("onnxVitisAIUseEpContextCache"); - if(cfg.contains("onnxVitisAIEpContextFilePath")) - ctx->vitisaiEpContextFilePath = cfg.getString("onnxVitisAIEpContextFilePath"); - if(cfg.contains("onnxVitisAIEpContextEmbedMode")) - ctx->vitisaiEpContextEmbedMode = Global::stringToInt(cfg.getString("onnxVitisAIEpContextEmbedMode")); - if(providerName == "vitisai" && ctx->vitisaiCacheDir.empty()) { - // No explicit override: default to a fixed subdir of katagodata, same convention as - // trtbackend.cpp's "trtcache" (see HomeData::getHomeDataDir), so the (slow, ~minutes-long) - // NPU compile only has to happen once per model rather than on every process launch. - string homeDataDir = HomeData::getHomeDataDir(true, homeDataDirOverride); - string cacheDir = homeDataDir + "/vitisaicache"; - MakeDir::make(cacheDir); - ctx->vitisaiCacheDir = cacheDir; - } - if(cfg.contains("onnxModelVersion")) { - int v = Global::stringToInt(cfg.getString("onnxModelVersion")); - if(v >= 0) - ctx->configModelVersion = v; - } - - return ctx; -} - -void NeuralNet::freeComputeContext(ComputeContext* computeContext) { - delete computeContext; -} - -//-------------------------------------------------------------- - -ComputeHandle* NeuralNet::createComputeHandle( - ComputeContext* context, - const LoadedModel* loadedModel, - Logger* logger, - int maxBatchSize, - bool requireExactNNLen, - bool inputsUseNHWC, - int gpuIdxForThisThread, - int serverThreadIdx -) { - (void)maxBatchSize; - (void)requireExactNNLen; - if(inputsUseNHWC) - throw StringError("ONNX backend: inputsUseNHWC = true not supported, must use NCHW"); - - // Apply the scale8 FP16-range workaround exactly once per model (unless onnxSkipScale8), - // before this handle builds the ONNX graph from modelDesc. - loadedModel->maybeApplyScale8(context->skipScale8); - - if(logger != NULL) { - logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + - ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion)); - logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + - ": Model name: " + loadedModel->modelDesc.name); - string deviceInfo = - context->providerName == "vitisai" - ? "n/a (single NPU device)" - : Global::intToString(gpuIdxForThisThread); - logger->write("ONNX backend thread " + Global::intToString(serverThreadIdx) + - ": provider=" + context->providerName + - " deviceIdx=" + deviceInfo); - } - - return new ComputeHandle(context, *loadedModel, logger, gpuIdxForThisThread); -} - -void NeuralNet::freeComputeHandle(ComputeHandle* computeHandle) { - delete computeHandle; -} - -bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { - (void)handle; - return false; -} - -bool NeuralNet::setIsWarmup(const ComputeHandle* handle, bool isWarmup) { - (void)handle; - (void)isWarmup; - return false; -} - -//-------------------------------------------------------------- - -static int findNameIndex(const vector& names, const vector& targets); - -#ifdef ENABLE_PYTHON_ONNXRUNTIME -// Run inference through the embedded Python onnxruntime.InferenceSession and copy the -// resulting NumPy arrays back into KataGo's output buffers. This path is used for the -// VitisAI provider when the public C/C++ API path fails (RyzenAI 1.7.1 SDK bug). -static void getOutputPython( - ComputeHandle* computeHandle, - InputBuffers* inputBuffers, - int numBatchEltsFilled, - NNResultBuf** inputBufs, - vector& outputs -) { - const int batchSize = numBatchEltsFilled; - const int nnXLen = computeHandle->context->nnXLen; - const int nnYLen = computeHandle->context->nnYLen; - const int numSpatialFeatures = computeHandle->numInputChannels; - const int numGlobalFeatures = computeHandle->numInputGlobalChannels; - const int numInputMetaChannels = computeHandle->numInputMetaChannels; - const ComputeContext* ctx = computeHandle->context; - - // Fill input buffers (same logic as the Ort::Session path). - for(int nIdx = 0; nIdx < batchSize; nIdx++) { - float* rowSpatialInput = inputBuffers->spatialInput.data() + (inputBuffers->singleInputElts * nIdx); - float* rowGlobalInput = inputBuffers->globalInput.data() + (inputBuffers->singleInputGlobalElts * nIdx); - const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); - const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); - std::copy(rowGlobal, rowGlobal + numGlobalFeatures, rowGlobalInput); - SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, false, inputBufs[nIdx]->symmetry); - if(numInputMetaChannels > 0) { - float* rowMetaInput = inputBuffers->metaInput.data() + (inputBuffers->singleInputMetaElts * nIdx); - const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); - std::copy(rowMeta, rowMeta + numInputMetaChannels, rowMetaInput); - } - } - - int spatialIdx = findNameIndex(computeHandle->inputNames, {ctx->inputSpatialName}); - int globalIdx = findNameIndex(computeHandle->inputNames, {ctx->inputGlobalName}); - if(spatialIdx < 0 || globalIdx < 0) - throw StringError("ONNX backend (Python path): could not find expected input names"); - - const int spatialPolicyLen = nnXLen * nnYLen; - int maskIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMaskName}); - vector maskBuf; - if(maskIdx >= 0) { - maskBuf.resize((size_t)batchSize * spatialPolicyLen); - for(int r = 0; r < batchSize; r++) { - const float* rowSpatial = inputBuffers->spatialInput.data() + inputBuffers->singleInputElts * r; - std::copy(rowSpatial, rowSpatial + spatialPolicyLen, maskBuf.data() + (size_t)r * spatialPolicyLen); - } - } - - int metaIdx = -1; - if(numInputMetaChannels > 0) { - metaIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMetaName}); - if(metaIdx < 0) - throw StringError("ONNX backend (Python path): model has metadata channels but could not find " + ctx->inputMetaName); - } - - PyGILState_STATE gil = PyGILState_Ensure(); - - // Build input_feed dict. - PyObject* inputFeed = PyDict_New(); - for(size_t i = 0; i < computeHandle->inputNames.size(); i++) { - float* data = nullptr; - size_t numFloats = 0; - vector shape; - if((int)i == spatialIdx) { - data = inputBuffers->spatialInput.data(); - numFloats = inputBuffers->singleInputElts * batchSize; - shape = {batchSize, numSpatialFeatures, nnYLen, nnXLen}; - } else if((int)i == globalIdx) { - data = inputBuffers->globalInput.data(); - numFloats = inputBuffers->singleInputGlobalElts * batchSize; - shape = {batchSize, numGlobalFeatures, 1, 1}; - } else if((int)i == metaIdx) { - data = inputBuffers->metaInput.data(); - numFloats = inputBuffers->singleInputMetaElts * batchSize; - shape = {batchSize, numInputMetaChannels, 1, 1}; - } else if((int)i == maskIdx) { - data = maskBuf.data(); - numFloats = maskBuf.size(); - shape = {batchSize, 1, nnYLen, nnXLen}; - } else { - PyGILState_Release(gil); - throw StringError("ONNX backend (Python path): unexpected input node '" + computeHandle->inputNames[i] + - "' -- only mask, spatial, global, and meta inputs are supported"); - } - PyObject* arr = numpyArrayFromBuffer(data, numFloats, shape); - if(!arr) { - pythonPrintError(); - PyGILState_Release(gil); - throw StringError("ONNX backend (Python path): failed to create numpy array for input '" + computeHandle->inputNames[i] + "'"); - } - PyDict_SetItemString(inputFeed, computeHandle->inputNames[i].c_str(), arr); - Py_DECREF(arr); - } - - // Run inference. - PyObject* runResult = PyObject_CallMethod(computeHandle->pySession, "run", "OO", Py_None, inputFeed); - Py_DECREF(inputFeed); - if(!runResult) { - pythonPrintError(); - PyGILState_Release(gil); - throw StringError("ONNX backend (Python path): session.run failed"); - } - - // Copy outputs and wrap them in Ort::Value tensors so the rest of getOutput can stay unchanged. - Py_ssize_t numOutputs = PyList_Size(runResult); - vector outputTensors; - outputTensors.reserve(numOutputs); - vector> outputData(numOutputs); - Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); - - for(Py_ssize_t i = 0; i < numOutputs; i++) { - PyObject* outArr = PyList_GET_ITEM(runResult, i); - PyObject* bytes = PyObject_CallMethod(outArr, "tobytes", nullptr); - if(!bytes) { - pythonPrintError(); - Py_DECREF(runResult); - PyGILState_Release(gil); - throw StringError("ONNX backend (Python path): failed to get output bytes"); - } - char* buf = nullptr; - Py_ssize_t len = 0; - PyBytes_AsStringAndSize(bytes, &buf, &len); - size_t numFloats = len / sizeof(float); - outputData[i].resize(numFloats); - std::memcpy(outputData[i].data(), buf, len); - Py_DECREF(bytes); - - // Use the stored output shape, replacing any symbolic dimension with the current batch size. - vector shape = computeHandle->outputShapes[i]; - int64_t product = 1; - for(size_t s = 0; s < shape.size(); s++) { - if(shape[s] < 0) shape[s] = batchSize; - product *= shape[s]; - } - // Fallback: if stored shape is empty or inconsistent, flatten to [batchSize, numFloats/batchSize]. - if(shape.empty() || product != (int64_t)numFloats) { - shape = {(int64_t)batchSize, (int64_t)(numFloats / batchSize)}; - } - outputTensors.push_back( - Ort::Value::CreateTensor(memInfo, outputData[i].data(), outputData[i].size(), shape.data(), shape.size()) - ); - } - Py_DECREF(runResult); - PyGILState_Release(gil); - - // The remainder of output extraction is identical to the C++ API path. - int policyPassOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyPassName}); - int policyOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyName}); - int valueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputValueName}); - int miscvalueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputMiscvalueName}); - int ownershipOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputOwnershipName}); - - if(policyPassOutputIdx < 0) - throw StringError("ONNX backend (Python path): could not find policy-pass output node '" + ctx->outputPolicyPassName + "'"); - if(policyOutputIdx < 0) - throw StringError("ONNX backend (Python path): could not find policy output node '" + ctx->outputPolicyName + "'"); - if(valueOutputIdx < 0) - throw StringError("ONNX backend (Python path): could not find value output node '" + ctx->outputValueName + "'"); - if(miscvalueOutputIdx < 0) - throw StringError("ONNX backend (Python path): could not find miscvalue output node '" + ctx->outputMiscvalueName + "'"); - if(ownershipOutputIdx < 0) - throw StringError("ONNX backend (Python path): could not find ownership output node '" + ctx->outputOwnershipName + "'"); - - const float* policyPassData = outputTensors[policyPassOutputIdx].GetTensorData(); - const float* policyData = outputTensors[policyOutputIdx].GetTensorData(); - const float* valueData = outputTensors[valueOutputIdx].GetTensorData(); - const float* miscvalueData = outputTensors[miscvalueOutputIdx].GetTensorData(); - const float* ownershipData = outputTensors[ownershipOutputIdx].GetTensorData(); - - assert(policyPassData != nullptr); - assert(policyData != nullptr); - assert(valueData != nullptr); - assert(miscvalueData != nullptr); - assert(ownershipData != nullptr); - assert((int)outputs.size() == batchSize); - - float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; - - for(int row = 0; row < batchSize; row++) { - NNOutput* output = outputs[row]; - assert(output->nnXLen == nnXLen); - assert(output->nnYLen == nnYLen); - float policyOptimism = (float)inputBufs[row]->policyOptimism; - - { - const float* policyRowBase = policyData + (size_t)row * computeHandle->numPolicyChannels * spatialPolicyLen; - const float* policyPassRowBase = policyPassData + (size_t)row * computeHandle->numPolicyChannels; - float* policyProbs = output->policyProbs; - - if(computeHandle->numPolicyChannels >= 2) { - const float* ch0 = policyRowBase; - const float* ch1 = policyRowBase + spatialPolicyLen; - for(int i = 0; i < spatialPolicyLen; i++) { - float p = ch0[i]; - float pOpt = ch1[i]; - policyProbsTmp[i] = p + (pOpt - p) * policyOptimism; - } - SymmetryHelpers::copyOutputsWithSymmetry(policyProbsTmp, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[spatialPolicyLen] = policyPassRowBase[0] + (policyPassRowBase[1] - policyPassRowBase[0]) * policyOptimism; - } else { - assert(computeHandle->numPolicyChannels == 1); - const float* ch0 = policyRowBase; - SymmetryHelpers::copyOutputsWithSymmetry(ch0, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[spatialPolicyLen] = policyPassRowBase[0]; - } - } - - { - int numVC = computeHandle->numValueChannels; - assert(numVC == 3); - output->whiteWinProb = valueData[row * numVC]; - output->whiteLossProb = valueData[row * numVC + 1]; - output->whiteNoResultProb = valueData[row * numVC + 2]; - } - - { - int numScoreValueChannels = computeHandle->numScoreValueChannels; - if(computeHandle->modelVersion >= 9) { - assert(numScoreValueChannels >= 6); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; - output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; - output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = miscvalueData[row * numScoreValueChannels + 4]; - output->shorttermScoreError = miscvalueData[row * numScoreValueChannels + 5]; - } - else if(computeHandle->modelVersion >= 8) { - assert(numScoreValueChannels >= 4); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; - output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; - output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(computeHandle->modelVersion >= 4) { - assert(numScoreValueChannels >= 2); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(computeHandle->modelVersion >= 3) { - assert(numScoreValueChannels >= 1); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else { - ASSERT_UNREACHABLE; - } - } - - if(output->whiteOwnerMap != NULL) { - assert(computeHandle->numOwnershipChannels == 1); - const float* ownershipRowBuf = ownershipData + row * nnXLen * nnYLen; - SymmetryHelpers::copyOutputsWithSymmetry(ownershipRowBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - } - } -} -#endif // ENABLE_PYTHON_ONNXRUNTIME - -//-------------------------------------------------------------- - -// Helper to find the index of a name in a vector, checking multiple alternatives. -static int findNameIndex(const vector& names, const vector& targets) { - for(size_t i = 0; i < names.size(); i++) { - for(const auto& t : targets) { - if(names[i] == t) - return (int)i; - } - } - return -1; -} - -void NeuralNet::getOutput( - ComputeHandle* computeHandle, - InputBuffers* inputBuffers, - int numBatchEltsFilled, - NNResultBuf** inputBufs, - vector& outputs -) { - assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); - assert(numBatchEltsFilled > 0); - const int batchSize = numBatchEltsFilled; - const int nnXLen = computeHandle->context->nnXLen; - const int nnYLen = computeHandle->context->nnYLen; - const int numSpatialFeatures = computeHandle->numInputChannels; - const int numGlobalFeatures = computeHandle->numInputGlobalChannels; - const int numPolicyChannels = computeHandle->numPolicyChannels; - -#ifdef ENABLE_PYTHON_ONNXRUNTIME - if(computeHandle->usePythonRuntime) { - getOutputPython(computeHandle, inputBuffers, numBatchEltsFilled, inputBufs, outputs); - return; - } -#endif - - // Fill input buffers - for(int nIdx = 0; nIdx < batchSize; nIdx++) { - float* rowSpatialInput = inputBuffers->spatialInput.data() + (inputBuffers->singleInputElts * nIdx); - float* rowGlobalInput = inputBuffers->globalInput.data() + (inputBuffers->singleInputGlobalElts * nIdx); - - const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); - const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); - std::copy(rowGlobal, rowGlobal + numGlobalFeatures, rowGlobalInput); - SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, false, inputBufs[nIdx]->symmetry); - - if(computeHandle->numInputMetaChannels > 0) { - float* rowMetaInput = inputBuffers->metaInput.data() + (inputBuffers->singleInputMetaElts * nIdx); - const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); - std::copy(rowMeta, rowMeta + computeHandle->numInputMetaChannels, rowMetaInput); - } - } - - // Create ONNX tensors - Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); - - std::array spatialShape = {batchSize, numSpatialFeatures, nnYLen, nnXLen}; - Ort::Value spatialTensor = Ort::Value::CreateTensor( - memInfo, inputBuffers->spatialInput.data(), inputBuffers->singleInputElts * batchSize, - spatialShape.data(), spatialShape.size() - ); - - // NC11 (rank 4), matching OnnxModelBuilder::build()'s addInputNC11("InputGlobal", ...). - std::array globalShape = {batchSize, numGlobalFeatures, 1, 1}; - Ort::Value globalTensor = Ort::Value::CreateTensor( - memInfo, inputBuffers->globalInput.data(), inputBuffers->singleInputGlobalElts * batchSize, - globalShape.data(), globalShape.size() - ); - - // Match input ordering using configured node names - const ComputeContext* ctx = computeHandle->context; - int spatialIdx = findNameIndex(computeHandle->inputNames, {ctx->inputSpatialName}); - int globalIdx = findNameIndex(computeHandle->inputNames, {ctx->inputGlobalName}); - if(spatialIdx < 0 || globalIdx < 0) - throw StringError("ONNX backend: could not find expected input names"); - - const int spatialPolicyLen = nnXLen * nnYLen; - - // InputMask (the on-board mask, [N,1,H,W]) is required by graphs built by OnnxModelBuilder::build() - // (used for .bin.gz models), but may be absent from hand-exported raw .onnx models - only require - // it if the session actually declares it. It's channel 0 of the spatial input (KataGo convention), - // but not contiguous across rows within the spatial buffer, so gather it into its own buffer. - int maskIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMaskName}); - vector maskBuf; - Ort::Value maskTensor(nullptr); - if(maskIdx >= 0) { - maskBuf.resize((size_t)batchSize * spatialPolicyLen); - for(int r = 0; r < batchSize; r++) { - const float* rowSpatial = inputBuffers->spatialInput.data() + inputBuffers->singleInputElts * r; - std::copy(rowSpatial, rowSpatial + spatialPolicyLen, maskBuf.data() + (size_t)r * spatialPolicyLen); - } - std::array maskShape = {batchSize, 1, nnYLen, nnXLen}; - maskTensor = Ort::Value::CreateTensor( - memInfo, maskBuf.data(), maskBuf.size(), maskShape.data(), maskShape.size() - ); - } - - int metaIdx = -1; - Ort::Value metaTensor(nullptr); - if(computeHandle->numInputMetaChannels > 0) { - metaIdx = findNameIndex(computeHandle->inputNames, {ctx->inputMetaName}); - if(metaIdx < 0) - throw StringError("ONNX backend: model has metadata channels but could not find " + ctx->inputMetaName); - // NC11 (rank 4), matching trtbackend.cpp's InputMeta declaration. - std::array metaShape = {batchSize, computeHandle->numInputMetaChannels, 1, 1}; - metaTensor = Ort::Value::CreateTensor( - memInfo, inputBuffers->metaInput.data(), inputBuffers->singleInputMetaElts * batchSize, - metaShape.data(), metaShape.size() - ); - } - - vector inputTensors; - inputTensors.reserve(computeHandle->inputNames.size()); - for(size_t i = 0; i < computeHandle->inputNames.size(); i++) { - if((int)i == spatialIdx) - inputTensors.push_back(std::move(spatialTensor)); - else if((int)i == globalIdx) - inputTensors.push_back(std::move(globalTensor)); - else if((int)i == metaIdx) - inputTensors.push_back(std::move(metaTensor)); - else if((int)i == maskIdx) - inputTensors.push_back(std::move(maskTensor)); - else { - throw StringError("ONNX backend: unexpected input node '" + computeHandle->inputNames[i] + - "' -- only mask, spatial, global, and meta inputs are supported"); - } - } - - // Run inference - auto outputTensors = computeHandle->session->Run( - Ort::RunOptions{nullptr}, - computeHandle->inputNamePtrs.data(), - inputTensors.data(), - inputTensors.size(), - computeHandle->outputNamePtrs.data(), - computeHandle->outputNamePtrs.size() - ); - - // Find output indices using configured node names. OutputPolicyPass ([N,C]) and OutputPolicy - // ([N,C,H,W]) are separate tensors in graphs built by OnnxModelBuilder::build() - the pass logit - // isn't appended to the spatial policy tensor. - int policyPassOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyPassName}); - int policyOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputPolicyName}); - int valueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputValueName}); - int miscvalueOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputMiscvalueName}); - int ownershipOutputIdx = findNameIndex(computeHandle->outputNames, {ctx->outputOwnershipName}); - - if(policyPassOutputIdx < 0) - throw StringError("ONNX backend: could not find policy-pass output node '" + ctx->outputPolicyPassName + "'"); - if(policyOutputIdx < 0) - throw StringError("ONNX backend: could not find policy output node '" + ctx->outputPolicyName + "'"); - if(valueOutputIdx < 0) - throw StringError("ONNX backend: could not find value output node '" + ctx->outputValueName + "'"); - if(miscvalueOutputIdx < 0) - throw StringError("ONNX backend: could not find miscvalue output node '" + ctx->outputMiscvalueName + "'"); - if(ownershipOutputIdx < 0) - throw StringError("ONNX backend: could not find ownership output node '" + ctx->outputOwnershipName + "'"); - - const float* policyPassData = outputTensors[policyPassOutputIdx].GetTensorData(); - const float* policyData = outputTensors[policyOutputIdx].GetTensorData(); - const float* valueData = outputTensors[valueOutputIdx].GetTensorData(); - const float* miscvalueData = outputTensors[miscvalueOutputIdx].GetTensorData(); - const float* ownershipData = outputTensors[ownershipOutputIdx].GetTensorData(); - - assert(policyPassData != nullptr); - assert(policyData != nullptr); - assert(valueData != nullptr); - assert(miscvalueData != nullptr); - assert(ownershipData != nullptr); - assert((int)outputs.size() == batchSize); - - float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; - - for(int row = 0; row < batchSize; row++) { - NNOutput* output = outputs[row]; - assert(output->nnXLen == nnXLen); - assert(output->nnYLen == nnYLen); - float policyOptimism = (float)inputBufs[row]->policyOptimism; - - // Policy: OutputPolicy is [N, C, H*W] (channel-major, NCHW), OutputPolicyPass is [N, C] - // (one pass logit per channel). These are two separate tensors, not a single [N,C,H*W+1]. - { - const float* policyRowBase = policyData + (size_t)row * numPolicyChannels * spatialPolicyLen; - const float* policyPassRowBase = policyPassData + (size_t)row * numPolicyChannels; - float* policyProbs = output->policyProbs; - - if(numPolicyChannels >= 2) { - const float* ch0 = policyRowBase; - const float* ch1 = policyRowBase + spatialPolicyLen; - for(int i = 0; i < spatialPolicyLen; i++) { - float p = ch0[i]; - float pOpt = ch1[i]; - policyProbsTmp[i] = p + (pOpt - p) * policyOptimism; - } - SymmetryHelpers::copyOutputsWithSymmetry(policyProbsTmp, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[spatialPolicyLen] = policyPassRowBase[0] + (policyPassRowBase[1] - policyPassRowBase[0]) * policyOptimism; - } else { - assert(numPolicyChannels == 1); - const float* ch0 = policyRowBase; - SymmetryHelpers::copyOutputsWithSymmetry(ch0, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - policyProbs[spatialPolicyLen] = policyPassRowBase[0]; - } - } - - // Value: [N, 3] - { - int numVC = computeHandle->numValueChannels; - assert(numVC == 3); - output->whiteWinProb = valueData[row * numVC]; - output->whiteLossProb = valueData[row * numVC + 1]; - output->whiteNoResultProb = valueData[row * numVC + 2]; - } - - // MiscValue: [N, numScoreValueChannels] -- version-dependent interpretation - { - int numScoreValueChannels = computeHandle->numScoreValueChannels; - if(computeHandle->modelVersion >= 9) { - assert(numScoreValueChannels >= 6); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; - output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; - output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = miscvalueData[row * numScoreValueChannels + 4]; - output->shorttermScoreError = miscvalueData[row * numScoreValueChannels + 5]; - } - else if(computeHandle->modelVersion >= 8) { - assert(numScoreValueChannels >= 4); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; - output->whiteLead = miscvalueData[row * numScoreValueChannels + 2]; - output->varTimeLeft = miscvalueData[row * numScoreValueChannels + 3]; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(computeHandle->modelVersion >= 4) { - assert(numScoreValueChannels >= 2); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = miscvalueData[row * numScoreValueChannels + 1]; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else if(computeHandle->modelVersion >= 3) { - assert(numScoreValueChannels >= 1); - output->whiteScoreMean = miscvalueData[row * numScoreValueChannels]; - output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; - output->whiteLead = output->whiteScoreMean; - output->varTimeLeft = 0; - output->shorttermWinlossError = 0; - output->shorttermScoreError = 0; - } - else { - ASSERT_UNREACHABLE; - } - } - - // Ownership: [N, 1, H, W] - if(output->whiteOwnerMap != NULL) { - assert(computeHandle->numOwnershipChannels == 1); - const float* ownershipRowBuf = ownershipData + row * nnXLen * nnYLen; - SymmetryHelpers::copyOutputsWithSymmetry(ownershipRowBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); - } - } -} - -void NeuralNet::printDevices() { - cout << "ONNX backend: device enumeration is provider-specific." << endl; - cout << "Use onnxProvider plus provider-specific settings in config." << endl; -} - -//-------------------------------------------------------------- -// FOR TESTING -- all return false (not implemented for this backend) - -bool NeuralNet::testEvaluateConv( - const ConvLayerDesc* desc, int batchSize, int nnXLen, int nnYLen, - bool useFP16, bool useNHWC, const std::vector& inputBuffer, std::vector& outputBuffer -) { - (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; - (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)outputBuffer; - return false; -} - -bool NeuralNet::testEvaluateBatchNorm( - const BatchNormLayerDesc* desc, int batchSize, int nnXLen, int nnYLen, - bool useFP16, bool useNHWC, const std::vector& inputBuffer, - const std::vector& maskBuffer, std::vector& outputBuffer -) { - (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; - (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)maskBuffer; (void)outputBuffer; - return false; -} - -bool NeuralNet::testEvaluateResidualBlock( - const ResidualBlockDesc* desc, int batchSize, int nnXLen, int nnYLen, - bool useFP16, bool useNHWC, const std::vector& inputBuffer, - const std::vector& maskBuffer, std::vector& outputBuffer -) { - (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; - (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)maskBuffer; (void)outputBuffer; - return false; -} - -bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( - const GlobalPoolingResidualBlockDesc* desc, int batchSize, int nnXLen, int nnYLen, - bool useFP16, bool useNHWC, const std::vector& inputBuffer, - const std::vector& maskBuffer, std::vector& outputBuffer -) { - (void)desc; (void)batchSize; (void)nnXLen; (void)nnYLen; - (void)useFP16; (void)useNHWC; (void)inputBuffer; (void)maskBuffer; (void)outputBuffer; - return false; -} diff --git a/cpp/neuralnet/onnxmodelbuilder.cpp b/cpp/neuralnet/onnxmodelbuilder.cpp index 03aa371d22..8b29ed53ea 100644 --- a/cpp/neuralnet/onnxmodelbuilder.cpp +++ b/cpp/neuralnet/onnxmodelbuilder.cpp @@ -8,22 +8,21 @@ #include "../neuralnet/modelversion.h" #include "../neuralnet/nninputs.h" -#include "onnx/onnx_pb.h" +#include "onnx.pb.h" using namespace std; namespace { // Builder that accumulates ONNX nodes and initializers into a single GraphProto, handing back -// tensor names as it goes. Tensors are float32; the trunk runs NCHW by -// default, or channel-last NHWC when transformerNHWC is set (see buildBlockStack / buildConv). +// tensor names as it goes. Tensors are float32; transformerNHWC selects a channel-last NHWC trunk +// instead of NCHW (see buildBlockStack / buildConv). struct Builder { onnx::GraphProto* graph; int nnXLen; int nnYLen; bool requireExactNNLen; bool transformerNHWC; // run the trunk block stack channel-last (NHWC) vs NCHW - bool emitFusedMishOp; // emit a native ONNX Mish node instead of Softplus+Tanh+Mul (see header) // Mask-derived feature tensor names (computed once, reused by every gpool). Empty if exact. string maskSumName; // [N,1,1,1] sum of mask over H,W (only when !exact) @@ -178,14 +177,7 @@ struct Builder { string out = uniq(desc.name); addNode("Conv", {input, wName}, out, desc.name); onnx::NodeProto* node = lastNode(); - // strides/pads/dilations default to (1,1)/(0,0,0,0)/(1,1) per the ONNX spec when omitted, which - // is exactly what a 1x1 conv needs here -- but some EPs' graph compilers (e.g. AMD VitisAI's xir, - // which requires "strides" to be explicitly present) don't apply ONNX's own default semantics, so - // set them explicitly rather than relying on the (spec-compliant but not universally honored) omission. { onnx::AttributeProto* a = addAttr(node, "kernel_shape"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(1); a->add_ints(1); } - { onnx::AttributeProto* a = addAttr(node, "strides"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(1); a->add_ints(1); } - { onnx::AttributeProto* a = addAttr(node, "pads"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(0); a->add_ints(0); a->add_ints(0); a->add_ints(0); } - { onnx::AttributeProto* a = addAttr(node, "dilations"); a->set_type(onnx::AttributeProto::INTS); a->add_ints(1); a->add_ints(1); } return out; } @@ -252,22 +244,6 @@ struct Builder { // The SCALE8 variant is the runtime applyScale8ToReduceActivations() transform that keeps // FP16 activations small. ONNX Softplus has no beta, so for SCALE8 we // scale the input by 8 before Softplus and do NOT scale the result. - if(emitFusedMishOp) { - // Native ONNX `Mish` (opset 18+) computes y = y*tanh(softplus(y)) with no beta parameter. - // For plain mish that's exactly mish(x), one node. For mish_scale8, substitute y=8x: - // Mish(8x) = 8x*tanh(softplus(8x)), so mish_scale8(x) = x*tanh(softplus(8x)) = Mish(8x)/8. - string mishIn = input; - if(act == ACTIVATION_MISH_SCALE8) { - string bName = addScalarInitializer(uniq(desc.name + "/beta8"), 8.0f); - mishIn = addNode("Mul", {input, bName}, uniq(desc.name + "/beta8mul"), desc.name + "/beta8mul"); - } - string m = addNode("Mish", {mishIn}, uniq(desc.name + "/mish"), desc.name + "/mish"); - if(act == ACTIVATION_MISH_SCALE8) { - string invBName = addScalarInitializer(uniq(desc.name + "/invbeta8"), 0.125f); - return addNode("Mul", {m, invBName}, uniq(desc.name), desc.name); - } - return m; - } string spIn = input; if(act == ACTIVATION_MISH_SCALE8) { string bName = addScalarInitializer(uniq(desc.name + "/beta8"), 8.0f); @@ -350,6 +326,21 @@ struct Builder { return addNode("Add", {maskName, c}, uniq(nameBase + "/gpmaskshift"), nameBase + "/gpmaskshift"); } + // SGF metadata encoder (HumanSL nets, metaEncoderVersion > 0): a small MLP over the [N,metaC,1,1] + // metadata input producing a [N,trunkC,1,1] bias that gets added into the trunk's initial bias + // alongside the global-input matmul. Mirrors SGFMetadataEncoder::apply in eigenbackend.cpp and + // ModelParser::buildSGFMetadataEncoder in trtbackend.cpp. All ops are NC11 channel matmuls/biases, + // so this is layout-independent (it runs before any NCHW->NHWC trunk conversion). + string buildSGFMetadataEncoder(const string& input, const SGFMetadataEncoderDesc& desc) { + string x = buildMatMul(input, desc.mul1); + x = buildMatBias(x, desc.bias1); + x = buildActivation(x, desc.act1); + x = buildMatMul(x, desc.mul2); + x = buildMatBias(x, desc.bias2); + x = buildActivation(x, desc.act2); + return buildMatMul(x, desc.mul3); + } + // ---- Residual block builders ---- // useNHWC: input and output are channel-last [N,H,W,C], and the block's internals run NHWC. The // elementwise BN/activation/mask ops and 1x1 convs are layout-free; spatial convs (k>1) bubble to @@ -429,10 +420,7 @@ struct Builder { testAssert((int)desc.weight.size() == C); int rmsStart = graph->node_size(); // meanSq over channels (axis 1), keepdims -> [N,1,H,W] - // Pow(x, 2.0) instead of Mul(x, x): OpenVINO's RMSFusion matcher requires Power(x, const(2)) - // and silently skips Mul(x,x), leaving the RMSNorm as an unfused ReduceMean->Sqrt->Div chain. - string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); - string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); + string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); string meanSq = addNode("ReduceMean", {sq, addInt64Initializer(uniq(desc.name + "/axC"), {1})}, uniq(desc.name + "/meansq"), desc.name + "/meansq"); { onnx::NodeProto* n = lastNode(); onnx::AttributeProto* a = addAttr(n, "keepdims"); a->set_type(onnx::AttributeProto::INT); a->set_i(1); } @@ -467,9 +455,7 @@ struct Builder { int C = desc.numChannels; testAssert((int)desc.weight.size() == C); int rmsStart = graph->node_size(); - // Pow(x, 2.0) instead of Mul(x, x): see transformerRMSNorm (NCHW variant) above. - string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); - string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); + string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); string meanSq = addNode("ReduceMean", {sq, addInt64Initializer(uniq(desc.name + "/axC"), {3})}, // C is axis 3 of [N,H,W,C] uniq(desc.name + "/meansq"), desc.name + "/meansq"); { onnx::NodeProto* n = lastNode(); onnx::AttributeProto* a = addAttr(n, "keepdims"); a->set_type(onnx::AttributeProto::INT); a->set_i(1); } @@ -500,9 +486,7 @@ struct Builder { string meanSq; if(!spatial) { // Per-position mean of squares over channels (axis 1) -> [N,1,H,W] - // Pow(x, 2.0) instead of Mul(x, x): see transformerRMSNorm above (same OpenVINO fusion requirement). - string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); - string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); + string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); meanSq = addNode("ReduceMean", {sq, addInt64Initializer(uniq(desc.name + "/axC"), {1})}, uniq(desc.name + "/meansq"), desc.name + "/meansq"); { onnx::NodeProto* n = lastNode(); onnx::AttributeProto* a = addAttr(n, "keepdims"); a->set_type(onnx::AttributeProto::INT); a->set_i(1); } @@ -521,9 +505,7 @@ struct Builder { // masked: meanSq = ReduceMean_{C,H,W}(x^2 * mask) / maskMean (recover the on-board mean; // maskMean = on-board fraction of the buffer, so dividing by it cancels the off-board // zeros that ReduceMean averaged over). maskMean is itself FP32-pinned. - // Pow(x, 2.0) instead of Mul(x, x): see transformerRMSNorm above (same OpenVINO fusion requirement). - string twoName = addScalarInitializer(uniq(desc.name + "/pow2"), 2.0f); - string sq = addNode("Pow", {input, twoName}, uniq(desc.name + "/sq"), desc.name + "/sq"); + string sq = addNode("Mul", {input, input}, uniq(desc.name + "/sq"), desc.name + "/sq"); string reduceInput = sq; if(!requireExactNNLen) reduceInput = addNode("Mul", {sq, maskName}, uniq(desc.name + "/sqmask"), desc.name + "/sqmask"); @@ -845,14 +827,10 @@ Result build( int nnYLen, bool requireExactNNLen, bool transformerNHWC, - Logger* logger, - bool emitFusedMishOp + Logger* logger ) { - if(desc.metaEncoderVersion > 0) - throw StringError("OnnxModelBuilder: SGF metadata encoder not yet supported"); - if(logger != NULL) - logger->write("Building internal onnx model, requireExactNNLen=" + Global::boolToString(requireExactNNLen) + " transformerNHWC=" + Global::boolToString(transformerNHWC) + " emitFusedMishOp=" + Global::boolToString(emitFusedMishOp)); + logger->write("Building internal onnx model, requireExactNNLen=" + Global::boolToString(requireExactNNLen) + " transformerNHWC=" + Global::boolToString(transformerNHWC)); int numInputChannels = desc.numInputChannels; int numInputGlobalChannels = desc.numInputGlobalChannels; @@ -882,7 +860,6 @@ Result build( b.nnYLen = nnYLen; b.requireExactNNLen = requireExactNNLen; b.transformerNHWC = transformerNHWC; - b.emitFusedMishOp = emitFusedMishOp; // ---- Inputs (NCHW, dynamic batch) ---- auto addInput = [&](const string& name, int channels) { @@ -907,17 +884,15 @@ Result build( shape->add_dim()->set_dim_value(1); shape->add_dim()->set_dim_value(1); }; - // Declaration order matters for the OpenVINO execution provider under ONNX Runtime: the EP builds - // its name->index map from declaration order while the runtime feeds the EP kernel input ports in - // a different order. With InputMask declared first, the two disagree and the EP misroutes the - // [N,1,H,W] mask tensor into the InputSpatial port, failing at runtime with a shape mismatch (e.g. - // "can't handle input tensor ...:InputSpatial, because model input (shape=[?,22,19,19]) and tensor - // (shape=[1,1,19,19]) are incompatible"). Declaring InputSpatial, InputGlobal, InputMask (in that - // order) fixes it. This is NOT the graph's first-reference order; it is an empirical, - // OpenVINO-EP-specific requirement. + addInput("InputMask", 1); addInput("InputSpatial", numInputChannels); addInputNC11("InputGlobal", numInputGlobalChannels); - addInput("InputMask", 1); + // HumanSL-style nets additionally take a per-row SGF metadata vector. Only declare the input when + // the model actually has an encoder - an unused graph input would just be dead weight (and the + // backend only allocates/binds an InputMeta buffer when numInputMetaChannels > 0). + bool hasMetaEncoder = desc.metaEncoderVersion > 0; + if(hasMetaEncoder) + addInputNC11("InputMeta", desc.numInputMetaChannels); // ---- Mask-derived features ---- if(!requireExactNNLen) { @@ -958,9 +933,15 @@ Result build( // Only needed when masking (variable board) and there are transformer attention blocks. if(!requireExactNNLen && desc.trunk.hasAnyTransformerBlocks()) { // (mask - 1) * BIG : on-board (1) -> 0, off-board (0) -> -BIG + // BIG must be exactly representable in fp16 (TensorRT runs this whole subgraph and the fused + // attention in fp16 in FP16 engines, a constant like 1e9 only works by luck of internal fp32 + // constant handling and risks 0 * inf = NaN on the on-board side if a TRT version casts the + // constant to fp16 before multiplying). -3e4 fits fp16 (max ~65504) and masks exactly: the + // softmax subtracts the row max, so exp(logit - 3e4 - rowmax) underflows to exactly 0 as long + // as the spread of genuine attention logits is below ~3e4. string one = b.addScalarInitializer(b.uniq("InputMask/biasone"), -1.0f); string mShift = b.addNode("Add", {"InputMask", one}, b.uniq("InputMask/biasshift"), "InputMask/biasshift"); - string big = b.addScalarInitializer(b.uniq("InputMask/biasbig"), 1.0e9f); + string big = b.addScalarInitializer(b.uniq("InputMask/biasbig"), 3.0e4f); string biasNCHW = b.addNode("Mul", {mShift, big}, b.uniq("InputMask/biasnchw"), "InputMask/biasnchw"); // [N,1,H,W] // reshape [N,1,H,W] -> [N,1,1,S] so it broadcasts over the key axis of [N,heads,S(query),S(key)] b.maskBiasName = b.reshape(biasNCHW, {0, 1, 1, nnXLen * nnYLen}, "InputMask/bias"); @@ -971,6 +952,12 @@ Result build( string initialConv = b.buildConv("InputSpatial", trunk.initialConv, false); string initialMatMul = b.buildMatMul("InputGlobal", trunk.initialMatMul); string cur = b.elementwise("Add", initialConv, initialMatMul, trunk.name + "/initbias"); + if(hasMetaEncoder) { + testAssert(trunk.metaEncoderVersion > 0); + testAssert(trunk.sgfMetadataEncoder.mul3.outChannels == trunk.initialMatMul.outChannels); + string initialMeta = b.buildSGFMetadataEncoder("InputMeta", trunk.sgfMetadataEncoder); + cur = b.elementwise("Add", cur, initialMeta, trunk.name + "/initmetabias"); + } // When transformerNHWC, run the entire trunk block stack channel-last: one NCHW->NHWC conversion // here and one NHWC->NCHW conversion before the trunk tip. Every block (convnet/gpool/nbt/ diff --git a/cpp/neuralnet/onnxmodelbuilder.h b/cpp/neuralnet/onnxmodelbuilder.h index b6cb64447d..10d3819150 100644 --- a/cpp/neuralnet/onnxmodelbuilder.h +++ b/cpp/neuralnet/onnxmodelbuilder.h @@ -32,28 +32,13 @@ namespace OnnxModelBuilder { }; // Build a serialized ONNX ModelProto for the given model. - // Inputs are always declared in the fixed order InputSpatial, InputGlobal, InputMask. This order - // is required by the OpenVINO execution provider under ONNX Runtime (its name->index map is built - // from declaration order while the runtime feeds the EP input ports in the order it expects; the - // default InputMask-first order misroutes the mask tensor at runtime). See onnxmodelbuilder.cpp - // for the full rationale. - // - // emitFusedMishOp: if true, KataGo's Mish activation (x * tanh(softplus(x))) is emitted as a - // single native ONNX `Mish` node (opset 18+) instead of the decomposed Softplus+Tanh+Mul used - // by default. The decomposition is what TensorRT's nvonnxparser and the live ONNX/WinML runtime - // backends have actually been tested against, so this defaults to false and only exportonnx (the - // offline FP32 export consumed by external quantizers, e.g. for AMD VitisAI/NPU) opts in: AMD's - // Ryzen AI DPU compiler recognizes the fused `Mish` op for XINT8 quantization but not the - // decomposed Softplus primitive, so without this the exported graph's Conv/activation layers - // fail to fuse into NPU-executable subgraphs and silently fall back to CPU end to end. Result build( const ModelDesc& desc, int nnXLen, int nnYLen, bool requireExactNNLen, bool transformerNHWC, - Logger* logger, - bool emitFusedMishOp + Logger* logger ); } diff --git a/cpp/neuralnet/openclbackend.cpp b/cpp/neuralnet/openclbackend.cpp index 1625f2973e..17fe078eb8 100644 --- a/cpp/neuralnet/openclbackend.cpp +++ b/cpp/neuralnet/openclbackend.cpp @@ -2392,6 +2392,7 @@ struct TransformerAttentionKernelSet { int blockKV = handle->tuneParams.transformer.ATTN_BLOCK_KV; compileOpts += " -DATTN_BLOCK_Q=" + Global::intToString(attnBlockQ); compileOpts += " -DATTN_BLOCK_KV=" + Global::intToString(blockKV); + compileOpts += " -DQ_PER_THREAD=" + Global::intToString(handle->tuneParams.transformer.Q_PER_THREAD); program = OpenCLHelpers::compileProgram( "transformerAttentionProgram", handle->clContext, deviceIdsToUse, OpenCLKernels::transformerScaledDotProductAttention, diff --git a/cpp/neuralnet/opencltuner.cpp b/cpp/neuralnet/opencltuner.cpp index 2db2b39d94..a13e025d4e 100644 --- a/cpp/neuralnet/opencltuner.cpp +++ b/cpp/neuralnet/opencltuner.cpp @@ -774,8 +774,8 @@ int OpenCLTuneParams::getPaddedNNXYLen(int nnXLen, int nnYLen, bool usingFP16Ten } -static const int TUNER_VERSION = 12; -static const char* TUNEPARAMS_VERSION_LINE = "VERSION=12"; +static const int TUNER_VERSION = 13; +static const char* TUNEPARAMS_VERSION_LINE = "VERSION=13"; void OpenCLTuneParams::save(const string& filename, const OpenCLTuneParams& config) { ofstream out; FileUtils::open(out,filename); diff --git a/cpp/neuralnet/opencltuner.h b/cpp/neuralnet/opencltuner.h index 61a1af8af9..75d7af6839 100644 --- a/cpp/neuralnet/opencltuner.h +++ b/cpp/neuralnet/opencltuner.h @@ -261,20 +261,20 @@ namespace OpenCLTuner { constexpr int DEFAULT_WINOGRAD_3X3_TILE_SIZE = 4; struct ModelInfoForTuning { - int maxConvChannels1x1; - int maxConvChannels3x3; - int trunkNumChannels; - int midNumChannels; - int regularNumChannels; - int gpoolNumChannels; - int modelVersion; + int maxConvChannels1x1 = 0; + int maxConvChannels3x3 = 0; + int trunkNumChannels = 0; + int midNumChannels = 0; + int regularNumChannels = 0; + int gpoolNumChannels = 0; + int modelVersion = 0; // Transformer-specific info (0 if no transformer blocks) - int transformerHeadDim; - int transformerVHeadDim; - int transformerNumHeads; - int transformerNumKVHeads; - int transformerFFNChannels; + int transformerHeadDim = 0; + int transformerVHeadDim = 0; + int transformerNumHeads = 0; + int transformerNumKVHeads = 0; + int transformerFFNChannels = 0; static ModelInfoForTuning ofDesc(const ModelDesc* desc); }; diff --git a/cpp/neuralnet/trtbackend.cpp b/cpp/neuralnet/trtbackend.cpp index c15aaa0bb0..886499c814 100644 --- a/cpp/neuralnet/trtbackend.cpp +++ b/cpp/neuralnet/trtbackend.cpp @@ -5,6 +5,12 @@ #include #include +// TensorRT versions before 10 cannot parse the ONNX this backend emits (verified failure on +// TensorRT 8.6: "Kernel weight dimension failed to broadcast to input" at parse time). +#if NV_TENSORRT_MAJOR < 10 +#error "The TensorRT backend requires TensorRT 10.0 or newer" +#endif + #include #include #include @@ -94,7 +100,6 @@ ComputeContext* NeuralNet::createComputeContext( ConfigParser& cfg) { (void)gpuIdxs; (void)logger; - (void)loadedModel; ComputeContext* context = new ComputeContext(); context->nnXLen = nnXLen; @@ -105,11 +110,14 @@ ComputeContext* NeuralNet::createComputeContext( // nvonnxparser (the default). trtDisableOnnx=true falls back to the hand-built ModelParser, which // supports convnets only (transformer models will error in createComputeHandle). context->useOnnx = !(cfg.contains("trtDisableOnnx") ? cfg.getBool("trtDisableOnnx") : false); - // ONNX transformer emitter layout. Default is NCHW (genuine channel-major attention/FFN): benchmarks - // show it matches or slightly beats the NHWC bubble path at the saturated throughput operating point - // KataGo runs at, and it's the simpler graph. trtTransformerNHWC=true opts into the NHWC path (whole - // trunk channel-last with NCHW<->NHWC conversions around it), which wins on single-stream latency. - context->transformerNHWC = cfg.contains("trtTransformerNHWC") ? cfg.getBool("trtTransformerNHWC") : false; + // ONNX transformer emitter layout. Default is NHWC (whole trunk channel-last with NCHW<->NHWC + // conversions around it). Equal or very slightly better than NCHW in accuracy and in throughput + // on TensorRT 10.9, but noticeably faster on many nvidia GPUs on TensorRT 10.16. + // Normalize convnets to false so their timing/plan cache keys don't change with this setting + // (the ONNX builder ignores it for models without transformers anyway). + context->transformerNHWC = + (cfg.contains("trtTransformerNHWC") ? cfg.getBool("trtTransformerNHWC") : true) && + NeuralNet::getModelDesc(loadedModel).hasAnyTransformerBlocks(); // Debugging: if set, the ONNX-emitter path dumps the emitted ONNX model and the built engine's // per-layer info (precision/format/tactic, via a detailed-profiling build + IEngineInspector) into // this directory. Files are disambiguated by board size, FP16/FP32, and exact/max NN-length so the @@ -192,7 +200,10 @@ struct ModelParser { // Bump this when between katago versions we want to forcibly drop old timing caches and plan caches. // Bumped 7->8 for the TensorRT ONNX overhaul (ONNX emitter as default path, NHWC trunk, FP32 pinning). - static constexpr int tuneSalt = 8; + // Bumped 8->9 for SGF metadata encoder support on the ONNX path, and to discard caches potentially + // polluted by the concurrent-engine-build bug fixed in "Serialize TensorRT engine builds across GPU + // threads" (#1225). + static constexpr int tuneSalt = 9; unique_ptr build( unique_ptr net, @@ -1022,18 +1033,23 @@ struct ModelParser { } ILayer* applyCastLayer(ILayer* inputLayer, DataType dataType) { -#if NV_TENSORRT_MAJOR == 8 && NV_TENSORRT_MINOR == 5 - auto castLayer = model->network->addIdentity(*inputLayer->getOutput(0)); - castLayer->setOutputType(0, dataType); -#else auto castLayer = model->network->addCast(*inputLayer->getOutput(0), dataType); -#endif auto castLayerName = string(inputLayer->getName()) + "/cast"; castLayer->setName(castLayerName.c_str()); return castLayer; } }; +// The builder's autotuner reports tactics that fail to compile or execute as ERROR-severity +// "Skipping tactic ... due to exception ..." messages, but these are recoverable: the autotuner +// moves on to other tactics, and if none work the build fails afterward with its own error. +// Such messages can mention cask convolution execution failures that would otherwise match the +// genuine GPU-health fatal checks below (observed on TensorRT 10.16 building on multiple +// heterogeneous GPUs), so exempt them rather than killing the process mid-build. +static bool isRecoverableTacticSkipMessage(const string& msg) { + return msg.find("Skipping tactic") != string::npos && msg.find("due to exception") != string::npos; +} + struct TRTLogger : ILogger { Logger* logger; Severity level; @@ -1052,7 +1068,7 @@ struct TRTLogger : ILogger { if(severity == Severity::kERROR && logger && !logger->isLoggingToStderr() && !logger->isLoggingToStdout()) { std::cerr << ("TensorRT backend: " + string(msg)) << std::endl; } - if(severity == Severity::kERROR) { + if(severity == Severity::kERROR && !isRecoverableTacticSkipMessage(string(msg))) { if((string(msg).find("Cask convolution") != std::string::npos) || (string(msg).find("Cask Convolution") != std::string::npos) || (string(msg).find("elementWiseRunner.cpp") != std::string::npos) || @@ -1111,12 +1127,15 @@ struct TRTErrorRecorder : IErrorRecorder { std::lock_guard lock(mutex); errors.emplace_back(val,string(desc)); if( - (val != ErrorCode::kUNSPECIFIED_ERROR && val != ErrorCode::kSUCCESS) - || (errors[errors.size()-1].second.find("Cask convolution") != std::string::npos) - || (errors[errors.size()-1].second.find("Cask Convolution") != std::string::npos) - || (errors[errors.size()-1].second.find("elementWiseRunner.cpp") != std::string::npos) - || (errors[errors.size()-1].second.find("convBaseRunner.cpp") != std::string::npos) - || (errors[errors.size()-1].second.find("Cuda Runtime") != std::string::npos) + !isRecoverableTacticSkipMessage(errors[errors.size()-1].second) + && ( + (val != ErrorCode::kUNSPECIFIED_ERROR && val != ErrorCode::kSUCCESS) + || (errors[errors.size()-1].second.find("Cask convolution") != std::string::npos) + || (errors[errors.size()-1].second.find("Cask Convolution") != std::string::npos) + || (errors[errors.size()-1].second.find("elementWiseRunner.cpp") != std::string::npos) + || (errors[errors.size()-1].second.find("convBaseRunner.cpp") != std::string::npos) + || (errors[errors.size()-1].second.find("Cuda Runtime") != std::string::npos) + ) ) { Global::fatalError("Fatal error reported from TensorRT: " + Global::intToString((int)val) + " " + std::string(desc)); } @@ -1230,7 +1249,7 @@ struct ComputeHandle { if(useOnnxEmit) { logger->write("TensorRT backend: building network via ONNX emitter"); const ModelDesc& desc = loadedModel->modelDesc; - OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build(desc, ctx->nnXLen, ctx->nnYLen, requireExactNNLen, ctx->transformerNHWC, logger, /*emitFusedMishOp=*/false); + OnnxModelBuilder::Result onnxResult = OnnxModelBuilder::build(desc, ctx->nnXLen, ctx->nnYLen, requireExactNNLen, ctx->transformerNHWC, logger); onnxBytes = std::move(onnxResult.serializedModel); if(dumpDebugPlan) { @@ -1293,6 +1312,8 @@ struct ComputeHandle { setProfile("InputMask", Dims4(1, 1, ctx->nnYLen, ctx->nnXLen), Dims4(maxBatchSize, 1, ctx->nnYLen, ctx->nnXLen)); setProfile("InputSpatial", Dims4(1, desc.numInputChannels, ctx->nnYLen, ctx->nnXLen), Dims4(maxBatchSize, desc.numInputChannels, ctx->nnYLen, ctx->nnXLen)); setProfile("InputGlobal", Dims4(1, desc.numInputGlobalChannels, 1, 1), Dims4(maxBatchSize, desc.numInputGlobalChannels, 1, 1)); + if(desc.metaEncoderVersion > 0) + setProfile("InputMeta", Dims4(1, desc.numInputMetaChannels, 1, 1), Dims4(maxBatchSize, desc.numInputMetaChannels, 1, 1)); model = make_unique(); model->nnXLen = ctx->nnXLen; @@ -1308,9 +1329,10 @@ struct ComputeHandle { // and the "nhwc" field distinguishes the NHWC vs NCHW trunk layout (different layer signatures), // so the two layouts don't share a timing-cache file full of mutual misses. string tuneDesc = Global::strprintf( - "\"onnxsalt\"(%d)\"nhwc\"(%d)\"model\"(%d,%d,%d)", + "\"onnxsalt\"(%d)\"nhwc\"(%d)\"model\"(%d,%d,%d,%d,%d)", ModelParser::tuneSalt, ctx->transformerNHWC ? 1 : 0, - desc.modelVersion, desc.numInputChannels, desc.numInputGlobalChannels); + desc.modelVersion, desc.numInputChannels, desc.numInputGlobalChannels, + desc.metaEncoderVersion, desc.numInputMetaChannels); SHA2::get256(tuneDesc.c_str(), model->tuneHash); } else { @@ -1325,22 +1347,11 @@ struct ComputeHandle { // constraint (kOBEY) so TensorRT cannot fall back to FP16; the ModelParser path uses kPREFER. config->setFlag(forceObeyPrecision ? BuilderFlag::kOBEY_PRECISION_CONSTRAINTS : BuilderFlag::kPREFER_PRECISION_CONSTRAINTS); -#if NV_TENSORRT_MAJOR == 8 && NV_TENSORRT_MINOR == 5 - // This is to avoid external tactic sources and tactics that have shape switching overhead - if(prop->major < 8) { - config->setTacticSources( - 1U << static_cast(TacticSource::kJIT_CONVOLUTIONS) | - 1U << static_cast(TacticSource::kEDGE_MASK_CONVOLUTIONS)); - } else { - config->setTacticSources(1U << static_cast(TacticSource::kJIT_CONVOLUTIONS)); - } -#else if(prop->major >= 8) { // This is to avoid tactics that have shape switching overhead config->setTacticSources(1U << static_cast(TacticSource::kJIT_CONVOLUTIONS)); config->setBuilderOptimizationLevel(2); } -#endif // For the debug plan dump, build with detailed profiling so the engine inspector can report // per-layer precision/format/tactic (see the inspector dump after deserialize). @@ -1351,13 +1362,16 @@ struct ComputeHandle { // See CUDA Runtime API document for more details related to NULL stream and synchronization behaviors config->setProfileStream(cudaStreamLegacy); - // Typical runtime allocation is much less than the 1 GiB specified below - config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1U << 30); + // Leave workspace at TensorRT's device-dependent default (the GPU's total memory). This is a + // tactic-selection cap, not a preallocation; fixed caps can reject all tactics for larger profiles. string plan; { static mutex tuneMutex; - tuneMutex.lock(); + // TensorRT 10.16 has been observed to segfault when builders on different devices call + // buildSerializedNetwork concurrently, particularly with timing-cache hits. Keep both cache + // access and engine building serialized, and use RAII so exceptions cannot leave the mutex held. + lock_guard tuneLock(tuneMutex); auto cacheDir = HomeData::getHomeDataDir(true, ctx->homeDataDirOverride); cacheDir += "/trtcache"; @@ -1451,9 +1465,7 @@ struct ComputeHandle { writeFileAtomically(planCacheFile, plan.data(), plan.size()); logger->write("Saved new plan cache to " + planCacheFile); plan.erase(plan.size() - 64 - paramStr.size()); - tuneMutex.unlock(); } else { - tuneMutex.unlock(); logger->write("Using existing plan cache at " + planCacheFile); } #else @@ -1506,9 +1518,7 @@ struct ComputeHandle { writeFileAtomically( timingCacheFile, static_cast(serializedTimingCache->data()), serializedTimingCache->size()); logger->write("Saved new timing cache to " + timingCacheFile); - tuneMutex.unlock(); } else { - tuneMutex.unlock(); planBuffer.reset(builder->buildSerializedNetwork(*model->network, *config)); if(!planBuffer) { throw StringError("TensorRT backend: failed to create plan"); diff --git a/cpp/program/gtpconfig.cpp b/cpp/program/gtpconfig.cpp index 44bcb875eb..3fa8651e5b 100644 --- a/cpp/program/gtpconfig.cpp +++ b/cpp/program/gtpconfig.cpp @@ -282,8 +282,6 @@ nnCacheSizePowerOfTwo = $$NN_CACHE_SIZE_POWER_OF_TWO # Size of mutex pool for nnCache is (2 ** this). nnMutexPoolSizePowerOfTwo = $$NN_MUTEX_POOL_SIZE_POWER_OF_TWO -$$ONNX_PROVIDER - $$MULTIPLE_GPUS # =========================================================================== @@ -470,8 +468,7 @@ string GTPConfig::makeConfig( const std::vector& deviceIdxs, int nnCacheSizePowerOfTwo, int nnMutexPoolSizePowerOfTwo, - int numSearchThreads, - const string& onnxProvider + int numSearchThreads ) { string config = gtpBasePart1 + gtpBasePart2; auto replace = [&](const string& key, const string& replacement) { @@ -524,27 +521,12 @@ string GTPConfig::makeConfig( replace("$$NN_CACHE_SIZE_POWER_OF_TWO", Global::intToString(nnCacheSizePowerOfTwo)); replace("$$NN_MUTEX_POOL_SIZE_POWER_OF_TWO", Global::intToString(nnMutexPoolSizePowerOfTwo)); -#ifdef USE_ONNX_BACKEND - string onnxProviderLower = Global::toLower(Global::trim(onnxProvider)); - string onnxProviderConfigValue = onnxProviderLower.empty() ? "cpu" : onnxProviderLower; - replace("$$ONNX_PROVIDER", "onnxProvider = " + onnxProviderConfigValue); -#else - (void)onnxProvider; - replace("$$ONNX_PROVIDER", ""); -#endif - if(deviceIdxs.size() <= 0) { replace("$$MULTIPLE_GPUS", ""); } else { string replacement = ""; replacement += "numNNServerThreadsPerModel = " + Global::uint64ToString(deviceIdxs.size()) + "\n"; -#ifdef USE_ONNX_BACKEND - bool onnxProviderSupportsThreadDeviceMap = - onnxProviderConfigValue == "cuda" || - onnxProviderConfigValue == "tensorrt" || - onnxProviderConfigValue == "migraphx"; -#endif for(int i = 0; i& deviceIdxs, int nnCacheSizePowerOfTwo, int nnMutexPoolSizePowerOfTwo, - int numSearchThreads, - const std::string& onnxProvider = "cpu" + int numSearchThreads ); } diff --git a/cpp/program/play.cpp b/cpp/program/play.cpp index 4b10ce8d7d..98b2af8802 100644 --- a/cpp/program/play.cpp +++ b/cpp/program/play.cpp @@ -388,11 +388,12 @@ void GameInitializer::createGame( const InitialPosition* initialPosition, const PlaySettings& playSettings, OtherGameProperties& otherGameProps, - const Sgf::PositionSample* startPosSample + const Sgf::PositionSample* startPosSample, + bool alwaysComputePassAliveUnderSuicideRules ) { //Multiple threads will be calling this, and we have some mutable state such as rand. lock_guard lock(createGameMutex); - createGameSharedUnsynchronized(board,pla,hist,extraBlackAndKomi,initialPosition,playSettings,otherGameProps,startPosSample); + createGameSharedUnsynchronized(board,pla,hist,extraBlackAndKomi,initialPosition,playSettings,otherGameProps,startPosSample,alwaysComputePassAliveUnderSuicideRules); if(noResultStdev != 0.0 || drawRandRadius != 0.0) throw StringError("GameInitializer::createGame called in a mode that doesn't support specifying noResultStdev or drawRandRadius"); } @@ -404,11 +405,12 @@ void GameInitializer::createGame( const InitialPosition* initialPosition, const PlaySettings& playSettings, OtherGameProperties& otherGameProps, - const Sgf::PositionSample* startPosSample + const Sgf::PositionSample* startPosSample, + bool alwaysComputePassAliveUnderSuicideRules ) { //Multiple threads will be calling this, and we have some mutable state such as rand. lock_guard lock(createGameMutex); - createGameSharedUnsynchronized(board,pla,hist,extraBlackAndKomi,initialPosition,playSettings,otherGameProps,startPosSample); + createGameSharedUnsynchronized(board,pla,hist,extraBlackAndKomi,initialPosition,playSettings,otherGameProps,startPosSample,alwaysComputePassAliveUnderSuicideRules); if(noResultStdev > 1e-30) { double mean = params.noResultUtilityForWhite; @@ -485,11 +487,17 @@ void GameInitializer::createGameSharedUnsynchronized( const InitialPosition* initialPosition, const PlaySettings& playSettings, OtherGameProperties& otherGameProps, - const Sgf::PositionSample* startPosSample + const Sgf::PositionSample* startPosSample, + bool alwaysComputePassAliveUnderSuicideRules ) { + //The game-level pass-alive computation mode, so that any adjudication during start position + //replay below is consistent with the game that will be played. (hist.clear() preserves this.) + hist.setAlwaysComputePassAliveUnderSuicideRules(alwaysComputePassAliveUnderSuicideRules); + if(initialPosition != NULL) { board = initialPosition->board; hist = initialPosition->hist; + hist.setAlwaysComputePassAliveUnderSuicideRules(alwaysComputePassAliveUnderSuicideRules); pla = initialPosition->pla; //No handicap when starting from an initial position. @@ -883,6 +891,9 @@ static NNRawStats computeNNRawStats(const Search* bot, const Board& board, const NNResultBuf buf; MiscNNInputParams nnInputParams; nnInputParams.drawEquivalentWinsForWhite = bot->searchParams.drawEquivalentWinsForWhite; + //Featurize the way this bot's own searches would, even if the passed history differs. + nnInputParams.passAliveSuicideRulesOverride = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(bot->searchParams, bot->nnEvaluator) ? 1 : 0; bot->nnEvaluator->evaluate(board,hist,pla,nnInputParams,buf,false,false); NNOutput& nnOutput = *(buf.result); @@ -902,6 +913,40 @@ static NNRawStats computeNNRawStats(const Search* bot, const Board& board, const return nnRawStats; } +//One turn's worth of the per-turn training targets and stats recorded for selfplay training data, extracted +//from the search a bot just completed on a position. Extracted both for every turn during the game and when +//reanalyzing a position after the game - if adding a new per-turn target, make sure both get it. +struct SearchTargetsThisTurn { + ValueTargets whiteValueTargets; + QValueTargets whiteQValueTargets; + std::vector* policyTarget; //Receiver takes ownership + int64_t unreducedNumVisits; + NNRawStats nnRawStats; + double policySurprise; + double policyEntropy; + double searchEntropy; + ReportedSearchValues rawNNValues; +}; + +static void extractSearchTargetsThisTurn( + SearchTargetsThisTurn& targets, + Search* toMoveBot, + const Board& board, const BoardHistory& hist, Player pla, + vector& locsBuf, vector& playSelectionValuesBuf +) { + extractValueTargets(targets.whiteValueTargets, toMoveBot, toMoveBot->rootNode); + targets.whiteQValueTargets.targets.clear(); + extractQValueTargets(targets.whiteQValueTargets.targets, toMoveBot, toMoveBot->rootNode); + targets.policyTarget = new vector(); + Play::extractPolicyTarget(*targets.policyTarget, toMoveBot, toMoveBot->rootNode, locsBuf, playSelectionValuesBuf); + targets.unreducedNumVisits = toMoveBot->getRootVisits(); + targets.nnRawStats = computeNNRawStats(toMoveBot, board, hist, pla); + bool success = toMoveBot->getPolicySurpriseAndEntropy(targets.policySurprise, targets.searchEntropy, targets.policyEntropy); + testAssert(success); + (void)success; //Avoid warning when asserts are disabled + targets.rawNNValues = toMoveBot->getRootRawNNValuesRequireSuccess(); +} + //Recursively walk non-root-node subtree under node recording positions that have enough visits //We also only record positions where the player to move made best moves along the tree so far. //Does NOT walk down branches of excludeLoc0 and excludeLoc1 - these are used to avoid writing @@ -1030,6 +1075,7 @@ struct SearchLimitsThisMove { bool clearBotBeforeSearchThisMove; bool removeRootNoise; float targetWeight; + bool isCheapSearch; //Note: these two behave slightly differently than the ones in searchParams - derived from OtherGameProperties //game, they make the playouts *actually* vary instead of only making the neural net think they do. @@ -1039,11 +1085,18 @@ struct SearchLimitsThisMove { Loc hintLoc; }; +//forceFullSearch skips the hint and random cheap search branches, giving the limits that a full-search turn +//would get, including any reduceVisits or asymmetric playout adjustments. +//Only the first numHistoricalMctsValuesToUse entries of historicalMctsWinLossValues count as the past for this +//turn - during the game that is all of them, while post-game reanalysis of a cheap-search position passes the +//turn index so as to reproduce the state as of that turn. static SearchLimitsThisMove getSearchLimitsThisMove( const Search* toMoveBot, Player pla, const PlaySettings& playSettings, Rand& gameRand, const vector& historicalMctsWinLossValues, + size_t numHistoricalMctsValuesToUse, bool clearBotBeforeSearch, - const OtherGameProperties& otherGameProps + const OtherGameProperties& otherGameProps, + bool forceFullSearch ) { bool doAlterVisitsPlayouts = false; int64_t numAlterVisits = toMoveBot->searchParams.maxVisits; @@ -1051,13 +1104,14 @@ static SearchLimitsThisMove getSearchLimitsThisMove( bool clearBotBeforeSearchThisMove = clearBotBeforeSearch; bool removeRootNoise = false; float targetWeight = 1.0f; + bool isCheapSearch = false; double playoutDoublingAdvantage = 0.0; Player playoutDoublingAdvantagePla = C_EMPTY; Loc hintLoc = Board::NULL_LOC; - double cheapSearchProb = playSettings.cheapSearchProb; + double cheapSearchProb = forceFullSearch ? 0.0 : playSettings.cheapSearchProb; const BoardHistory& hist = toMoveBot->getRootHist(); - if(otherGameProps.hintLoc != Board::NULL_LOC) { + if(!forceFullSearch && otherGameProps.hintLoc != Board::NULL_LOC) { if(otherGameProps.hintTurn == hist.moveHistory.size() && otherGameProps.hintPosHash == toMoveBot->getRootBoard().pos_hash) { hintLoc = otherGameProps.hintLoc; @@ -1081,6 +1135,7 @@ static SearchLimitsThisMove getSearchLimitsThisMove( throw StringError("playSettings.cheapSearchVisits > maxVisits and/or maxPlayouts"); doAlterVisitsPlayouts = true; + isCheapSearch = true; numAlterVisits = std::min(numAlterVisits,(int64_t)playSettings.cheapSearchVisits); numAlterPlayouts = std::min(numAlterPlayouts,(int64_t)playSettings.cheapSearchVisits); targetWeight *= playSettings.cheapSearchTargetWeight; @@ -1098,11 +1153,12 @@ static SearchLimitsThisMove getSearchLimitsThisMove( playSettings.reducedVisitsMin > toMoveBot->searchParams.maxPlayouts) throw StringError("playSettings.reducedVisitsMin > maxVisits and/or maxPlayouts"); - if(historicalMctsWinLossValues.size() >= playSettings.reduceVisitsThresholdLookback) { + size_t numHistoricalValues = std::min(numHistoricalMctsValuesToUse, historicalMctsWinLossValues.size()); + if(numHistoricalValues >= (size_t)playSettings.reduceVisitsThresholdLookback) { double minWinLossValue = 1e20; double maxWinLossValue = -1e20; for(int j = 0; j maxWinLossValue) @@ -1161,6 +1217,7 @@ static SearchLimitsThisMove getSearchLimitsThisMove( limits.clearBotBeforeSearchThisMove = clearBotBeforeSearchThisMove; limits.removeRootNoise = removeRootNoise; limits.targetWeight = targetWeight; + limits.isCheapSearch = isCheapSearch; limits.playoutDoublingAdvantage = playoutDoublingAdvantage; limits.playoutDoublingAdvantagePla = playoutDoublingAdvantagePla; limits.hintLoc = hintLoc; @@ -1242,6 +1299,191 @@ static Loc runBotWithLimits( return loc; } +//KL divergence of a win/loss/noresult distribution from the raw neural net value prediction, capped at 1. +static double valueSurpriseKL(double winValue, double lossValue, double noResultValue, const ReportedSearchValues& rawNNValues) { + double valueSurprise = 0.0; + if(winValue > 1e-100) valueSurprise += winValue * (log(winValue) - log(std::max((double)rawNNValues.winValue,1e-100))); + if(lossValue > 1e-100) valueSurprise += lossValue * (log(lossValue) - log(std::max((double)rawNNValues.lossValue,1e-100))); + if(noResultValue > 1e-100) valueSurprise += noResultValue * (log(noResultValue) - log(std::max((double)rawNNValues.noResultValue,1e-100))); + + //Just in case, guard against float imprecision + if(valueSurprise < 0.0) + valueSurprise = 0.0; + //Cap value surprise at extreme value, to reduce the chance of a ridiculous weight on a move. + return std::min(valueSurprise,1.0); +} + +//Compute how surprising the value result at each turn was (KL divergence), relative to the raw neural net +//value prediction at that turn. By default the value result compared is the smoothed forward-looking game +//result, which depends on how the game actually continued and ended. If useSearchValueSurprise is true, it is +//instead the value result of that turn's own search, which depends only on information available at the time +//of the search, so that data weighting/selection based on it does not condition on the game's realized outcome. +//whiteValueTargetsByTurn should have one entry per turn plus a final entry for the game outcome. +static void computeValueSurpriseByTurn( + vector& valueSurpriseByTurn, + const vector& whiteValueTargetsByTurn, + const vector& rawNNValues, + int boardArea, + bool useSearchValueSurprise +) { + testAssert(whiteValueTargetsByTurn.size() == rawNNValues.size() + 1); + valueSurpriseByTurn.resize(rawNNValues.size()); + + if(useSearchValueSurprise) { + for(int i = 0; i < (int)rawNNValues.size(); i++) { + const ValueTargets& searchValues = whiteValueTargetsByTurn[i]; + valueSurpriseByTurn[i] = valueSurpriseKL(searchValues.win, searchValues.loss, searchValues.noResult, rawNNValues[i]); + } + return; + } + + double nowFactor = 1.0/(1.0 + boardArea * 0.016); + + double winValue = whiteValueTargetsByTurn[whiteValueTargetsByTurn.size()-1].win; + double lossValue = whiteValueTargetsByTurn[whiteValueTargetsByTurn.size()-1].loss; + double noResultValue = whiteValueTargetsByTurn[whiteValueTargetsByTurn.size()-1].noResult; + for(int i = (int)rawNNValues.size()-1; i >= 0; i--) { + winValue = winValue + nowFactor * (whiteValueTargetsByTurn[i].win - winValue); + lossValue = lossValue + nowFactor * (whiteValueTargetsByTurn[i].loss - lossValue); + noResultValue = noResultValue + nowFactor * (whiteValueTargetsByTurn[i].noResult - noResultValue); + + valueSurpriseByTurn[i] = valueSurpriseKL(winValue, lossValue, noResultValue, rawNNValues[i]); + } +} + +//After a game finishes, select some of the positions that got only cheap searches, favoring positions whose +//cheap search was surprising, and redo them with full searches. Overwrites those turns' recorded targets and +//stats with those of the new full searches and raises their target weights to what a full-search turn would get, +//so that they get recorded as full-quality training positions. Does not affect the game itself in any way. +static void reanalyzeCheapSearchPositions( + Search* botB, Search* botW, + const PlaySettings& playSettings, + const OtherGameProperties& otherGameProps, + bool clearBotBeforeSearch, + const vector& wasCheapSearchByTurn, + const vector& valueSurpriseByTurn, + const vector& historicalMctsWinLossValues, + Rand& gameRand, + const std::function& shouldStop, + const WaitableFlag* shouldPause, + const std::function& maybeCheckForNewNNEval, + vector& rawNNValues, + vector& locsBuf, vector& playSelectionValuesBuf, + FinishedGameData* gameData +) { + int numMoves = (int)gameData->targetWeightByTurn.size(); + testAssert((int)wasCheapSearchByTurn.size() == numMoves); + testAssert((int)valueSurpriseByTurn.size() == numMoves); + testAssert((int)gameData->policySurpriseByTurn.size() == numMoves); + testAssert((int)gameData->reanalysisByTurn.size() == numMoves); + + vector candidateTurns; + for(int i = 0; i relProbs(candidateTurns.size()); + for(size_t i = 0; ipolicySurpriseByTurn[turn] + + playSettings.reanalyzeValueSurpriseWeight * valueSurpriseByTurn[turn]; + relProbs[i] = pow(surprise, playSettings.reanalyzeSurpriseExponent); + } + vector turnsToReanalyze; + for(int k = 0; k 1e-30) + chosen = gameRand.nextUInt(relProbs.data(),relProbs.size()); + else + chosen = gameRand.nextUInt((uint32_t)relProbs.size()); + turnsToReanalyze.push_back(candidateTurns[chosen]); + candidateTurns.erase(candidateTurns.begin()+chosen); + relProbs.erase(relProbs.begin()+chosen); + } + std::sort(turnsToReanalyze.begin(),turnsToReanalyze.end()); + + //Replay the game forward, redoing a full search at each selected turn. + Board board = gameData->startBoard; + BoardHistory hist = gameData->startHist; + Player pla = gameData->startPla; + int startTurnIdx = (int)gameData->startHist.moveHistory.size(); + + size_t whichIdx = 0; + for(int turnAfterStart = 0; turnAfterStartwaitUntilFalse(); + if(shouldStop != nullptr && shouldStop()) + break; + + Search* toMoveBot = pla == P_BLACK ? botB : botW; + toMoveBot->setPosition(pla,board,hist); + + //Reproduce the search limits that this turn would have gotten if it had been a full-search turn, + //including any reduceVisits and asymmetric playout adjustments, based on the mcts winloss values + //of the turns leading up to this one. + SearchLimitsThisMove limits = getSearchLimitsThisMove( + toMoveBot, pla, playSettings, gameRand, historicalMctsWinLossValues, (size_t)turnAfterStart, + clearBotBeforeSearch, otherGameProps, true + ); + runBotWithLimits(toMoveBot, pla, playSettings, limits); + + //Record the original cheap search's surprise stats that drove the selection of this position, and its visits. + ReanalysisData& reanalysisData = gameData->reanalysisByTurn[turnAfterStart]; + reanalysisData.wasReanalyzed = true; + reanalysisData.usedOutcomeTargets = playSettings.reanalyzeUseOutcomeTargets; + reanalysisData.selectionPolicySurprise = (float)gameData->policySurpriseByTurn[turnAfterStart]; + reanalysisData.selectionValueSurprise = (float)valueSurpriseByTurn[turnAfterStart]; + reanalysisData.originalNumVisits = gameData->policyTargetsByTurn[turnAfterStart].unreducedNumVisits; + reanalysisData.numNeuralNetChangesSoFar = (int)gameData->changedNeuralNets.size(); + + //Overwrite this turn's recorded targets and stats with those of the new full search. + //Note: replacing this turn's entry in whiteValueTargetsByTurn means the winloss-variance-timing training + //target of earlier turns will see cheap-vs-full estimator deltas at the boundaries of this turn that + //aren't purely game variance. Deltas of similar scale already pervade that target from consecutive + //cheap/full searches during play, and it is a tiny auxiliary target, so this is accepted. + SearchTargetsThisTurn targets; + extractSearchTargetsThisTurn(targets, toMoveBot, board, hist, pla, locsBuf, playSelectionValuesBuf); + gameData->whiteValueTargetsByTurn[turnAfterStart] = targets.whiteValueTargets; + gameData->whiteQValueTargetsByTurn[turnAfterStart] = targets.whiteQValueTargets; + delete gameData->policyTargetsByTurn[turnAfterStart].policyTargets; + gameData->policyTargetsByTurn[turnAfterStart].policyTargets = targets.policyTarget; + gameData->policyTargetsByTurn[turnAfterStart].unreducedNumVisits = targets.unreducedNumVisits; + gameData->nnRawStatsByTurn[turnAfterStart] = targets.nnRawStats; + gameData->policySurpriseByTurn[turnAfterStart] = targets.policySurprise; + gameData->policyEntropyByTurn[turnAfterStart] = targets.policyEntropy; + gameData->searchEntropyByTurn[turnAfterStart] = targets.searchEntropy; + rawNNValues[turnAfterStart] = targets.rawNNValues; + gameData->targetWeightByTurn[turnAfterStart] = limits.targetWeight; + + testAssert(gameData->endHist.moveHistory.size() < 0x1FFFffff); + maybeCheckForNewNNEval((int)gameData->endHist.moveHistory.size()); + } + + Move move = gameData->endHist.moveHistory[turnAfterStart + startTurnIdx]; + testAssert(move.pla == pla); + testAssert(hist.isLegal(board,move.loc,move.pla)); + hist.makeBoardMoveAssumeLegal(board, move.loc, move.pla, NULL); + pla = getOpp(pla); + } +} + //Run a game between two bots. It is OK if both bots are the same bot. FinishedGameData* Play::runGame( @@ -1306,6 +1548,14 @@ FinishedGameData* Play::runGame( Board board(startBoard); BoardHistory hist(startHist); + //Game-level pass-alive computation mode, used for whole-game adjudication (endGameIfAllPassAlive, + //final scoring) and training data targets: use the suicide-rules-based computation only if BOTH + //bots' searches will be using it. Each bot's Search still stamps its own resolved setting onto its + //internal copy of the history, which may differ from this when the two bots' settings differ. + hist.setAlwaysComputePassAliveUnderSuicideRules( + Search::resolveAlwaysComputePassAliveUnderSuicideRules(botSpecB.baseParams, botSpecB.nnEval) && + Search::resolveAlwaysComputePassAliveUnderSuicideRules(botSpecW.baseParams, botSpecW.nnEval) + ); Player pla = startPla; testAssert(!(extraBlackAndKomi.makeGameFair && extraBlackAndKomi.makeGameFairForEmptyBoard)); testAssert(!(playSettings.forSelfPlay && !clearBotBeforeSearch)); @@ -1315,7 +1565,8 @@ FinishedGameData* Play::runGame( Player makeFairPla = P_BLACK; if(playSettings.flipKomiProbWhenNoCompensate != 0.0 && gameRand.nextBool(playSettings.flipKomiProbWhenNoCompensate)) makeFairPla = P_WHITE; - BoardHistory h(b,makeFairPla,startHist.rules,startHist.encorePhase); + //Use the game-level pass-alive computation mode for the komi-fairing evals too. + BoardHistory h(b,makeFairPla,startHist.rules,startHist.encorePhase,hist.alwaysComputePassAliveUnderSuicideRules); //Restore baseline on empty hist, adjust empty hist to fair, then apply to real history. PlayUtils::setKomiWithoutNoise(extraBlackAndKomi,h); PlayUtils::adjustKomiToEven(botB,botW,b,h,makeFairPla,playSettings.compensateKomiVisits,otherGameProps,gameRand); @@ -1404,6 +1655,10 @@ FinishedGameData* Play::runGame( auto maybeCheckForNewNNEval = [&botB,&botW,&botSpecB,&botSpecW,&checkForNewNNEval,&gameRand,&gameData](int nextTurnIdx) { //Check if we got a new nnEval, with some probability. //Randomized and low-probability so as to reduce contention in checking, while still probably happening in a timely manner. + //NOTE: swapping the nnEval mid-game re-resolves each bot's alwaysComputePassAliveUnderSuicideRules mode + //(via Search::setNNEval), but the game-level hist deliberately KEEPS the mode stamped at the start of the + //game - re-adjudicating a game under a different mode than it started with would be worse than letting + //the searches briefly disagree with the game-level adjudication for the remainder of this one game. if(checkForNewNNEval != nullptr && gameRand.nextBool(0.1)) { NNEvaluator* newNNEval = checkForNewNNEval(); if(newNNEval != NULL) { @@ -1494,6 +1749,7 @@ FinishedGameData* Play::runGame( vector historicalMctsLeads; vector historicalMctsScoreStdevs; vector rawNNValues; + vector wasCheapSearchByTurn; ClockTimer timer; @@ -1531,7 +1787,8 @@ FinishedGameData* Play::runGame( } SearchLimitsThisMove limits = getSearchLimitsThisMove( - toMoveBot, pla, playSettings, gameRand, historicalMctsWinLossValues, clearBotBeforeSearch, otherGameProps + toMoveBot, pla, playSettings, gameRand, historicalMctsWinLossValues, historicalMctsWinLossValues.size(), + clearBotBeforeSearch, otherGameProps, false ); Loc loc; if(playSettings.recordTimePerMove) { @@ -1559,36 +1816,32 @@ FinishedGameData* Play::runGame( if(logMoves) logger.write("Move " + Global::uint64ToString(hist.moveHistory.size()) + " made: " + Location::toString(loc,board)); - ValueTargets whiteValueTargets; - extractValueTargets(whiteValueTargets, toMoveBot, toMoveBot->rootNode); - gameData->whiteValueTargetsByTurn.push_back(whiteValueTargets); - QValueTargets whiteQValueTargets; - extractQValueTargets(whiteQValueTargets.targets, toMoveBot, toMoveBot->rootNode); - gameData->whiteQValueTargetsByTurn.push_back(whiteQValueTargets); - if(!recordFullData) { + ValueTargets whiteValueTargets; + extractValueTargets(whiteValueTargets, toMoveBot, toMoveBot->rootNode); + gameData->whiteValueTargetsByTurn.push_back(whiteValueTargets); + QValueTargets whiteQValueTargets; + extractQValueTargets(whiteQValueTargets.targets, toMoveBot, toMoveBot->rootNode); + gameData->whiteQValueTargetsByTurn.push_back(whiteQValueTargets); //Go ahead and record this anyways with just the visits, as a bit of a hack so that the sgf output can also write the number of visits. int64_t unreducedNumVisits = toMoveBot->getRootVisits(); gameData->policyTargetsByTurn.emplace_back(nullptr,unreducedNumVisits); } else { - vector* policyTarget = new vector(); - int64_t unreducedNumVisits = toMoveBot->getRootVisits(); - Play::extractPolicyTarget(*policyTarget, toMoveBot, toMoveBot->rootNode, locsBuf, playSelectionValuesBuf); - gameData->policyTargetsByTurn.emplace_back(policyTarget,unreducedNumVisits); - gameData->nnRawStatsByTurn.push_back(computeNNRawStats(toMoveBot, board, hist, pla)); + SearchTargetsThisTurn targets; + extractSearchTargetsThisTurn(targets, toMoveBot, board, hist, pla, locsBuf, playSelectionValuesBuf); + gameData->whiteValueTargetsByTurn.push_back(targets.whiteValueTargets); + gameData->whiteQValueTargetsByTurn.push_back(targets.whiteQValueTargets); + gameData->policyTargetsByTurn.emplace_back(targets.policyTarget,targets.unreducedNumVisits); + gameData->nnRawStatsByTurn.push_back(targets.nnRawStats); + gameData->policySurpriseByTurn.push_back(targets.policySurprise); + gameData->policyEntropyByTurn.push_back(targets.policyEntropy); + gameData->searchEntropyByTurn.push_back(targets.searchEntropy); + rawNNValues.push_back(targets.rawNNValues); gameData->targetWeightByTurn.push_back(limits.targetWeight); - - double policySurprise = 0.0, policyEntropy = 0.0, searchEntropy = 0.0; - bool success = toMoveBot->getPolicySurpriseAndEntropy(policySurprise, searchEntropy, policyEntropy); - testAssert(success); - - gameData->policySurpriseByTurn.push_back(policySurprise); - gameData->policyEntropyByTurn.push_back(policyEntropy); - gameData->searchEntropyByTurn.push_back(searchEntropy); - - rawNNValues.push_back(toMoveBot->getRootRawNNValuesRequireSuccess()); + gameData->reanalysisByTurn.emplace_back(); + wasCheapSearchByTurn.push_back(limits.isCheapSearch); //Occasionally fork off some positions to evaluate Loc sidePositionForkLoc = Board::NULL_LOC; @@ -1747,11 +2000,11 @@ FinishedGameData* Play::runGame( //Fill full and seki areas { - board.calculateArea(gameData->finalFullArea, true, true, true, hist.rules.multiStoneSuicideLegal); + board.calculateArea(gameData->finalFullArea, true, true, true, hist.suicideLegalForPassAlive()); Color* independentLifeArea = new Color[Board::MAX_ARR_SIZE]; int whiteMinusBlackIndependentLifeRegionCount; - board.calculateIndependentLifeArea(independentLifeArea,whiteMinusBlackIndependentLifeRegionCount, false, false, hist.rules.multiStoneSuicideLegal); + board.calculateIndependentLifeArea(independentLifeArea,whiteMinusBlackIndependentLifeRegionCount, false, false, hist.suicideLegalForPassAlive()); for(int i = 0; ifinalFullArea[i] == C_BLACK || gameData->finalFullArea[i] == C_WHITE)) gameData->finalSekiAreas[i] = true; @@ -1775,37 +2028,58 @@ FinishedGameData* Play::runGame( gameData->hasFullData = true; + testAssert(gameData->whiteValueTargetsByTurn.size() == gameData->targetWeightByTurn.size() + 1); + testAssert(rawNNValues.size() == gameData->targetWeightByTurn.size()); + vector valueSurpriseByTurn; - { - const vector& whiteValueTargetsByTurn = gameData->whiteValueTargetsByTurn; - testAssert(whiteValueTargetsByTurn.size() == gameData->targetWeightByTurn.size() + 1); - testAssert(rawNNValues.size() == gameData->targetWeightByTurn.size()); - valueSurpriseByTurn.resize(rawNNValues.size()); - - int boardArea = board.x_size * board.y_size; - double nowFactor = 1.0/(1.0 + boardArea * 0.016); - - double winValue = whiteValueTargetsByTurn[whiteValueTargetsByTurn.size()-1].win; - double lossValue = whiteValueTargetsByTurn[whiteValueTargetsByTurn.size()-1].loss; - double noResultValue = whiteValueTargetsByTurn[whiteValueTargetsByTurn.size()-1].noResult; - for(int i = (int)rawNNValues.size()-1; i >= 0; i--) { - winValue = winValue + nowFactor * (whiteValueTargetsByTurn[i].win - winValue); - lossValue = lossValue + nowFactor * (whiteValueTargetsByTurn[i].loss - lossValue); - noResultValue = noResultValue + nowFactor * (whiteValueTargetsByTurn[i].noResult - noResultValue); - - double valueSurprise = 0.0; - if(winValue > 1e-100) valueSurprise += winValue * (log(winValue) - log(std::max((double)rawNNValues[i].winValue,1e-100))); - if(lossValue > 1e-100) valueSurprise += lossValue * (log(lossValue) - log(std::max((double)rawNNValues[i].lossValue,1e-100))); - if(noResultValue > 1e-100) valueSurprise += noResultValue * (log(noResultValue) - log(std::max((double)rawNNValues[i].noResultValue,1e-100))); - - //Just in case, guard against float imprecision - if(valueSurprise < 0.0) - valueSurprise = 0.0; - //Cap value surprise at extreme value, to reduce the chance of a ridiculous weight on a move. - valueSurpriseByTurn[i] = std::min(valueSurprise,1.0); + computeValueSurpriseByTurn( + valueSurpriseByTurn, gameData->whiteValueTargetsByTurn, rawNNValues, board.x_size * board.y_size, + playSettings.useSearchValueSurprise + ); + + //After the game, select some of the positions that got only cheap searches and redo them with full searches, + //so that they get recorded as full training positions. This happens entirely after the game so it cannot + //affect the game's moves or outcome in any way. + if(playSettings.useReanalyze && playSettings.reanalyzeProp > 0.0) { + reanalyzeCheapSearchPositions( + botB, botW, playSettings, otherGameProps, clearBotBeforeSearch, + wasCheapSearchByTurn, valueSurpriseByTurn, historicalMctsWinLossValues, + gameRand, shouldStop, shouldPause, maybeCheckForNewNNEval, + rawNNValues, locsBuf, playSelectionValuesBuf, + gameData + ); + //If we had a hintloc, refresh the copy of turn 1's value into turn 0 made above, in case turn 1 was + //reanalyzed and its value was updated. + if(otherGameProps.hintLoc != Board::NULL_LOC) { + gameData->whiteValueTargetsByTurn[0] = gameData->whiteValueTargetsByTurn[std::min((size_t)1,gameData->whiteValueTargetsByTurn.size()-1)]; + } + + //Reanalysis overwrote the searched values at the reanalyzed turns, which feed into the value targets and + //the value surprise of every turn at or before them (of just those turns themselves, for search value + //surprise), so recompute. + computeValueSurpriseByTurn( + valueSurpriseByTurn, gameData->whiteValueTargetsByTurn, rawNNValues, board.x_size * board.y_size, + playSettings.useSearchValueSurprise + ); + + if(logSearchInfo || logMoves) { + int numCheapSearchTurns = 0; + for(size_t i = 0; ireanalysisByTurn.size(); i++) + numReanalyzedTurns += gameData->reanalysisByTurn[i].wasReanalyzed ? 1 : 0; + logger.write( + "Reanalyzed " + Global::intToString(numReanalyzedTurns) + " of " + + Global::intToString(numCheapSearchTurns) + " cheap-search positions for training data" + ); } } + //Record for statistical purposes (e.g. the selfplaysurprisedump command) + gameData->valueSurpriseByTurn = valueSurpriseByTurn; + gameData->wasCheapSearchByTurn = wasCheapSearchByTurn; + //Compute desired expectation with which to write main game rows if(playSettings.policySurpriseDataWeight > 0 || playSettings.valueSurpriseDataWeight > 0) { size_t numWeights = gameData->targetWeightByTurn.size(); @@ -1839,8 +2113,25 @@ FinishedGameData* Play::runGame( } //We also include some rows from non-full searches, if despite the shallow search - //they were quite surprising to the policy. + //they were quite surprising to the policy. When using reanalyze, reanalysis of the most surprising + //cheap searches replaces this behavior for cheap searches that were not reanalyzed, so for those the + //excess surprise term is turned off. It still applies to all other reduced-weight rows - rows whose + //visits and weight were reduced due to extreme winrates, including reanalyzed rows reduced that way + //(judged on the reanalysis search's own policy surprise). double thresholdToIncludeReduced = averagePolicySurpriseWeighted * 1.5; + auto policySurprisePropValueOfTurn = [&](int i) { + float targetWeight = gameData->targetWeightByTurn[i]; + double policySurprise = gameData->policySurpriseByTurn[i]; + bool excludeExcessSurprise = + playSettings.useReanalyze && wasCheapSearchByTurn[i] && !gameData->reanalysisByTurn[i].wasReanalyzed; + double excessSurprise = excludeExcessSurprise ? 0.0 : std::max(0.0,policySurprise-thresholdToIncludeReduced); + return targetWeight * policySurprise + (1-targetWeight) * excessSurprise; + }; + auto valueSurprisePropValueOfTurn = [&](int i) { + float targetWeight = gameData->targetWeightByTurn[i]; + double valueSurprise = valueSurpriseByTurn[i]; + return targetWeight * valueSurprise; + }; //Part of the weight will be proportional to surprisePropValue which is just policySurprise on normal rows //and the excess policySurprise beyond threshold on shallow searches. @@ -1848,15 +2139,8 @@ FinishedGameData* Play::runGame( double sumPolicySurprisePropValue = 0.0; double sumValueSurprisePropValue = 0.0; for(int i = 0; itargetWeightByTurn[i]; - double policySurprise = gameData->policySurpriseByTurn[i]; - double valueSurprise = valueSurpriseByTurn[i]; - double policySurprisePropValue = - targetWeight * policySurprise + (1-targetWeight) * std::max(0.0,policySurprise-thresholdToIncludeReduced); - double valueSurprisePropValue = - targetWeight * valueSurprise; - sumPolicySurprisePropValue += policySurprisePropValue; - sumValueSurprisePropValue += valueSurprisePropValue; + sumPolicySurprisePropValue += policySurprisePropValueOfTurn(i); + sumValueSurprisePropValue += valueSurprisePropValueOfTurn(i); } //Just in case, avoid div by 0 @@ -1864,13 +2148,11 @@ FinishedGameData* Play::runGame( sumValueSurprisePropValue = std::max(sumValueSurprisePropValue,1e-10); for(int i = 0; itargetWeightByTurn[i]; - double policySurprise = gameData->policySurpriseByTurn[i]; - double valueSurprise = valueSurpriseByTurn[i]; - double policySurprisePropValue = - targetWeight * policySurprise + (1-targetWeight) * std::max(0.0,policySurprise-thresholdToIncludeReduced); - double valueSurprisePropValue = - targetWeight * valueSurprise; + double policySurprisePropValue = policySurprisePropValueOfTurn(i); + double valueSurprisePropValue = valueSurprisePropValueOfTurn(i); double newValue = (1.0-playSettings.policySurpriseDataWeight-valueSurpriseDataWeight) * targetWeight + playSettings.policySurpriseDataWeight * policySurprisePropValue * sumWeights / sumPolicySurprisePropValue @@ -1951,6 +2233,9 @@ FinishedGameData* Play::runGame( Search* toMoveBot2 = sp2->pla == P_BLACK ? botB : botW; MiscNNInputParams nnInputParams; nnInputParams.drawEquivalentWinsForWhite = toMoveBot2->searchParams.drawEquivalentWinsForWhite; + //Featurize the way this bot's own searches would, even if the game-level history differs. + nnInputParams.passAliveSuicideRulesOverride = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(toMoveBot2->searchParams, toMoveBot2->nnEvaluator) ? 1 : 0; toMoveBot2->nnEvaluator->evaluate( sp2->board,sp2->hist,sp2->pla,nnInputParams, nnResultBuf,false,false @@ -2072,6 +2357,10 @@ static void replayGameUpToMove(const FinishedGameData* finishedGameData, int mov board = finishedGameData->startHist.initialBoard; pla = finishedGameData->startHist.initialPla; + //Replay under the same pass-alive computation mode that the game was actually played and + //adjudicated with (clear() below preserves this). + hist.setAlwaysComputePassAliveUnderSuicideRules(finishedGameData->endHist.alwaysComputePassAliveUnderSuicideRules); + if(rules.scoringRule == Rules::SCORING_AREA) hist.clear(board,pla,rules,0); else @@ -2195,6 +2484,9 @@ void Play::maybeForkGame( copyHist.makeBoardMoveAssumeLegal(copy,loc,pla,NULL); MiscNNInputParams nnInputParams; nnInputParams.drawEquivalentWinsForWhite = drawEquivalentWinsForWhite; + //Featurize the way this bot's own searches would, even if the replayed game-level history differs. + nnInputParams.passAliveSuicideRulesOverride = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(bot->searchParams, bot->nnEvaluator) ? 1 : 0; bot->nnEvaluator->evaluate(copy,copyHist,getOpp(pla),nnInputParams,buf,false,false); std::shared_ptr nnOutput = std::move(buf.result); double whiteScore = nnOutput->whiteScoreMean; @@ -2371,15 +2663,20 @@ FinishedGameData* GameRunner::runGame( BoardHistory hist; ExtraBlackAndKomi extraBlackAndKomi; OtherGameProperties otherGameProps; + //Game-level pass-alive computation mode for this game, matching the value Play::runGame will + //stamp onto the game history it plays out: on only if BOTH bots' searches will be using it. + const bool gamePassAliveSuicideMode = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(botSpecB.baseParams, botSpecB.nnEval) && + Search::resolveAlwaysComputePassAliveUnderSuicideRules(botSpecW.baseParams, botSpecW.nnEval); if(playSettings.forSelfPlay) { testAssert(botSpecB.botIdx == botSpecW.botIdx); SearchParams params = botSpecB.baseParams; - gameInit->createGame(board,pla,hist,extraBlackAndKomi,params,initialPosition,playSettings,otherGameProps,startPosSample); + gameInit->createGame(board,pla,hist,extraBlackAndKomi,params,initialPosition,playSettings,otherGameProps,startPosSample,gamePassAliveSuicideMode); botSpecB.baseParams = params; botSpecW.baseParams = params; } else { - gameInit->createGame(board,pla,hist,extraBlackAndKomi,initialPosition,playSettings,otherGameProps,startPosSample); + gameInit->createGame(board,pla,hist,extraBlackAndKomi,initialPosition,playSettings,otherGameProps,startPosSample,gamePassAliveSuicideMode); bool rulesWereSupported; if(botSpecB.nnEval != NULL) { diff --git a/cpp/program/play.h b/cpp/program/play.h index eea746a7c9..f33d9f4ba2 100644 --- a/cpp/program/play.h +++ b/cpp/program/play.h @@ -94,7 +94,8 @@ class GameInitializer { const InitialPosition* initialPosition, const PlaySettings& playSettings, OtherGameProperties& otherGameProps, - const Sgf::PositionSample* startPosSample + const Sgf::PositionSample* startPosSample, + bool alwaysComputePassAliveUnderSuicideRules ); //A version that doesn't randomize params @@ -104,7 +105,8 @@ class GameInitializer { const InitialPosition* initialPosition, const PlaySettings& playSettings, OtherGameProperties& otherGameProps, - const Sgf::PositionSample* startPosSample + const Sgf::PositionSample* startPosSample, + bool alwaysComputePassAliveUnderSuicideRules ); Rules randomizeScoringAndTaxRules(Rules rules, Rand& randToUse) const; @@ -127,7 +129,8 @@ class GameInitializer { const InitialPosition* initialPosition, const PlaySettings& playSettings, OtherGameProperties& otherGameProps, - const Sgf::PositionSample* startPosSample + const Sgf::PositionSample* startPosSample, + bool alwaysComputePassAliveUnderSuicideRules ); Rules createRulesUnsynchronized(); diff --git a/cpp/program/playsettings.cpp b/cpp/program/playsettings.cpp index 7e048b00e5..aff0c054fb 100644 --- a/cpp/program/playsettings.cpp +++ b/cpp/program/playsettings.cpp @@ -10,7 +10,10 @@ PlaySettings::PlaySettings() sekiForkHackProb(0.0),fancyKomiVarying(false), cheapSearchProb(0),cheapSearchVisits(0),cheapSearchTargetWeight(0.0f), reduceVisits(false),reduceVisitsThreshold(100.0),reduceVisitsThresholdLookback(1),reducedVisitsMin(0),reducedVisitsWeight(1.0f), - policySurpriseDataWeight(0.0),valueSurpriseDataWeight(0.0),scaleDataWeight(1.0), + policySurpriseDataWeight(0.0),valueSurpriseDataWeight(0.0),useSearchValueSurprise(false),scaleDataWeight(1.0), + useReanalyze(false),reanalyzeProp(0.0), + reanalyzePolicySurpriseWeight(1.0),reanalyzeValueSurpriseWeight(1.0),reanalyzeSurpriseExponent(1.0), + reanalyzeUseOutcomeTargets(true), recordTreePositions(false),recordTreeThreshold(0),recordTreeTargetWeight(0.0f), noResolveTargetWeights(false), allowResignation(false),resignThreshold(0.0),resignConsecTurns(1), @@ -102,7 +105,16 @@ PlaySettings PlaySettings::loadForSelfplay(ConfigParser& cfg, bool isDistributed playSettings.reducedVisitsWeight = cfg.getFloat("reducedVisitsWeight",0.0f,1.0f); playSettings.policySurpriseDataWeight = cfg.getDouble("policySurpriseDataWeight",0.0,1.0); playSettings.valueSurpriseDataWeight = cfg.getDouble("valueSurpriseDataWeight",0.0,1.0); + playSettings.useSearchValueSurprise = cfg.contains("useSearchValueSurprise") ? cfg.getBool("useSearchValueSurprise") : false; playSettings.scaleDataWeight = cfg.contains("scaleDataWeight") ? cfg.getDouble("scaleDataWeight",0.01,10.0) : 1.0; + playSettings.useReanalyze = cfg.contains("useReanalyze") ? cfg.getBool("useReanalyze") : false; + if(playSettings.useReanalyze) { + playSettings.reanalyzeProp = cfg.getDouble("reanalyzeProp",0.0,1.0); + playSettings.reanalyzePolicySurpriseWeight = cfg.getDouble("reanalyzePolicySurpriseWeight",0.0,100.0); + playSettings.reanalyzeValueSurpriseWeight = cfg.getDouble("reanalyzeValueSurpriseWeight",0.0,100.0); + playSettings.reanalyzeSurpriseExponent = cfg.getDouble("reanalyzeSurpriseExponent",0.0,10.0); + playSettings.reanalyzeUseOutcomeTargets = cfg.getBool("reanalyzeUseOutcomeTargets"); + } playSettings.handicapAsymmetricPlayoutProb = cfg.getDouble("handicapAsymmetricPlayoutProb",0.0,1.0); playSettings.normalAsymmetricPlayoutProb = cfg.getDouble("normalAsymmetricPlayoutProb",0.0,1.0); playSettings.maxAsymmetricRatio = cfg.getDouble("maxAsymmetricRatio",1.0,100.0); diff --git a/cpp/program/playsettings.h b/cpp/program/playsettings.h index 0d22f6bf41..74d2f2f52e 100644 --- a/cpp/program/playsettings.h +++ b/cpp/program/playsettings.h @@ -56,9 +56,38 @@ struct PlaySettings { double policySurpriseDataWeight; //Probabilistically favor samples that had high winLossValue surprise (kl divergence). double valueSurpriseDataWeight; + //If true, value surprise (both for valueSurpriseDataWeight and for reanalyze selection) is the KL divergence + //of this turn's own search value result from the raw neural net value prediction, instead of the KL divergence + //of the smoothed forward-looking game result from that prediction. The search value surprise depends only on + //information available at the time of the search, so it does not condition data weighting/selection on the + //game's realized outcome, at the cost of not noticing surprises that only the actual continuation of the game + //would reveal. Its typical magnitude is also smaller, so valueSurpriseDataWeight and + //reanalyzeValueSurpriseWeight may need retuning when enabling this. + bool useSearchValueSurprise; //Scale frequency weights for writing data by this double scaleDataWeight; + //After the game ends, select some cheap-search positions and redo them with a full search to record + //as training data, favoring positions whose cheap search was surprising. Replaces the behavior where + //sufficiently policy-surprising cheap searches would be recorded (at reduced weight) based on the cheap + //search itself - note that this replaced behavior is disabled for cheap searches whenever useReanalyze is + //true, even if reanalyzeProp is 0. It remains active for reduced-weight rows that are not cheap searches, + //i.e. rows whose visits were reduced due to extreme winrates, including reanalyzed rows reduced that way. + bool useReanalyze; + //Number of positions reanalyzed is binomial with this probability on the number of cheap-search positions. + double reanalyzeProp; + //Positions are drawn without replacement with probability proportional to + //(reanalyzePolicySurpriseWeight * policySurprise + reanalyzeValueSurpriseWeight * valueSurprise) ** reanalyzeSurpriseExponent + //where policySurprise and valueSurprise are those of the original cheap search. + double reanalyzePolicySurpriseWeight; + double reanalyzeValueSurpriseWeight; + double reanalyzeSurpriseExponent; + //If true, reanalyzed positions are recorded exactly like normal full-search positions. If false, they omit the + //targets derived from the final board and the actual game continuation (ownership, final score, future board + //positions), but still record policy, lead, and value targets (which as usual blend the searched values of this + //and later turns with the game outcome). + bool reanalyzeUseOutcomeTargets; + //Record positions from within the search tree that had at least this many visits, recording only with this weight. bool recordTreePositions; int recordTreeThreshold; diff --git a/cpp/program/playutils.cpp b/cpp/program/playutils.cpp index f5b479af47..a3db385941 100644 --- a/cpp/program/playutils.cpp +++ b/cpp/program/playutils.cpp @@ -180,9 +180,14 @@ Loc PlayUtils::getGameInitializationMove( Search* botB, Search* botW, const Board& board, const BoardHistory& hist, Player pla, NNResultBuf& buf, Rand& gameRand, double temperature ) { - NNEvaluator* nnEval = (pla == P_BLACK ? botB : botW)->nnEvaluator; + const Search* searcher = (pla == P_BLACK ? botB : botW); + NNEvaluator* nnEval = searcher->nnEvaluator; MiscNNInputParams nnInputParams; - nnInputParams.drawEquivalentWinsForWhite = (pla == P_BLACK ? botB : botW)->searchParams.drawEquivalentWinsForWhite; + nnInputParams.drawEquivalentWinsForWhite = searcher->searchParams.drawEquivalentWinsForWhite; + //Featurize for this bot's net the way that bot's own searches would, even if the game-level history + //carries a different pass-alive computation mode. + nnInputParams.passAliveSuicideRulesOverride = + Search::resolveAlwaysComputePassAliveUnderSuicideRules(searcher->searchParams, nnEval) ? 1 : 0; nnEval->evaluate(board,hist,pla,nnInputParams,buf,false,false); std::shared_ptr nnOutput = std::move(buf.result); @@ -276,9 +281,12 @@ void PlayUtils::playExtraBlack( if(!hist.isGameFinished) { NNResultBuf buf; + bool botPassAliveMode = Search::resolveAlwaysComputePassAliveUnderSuicideRules(bot->searchParams, bot->nnEvaluator); for(int i = 0; isearchParams.drawEquivalentWinsForWhite; + //Featurize the way this bot's own searches would, even if the passed history differs. + nnInputParams.passAliveSuicideRulesOverride = botPassAliveMode ? 1 : 0; bot->nnEvaluator->evaluate(board,hist,pla,nnInputParams,buf,false,false); std::shared_ptr nnOutput = std::move(buf.result); @@ -956,7 +964,7 @@ PlayUtils::BenchmarkResults PlayUtils::benchmarkSearchOnPositionsAndPrint( Board board; Player nextPla; BoardHistory hist; - sgf.setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf.setupInitialBoardAndHist(initialRules, board, nextPla, hist, Search::resolveAlwaysComputePassAliveUnderSuicideRules(params, nnEval)); int moveNum = 0; @@ -1159,7 +1167,7 @@ Loc PlayUtils::maybeFriendlyPass( bool nonPassAliveStones = true; bool safeBigTerritories = true; bool unsafeBigTerritories = true; - bool isMultiStoneSuicideLegal = hist.rules.multiStoneSuicideLegal; + bool isMultiStoneSuicideLegal = hist.suicideLegalForPassAlive(); cleanBoard.calculateArea(area, nonPassAliveStones, safeBigTerritories, unsafeBigTerritories, isMultiStoneSuicideLegal); } const double highOwnershipThreshold = 0.75; diff --git a/cpp/program/selfplaymanager.cpp b/cpp/program/selfplaymanager.cpp index abb2b9c394..fd199c7f12 100644 --- a/cpp/program/selfplaymanager.cpp +++ b/cpp/program/selfplaymanager.cpp @@ -13,6 +13,8 @@ SelfplayManager::ModelData::ModelData( modelName(name), nnEval(neval), gameStartedCount(0), + gamesFinishedCount(0), + movesPlayedCount(0), lastReleaseTime(initialTime), hasDataWriteLoop(hasDataLoop), finishedGameQueue(maxDQueueSize), @@ -291,9 +293,14 @@ void SelfplayManager::countOneGameStarted(NNEvaluator* nnEval) { int64_t logNNEvery = logGamesEvery*100 > 1000 ? logGamesEvery*100 : 1000; if(logger != NULL && gameStartedCount % logNNEvery == 0) { logger->write(nnEval->getModelFileName()); + logger->write("Games finished: " + Global::int64ToString(foundData->gamesFinishedCount.load(std::memory_order_relaxed))); + logger->write("Moves played: " + Global::int64ToString(foundData->movesPlayedCount.load(std::memory_order_relaxed))); + if(foundData->tdataWriter != NULL) + logger->write("Data rows: " + Global::int64ToString(foundData->tdataWriter->numRowsWritten())); logger->write("NN rows: " + Global::int64ToString(nnEval->numRowsProcessed())); logger->write("NN batches: " + Global::int64ToString(nnEval->numBatchesProcessed())); logger->write("NN avg batch size: " + Global::doubleToString(nnEval->averageProcessedBatchSize())); + logger->write("NN cache hits: " + Global::int64ToString((int64_t)nnEval->numCacheHits())); } } @@ -357,6 +364,14 @@ void SelfplayManager::runDataWriteLoopImpl(ModelData* modelData) { modelData->tdataWriter->writeGame(*gameData); + modelData->gamesFinishedCount.fetch_add(1, std::memory_order_relaxed); + // Moves actually played by search this game (excludes any pre-placed opening/start-position moves). + testAssert(gameData->startHist.moveHistory.size() <= gameData->endHist.moveHistory.size()); + modelData->movesPlayedCount.fetch_add( + (int64_t)(gameData->endHist.moveHistory.size() - gameData->startHist.moveHistory.size()), + std::memory_order_relaxed + ); + if(modelData->sgfOut != NULL) { testAssert(gameData->startHist.moveHistory.size() <= gameData->endHist.moveHistory.size()); WriteSgf::writeSgf(*modelData->sgfOut,gameData->bName,gameData->wName,gameData->endHist,gameData,false,true); @@ -392,9 +407,13 @@ void SelfplayManager::runDataWriteLoopImpl(ModelData* modelData) { //block anyone else if(logger != NULL) { logger->write("Final cleanup of net: " + modelData->nnEval->getModelFileName()); + logger->write("Final games finished: " + Global::int64ToString(modelData->gamesFinishedCount.load(std::memory_order_relaxed))); + logger->write("Final moves played: " + Global::int64ToString(modelData->movesPlayedCount.load(std::memory_order_relaxed))); + logger->write("Final data rows: " + Global::int64ToString(modelData->tdataWriter->numRowsWritten())); logger->write("Final NN rows: " + Global::int64ToString(modelData->nnEval->numRowsProcessed())); logger->write("Final NN batches: " + Global::int64ToString(modelData->nnEval->numBatchesProcessed())); logger->write("Final NN avg batch size: " + Global::doubleToString(modelData->nnEval->averageProcessedBatchSize())); + logger->write("Final NN cache hits: " + Global::int64ToString((int64_t)modelData->nnEval->numCacheHits())); } delete modelData; diff --git a/cpp/program/selfplaymanager.h b/cpp/program/selfplaymanager.h index 8b32826e76..574b8f0433 100644 --- a/cpp/program/selfplaymanager.h +++ b/cpp/program/selfplaymanager.h @@ -1,6 +1,8 @@ #ifndef PROGRAM_SELFPLAYMANAGER_H_ #define PROGRAM_SELFPLAYMANAGER_H_ +#include + #include "../core/threadsafequeue.h" #include "../core/timer.h" #include "../dataio/sgf.h" @@ -85,6 +87,9 @@ class SelfplayManager { std::string modelName; NNEvaluator* nnEval; int64_t gameStartedCount; + // Counted at game-finish in the data write loop (lock-free), read cross-thread for logging. + std::atomic gamesFinishedCount; + std::atomic movesPlayedCount; double lastReleaseTime; bool hasDataWriteLoop; diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index ce635e7ccb..bf7950315e 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -21,7 +21,6 @@ std::vector Setup::getBackendPrefixes() { prefixes.push_back("metal"); prefixes.push_back("opencl"); prefixes.push_back("eigen"); - prefixes.push_back("onnx"); prefixes.push_back("dummybackend"); return prefixes; } @@ -88,40 +87,12 @@ vector Setup::initializeNNEvaluators( string backendPrefix = "metal"; #elif defined(USE_OPENCL_BACKEND) string backendPrefix = "opencl"; - #elif defined(USE_ONNX_BACKEND) - string backendPrefix = "onnx"; #elif defined(USE_EIGEN_BACKEND) string backendPrefix = "eigen"; #else string backendPrefix = "dummybackend"; #endif -#if !defined(USE_ONNX_BACKEND) - // In non-ONNX builds, fail fast on any ONNX-specific config instead of silently ignoring it. - { - const vector allKeys = cfg.unusedKeys(); - for(const string& key : allKeys) { - if(Global::isPrefix(Global::toLower(key),"onnx")) { - throw StringError( - "Config key '" + key + "' requires ONNX backend, but this executable is not built with USE_BACKEND=ONNX. " - "Remove onnx* settings or rebuild with -DUSE_BACKEND=ONNX." - ); - } - } - } -#endif - -#if defined(USE_ONNX_BACKEND) - // Distributed selfplay (contribute) uploads training data, which must never contain FP16-overflow - // NaN rows, so always apply the scale8 workaround regardless of onnxSkipScale8. - if(setupFor == SETUP_FOR_DISTRIBUTED && cfg.contains("onnxSkipScale8") && cfg.getBool("onnxSkipScale8")) { - cfg.overrideKey("onnxSkipScale8", "false"); - logger.write( - "WARNING: onnxSkipScale8 = true is not allowed for contribute (distributed selfplay); " - "forcing it to false so FP16-overflow NaNs cannot poison contributed training data."); - } -#endif - //Automatically flag keys that are for other backends as used so that we don't warn about unused keys //for those options for(const string& prefix: getBackendPrefixes()) { @@ -171,7 +142,7 @@ vector Setup::initializeNNEvaluators( requireExactNNLen = cfg.getBool("requireMaxBoardSize"); } - bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" || backendPrefix == "onnx" ? false : true; + bool inputsUseNHWC = backendPrefix == "opencl" || backendPrefix == "trt" || backendPrefix == "metal" ? false : true; if(cfg.contains(backendPrefix+"InputsUseNHWC"+idxStr)) inputsUseNHWC = cfg.getBool(backendPrefix+"InputsUseNHWC"+idxStr); else if(cfg.contains("inputsUseNHWC"+idxStr)) @@ -250,11 +221,10 @@ vector Setup::initializeNNEvaluators( string homeDataDirOverride = loadHomeDataDirOverride(cfg); - // Backend-specific options (e.g. openclTunerFile, cudaDisableGraphSDPA, onnxProvider, - // onnxVitisAIConfigFile) are read directly by the relevant compute backend off of cfg (see - // each backend's createComputeContext). Because they follow the backend prefix convention, - // the getBackendPrefixes() loop above already marks them used for the backends that don't - // read them, so no explicit mark-used or pass-through is needed here. + // Backend-specific options (e.g. openclTunerFile, cudaDisableGraphSDPA) are read directly by the + // relevant compute backend off of cfg (see createComputeContext). Because they follow the backend + // prefix convention, the getBackendPrefixes() loop above already marks them used for the backends + // that don't read them, so no explicit mark-used is needed here. enabled_t useFP16Mode = enabled_t::Auto; if(cfg.contains(backendPrefix+"UseFP16-"+idxStr)) @@ -678,6 +648,9 @@ vector Setup::loadParams( if(cfg.contains("fillDameBeforePass"+idxStr)) params.fillDameBeforePass = cfg.getBool("fillDameBeforePass"+idxStr); else if(cfg.contains("fillDameBeforePass")) params.fillDameBeforePass = cfg.getBool("fillDameBeforePass"); else params.fillDameBeforePass = false; + if(cfg.contains("alwaysComputePassAliveUnderSuicideRules"+idxStr)) params.alwaysComputePassAliveUnderSuicideRules = cfg.getEnabled("alwaysComputePassAliveUnderSuicideRules"+idxStr); + else if(cfg.contains("alwaysComputePassAliveUnderSuicideRules")) params.alwaysComputePassAliveUnderSuicideRules = cfg.getEnabled("alwaysComputePassAliveUnderSuicideRules"); + else params.alwaysComputePassAliveUnderSuicideRules = enabled_t::Auto; //Controlled by GTP directly, not used in any other mode params.avoidMYTDaggerHackPla = C_EMPTY; if(cfg.contains("wideRootNoise"+idxStr)) params.wideRootNoise = cfg.getDouble("wideRootNoise"+idxStr, 0.0, 5.0); diff --git a/cpp/rungpuerrortest.sh b/cpp/rungpuerrortest.sh index 9827d2a7c0..6c0e3b065e 100755 --- a/cpp/rungpuerrortest.sh +++ b/cpp/rungpuerrortest.sh @@ -174,4 +174,37 @@ MODELBASE12=$(basename "$MODEL12") -override-config "requireMaxBoardSize=False,maxBoardXSizeForNNBuffer=16,maxBoardYSizeForNNBuffer=11,maxBatchSize=15,policyOptimism=0.70${EXTRA_OVERRIDE}" \ -reference-file "$REFERENCEDIR"/"$MODELBASE11"_size9_rectbuffer.txt | tee "$RESULTSDIR"/"$MODELBASE11"_size9_rectbuffer.txt +# Larger transformer models (not publicly downloadable, so these entries are commented out; +# place the model files in models/ manually to run them). Like all reference files, the +# references are machine-local (tests/results/gpu_error_reference_files/ is not in git): +# generate them by running these same commands with an Eigen-backend build of katago, which +# writes the reference file instead of checking against it. The _quick suffix marks the +# -quick position subsample (large models are slow on CPU) - the flag must match between +# reference generation and checking. +# +# MODEL13=models/b10c384h6nbttflrs.bin.gz # v17 transformer, 6 heads, learnable rope, rmsnorm trunk tip +# MODEL14=models/b15c512h8nbttflrs-fson-silu.bin.gz # v17 transformer, 8 heads, learnable rope, silu +# MODEL15=models/b11c768h12nbt3tflrs-fson-silu.bin.gz # v17 transformer, 12 heads, learnable rope, silu, largest +# MODELBASE13=$(basename "$MODEL13") +# MODELBASE14=$(basename "$MODEL14") +# MODELBASE15=$(basename "$MODEL15") +# +# ./katago testgpuerror -model "$MODEL13" -config configs/gtp_example.cfg -boardsize 19 -quick \ +# -override-config "requireMaxBoardSize=False${EXTRA_OVERRIDE}" \ +# -reference-file "$REFERENCEDIR"/"$MODELBASE13"_size19_quick.txt | tee "$RESULTSDIR"/"$MODELBASE13"_size19_quick.txt +# ./katago testgpuerror -model "$MODEL13" -config configs/gtp_example.cfg -boardsize rectangle -quick \ +# -override-config "requireMaxBoardSize=False${EXTRA_OVERRIDE}" \ +# -reference-file "$REFERENCEDIR"/"$MODELBASE13"_sizerect_quick.txt | tee "$RESULTSDIR"/"$MODELBASE13"_sizerect_quick.txt +# ./katago testgpuerror -model "$MODEL13" -config configs/gtp_example.cfg -boardsize 9 -quick \ +# -override-config "requireMaxBoardSize=False,maxBoardXSizeForNNBuffer=16,maxBoardYSizeForNNBuffer=11,maxBatchSize=9${EXTRA_OVERRIDE}" \ +# -reference-file "$REFERENCEDIR"/"$MODELBASE13"_size9_rectbuffer_quick.txt | tee "$RESULTSDIR"/"$MODELBASE13"_size9_rectbuffer_quick.txt +# +# ./katago testgpuerror -model "$MODEL14" -config configs/gtp_example.cfg -boardsize 19 -quick \ +# -override-config "requireMaxBoardSize=False${EXTRA_OVERRIDE}" \ +# -reference-file "$REFERENCEDIR"/"$MODELBASE14"_size19_quick.txt | tee "$RESULTSDIR"/"$MODELBASE14"_size19_quick.txt +# +# ./katago testgpuerror -model "$MODEL15" -config configs/gtp_example.cfg -boardsize 19 -quick \ +# -override-config "requireMaxBoardSize=False${EXTRA_OVERRIDE}" \ +# -reference-file "$REFERENCEDIR"/"$MODELBASE15"_size19_quick.txt | tee "$RESULTSDIR"/"$MODELBASE15"_size19_quick.txt + diff --git a/cpp/runonnxtests.sh b/cpp/runonnxtests.sh deleted file mode 100644 index 2aff647334..0000000000 --- a/cpp/runonnxtests.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -eux -set -o pipefail -{ -# --------------------------------------------------------------- -# ONNX backend integration tests -# -# Exercises three levels of the inference pipeline: -# 1. runtinynntests — tiny model, full pipeline (no external model) -# 2. testgpuerror -quick — FP32 unbatched vs batched comparison -# 3. runnnevalcanarytests — sanity checks on real game positions -# --------------------------------------------------------------- - -mkdir -p tests/scratch - -# 1. Tiny NN tests — self-contained, no external model needed -echo "=== runtinynntests ===" -./katago runtinynntests tests/scratch 1.0 \ - | grep -v ': nnRandSeed0 = ' \ - | grep -v 'finishing, processed' - -# 2. GPU error test (quick) — compares unbatched vs batched inference -# For CPU ONNX provider both paths are FP32, so errors should be near zero. -# Any ownership indexing bug would surface as large ownership error. -echo "=== testgpuerror -quick ===" -./katago testgpuerror \ - -config configs/gtp_example.cfg \ - -model tests/models/g170-b6c96-s175395328-d26788732.bin.gz \ - -quick \ - -override-config "nnRandSeed=forTesting,forDeterministicTesting=true" - -# 3. NN eval canary tests — sanity checks on 5 real game positions -# Uses symmetries 0, 3, 6 (same as runsearchtests.sh) -echo "=== runnnevalcanarytests ===" -./katago runnnevalcanarytests configs/gtp_example.cfg tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz 0 \ - | grep -v ': nnRandSeed0 = ' -./katago runnnevalcanarytests configs/gtp_example.cfg tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz 3 \ - | grep -v ': nnRandSeed0 = ' -./katago runnnevalcanarytests configs/gtp_example.cfg tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz 6 \ - | grep -v ': nnRandSeed0 = ' - -echo "=== All ONNX tests passed ===" -exit 0 -} diff --git a/cpp/search/patternbonustable.cpp b/cpp/search/patternbonustable.cpp index 2db7204488..57ab67c853 100644 --- a/cpp/search/patternbonustable.cpp +++ b/cpp/search/patternbonustable.cpp @@ -118,7 +118,8 @@ void PatternBonusTable::addBonusForGameMoves(const BoardHistory& game, double bo void PatternBonusTable::addBonusForGameMoves(const BoardHistory& game, double bonus, Player onlyPla) { std::set hashesThisGame; Board board = game.initialBoard; - BoardHistory hist(board, game.initialPla, game.rules, game.initialEncorePhase); + //Replay under the same pass-alive computation mode as the history we're replaying. + BoardHistory hist(board, game.initialPla, game.rules, game.initialEncorePhase, game.alwaysComputePassAliveUnderSuicideRules); for(size_t i = 0; imutexPool->getNumMutexes()); rootHistory.clear(rootBoard,rootPla,Rules(),0); + applyPassAliveModeToRootHistory(); rootKoHashTable->recompute(rootHistory); } @@ -172,12 +173,30 @@ Player Search::getPlayoutDoublingAdvantagePla() const { return searchParams.playoutDoublingAdvantagePla == C_EMPTY ? plaThatSearchIsFor : searchParams.playoutDoublingAdvantagePla; } +bool Search::resolveAlwaysComputePassAliveUnderSuicideRules(const SearchParams& params, const NNEvaluator* nnEval) { + if(params.alwaysComputePassAliveUnderSuicideRules == enabled_t::True) + return true; + if(params.alwaysComputePassAliveUnderSuicideRules == enabled_t::False) + return false; + return nnEval != NULL && nnEval->modelPreferPassAliveUnderSuicideRules(); +} + +void Search::applyPassAliveModeToRootHistory() { + bool b = resolveAlwaysComputePassAliveUnderSuicideRules(searchParams, nnEvaluator); + if(rootHistory.alwaysComputePassAliveUnderSuicideRules != b) { + //Changing the mode changes graph hashes and in-tree adjudication, so no search state can be kept. + clearSearch(); + rootHistory.setAlwaysComputePassAliveUnderSuicideRules(b); + } +} + void Search::setPosition(Player pla, const Board& board, const BoardHistory& history) { clearSearch(); rootPla = pla; plaThatSearchIsFor = C_EMPTY; rootBoard = board; rootHistory = history; + applyPassAliveModeToRootHistory(); rootKoHashTable->recompute(rootHistory); avoidMoveUntilByLocBlack.clear(); avoidMoveUntilByLocWhite.clear(); @@ -193,6 +212,7 @@ void Search::setPlayerAndClearHistory(Player pla) { bool assumeMultipleStartingBlackMovesAreHandicap = rootHistory.assumeMultipleStartingBlackMovesAreHandicap; rootHistory.clear(rootBoard,rootPla,rules,rootHistory.encorePhase); rootHistory.setAssumeMultipleStartingBlackMovesAreHandicap(assumeMultipleStartingBlackMovesAreHandicap); + applyPassAliveModeToRootHistory(); rootKoHashTable->recompute(rootHistory); @@ -213,6 +233,7 @@ void Search::setKomiIfNew(float newKomi) { clearSearch(); rootHistory.setKomi(newKomi); } + applyPassAliveModeToRootHistory(); } void Search::setAvoidMoveUntilByLoc(const std::vector& bVec, const std::vector& wVec) { @@ -252,10 +273,14 @@ void Search::setRootSymmetryPruningOnly(const std::vector& v) { void Search::setParams(const SearchParams& params) { clearSearch(); searchParams = params; + applyPassAliveModeToRootHistory(); } void Search::setParamsNoClearing(const SearchParams& params) { searchParams = params; + //Deliberately overrides the "no clearing" if the resolved pass-alive mode actually changes, + //since in that case no search state is valid to keep. + applyPassAliveModeToRootHistory(); } void Search::setExternalPatternBonusTable(std::unique_ptr&& table) { @@ -291,6 +316,7 @@ void Search::setNNEval(NNEvaluator* nnEval) { if(humanEvaluator->getNNXLen() != nnXLen || humanEvaluator->getNNYLen() != nnYLen) throw StringError("Search::setNNEval - humanEval has different nnXLen or nnYLen"); } + applyPassAliveModeToRootHistory(); } void Search::clearSearch() { @@ -626,6 +652,13 @@ void Search::beginSearch(bool pondering) { throw StringError("Search got from NNEval nnXLen = " + Global::intToString(nnXLen) + " nnYLen = " + Global::intToString(nnYLen) + " but was asked to search board with larger x or y size"); + //Invariant: every setter that installs or rebuilds rootHistory or changes params/nnEvaluator + //re-stamps this flag, so it should always be consistent by the time a search begins. + testAssert( + rootHistory.alwaysComputePassAliveUnderSuicideRules == + resolveAlwaysComputePassAliveUnderSuicideRules(searchParams, nnEvaluator) + ); + rootBoard.checkConsistency(); numSearchesBegun++; @@ -1080,7 +1113,7 @@ void Search::computeRootValues() { bool nonPassAliveStones = false; bool safeBigTerritories = false; bool unsafeBigTerritories = false; - bool isMultiStoneSuicideLegal = rootHistory.rules.multiStoneSuicideLegal; + bool isMultiStoneSuicideLegal = rootHistory.suicideLegalForPassAlive(); rootBoard.calculateArea( rootSafeArea, nonPassAliveStones, diff --git a/cpp/search/search.h b/cpp/search/search.h index 30b3c7a0e9..b822a942f9 100644 --- a/cpp/search/search.h +++ b/cpp/search/search.h @@ -234,6 +234,9 @@ struct Search { void setRootSymmetryPruningOnly(const std::vector& rootPruneOnlySymmetries); void setParams(const SearchParams& params); void setParamsNoClearing(const SearchParams& params); //Does not clear search + //Resolve a false/auto/true alwaysComputePassAliveUnderSuicideRules setting against what a neural net + //declares that it expects. Auto resolves to the net's declaration (false if nnEval is NULL). + static bool resolveAlwaysComputePassAliveUnderSuicideRules(const SearchParams& params, const NNEvaluator* nnEval); void setExternalPatternBonusTable(std::unique_ptr&& table); void setCopyOfExternalPatternBonusTable(const std::unique_ptr& table); void setExternalEvalCache(const std::shared_ptr& cache); @@ -667,6 +670,14 @@ struct Search { // Initialization and core search logic // search.cpp //---------------------------------------------------------------------------------------- + //Enforce the invariant that rootHistory's alwaysComputePassAliveUnderSuicideRules always matches + //what searchParams and nnEvaluator resolve to, regardless of any history set into this Search. + //Clears search if this changes the flag, since all graph hashes and in-tree adjudication change. + //Called by every setter that installs or rebuilds rootHistory or changes params or nnEvaluator. + void applyPassAliveModeToRootHistory(); + //Copy of nnInputParams for querying humanEvaluator, overriding the pass-alive featurization mode + //with the human net's own resolution, which may differ from the mode the search is using. + MiscNNInputParams paramsForHumanEvaluator(const MiscNNInputParams& nnInputParams) const; void computeRootValues(); // Helper for begin search void recursivelyRecomputeStats(SearchNode& node); // Helper for search initialization void recursivelyRecordEvalCache(SearchNode& n); diff --git a/cpp/search/searchnnhelpers.cpp b/cpp/search/searchnnhelpers.cpp index 2872a27080..1d7660385e 100644 --- a/cpp/search/searchnnhelpers.cpp +++ b/cpp/search/searchnnhelpers.cpp @@ -34,6 +34,15 @@ void Search::computeRootNNEvaluation(NNResultBuf& nnResultBuf, bool includeOwner ); } +MiscNNInputParams Search::paramsForHumanEvaluator(const MiscNNInputParams& nnInputParams) const { + MiscNNInputParams humanNNInputParams = nnInputParams; + //Featurize for the human net per its own resolution (its own declaration when the param is auto), + //which may differ from the mode the search itself is using. + humanNNInputParams.passAliveSuicideRulesOverride = + resolveAlwaysComputePassAliveUnderSuicideRules(searchParams, humanEvaluator) ? 1 : 0; + return humanNNInputParams; +} + bool Search::needsHumanOutputAtRoot() const { return humanEvaluator != NULL && (searchParams.humanSLProfile.initialized || !humanEvaluator->requiresSGFMetadata()); } @@ -93,7 +102,7 @@ bool Search::initNodeNNOutput( if(needsHumanOutputInTree() || (isRoot && needsHumanOutputAtRoot())) { humanResult = humanEvaluator->averageMultipleSymmetries( thread.board, thread.history, thread.pla, &searchParams.humanSLProfile, - nnInputParams, + paramsForHumanEvaluator(nnInputParams), thread.nnResultBuf, includeOwnerMap, thread.rand, searchParams.rootNumSymmetriesToSample ); @@ -109,7 +118,7 @@ bool Search::initNodeNNOutput( if(needsHumanOutputInTree() || (isRoot && needsHumanOutputAtRoot())) { humanEvaluator->evaluate( thread.board, thread.history, thread.pla, &searchParams.humanSLProfile, - nnInputParams, + paramsForHumanEvaluator(nnInputParams), thread.nnResultBuf, skipCache, includeOwnerMap ); humanResult = new std::shared_ptr(std::move(thread.nnResultBuf.result)); diff --git a/cpp/search/searchparams.cpp b/cpp/search/searchparams.cpp index 035b62ed4b..8f02bdc7d3 100644 --- a/cpp/search/searchparams.cpp +++ b/cpp/search/searchparams.cpp @@ -71,6 +71,7 @@ SearchParams::SearchParams() wideRootNoise(0.0), enablePassingHacks(false), enableMorePassingHacks(false), + alwaysComputePassAliveUnderSuicideRules(enabled_t::Auto), playoutDoublingAdvantage(0.0), playoutDoublingAdvantagePla(C_EMPTY), avoidRepeatedPatternUtility(0.0), @@ -199,6 +200,7 @@ bool SearchParams::operator==(const SearchParams& other) const { wideRootNoise == other.wideRootNoise && enablePassingHacks == other.enablePassingHacks && enableMorePassingHacks == other.enableMorePassingHacks && + alwaysComputePassAliveUnderSuicideRules == other.alwaysComputePassAliveUnderSuicideRules && playoutDoublingAdvantage == other.playoutDoublingAdvantage && playoutDoublingAdvantagePla == other.playoutDoublingAdvantagePla && @@ -454,6 +456,7 @@ json SearchParams::changeableParametersToJson() const { ret["wideRootNoise"] = wideRootNoise; ret["enablePassingHacks"] = enablePassingHacks; ret["enableMorePassingHacks"] = enableMorePassingHacks; + ret["alwaysComputePassAliveUnderSuicideRules"] = alwaysComputePassAliveUnderSuicideRules.toString(); // Special handling in GTP ret["playoutDoublingAdvantage"] = playoutDoublingAdvantage; @@ -637,6 +640,7 @@ void SearchParams::printParams(std::ostream& out) const { PRINTPARAM(wideRootNoise); PRINTPARAM(enablePassingHacks); PRINTPARAM(enableMorePassingHacks); + out << "alwaysComputePassAliveUnderSuicideRules: " << alwaysComputePassAliveUnderSuicideRules.toString() << std::endl; PRINTPARAM(playoutDoublingAdvantage); std::cout << "playoutDoublingAdvantagePla" << ": " << (int)playoutDoublingAdvantagePla << std::endl; diff --git a/cpp/search/searchparams.h b/cpp/search/searchparams.h index 2a51687977..309c0500ed 100644 --- a/cpp/search/searchparams.h +++ b/cpp/search/searchparams.h @@ -2,6 +2,7 @@ #define SEARCH_SEARCHPARAMS_H_ #include "../core/global.h" +#include "../core/commontypes.h" #include "../game/board.h" #include "../neuralnet/sgfmetadata.h" @@ -91,6 +92,10 @@ struct SearchParams { double wideRootNoise; //Explore at the root more widely bool enablePassingHacks; //Enable some hacks that mitigate rare instances when passing messes up deeper searches. bool enableMorePassingHacks; //Always weightless search passing and non passing moves when a pass would end the phase after a few visits. + //Whether to compute pass-alive areas as if multi-stone suicide were always legal regardless of the actual suicide + //rule, for game end/scoring within the search tree and for nn input featurization. + //Auto = do so if and only if the neural net declares that it expects this. See BoardHistory::alwaysComputePassAliveUnderSuicideRules. + enabled_t alwaysComputePassAliveUnderSuicideRules; double playoutDoublingAdvantage; //Play as if we have this many doublings of playouts vs the opponent Player playoutDoublingAdvantagePla; //Negate playoutDoublingAdvantage when making a move for the opponent of this player. If empty, opponent of the root player. diff --git a/cpp/tests/gtp/passalivemode.txt b/cpp/tests/gtp/passalivemode.txt new file mode 100644 index 0000000000..e82ca00df6 --- /dev/null +++ b/cpp/tests/gtp/passalivemode.txt @@ -0,0 +1,25 @@ +boardsize 4 5 +kata-set-rules {"ko":"SIMPLE","scoring":"AREA","tax":"NONE","suicide":false,"hasButton":false,"friendlyPassOk":false,"whiteHandicapBonus":"0"} +komi 0 +set_position b d5 b a4 b b4 w a3 b b3 b c3 b d3 w a2 w b2 b c2 b b1 b d1 +showboard +kata-get-param alwaysComputePassAliveUnderSuicideRules +play w pass +genmove_debug b +undo +kata-set-param alwaysComputePassAliveUnderSuicideRules true +kata-get-param alwaysComputePassAliveUnderSuicideRules +genmove_debug b +undo +kata-set-param alwaysComputePassAliveUnderSuicideRules auto +play b pass +final_score +final_status_list dead +kata-set-param alwaysComputePassAliveUnderSuicideRules true +final_score +final_status_list dead +kata-set-param alwaysComputePassAliveUnderSuicideRules false +final_score +kata-set-param alwaysComputePassAliveUnderSuicideRules auto +final_score +showboard diff --git a/cpp/tests/results/analysis/badoverride.txt.log b/cpp/tests/results/analysis/badoverride.txt.log index 53463acd51..f38935618a 100644 --- a/cpp/tests/results/analysis/badoverride.txt.log +++ b/cpp/tests/results/analysis/badoverride.txt.log @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/badoverride.txt.stderr b/cpp/tests/results/analysis/badoverride.txt.stderr index 53463acd51..f38935618a 100644 --- a/cpp/tests/results/analysis/badoverride.txt.stderr +++ b/cpp/tests/results/analysis/badoverride.txt.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/basic.txt.log b/cpp/tests/results/analysis/basic.txt.log index f354bfbd87..a73bb204e7 100644 --- a/cpp/tests/results/analysis/basic.txt.log +++ b/cpp/tests/results/analysis/basic.txt.log @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/basic.txt.stderr b/cpp/tests/results/analysis/basic.txt.stderr index f354bfbd87..a73bb204e7 100644 --- a/cpp/tests/results/analysis/basic.txt.stderr +++ b/cpp/tests/results/analysis/basic.txt.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/basic_sidetomove.stderr b/cpp/tests/results/analysis/basic_sidetomove.stderr index 6428e73a0b..9aa351faf5 100644 --- a/cpp/tests/results/analysis/basic_sidetomove.stderr +++ b/cpp/tests/results/analysis/basic_sidetomove.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/basic_sidetomove.txt.log b/cpp/tests/results/analysis/basic_sidetomove.txt.log index 6428e73a0b..9aa351faf5 100644 --- a/cpp/tests/results/analysis/basic_sidetomove.txt.log +++ b/cpp/tests/results/analysis/basic_sidetomove.txt.log @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/clear_cache.txt.stderr b/cpp/tests/results/analysis/clear_cache.txt.stderr index 6f603ee19b..a9da707d67 100644 --- a/cpp/tests/results/analysis/clear_cache.txt.stderr +++ b/cpp/tests/results/analysis/clear_cache.txt.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/eval_cache.txt.log b/cpp/tests/results/analysis/eval_cache.txt.log index 4ff937b9ff..7dd8fafb23 100644 --- a/cpp/tests/results/analysis/eval_cache.txt.log +++ b/cpp/tests/results/analysis/eval_cache.txt.log @@ -24,11 +24,11 @@ useEvalCache = true useGraphSearch = true : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b10c128-s1141046784-d204142634 (convnet, 2994503 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/humansl_sidetomove.stderr b/cpp/tests/results/analysis/humansl_sidetomove.stderr index fc87763d9d..cb29f5e134 100644 --- a/cpp/tests/results/analysis/humansl_sidetomove.stderr +++ b/cpp/tests/results/analysis/humansl_sidetomove.stderr @@ -23,17 +23,17 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = models/b18c384nbt-humanv0.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 15 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: b18c384nbt-humanv0 (nbt convnet, 26740121 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/pvvisits.txt.log b/cpp/tests/results/analysis/pvvisits.txt.log index 0a401538e0..821a336465 100644 --- a/cpp/tests/results/analysis/pvvisits.txt.log +++ b/cpp/tests/results/analysis/pvvisits.txt.log @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/pvvisits.txt.stderr b/cpp/tests/results/analysis/pvvisits.txt.stderr index 0a401538e0..821a336465 100644 --- a/cpp/tests/results/analysis/pvvisits.txt.stderr +++ b/cpp/tests/results/analysis/pvvisits.txt.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/pvvisits_nograph.stderr b/cpp/tests/results/analysis/pvvisits_nograph.stderr index b696c6e6e4..61a314baa4 100644 --- a/cpp/tests/results/analysis/pvvisits_nograph.stderr +++ b/cpp/tests/results/analysis/pvvisits_nograph.stderr @@ -22,11 +22,11 @@ trtUseFP16 = false useGraphSearch = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/pvvisits_nograph.txt.log b/cpp/tests/results/analysis/pvvisits_nograph.txt.log index b696c6e6e4..61a314baa4 100644 --- a/cpp/tests/results/analysis/pvvisits_nograph.txt.log +++ b/cpp/tests/results/analysis/pvvisits_nograph.txt.log @@ -22,11 +22,11 @@ trtUseFP16 = false useGraphSearch = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/symmetry.txt.log b/cpp/tests/results/analysis/symmetry.txt.log index 9ddc41c1cd..744c15d913 100644 --- a/cpp/tests/results/analysis/symmetry.txt.log +++ b/cpp/tests/results/analysis/symmetry.txt.log @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/symmetry.txt.stderr b/cpp/tests/results/analysis/symmetry.txt.stderr index 9ddc41c1cd..744c15d913 100644 --- a/cpp/tests/results/analysis/symmetry.txt.stderr +++ b/cpp/tests/results/analysis/symmetry.txt.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = false trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/symmetry_with_pruning.stderr b/cpp/tests/results/analysis/symmetry_with_pruning.stderr index 7efe9fd203..80e5da40e0 100644 --- a/cpp/tests/results/analysis/symmetry_with_pruning.stderr +++ b/cpp/tests/results/analysis/symmetry_with_pruning.stderr @@ -22,11 +22,11 @@ rootSymmetryPruning = true trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/analysis/symmetry_with_pruning.txt.log b/cpp/tests/results/analysis/symmetry_with_pruning.txt.log index 7efe9fd203..80e5da40e0 100644 --- a/cpp/tests/results/analysis/symmetry_with_pruning.txt.log +++ b/cpp/tests/results/analysis/symmetry_with_pruning.txt.log @@ -22,11 +22,11 @@ rootSymmetryPruning = true trtUseFP16 = false : Analysis Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : nnRandSeed0 = analysisTest : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded config configs/analysis_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/avoidcorners.log b/cpp/tests/results/gtp/avoidcorners.log index 9204904006..28240c6c7e 100644 --- a/cpp/tests/results/gtp/avoidcorners.log +++ b/cpp/tests/results/gtp/avoidcorners.log @@ -37,14 +37,14 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : Added 48 shapes to penalize repeats for bot 0 from tests/data/cornermoves.sgf : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/avoidcorners.stderr b/cpp/tests/results/gtp/avoidcorners.stderr index f20b8b1766..248529031d 100644 --- a/cpp/tests/results/gtp/avoidcorners.stderr +++ b/cpp/tests/results/gtp/avoidcorners.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/basic.txt.log b/cpp/tests/results/gtp/basic.txt.log index fe733acf74..7ccea526f2 100644 --- a/cpp/tests/results/gtp/basic.txt.log +++ b/cpp/tests/results/gtp/basic.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -252,7 +252,7 @@ Q16 : T -2.84c W -0.88c S -0.18c ( -0.4 L -0.5) LCB -151.93c P 5.31% WF 2 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 9 * 9 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 9 nnYLen 9 diff --git a/cpp/tests/results/gtp/basic.txt.stderr b/cpp/tests/results/gtp/basic.txt.stderr index a153b9d2db..15969dda12 100644 --- a/cpp/tests/results/gtp/basic.txt.stderr +++ b/cpp/tests/results/gtp/basic.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/defaultkomibutton.log b/cpp/tests/results/gtp/defaultkomibutton.log index 5b458330b3..28bab738c7 100644 --- a/cpp/tests/results/gtp/defaultkomibutton.log +++ b/cpp/tests/results/gtp/defaultkomibutton.log @@ -34,13 +34,13 @@ taxRule = NONE trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using koPOSITIONALscoreAREAtaxNONEsui0button1 rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/defaultkomibutton.stderr b/cpp/tests/results/gtp/defaultkomibutton.stderr index 67b0011cd9..ffd19695dc 100644 --- a/cpp/tests/results/gtp/defaultkomibutton.stderr +++ b/cpp/tests/results/gtp/defaultkomibutton.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using koPOSITIONALscoreAREAtaxNONEsui0button1 rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/defaultkomiterr.log b/cpp/tests/results/gtp/defaultkomiterr.log index d7cba8a210..687a9d1442 100644 --- a/cpp/tests/results/gtp/defaultkomiterr.log +++ b/cpp/tests/results/gtp/defaultkomiterr.log @@ -34,13 +34,13 @@ taxRule = NONE trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using koPOSITIONALscoreTERRITORYtaxNONEsui0 rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/defaultkomiterr.stderr b/cpp/tests/results/gtp/defaultkomiterr.stderr index e2e5770994..8fc86e4629 100644 --- a/cpp/tests/results/gtp/defaultkomiterr.stderr +++ b/cpp/tests/results/gtp/defaultkomiterr.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using koPOSITIONALscoreTERRITORYtaxNONEsui0 rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/defaultkomitt.log b/cpp/tests/results/gtp/defaultkomitt.log index a4881b9699..41d901f654 100644 --- a/cpp/tests/results/gtp/defaultkomitt.log +++ b/cpp/tests/results/gtp/defaultkomitt.log @@ -34,13 +34,13 @@ taxRule = NONE trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using koPOSITIONALscoreAREAtaxNONEsui0 rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/defaultkomitt.stderr b/cpp/tests/results/gtp/defaultkomitt.stderr index 26aef0fa26..2dc301a387 100644 --- a/cpp/tests/results/gtp/defaultkomitt.stderr +++ b/cpp/tests/results/gtp/defaultkomitt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using koPOSITIONALscoreAREAtaxNONEsui0 rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/ending.txt.log b/cpp/tests/results/gtp/ending.txt.log index 3a8c0b22f1..5fad8bc3ce 100644 --- a/cpp/tests/results/gtp/ending.txt.log +++ b/cpp/tests/results/gtp/ending.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -66,7 +66,7 @@ trtUseFP16 = false : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 7 * 7 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 7 nnYLen 7 diff --git a/cpp/tests/results/gtp/ending.txt.stderr b/cpp/tests/results/gtp/ending.txt.stderr index 5d192718aa..bc64645f32 100644 --- a/cpp/tests/results/gtp/ending.txt.stderr +++ b/cpp/tests/results/gtp/ending.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/forcedkomi.log b/cpp/tests/results/gtp/forcedkomi.log index ab0d6939f0..ecf727e0f0 100644 --- a/cpp/tests/results/gtp/forcedkomi.log +++ b/cpp/tests/results/gtp/forcedkomi.log @@ -35,13 +35,13 @@ taxRule = NONE trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using koPOSITIONALscoreAREAtaxNONEsui0button1 rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/forcedkomi.stderr b/cpp/tests/results/gtp/forcedkomi.stderr index 340d9a271c..9270b5bfdc 100644 --- a/cpp/tests/results/gtp/forcedkomi.stderr +++ b/cpp/tests/results/gtp/forcedkomi.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using koPOSITIONALscoreAREAtaxNONEsui0button1 rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/genmoveanalyze.log b/cpp/tests/results/gtp/genmoveanalyze.log index d1f45111f6..75dfba1994 100644 --- a/cpp/tests/results/gtp/genmoveanalyze.log +++ b/cpp/tests/results/gtp/genmoveanalyze.log @@ -1,11 +1,11 @@ : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = models/b18c384nbt-uec.bin.gz useFP16 false : Initializing neural net buffer to be size 9 * 9 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 11 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: b18c384nbt-uec-20221121b (nbt convnet, 26326793 params) : Loaded neural net with nnXLen 9 nnYLen 9 diff --git a/cpp/tests/results/gtp/genmoveanalyze.stderr b/cpp/tests/results/gtp/genmoveanalyze.stderr index b982232f80..536344b101 100644 --- a/cpp/tests/results/gtp/genmoveanalyze.stderr +++ b/cpp/tests/results/gtp/genmoveanalyze.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 9 boardYSize 9 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/handicap.txt.log b/cpp/tests/results/gtp/handicap.txt.log index 01c361f9ab..0a3a6ac204 100644 --- a/cpp/tests/results/gtp/handicap.txt.log +++ b/cpp/tests/results/gtp/handicap.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -420,7 +420,7 @@ R3 : T 40.99c W 42.55c S 2.71c (+12.6 L +12.8) LCB -108.86c P 6.96% WF 2 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 13 * 13 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 13 nnYLen 13 @@ -574,7 +574,7 @@ C11 : T 58.46c W 56.58c S 1.89c ( +8.0 L +8.4) LCB -291.54c P 2.36% WF 1 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 2 * 2 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 2 nnYLen 2 diff --git a/cpp/tests/results/gtp/handicap.txt.stderr b/cpp/tests/results/gtp/handicap.txt.stderr index 7e83f25a0a..95edc544b4 100644 --- a/cpp/tests/results/gtp/handicap.txt.stderr +++ b/cpp/tests/results/gtp/handicap.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/humansl.log b/cpp/tests/results/gtp/humansl.log index 1b784fc188..abcbaffcf6 100644 --- a/cpp/tests/results/gtp/humansl.log +++ b/cpp/tests/results/gtp/humansl.log @@ -1,18 +1,18 @@ : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using Japanese rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = models/b18c384nbt-uec.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 11 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: b18c384nbt-uec-20221121b (nbt convnet, 26326793 params) : Loaded neural net with nnXLen 19 nnYLen 19 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = models/b18c384nbt-humanv0.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 15 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: b18c384nbt-humanv0 (nbt convnet, 26740121 params) : Loaded human SL net with nnXLen 19 nnYLen 19 @@ -472,7 +472,7 @@ whiteOwnership 0.1769083 0.1553447 0.2164454 0.2194278 0.1888992 0.0994612 0.0712061 0.0341133 0.0123989 -0.0080449 -0.0024268 0.0299050 0.0140132 -0.0804372 -0.1732652 -0.3272057 -0.4675705 -0.5340660 -0.5650671 0.2079775 0.1772159 0.1668886 0.1635177 0.1686190 0.1211975 0.0785596 0.0311163 -0.0007647 -0.0073765 0.0140151 0.0324351 0.0129053 -0.0684741 -0.1544852 -0.3148718 -0.4033215 -0.4870633 -0.5389509 : Controller: kata-get-params -: = {"allowResignation":"true","analysisIgnorePreRootHistory":"false","analysisWideRootNoise":"0.04","antiMirror":"false","chosenMovePrune":0.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.7,"chosenMoveTemperatureEarly":0.85,"chosenMoveTemperatureHalflife":80.0,"chosenMoveTemperatureOnlyBelowProb":0.01,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"10","delayMoveScale":"2","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.0,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":true,"humanSLChosenMovePiklLambda":100000000.0,"humanSLChosenMoveProp":1.0,"humanSLCpuctExploration":0.5,"humanSLCpuctPermanent":0.2,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"preaz_12k","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":1125899906842624,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":1e+20,"maxVisits":40,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":0.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":2,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":true,"searchFactorAfterOnePass":1.0,"searchFactorAfterTwoPass":1.0,"staticScoreUtilityFactor":0.3,"subtreeValueBiasFactor":0.0,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":false,"useNoisePruning":false,"useNonBuggyLcb":true,"useUncertainty":false,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} +: = {"allowResignation":"true","alwaysComputePassAliveUnderSuicideRules":"auto","analysisIgnorePreRootHistory":"false","analysisWideRootNoise":"0.04","antiMirror":"false","chosenMovePrune":0.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.7,"chosenMoveTemperatureEarly":0.85,"chosenMoveTemperatureHalflife":80.0,"chosenMoveTemperatureOnlyBelowProb":0.01,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"10","delayMoveScale":"2","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.0,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":true,"humanSLChosenMovePiklLambda":100000000.0,"humanSLChosenMoveProp":1.0,"humanSLCpuctExploration":0.5,"humanSLCpuctPermanent":0.2,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"preaz_12k","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":1125899906842624,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":1e+20,"maxVisits":40,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":0.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":2,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":true,"searchFactorAfterOnePass":1.0,"searchFactorAfterTwoPass":1.0,"staticScoreUtilityFactor":0.3,"subtreeValueBiasFactor":0.0,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":false,"useNoisePruning":false,"useNonBuggyLcb":true,"useUncertainty":false,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} : Controller: kata-get-param humanSLProfile : = preaz_12k : Controller: kata-set-param humanSLProfile preaz_5d diff --git a/cpp/tests/results/gtp/humansl.stderr b/cpp/tests/results/gtp/humansl.stderr index d0ba44344d..92fde7eb2f 100644 --- a/cpp/tests/results/gtp/humansl.stderr +++ b/cpp/tests/results/gtp/humansl.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using Japanese rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_human5k_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/humansl.stdout b/cpp/tests/results/gtp/humansl.stdout index f2db94f730..2df4083551 100644 --- a/cpp/tests/results/gtp/humansl.stdout +++ b/cpp/tests/results/gtp/humansl.stdout @@ -68,7 +68,7 @@ whiteOwnership 0.1769083 0.1553447 0.2164454 0.2194278 0.1888992 0.0994612 0.0712061 0.0341133 0.0123989 -0.0080449 -0.0024268 0.0299050 0.0140132 -0.0804372 -0.1732652 -0.3272057 -0.4675705 -0.5340660 -0.5650671 0.2079775 0.1772159 0.1668886 0.1635177 0.1686190 0.1211975 0.0785596 0.0311163 -0.0007647 -0.0073765 0.0140151 0.0324351 0.0129053 -0.0684741 -0.1544852 -0.3148718 -0.4033215 -0.4870633 -0.5389509 -= {"allowResignation":"true","analysisIgnorePreRootHistory":"false","analysisWideRootNoise":"0.04","antiMirror":"false","chosenMovePrune":0.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.7,"chosenMoveTemperatureEarly":0.85,"chosenMoveTemperatureHalflife":80.0,"chosenMoveTemperatureOnlyBelowProb":0.01,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"10","delayMoveScale":"2","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.0,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":true,"humanSLChosenMovePiklLambda":100000000.0,"humanSLChosenMoveProp":1.0,"humanSLCpuctExploration":0.5,"humanSLCpuctPermanent":0.2,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"preaz_12k","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":1125899906842624,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":1e+20,"maxVisits":40,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":0.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":2,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":true,"searchFactorAfterOnePass":1.0,"searchFactorAfterTwoPass":1.0,"staticScoreUtilityFactor":0.3,"subtreeValueBiasFactor":0.0,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":false,"useNoisePruning":false,"useNonBuggyLcb":true,"useUncertainty":false,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} += {"allowResignation":"true","alwaysComputePassAliveUnderSuicideRules":"auto","analysisIgnorePreRootHistory":"false","analysisWideRootNoise":"0.04","antiMirror":"false","chosenMovePrune":0.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.7,"chosenMoveTemperatureEarly":0.85,"chosenMoveTemperatureHalflife":80.0,"chosenMoveTemperatureOnlyBelowProb":0.01,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"10","delayMoveScale":"2","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.0,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":true,"humanSLChosenMovePiklLambda":100000000.0,"humanSLChosenMoveProp":1.0,"humanSLCpuctExploration":0.5,"humanSLCpuctPermanent":0.2,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"preaz_12k","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":1125899906842624,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":1e+20,"maxVisits":40,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":0.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":2,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":true,"searchFactorAfterOnePass":1.0,"searchFactorAfterTwoPass":1.0,"staticScoreUtilityFactor":0.3,"subtreeValueBiasFactor":0.0,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":false,"useNoisePruning":false,"useNonBuggyLcb":true,"useUncertainty":false,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} = preaz_12k diff --git a/cpp/tests/results/gtp/humansl2.stderr b/cpp/tests/results/gtp/humansl2.stderr index 1808dde0d2..14a7ea977a 100644 --- a/cpp/tests/results/gtp/humansl2.stderr +++ b/cpp/tests/results/gtp/humansl2.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using Japanese rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_human5k_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/misc.txt.log b/cpp/tests/results/gtp/misc.txt.log index ca6394475f..a814e21d79 100644 --- a/cpp/tests/results/gtp/misc.txt.log +++ b/cpp/tests/results/gtp/misc.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -61,7 +61,7 @@ trtUseFP16 = false : Model name: g170-b6c96-s175395328-d26788732 : GTP ready, beginning main protocol loop : Controller: kata-list-params -: = analysisWideRootNoise analysisIgnorePreRootHistory genmoveAntiMirror antiMirror humanSLProfile allowResignation ponderingEnabled delayMoveScale delayMoveMax chosenMovePrune chosenMoveSubtract chosenMoveTemperature chosenMoveTemperatureEarly chosenMoveTemperatureHalflife chosenMoveTemperatureOnlyBelowProb conservativePass cpuctExploration cpuctExplorationBase cpuctExplorationLog cpuctUtilityStdevPrior cpuctUtilityStdevPriorWeight cpuctUtilityStdevScale drawEquivalentWinsForWhite dynamicScoreCenterScale dynamicScoreCenterZeroWeight dynamicScoreUtilityFactor enableMorePassingHacks enablePassingHacks endgameTurnTimeDecay fillDameBeforePass fpuLossProp fpuParentWeight fpuParentWeightByVisitedPolicy fpuParentWeightByVisitedPolicyPow fpuReductionMax futileVisitsThreshold graphSearchCatchUpLeakProb graphSearchRepBound humanSLChosenMoveIgnorePass humanSLChosenMovePiklLambda humanSLChosenMoveProp humanSLCpuctExploration humanSLCpuctPermanent humanSLOppExploreProbWeightful humanSLOppExploreProbWeightless humanSLPlaExploreProbWeightful humanSLPlaExploreProbWeightless humanSLRootExploreProbWeightful humanSLRootExploreProbWeightless ignoreAllHistory ignorePreRootHistory lagBuffer lcbStdevs maxPlayouts maxPlayoutsPondering maxTime maxTimePondering maxVisits maxVisitsPondering midgameTimeFactor midgameTurnPeakTime minPlayoutsPerThread minVisitPropForLCB nnPolicyTemperature noResultUtilityForWhite noisePruneUtilityScale noisePruningCap numSearchThreads numVirtualLossesPerThread obviousMovesPolicyEntropyTolerance obviousMovesPolicySurpriseTolerance obviousMovesTimeFactor overallocateTimeFactor playoutDoublingAdvantage playoutDoublingAdvantagePla policyOptimism rootDesiredPerChildVisitsCoeff rootDirichletNoiseTotalConcentration rootDirichletNoiseWeight rootEndingBonusPoints rootFpuLossProp rootFpuReductionMax rootNoiseEnabled rootNumSymmetriesToSample rootPolicyOptimism rootPolicyTemperature rootPolicyTemperatureEarly rootPruneUselessMoves rootSymmetryPruning searchFactorAfterOnePass searchFactorAfterTwoPass staticScoreUtilityFactor subtreeValueBiasFactor subtreeValueBiasFreeProp subtreeValueBiasTableNumShards subtreeValueBiasWeightExponent treeReuseCarryOverTimeFactor uncertaintyCoeff uncertaintyExponent uncertaintyMaxWeight useGraphSearch useLcbForSelection useNoisePruning useNonBuggyLcb useUncertainty valueWeightExponent wideRootNoise winLossUtilityFactor +: = analysisWideRootNoise analysisIgnorePreRootHistory genmoveAntiMirror antiMirror humanSLProfile allowResignation ponderingEnabled delayMoveScale delayMoveMax alwaysComputePassAliveUnderSuicideRules chosenMovePrune chosenMoveSubtract chosenMoveTemperature chosenMoveTemperatureEarly chosenMoveTemperatureHalflife chosenMoveTemperatureOnlyBelowProb conservativePass cpuctExploration cpuctExplorationBase cpuctExplorationLog cpuctUtilityStdevPrior cpuctUtilityStdevPriorWeight cpuctUtilityStdevScale drawEquivalentWinsForWhite dynamicScoreCenterScale dynamicScoreCenterZeroWeight dynamicScoreUtilityFactor enableMorePassingHacks enablePassingHacks endgameTurnTimeDecay fillDameBeforePass fpuLossProp fpuParentWeight fpuParentWeightByVisitedPolicy fpuParentWeightByVisitedPolicyPow fpuReductionMax futileVisitsThreshold graphSearchCatchUpLeakProb graphSearchRepBound humanSLChosenMoveIgnorePass humanSLChosenMovePiklLambda humanSLChosenMoveProp humanSLCpuctExploration humanSLCpuctPermanent humanSLOppExploreProbWeightful humanSLOppExploreProbWeightless humanSLPlaExploreProbWeightful humanSLPlaExploreProbWeightless humanSLRootExploreProbWeightful humanSLRootExploreProbWeightless ignoreAllHistory ignorePreRootHistory lagBuffer lcbStdevs maxPlayouts maxPlayoutsPondering maxTime maxTimePondering maxVisits maxVisitsPondering midgameTimeFactor midgameTurnPeakTime minPlayoutsPerThread minVisitPropForLCB nnPolicyTemperature noResultUtilityForWhite noisePruneUtilityScale noisePruningCap numSearchThreads numVirtualLossesPerThread obviousMovesPolicyEntropyTolerance obviousMovesPolicySurpriseTolerance obviousMovesTimeFactor overallocateTimeFactor playoutDoublingAdvantage playoutDoublingAdvantagePla policyOptimism rootDesiredPerChildVisitsCoeff rootDirichletNoiseTotalConcentration rootDirichletNoiseWeight rootEndingBonusPoints rootFpuLossProp rootFpuReductionMax rootNoiseEnabled rootNumSymmetriesToSample rootPolicyOptimism rootPolicyTemperature rootPolicyTemperatureEarly rootPruneUselessMoves rootSymmetryPruning searchFactorAfterOnePass searchFactorAfterTwoPass staticScoreUtilityFactor subtreeValueBiasFactor subtreeValueBiasFreeProp subtreeValueBiasTableNumShards subtreeValueBiasWeightExponent treeReuseCarryOverTimeFactor uncertaintyCoeff uncertaintyExponent uncertaintyMaxWeight useGraphSearch useLcbForSelection useNoisePruning useNonBuggyLcb useUncertainty valueWeightExponent wideRootNoise winLossUtilityFactor : Controller: komi 50.5 : = : Controller: get_komi @@ -71,7 +71,7 @@ trtUseFP16 = false : Controller: get_komi : = -23 : Controller: version -: = 1.16.5+g170-b6c96-s175M +: = 1.17.2+g170-b6c96-s175M : Controller: kata-get-models : = [{"internalName":"g170-b6c96-s175395328-d26788732","maxBatchSize":8,"name":"tests/models/g170-b6c96-s175395328-d26788732.bin.gz","usesHumanSLProfile":false,"usingFP16":"false","version":8}] : Controller: kata-set-param humanSLProfile rank_10k diff --git a/cpp/tests/results/gtp/misc.txt.stderr b/cpp/tests/results/gtp/misc.txt.stderr index 9e46544369..1f8d6d04c0 100644 --- a/cpp/tests/results/gtp/misc.txt.stderr +++ b/cpp/tests/results/gtp/misc.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/misc.txt.stdout b/cpp/tests/results/gtp/misc.txt.stdout index 54b571add8..6bb906ada1 100644 --- a/cpp/tests/results/gtp/misc.txt.stdout +++ b/cpp/tests/results/gtp/misc.txt.stdout @@ -1,4 +1,4 @@ -= analysisWideRootNoise analysisIgnorePreRootHistory genmoveAntiMirror antiMirror humanSLProfile allowResignation ponderingEnabled delayMoveScale delayMoveMax chosenMovePrune chosenMoveSubtract chosenMoveTemperature chosenMoveTemperatureEarly chosenMoveTemperatureHalflife chosenMoveTemperatureOnlyBelowProb conservativePass cpuctExploration cpuctExplorationBase cpuctExplorationLog cpuctUtilityStdevPrior cpuctUtilityStdevPriorWeight cpuctUtilityStdevScale drawEquivalentWinsForWhite dynamicScoreCenterScale dynamicScoreCenterZeroWeight dynamicScoreUtilityFactor enableMorePassingHacks enablePassingHacks endgameTurnTimeDecay fillDameBeforePass fpuLossProp fpuParentWeight fpuParentWeightByVisitedPolicy fpuParentWeightByVisitedPolicyPow fpuReductionMax futileVisitsThreshold graphSearchCatchUpLeakProb graphSearchRepBound humanSLChosenMoveIgnorePass humanSLChosenMovePiklLambda humanSLChosenMoveProp humanSLCpuctExploration humanSLCpuctPermanent humanSLOppExploreProbWeightful humanSLOppExploreProbWeightless humanSLPlaExploreProbWeightful humanSLPlaExploreProbWeightless humanSLRootExploreProbWeightful humanSLRootExploreProbWeightless ignoreAllHistory ignorePreRootHistory lagBuffer lcbStdevs maxPlayouts maxPlayoutsPondering maxTime maxTimePondering maxVisits maxVisitsPondering midgameTimeFactor midgameTurnPeakTime minPlayoutsPerThread minVisitPropForLCB nnPolicyTemperature noResultUtilityForWhite noisePruneUtilityScale noisePruningCap numSearchThreads numVirtualLossesPerThread obviousMovesPolicyEntropyTolerance obviousMovesPolicySurpriseTolerance obviousMovesTimeFactor overallocateTimeFactor playoutDoublingAdvantage playoutDoublingAdvantagePla policyOptimism rootDesiredPerChildVisitsCoeff rootDirichletNoiseTotalConcentration rootDirichletNoiseWeight rootEndingBonusPoints rootFpuLossProp rootFpuReductionMax rootNoiseEnabled rootNumSymmetriesToSample rootPolicyOptimism rootPolicyTemperature rootPolicyTemperatureEarly rootPruneUselessMoves rootSymmetryPruning searchFactorAfterOnePass searchFactorAfterTwoPass staticScoreUtilityFactor subtreeValueBiasFactor subtreeValueBiasFreeProp subtreeValueBiasTableNumShards subtreeValueBiasWeightExponent treeReuseCarryOverTimeFactor uncertaintyCoeff uncertaintyExponent uncertaintyMaxWeight useGraphSearch useLcbForSelection useNoisePruning useNonBuggyLcb useUncertainty valueWeightExponent wideRootNoise winLossUtilityFactor += analysisWideRootNoise analysisIgnorePreRootHistory genmoveAntiMirror antiMirror humanSLProfile allowResignation ponderingEnabled delayMoveScale delayMoveMax alwaysComputePassAliveUnderSuicideRules chosenMovePrune chosenMoveSubtract chosenMoveTemperature chosenMoveTemperatureEarly chosenMoveTemperatureHalflife chosenMoveTemperatureOnlyBelowProb conservativePass cpuctExploration cpuctExplorationBase cpuctExplorationLog cpuctUtilityStdevPrior cpuctUtilityStdevPriorWeight cpuctUtilityStdevScale drawEquivalentWinsForWhite dynamicScoreCenterScale dynamicScoreCenterZeroWeight dynamicScoreUtilityFactor enableMorePassingHacks enablePassingHacks endgameTurnTimeDecay fillDameBeforePass fpuLossProp fpuParentWeight fpuParentWeightByVisitedPolicy fpuParentWeightByVisitedPolicyPow fpuReductionMax futileVisitsThreshold graphSearchCatchUpLeakProb graphSearchRepBound humanSLChosenMoveIgnorePass humanSLChosenMovePiklLambda humanSLChosenMoveProp humanSLCpuctExploration humanSLCpuctPermanent humanSLOppExploreProbWeightful humanSLOppExploreProbWeightless humanSLPlaExploreProbWeightful humanSLPlaExploreProbWeightless humanSLRootExploreProbWeightful humanSLRootExploreProbWeightless ignoreAllHistory ignorePreRootHistory lagBuffer lcbStdevs maxPlayouts maxPlayoutsPondering maxTime maxTimePondering maxVisits maxVisitsPondering midgameTimeFactor midgameTurnPeakTime minPlayoutsPerThread minVisitPropForLCB nnPolicyTemperature noResultUtilityForWhite noisePruneUtilityScale noisePruningCap numSearchThreads numVirtualLossesPerThread obviousMovesPolicyEntropyTolerance obviousMovesPolicySurpriseTolerance obviousMovesTimeFactor overallocateTimeFactor playoutDoublingAdvantage playoutDoublingAdvantagePla policyOptimism rootDesiredPerChildVisitsCoeff rootDirichletNoiseTotalConcentration rootDirichletNoiseWeight rootEndingBonusPoints rootFpuLossProp rootFpuReductionMax rootNoiseEnabled rootNumSymmetriesToSample rootPolicyOptimism rootPolicyTemperature rootPolicyTemperatureEarly rootPruneUselessMoves rootSymmetryPruning searchFactorAfterOnePass searchFactorAfterTwoPass staticScoreUtilityFactor subtreeValueBiasFactor subtreeValueBiasFreeProp subtreeValueBiasTableNumShards subtreeValueBiasWeightExponent treeReuseCarryOverTimeFactor uncertaintyCoeff uncertaintyExponent uncertaintyMaxWeight useGraphSearch useLcbForSelection useNoisePruning useNonBuggyLcb useUncertainty valueWeightExponent wideRootNoise winLossUtilityFactor = @@ -8,7 +8,7 @@ = -23 -= 1.16.5+g170-b6c96-s175M += 1.17.2+g170-b6c96-s175M = [{"internalName":"g170-b6c96-s175395328-d26788732","maxBatchSize":8,"name":"tests/models/g170-b6c96-s175395328-d26788732.bin.gz","usesHumanSLProfile":false,"usingFP16":"false","version":8}] diff --git a/cpp/tests/results/gtp/nologconfig.log b/cpp/tests/results/gtp/nologconfig.log index ece0053a06..e36c9def44 100644 --- a/cpp/tests/results/gtp/nologconfig.log +++ b/cpp/tests/results/gtp/nologconfig.log @@ -1,11 +1,11 @@ : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/nologconfig.stderr b/cpp/tests/results/gtp/nologconfig.stderr index 9e05e34801..be218ac2b1 100644 --- a/cpp/tests/results/gtp/nologconfig.stderr +++ b/cpp/tests/results/gtp/nologconfig.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/passalivemode.txt.stderr b/cpp/tests/results/gtp/passalivemode.txt.stderr new file mode 100644 index 0000000000..af56fd4472 --- /dev/null +++ b/cpp/tests/results/gtp/passalivemode.txt.stderr @@ -0,0 +1,63 @@ +KataGo v1.17.2 +Using TrompTaylor rules initially, unless GTP/GUI overrides this +Initializing board with boardXSize 19 boardYSize 19 +Loaded config configs/gtp_example.cfg and/or command-line and query overrides +Loaded model tests/models/g170-b6c96-s175395328-d26788732.bin.gz +Model name: g170-b6c96-s175395328-d26788732 +GTP ready, beginning main protocol loop +Initializing board with boardXSize 4 boardYSize 5 +Changed rules to koSIMPLEscoreAREAtaxNONEsui0 +MoveNum: 1 HASH: 296C7FD2F430C547A7F740C78DBA7C20 + A B C D + 5 . . . X + 4 X X . . + 3 O X X X + 2 O O X . + 1 @ X . X + +koSIMPLEscoreAREAtaxNONEsui0komi0 +Time taken: ### +Root visits: 50 +New playouts: 50 +NN rows: 39 +NN batches: 39 +NN avg batch size: 1 +PV: A1 pass pass +Tree: +: T 120.70c W 99.87c S 20.20c (+21.4 L +18.2) N 50 -- A1 pass pass +---Black(^)--- +A1 : T 124.00c W 99.86c S 23.02c (+22.6 L +19.0) LCB 121.15c P 19.81% WF 19.2 PSV 49 N 19 -- A1 pass pass +pss : T 120.06c W 99.85c S 19.55c (+21.0 L +17.9) LCB 115.82c P 31.25% WF 15.9 PSV 15 N 16 -- pass C5 D4 pass +C4 : T 122.96c W 99.92c S 21.25c (+21.2 L +20.0) LCB 93.70c P 8.34% WF 5.0 PSV 5 N 5 -- C4 pass pass +C1 : T 113.99c W 99.92c S 15.16c (+19.4 L +16.7) LCB -35.94c P 8.75% WF 2.0 PSV 2 N 2 -- C1 pass +B5 : T 116.74c W 99.89c S 16.92c (+20.1 L +16.7) LCB -33.05c P 7.70% WF 2.0 PSV 2 N 2 -- B5 pass +D4 : T 111.08c W 99.87c S 14.39c (+19.3 L +15.6) LCB -38.19c P 7.35% WF 1.9 PSV 1 N 2 -- D4 pass +C5 : T 112.18c W 99.87c S 14.58c (+19.2 L +15.8) LCB -37.87c P 7.27% WF 1.9 PSV 1 N 2 -- C5 pass +D2 : T 116.63c W 99.99c S 16.64c (+20.6 L +14.1) LCB -234.23c P 5.74% WF 1.0 PSV 1 N 1 -- D2 +MoveNum: 1 HASH: 296C7FD2F430C547A7F740C78DBA7C20 + A B C D + 5 . . . X + 4 X X . . + 3 O X X X + 2 O O X . + 1 @ X . X + +koSIMPLEscoreAREAtaxNONEsui0komi0 +Time taken: ### +Root visits: 50 +New playouts: 50 +NN rows: 41 +NN batches: 41 +NN avg batch size: 1 +PV: A1 C5 C4 D4 B5 +Tree: +: T 122.91c W 99.81c S 23.02c (+21.2 L +18.1) N 50 -- A1 C5 C4 D4 B5 +---Black(^)--- +A1 : T 126.29c W 99.82c S 25.70c (+22.4 L +19.1) LCB 124.62c P 38.69% WF 32.4 PSV 32 N 32 -- A1 C5 C4 D4 B5 +C4 : T 125.00c W 99.80c S 24.53c (+22.3 L +19.1) LCB 95.61c P 8.76% WF 5.0 PSV 5 N 5 -- C4 pass A1 C5 +C1 : T 113.09c W 99.82c S 15.85c (+18.0 L +15.4) LCB -36.10c P 10.45% WF 1.9 PSV 2 N 2 -- C1 pass +pss : T 108.62c W 100.00c S 11.16c (+16.0 L +12.1) LCB -42.77c P 10.76% WF 1.9 PSV 1 N 2 -- pass pass +D4 : T 111.94c W 99.75c S 15.61c (+18.1 L +15.0) LCB -37.42c P 7.35% WF 1.9 PSV 1 N 2 -- D4 pass +B5 : T 116.74c W 99.78c S 17.96c (+18.8 L +15.8) LCB -33.12c P 7.18% WF 2.0 PSV 1 N 2 -- B5 pass +C5 : T 111.97c W 99.79c S 15.10c (+17.7 L +14.8) LCB -38.23c P 6.49% WF 1.9 PSV 1 N 2 -- C5 pass +D2 : T 116.79c W 99.80c S 17.93c (+18.9 L +16.4) LCB -32.19c P 5.93% WF 2.0 PSV 1 N 2 -- D2 pass diff --git a/cpp/tests/results/gtp/passalivemode.txt.stdout b/cpp/tests/results/gtp/passalivemode.txt.stdout new file mode 100644 index 0000000000..a517939d6f --- /dev/null +++ b/cpp/tests/results/gtp/passalivemode.txt.stdout @@ -0,0 +1,70 @@ += + += + += + += + += MoveNum: 0 HASH: 296C7FD2F430C547A7F740C78DBA7C20 + A B C D + 5 . . . X + 4 X X . . + 3 O X X X + 2 O O X . + 1 . X . X +Next player: Black +Rules: {"friendlyPassOk":false,"hasButton":false,"ko":"SIMPLE","komi":0.0,"scoring":"AREA","suicide":false,"tax":"NONE","whiteHandicapBonus":"0"} +B stones captured: 0 +W stones captured: 0 + += "auto" + += + += A1 + += + += + += "true" + += A1 + += + += + += + += B+20.0 + += A3 A2 B2 + += + += B+13.0 + += + += + += B+20.0 + += + += B+20.0 + += MoveNum: 2 HASH: 296C7FD2F430C547A7F740C78DBA7C20 + A B C D + 5 . . . X + 4 X X . . + 3 O X X X + 2 O O X . + 1 . X . X +Next player: White +Rules: {"friendlyPassOk":false,"hasButton":false,"ko":"SIMPLE","komi":0.0,"scoring":"AREA","suicide":false,"tax":"NONE","whiteHandicapBonus":"0"} +B stones captured: 0 +W stones captured: 0 + diff --git a/cpp/tests/results/gtp/printsgf.txt.log b/cpp/tests/results/gtp/printsgf.txt.log index 4e28bccb19..d6e18c0a0e 100644 --- a/cpp/tests/results/gtp/printsgf.txt.log +++ b/cpp/tests/results/gtp/printsgf.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -68,7 +68,7 @@ trtUseFP16 = false : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 9 * 9 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 9 nnYLen 9 @@ -93,7 +93,7 @@ trtUseFP16 = false : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 9 * 13 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 9 nnYLen 13 diff --git a/cpp/tests/results/gtp/printsgf.txt.stderr b/cpp/tests/results/gtp/printsgf.txt.stderr index 6044c2b82b..066c411037 100644 --- a/cpp/tests/results/gtp/printsgf.txt.stderr +++ b/cpp/tests/results/gtp/printsgf.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/printsgffinalscore.txt.log b/cpp/tests/results/gtp/printsgffinalscore.txt.log index 75628c3ed0..6ece7110be 100644 --- a/cpp/tests/results/gtp/printsgffinalscore.txt.log +++ b/cpp/tests/results/gtp/printsgffinalscore.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -68,7 +68,7 @@ trtUseFP16 = false : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 7 * 7 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 7 nnYLen 7 diff --git a/cpp/tests/results/gtp/printsgffinalscore.txt.stderr b/cpp/tests/results/gtp/printsgffinalscore.txt.stderr index c144b2f021..98d744cee6 100644 --- a/cpp/tests/results/gtp/printsgffinalscore.txt.stderr +++ b/cpp/tests/results/gtp/printsgffinalscore.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/rawnn.txt.log b/cpp/tests/results/gtp/rawnn.txt.log index 0612c64fd6..130ce60153 100644 --- a/cpp/tests/results/gtp/rawnn.txt.log +++ b/cpp/tests/results/gtp/rawnn.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -66,7 +66,7 @@ trtUseFP16 = false : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 9 * 9 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 9 nnYLen 9 @@ -181,7 +181,7 @@ whiteOwnership : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 7 * 10 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 7 nnYLen 10 diff --git a/cpp/tests/results/gtp/rawnn.txt.stderr b/cpp/tests/results/gtp/rawnn.txt.stderr index 5e133331d5..6aa64d253e 100644 --- a/cpp/tests/results/gtp/rawnn.txt.stderr +++ b/cpp/tests/results/gtp/rawnn.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/rootsymprune.log b/cpp/tests/results/gtp/rootsymprune.log index 45f47c7925..3d68c0bdf7 100644 --- a/cpp/tests/results/gtp/rootsymprune.log +++ b/cpp/tests/results/gtp/rootsymprune.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/rootsymprune.stderr b/cpp/tests/results/gtp/rootsymprune.stderr index ab143c4cb2..091f27de72 100644 --- a/cpp/tests/results/gtp/rootsymprune.stderr +++ b/cpp/tests/results/gtp/rootsymprune.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/rules.txt.log b/cpp/tests/results/gtp/rules.txt.log index 988a01d615..d03dcfbc23 100644 --- a/cpp/tests/results/gtp/rules.txt.log +++ b/cpp/tests/results/gtp/rules.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/rules.txt.stderr b/cpp/tests/results/gtp/rules.txt.stderr index 8aaf4e99d9..8957a8f432 100644 --- a/cpp/tests/results/gtp/rules.txt.stderr +++ b/cpp/tests/results/gtp/rules.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/searchcancellable.log b/cpp/tests/results/gtp/searchcancellable.log index a34b16bb9a..ba6c96b398 100644 --- a/cpp/tests/results/gtp/searchcancellable.log +++ b/cpp/tests/results/gtp/searchcancellable.log @@ -1,11 +1,11 @@ : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = models/b18c384nbt-uec.bin.gz useFP16 false : Initializing neural net buffer to be size 9 * 9 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 11 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: b18c384nbt-uec-20221121b (nbt convnet, 26326793 params) : Loaded neural net with nnXLen 9 nnYLen 9 diff --git a/cpp/tests/results/gtp/searchcancellable.stderr b/cpp/tests/results/gtp/searchcancellable.stderr index b982232f80..536344b101 100644 --- a/cpp/tests/results/gtp/searchcancellable.stderr +++ b/cpp/tests/results/gtp/searchcancellable.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 9 boardYSize 9 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/set_boardsize_twice.txt.log b/cpp/tests/results/gtp/set_boardsize_twice.txt.log index 46a4c28071..0f6703f808 100644 --- a/cpp/tests/results/gtp/set_boardsize_twice.txt.log +++ b/cpp/tests/results/gtp/set_boardsize_twice.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -66,7 +66,7 @@ trtUseFP16 = false : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 15 * 15 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 15 nnYLen 15 @@ -150,7 +150,7 @@ W stones captured: 0 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/set_boardsize_twice.txt.stderr b/cpp/tests/results/gtp/set_boardsize_twice.txt.stderr index 2eb99bcaa5..b62e36e294 100644 --- a/cpp/tests/results/gtp/set_boardsize_twice.txt.stderr +++ b/cpp/tests/results/gtp/set_boardsize_twice.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/set_position.txt.log b/cpp/tests/results/gtp/set_position.txt.log index e5a94e6cbd..8f24a99184 100644 --- a/cpp/tests/results/gtp/set_position.txt.log +++ b/cpp/tests/results/gtp/set_position.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -148,7 +148,7 @@ W stones captured: 0 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 13 * 13 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 13 nnYLen 13 @@ -378,7 +378,7 @@ W stones captured: 0 : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 3 * 3 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 3 nnYLen 3 diff --git a/cpp/tests/results/gtp/set_position.txt.stderr b/cpp/tests/results/gtp/set_position.txt.stderr index 88f3f37965..8417114ec0 100644 --- a/cpp/tests/results/gtp/set_position.txt.stderr +++ b/cpp/tests/results/gtp/set_position.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/setparams.txt.log b/cpp/tests/results/gtp/setparams.txt.log index 568c8296ff..cf4a695482 100644 --- a/cpp/tests/results/gtp/setparams.txt.log +++ b/cpp/tests/results/gtp/setparams.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 @@ -269,7 +269,7 @@ D16 : T -1.32c W -1.18c S -0.10c ( -0.5 L -0.4) LCB -20.75c P 5.50% WF 6 : Controller: kata-set-param playoutDoublingAdvantage 1 : = : Controller: kata-get-params -: = {"allowResignation":"true","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} +: = {"allowResignation":"true","alwaysComputePassAliveUnderSuicideRules":"auto","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} : Controller: genmove w : MoveNum: 1 HASH: 87712726FD65E13B89C878D9CA82BF83 A B C D E F G H J K L M N O P Q R S T @@ -321,7 +321,7 @@ D4 : T 42.34c W 44.11c S 2.22c (+11.1 L +10.1) LCB -107.41c P 4.14% WF 2 : Controller: kata-set-param dynamicPlayoutDoublingAdvantageCapPerOppLead 0.045 : ? Could not set params: Cannot be overridden in kata-set-param: dynamicPlayoutDoublingAdvantageCapPerOppLead : Controller: kata-get-params -: = {"allowResignation":"true","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} +: = {"allowResignation":"true","alwaysComputePassAliveUnderSuicideRules":"auto","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} : Controller: genmove w : MoveNum: 1 HASH: 87712726FD65E13B89C878D9CA82BF83 A B C D E F G H J K L M N O P Q R S T diff --git a/cpp/tests/results/gtp/setparams.txt.stderr b/cpp/tests/results/gtp/setparams.txt.stderr index d8a4169f56..5b2902a7ac 100644 --- a/cpp/tests/results/gtp/setparams.txt.stderr +++ b/cpp/tests/results/gtp/setparams.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/gtp/setparams.txt.stdout b/cpp/tests/results/gtp/setparams.txt.stdout index 4d75479d3f..2779351e7d 100644 --- a/cpp/tests/results/gtp/setparams.txt.stdout +++ b/cpp/tests/results/gtp/setparams.txt.stdout @@ -30,7 +30,7 @@ = -= {"allowResignation":"true","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} += {"allowResignation":"true","alwaysComputePassAliveUnderSuicideRules":"auto","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} = D3 @@ -38,7 +38,7 @@ ? Could not set params: Cannot be overridden in kata-set-param: dynamicPlayoutDoublingAdvantageCapPerOppLead -= {"allowResignation":"true","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} += {"allowResignation":"true","alwaysComputePassAliveUnderSuicideRules":"auto","analysisIgnorePreRootHistory":"true","analysisWideRootNoise":"0.9","antiMirror":"false","chosenMovePrune":1.0,"chosenMoveSubtract":0.0,"chosenMoveTemperature":0.1,"chosenMoveTemperatureEarly":0.5,"chosenMoveTemperatureHalflife":19.0,"chosenMoveTemperatureOnlyBelowProb":1.0,"conservativePass":true,"cpuctExploration":1.0,"cpuctExplorationBase":500.0,"cpuctExplorationLog":0.45,"cpuctUtilityStdevPrior":0.4,"cpuctUtilityStdevPriorWeight":2.0,"cpuctUtilityStdevScale":0.85,"delayMoveMax":"1e+06","delayMoveScale":"0","drawEquivalentWinsForWhite":0.5,"dynamicScoreCenterScale":0.75,"dynamicScoreCenterZeroWeight":0.2,"dynamicScoreUtilityFactor":0.3,"enableMorePassingHacks":true,"enablePassingHacks":true,"endgameTurnTimeDecay":100.0,"fillDameBeforePass":true,"fpuLossProp":0.0,"fpuParentWeight":0.0,"fpuParentWeightByVisitedPolicy":true,"fpuParentWeightByVisitedPolicyPow":2.0,"fpuReductionMax":0.2,"futileVisitsThreshold":0.0,"genmoveAntiMirror":"true","graphSearchCatchUpLeakProb":0.0,"graphSearchRepBound":11,"humanSLChosenMoveIgnorePass":false,"humanSLChosenMovePiklLambda":1000000000.0,"humanSLChosenMoveProp":0.0,"humanSLCpuctExploration":1.0,"humanSLCpuctPermanent":0.0,"humanSLOppExploreProbWeightful":0.0,"humanSLOppExploreProbWeightless":0.0,"humanSLPlaExploreProbWeightful":0.0,"humanSLPlaExploreProbWeightless":0.0,"humanSLProfile":"","humanSLRootExploreProbWeightful":0.0,"humanSLRootExploreProbWeightless":0.0,"ignoreAllHistory":false,"ignorePreRootHistory":false,"lagBuffer":1.0,"lcbStdevs":5.0,"maxPlayouts":10000,"maxPlayoutsPondering":1125899906842624,"maxTime":1e+20,"maxTimePondering":60.0,"maxVisits":100,"maxVisitsPondering":1125899906842624,"midgameTimeFactor":1.0,"midgameTurnPeakTime":130.0,"minPlayoutsPerThread":8.0,"minVisitPropForLCB":0.15,"nnPolicyTemperature":1.0,"noResultUtilityForWhite":0.0,"noisePruneUtilityScale":0.15,"noisePruningCap":1e+50,"numSearchThreads":1,"numVirtualLossesPerThread":1.0,"obviousMovesPolicyEntropyTolerance":0.3,"obviousMovesPolicySurpriseTolerance":0.15,"obviousMovesTimeFactor":1.0,"overallocateTimeFactor":1.0,"playoutDoublingAdvantage":1.0,"playoutDoublingAdvantagePla":"E","policyOptimism":1.0,"ponderingEnabled":"false","rootDesiredPerChildVisitsCoeff":0.0,"rootDirichletNoiseTotalConcentration":10.83,"rootDirichletNoiseWeight":0.25,"rootEndingBonusPoints":0.5,"rootFpuLossProp":0.0,"rootFpuReductionMax":0.1,"rootNoiseEnabled":false,"rootNumSymmetriesToSample":1,"rootPolicyOptimism":0.2,"rootPolicyTemperature":1.0,"rootPolicyTemperatureEarly":1.0,"rootPruneUselessMoves":true,"rootSymmetryPruning":false,"searchFactorAfterOnePass":0.5,"searchFactorAfterTwoPass":0.25,"staticScoreUtilityFactor":0.1,"subtreeValueBiasFactor":0.45,"subtreeValueBiasFreeProp":0.8,"subtreeValueBiasTableNumShards":65536,"subtreeValueBiasWeightExponent":0.85,"treeReuseCarryOverTimeFactor":0.0,"uncertaintyCoeff":0.25,"uncertaintyExponent":1.0,"uncertaintyMaxWeight":8.0,"useGraphSearch":true,"useLcbForSelection":true,"useNoisePruning":true,"useNonBuggyLcb":true,"useUncertainty":true,"valueWeightExponent":0.25,"wideRootNoise":0.0,"winLossUtilityFactor":1.0} = D3 diff --git a/cpp/tests/results/gtp/time.txt.log b/cpp/tests/results/gtp/time.txt.log index 1539096f71..996d3e6a6e 100644 --- a/cpp/tests/results/gtp/time.txt.log +++ b/cpp/tests/results/gtp/time.txt.log @@ -30,13 +30,13 @@ searchRandSeed = forTesting trtUseFP16 = false : GTP Engine starting... -: KataGo v1.16.5 +: KataGo v1.17.2 : Using TrompTaylor rules initially, unless GTP/GUI overrides this : Using 1 CPU thread(s) for search : nnRandSeed0 = forTesting : After dedups: nnModelFile0 = tests/models/g170-b6c96-s175395328-d26788732.bin.gz useFP16 false : Initializing neural net buffer to be size 19 * 19 exactly -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) : Loaded neural net with nnXLen 19 nnYLen 19 diff --git a/cpp/tests/results/gtp/time.txt.stderr b/cpp/tests/results/gtp/time.txt.stderr index 9e46544369..1f8d6d04c0 100644 --- a/cpp/tests/results/gtp/time.txt.stderr +++ b/cpp/tests/results/gtp/time.txt.stderr @@ -1,4 +1,4 @@ -KataGo v1.16.5 +KataGo v1.17.2 Using TrompTaylor rules initially, unless GTP/GUI overrides this Initializing board with boardXSize 19 boardYSize 19 Loaded config configs/gtp_example.cfg and/or command-line and query overrides diff --git a/cpp/tests/results/runNNCanaryTests.txt b/cpp/tests/results/runNNCanaryTests.txt index 1acf3ea961..cb9c9b3e19 100644 --- a/cpp/tests/results/runNNCanaryTests.txt +++ b/cpp/tests/results/runNNCanaryTests.txt @@ -20,7 +20,7 @@ searchFactorWhenWinningThreshold = 0.95 : After dedups: nnModelFile0 = tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz useFP16 auto : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = true useNHWC = true : Cuda backend thread 0: Model name: g170-b10c128-s1141046784-d204142634 (convnet, 2994503 params) nnEval->getTrunkSpatialConvDepth() 22 @@ -474,7 +474,7 @@ searchFactorWhenWinningThreshold = 0.95 : After dedups: nnModelFile0 = tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz useFP16 auto : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = true useNHWC = true : Cuda backend thread 0: Model name: g170-b10c128-s1141046784-d204142634 (convnet, 2994503 params) nnEval->getTrunkSpatialConvDepth() 22 @@ -928,7 +928,7 @@ searchFactorWhenWinningThreshold = 0.95 : After dedups: nnModelFile0 = tests/models/g170e-b10c128-s1141046784-d204142634.bin.gz useFP16 auto : Initializing neural net buffer to be size 19 * 19 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = true useNHWC = true : Cuda backend thread 0: Model name: g170-b10c128-s1141046784-d204142634 (convnet, 2994503 params) nnEval->getTrunkSpatialConvDepth() 22 diff --git a/cpp/tests/results/runNNOnTinyBoardTest.txt b/cpp/tests/results/runNNOnTinyBoardTest.txt index b7f5213744..067e995352 100644 --- a/cpp/tests/results/runNNOnTinyBoardTest.txt +++ b/cpp/tests/results/runNNOnTinyBoardTest.txt @@ -1,5 +1,5 @@ : Initializing neural net buffer to be size 6 * 6 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 8 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: g170-b6c96-s175395328-d26788732 (convnet, 1027911 params) HASH: 53602E4395E2B2B556BA45566880843F diff --git a/cpp/tests/results/runNNOnTinyBoardTestB28.txt b/cpp/tests/results/runNNOnTinyBoardTestB28.txt index 3037b4848d..6096f5c5ae 100644 --- a/cpp/tests/results/runNNOnTinyBoardTestB28.txt +++ b/cpp/tests/results/runNNOnTinyBoardTestB28.txt @@ -1,5 +1,5 @@ : Initializing neural net buffer to be size 6 * 6 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 15 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: kata1-b28c512nbt-s8326494464-d4628051565 (nbt convnet, 72830569 params) HASH: 53602E4395E2B2B556BA45566880843F diff --git a/cpp/tests/results/runNNSymmetriesTest.txt b/cpp/tests/results/runNNSymmetriesTest.txt index a12d12ebdc..7bdf5e5609 100644 --- a/cpp/tests/results/runNNSymmetriesTest.txt +++ b/cpp/tests/results/runNNSymmetriesTest.txt @@ -1,5 +1,5 @@ : Initializing neural net buffer to be size 13 * 13 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 5 useFP16 = false useNHWC = false : Cuda backend thread 0: Model name: b6c96-s103408384-d26419149 (convnet, 1025157 params) HASH: CB68B3094EEB7B7B88E4579363578B4B diff --git a/cpp/tests/results/runNNSymmetriesTestFP16.txt b/cpp/tests/results/runNNSymmetriesTestFP16.txt index 65d7145998..c6db1d4090 100644 --- a/cpp/tests/results/runNNSymmetriesTestFP16.txt +++ b/cpp/tests/results/runNNSymmetriesTestFP16.txt @@ -1,5 +1,5 @@ : Initializing neural net buffer to be size 13 * 13 allowing smaller boards -: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25425608704 compute capability major 8 minor 6 +: Cuda backend thread 0: Found GPU NVIDIA RTX A5000 memory 25285623808 compute capability major 8 minor 6 : Cuda backend thread 0: Model version 5 useFP16 = true useNHWC = true : Cuda backend thread 0: Model name: b6c96-s103408384-d26419149 (convnet, 1025157 params) HASH: CB68B3094EEB7B7B88E4579363578B4B diff --git a/cpp/tests/results/runOutputTests.txt b/cpp/tests/results/runOutputTests.txt index 61959d16a4..344c0442a5 100644 --- a/cpp/tests/results/runOutputTests.txt +++ b/cpp/tests/results/runOutputTests.txt @@ -20732,6 +20732,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 0 enableMorePassingHacks: 0 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -20841,6 +20842,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 0 enableMorePassingHacks: 0 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -20950,6 +20952,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 1 enableMorePassingHacks: 1 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -21059,6 +21062,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0.04 enablePassingHacks: 1 enableMorePassingHacks: 1 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -21168,6 +21172,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 0 enableMorePassingHacks: 0 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -21277,6 +21282,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 0 enableMorePassingHacks: 0 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -21386,6 +21392,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 0 enableMorePassingHacks: 0 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -21495,6 +21502,7 @@ avoidMYTDaggerHackPla: 0 wideRootNoise: 0 enablePassingHacks: 0 enableMorePassingHacks: 0 +alwaysComputePassAliveUnderSuicideRules: auto playoutDoublingAdvantage: 0 playoutDoublingAdvantagePla: 0 avoidRepeatedPatternUtility: 0 @@ -21574,6 +21582,8 @@ Board size distribution 8x8 32754 Done Running training write tests +Running reanalysis row channels test +Reanalysis row channels test passed : Initializing neural net buffer to be size 19 * 19 allowing smaller boards seedBase: testtrainingwrite-tt HASH: 67277BB4C5452970ADAEDA0847614349 @@ -21647,16 +21657,16 @@ policyTargetsNCMove 0 0 0 7 0 0 6 0 0 0 0 0 0 2 40 0 0 0 2 12 3 0 0 0 0 20 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 globalTargetsNC --109 78 85 77 80 89 1 0 -10 0 {'descr':'getRoot(); Board board(initialBoard); - BoardHistory hist(board,initialPla,rules,0); + BoardHistory hist(board,initialPla,rules,0,book->alwaysComputePassAliveUnderSuicideRules); int branchLen = rand.nextUInt(10); for(int turnIdx = 0; turnIdx +#include #include //------------------------ @@ -152,4 +154,57 @@ void Tests::runLoadModelTests() { testAssert(Global::isPrefix(FileUtils::weaklyCanonical(modelDir), FileUtils::weaklyCanonical(modelsDir))); } cout << "testloadmodel okay" << endl; + + //A real v17 model file whose header slot after metaEncoderVersion is patched to 1 parses as + //declaring preferPassAliveUnderSuicideRules - the engine side of the model-declaration handshake + //that lets the alwaysComputePassAliveUnderSuicideRules auto mode turn on. The same slot layout is + //what export_model_pytorch.py writes. + { + const string modelFile = "tests/models/b7c96h6kv3qk32v16tflrs-fson-bnh.bin.gz"; + string uncompressed; + FileUtils::uncompressAndLoadFileIntoString(modelFile,"",uncompressed); + + size_t binStart = uncompressed.find("@BIN@"); + testAssert(binStart != string::npos); + const string headerPrefix = uncompressed.substr(0,binStart); + const string rest = uncompressed.substr(binStart); + vector tokens = Global::split(headerPrefix); + //Header layout: name, version, numInputChannels, numInputGlobalChannels, 7 postprocess params, + //metaEncoderVersion, preferPassAliveUnderSuicideRules, 6 unused option slots, then the trunk. + testAssert(tokens.size() > 19); + testAssert(tokens[1] == "17"); + testAssert(tokens[11] == "0"); + testAssert(tokens[12] == "0"); + testAssert(tokens[19] == "trunk"); + + auto parseWithSlot = [&](const string& slotValue) { + vector patched = tokens; + patched[12] = slotValue; + string contents = Global::concat(patched," ") + " " + rest; + std::istringstream in(contents); + return ModelDesc(in,"",true); + }; + + { + ModelDesc desc = parseWithSlot("0"); + testAssert(desc.modelVersion == 17); + testAssert(!desc.preferPassAliveUnderSuicideRules); + } + { + ModelDesc desc = parseWithSlot("1"); + testAssert(desc.modelVersion == 17); + testAssert(desc.preferPassAliveUnderSuicideRules); + } + { + bool threw = false; + try { + ModelDesc desc = parseWithSlot("2"); + } + catch(const StringError&) { + threw = true; + } + testAssert(threw); + } + cout << "model declaration parsing okay" << endl; + } } diff --git a/cpp/tests/testnnevalcanary.cpp b/cpp/tests/testnnevalcanary.cpp index af3beb7bd5..b08b078f5e 100644 --- a/cpp/tests/testnnevalcanary.cpp +++ b/cpp/tests/testnnevalcanary.cpp @@ -49,7 +49,8 @@ void Tests::runCanaryTests(NNEvaluator* nnEval, int symmetry, bool print) { BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); int turnIdx = 18; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + //Featurize per the model's own declared pass-alive computation mode. + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, nnEval->modelPreferPassAliveUnderSuicideRules()); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -84,7 +85,8 @@ void Tests::runCanaryTests(NNEvaluator* nnEval, int symmetry, bool print) { BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); int turnIdx = 36; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + //Featurize per the model's own declared pass-alive computation mode. + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, nnEval->modelPreferPassAliveUnderSuicideRules()); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -118,7 +120,8 @@ void Tests::runCanaryTests(NNEvaluator* nnEval, int symmetry, bool print) { BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); int turnIdx = 23; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + //Featurize per the model's own declared pass-alive computation mode. + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, nnEval->modelPreferPassAliveUnderSuicideRules()); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -153,7 +156,8 @@ void Tests::runCanaryTests(NNEvaluator* nnEval, int symmetry, bool print) { BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); int turnIdx = 23; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + //Featurize per the model's own declared pass-alive computation mode. + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, nnEval->modelPreferPassAliveUnderSuicideRules()); hist.setKomi(-7); MiscNNInputParams nnInputParams; @@ -185,7 +189,8 @@ void Tests::runCanaryTests(NNEvaluator* nnEval, int symmetry, bool print) { BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); int turnIdx = 23; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + //Featurize per the model's own declared pass-alive computation mode. + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, nnEval->modelPreferPassAliveUnderSuicideRules()); hist.setKomi(21); MiscNNInputParams nnInputParams; @@ -220,7 +225,8 @@ void Tests::runCanaryTests(NNEvaluator* nnEval, int symmetry, bool print) { BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); int turnIdx = 7; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + //Featurize per the model's own declared pass-alive computation mode. + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, nnEval->modelPreferPassAliveUnderSuicideRules()); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -366,6 +372,56 @@ struct GpuErrorStats { ); } + // The largest ratio of measured error to its allowed limit across all metrics, for the same + // limits and scalings as checkStats99 (useMax=false) or checkStatsMax (useMax=true). + // A ratio > 1 means that metric failed its check; the largest ratio is the "closest" margin. + double worstRatioVsLimits(bool useMax, double wr, double score, double tpd, double pkld, std::string& whichMetricOut) { + sortErrors(); + auto pct = [&](const std::vector& v) { return useMax ? getMaxPercentile(v) : get99Percentile(v); }; + const double ownershipMult = useMax ? 4.0 : 1.75; + const std::pair ratios[] = { + {"winrateError", 100*pct(winrateError) / wr}, + {"leadError", pct(leadError) / score}, + {"scoreMeanError", pct(scoreMeanError) / score}, + {"scoreStdevError", pct(scoreStdevError) / (score*0.6)}, + {"topPolicyDelta", 100*pct(topPolicyDiff) / tpd}, + {"policyKLDiv", pct(policyKLDiv) / pkld}, + {"stWLErrorError", 100*pct(shorttermWinlossErrorError) / (wr*1.8)}, + {"stScErrorError", pct(shorttermScoreErrorError) / (score*0.75)}, + {"ownershipError", 100*pct(ownershipError) / (wr*ownershipMult)}, + }; + double worst = -1; + whichMetricOut = ""; + for(const auto& r: ratios) { + if(r.second > worst) { + worst = r.second; + whichMetricOut = r.first; + } + } + return worst; + } + + void reportClosestMargin( + const string& name, Logger& logger, + double wr99, double score99, double tpd99, double pkld99, + double wrMax, double scoreMax, double tpdMax, double pkldMax + ) { + auto rpad = [](const string& s, int n) { + if(s.size() < n) + return s + std::string(n - s.size(),' '); + return s; + }; + std::string which99, whichMax; + double r99 = worstRatioVsLimits(false, wr99, score99, tpd99, pkld99, which99); + double rMax = worstRatioVsLimits(true, wrMax, scoreMax, tpdMax, pkldMax, whichMax); + logger.write( + rpad(name + " closest margin: ", 60) + + Global::strprintf( + " %.3gx of limit (%s 99%%), %.3gx of limit (%s max)", + r99, which99.c_str(), rMax, whichMax.c_str()) + ); + } + void reportStats(const string& name, Logger& logger) { sortErrors(); @@ -604,6 +660,8 @@ bool Tests::runBackendErrorTest( nnInputParams.policyOptimism = policyOptimismForTest; nnInputParams.playoutDoublingAdvantage = pdaForTest; nnInputParams.nnPolicyTemperature = (float)nnPolicyTemperatureForTest; + //Featurize per the model's own declared pass-alive computation mode. + nnInputParams.passAliveSuicideRulesOverride = nnE->modelPreferPassAliveUnderSuicideRules() ? 1 : 0; NNResultBuf buf; bool skipCache = true; @@ -724,15 +782,21 @@ bool Tests::runBackendErrorTest( { GpuErrorStats stats; computeStats("fp32 error vs reference", fp32, stats); - fp32BatchSuccessBuf = fp32BatchSuccessBuf && stats.checkStats99( 0.45, 0.225, 0.45, 0.0006); + // 99% score limit is looser than max/4 would give: leadError/scoreMeanError run a touch noisier on + // some backends (notably TensorRT, whose "fp32" uses TF32/fused tensor-core GEMMs) on rectangle boards. + fp32BatchSuccessBuf = fp32BatchSuccessBuf && stats.checkStats99( 0.45, 0.34, 0.45, 0.0006); fp32BatchSuccessBuf = fp32BatchSuccessBuf && stats.checkStatsMax(1.35, 0.900, 1.35, 0.0012); + if(verbose) + stats.reportClosestMargin("fp32 error vs reference", logger, 0.45, 0.34, 0.45, 0.0006, 1.35, 0.900, 1.35, 0.0012); } { GpuErrorStats stats; computeStats("batched fp32 error vs reference", fp32Batched, stats); - fp32BatchSuccessBuf = fp32BatchSuccessBuf && stats.checkStats99( 0.45, 0.225, 0.45, 0.0006); + fp32BatchSuccessBuf = fp32BatchSuccessBuf && stats.checkStats99( 0.45, 0.34, 0.45, 0.0006); fp32BatchSuccessBuf = fp32BatchSuccessBuf && stats.checkStatsMax(1.35, 0.900, 1.35, 0.0012); + if(verbose) + stats.reportClosestMargin("batched fp32 error vs reference", logger, 0.45, 0.34, 0.45, 0.0006, 1.35, 0.900, 1.35, 0.0012); } if(nnEval32 != nnEval) { @@ -741,12 +805,16 @@ bool Tests::runBackendErrorTest( computeStats("current cfg error vs reference", current, stats); success = success && stats.checkStats99( 2.0, 1.00, 2.50, 0.0020); success = success && stats.checkStatsMax(5.0, 3.00, 6.00, 0.0040); + if(verbose) + stats.reportClosestMargin("current cfg error vs reference", logger, 2.0, 1.00, 2.50, 0.0020, 5.0, 3.00, 6.00, 0.0040); } { GpuErrorStats stats; computeStats("batched current cfg error vs reference", currentBatched, stats); success = success && stats.checkStats99( 2.0, 1.00, 2.50, 0.0020); success = success && stats.checkStatsMax(5.0, 3.00, 6.00, 0.0040); + if(verbose) + stats.reportClosestMargin("batched current cfg error vs reference", logger, 2.0, 1.00, 2.50, 0.0020, 5.0, 3.00, 6.00, 0.0040); } } diff --git a/cpp/tests/testnninputs.cpp b/cpp/tests/testnninputs.cpp index d1fecd476a..049b2b5767 100644 --- a/cpp/tests/testnninputs.cpp +++ b/cpp/tests/testnninputs.cpp @@ -200,7 +200,7 @@ void Tests::runNNInputsV3V4Tests() { BoardHistory hist; Rules initialRules = Rules::getTrompTaylorish(); initialRules = sgf->getRulesOrFailAllowUnspecified(initialRules); - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); vector& moves = sgf->moves; for(size_t i = 0; igetRulesOrFailAllowUnspecified(initialRules); - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); vector& moves = sgf->moves; for(size_t i = 0; igetRulesOrFailAllowUnspecified(initialRules); - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); vector& moves = sgf->moves; for(size_t i = 0; igetRulesOrFailAllowUnspecified(initialRules); - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); vector& moves = sgf->moves; for(size_t i = 0; igetRulesOrFailAllowUnspecified(initialRules); - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); int nnXLen = 6; int nnYLen = 6; @@ -714,7 +714,7 @@ xxx..xx BoardHistory hist; Rules initialRules; initialRules = sgf->getRulesOrFailAllowUnspecified(initialRules); - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); vector& moves = sgf->moves; int nnXLen = 13; @@ -789,7 +789,7 @@ o.xoo.x rules.komi = 6.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichRules]; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); auto run = [&](bool inputsUseNHWC) { Player nextPla = hist.moveHistory.size() > 0 ? getOpp(hist.moveHistory[hist.moveHistory.size()-1].pla) : hist.initialPla; @@ -890,7 +890,7 @@ o.xoo.x Board board = Board(9,1); Player nextPla = P_BLACK; Rules initialRules = Rules::getSimpleTerritory(); - BoardHistory hist(board,nextPla,initialRules,0); + BoardHistory hist(board,nextPla,initialRules,0,false); auto run = [&](bool inputsUseNHWC) { Hash128 hash; @@ -974,7 +974,7 @@ o.xoo.x Board board = Board(size,size); Player nextPla = P_BLACK; Rules initialRules = rules[i]; - BoardHistory hist(board,nextPla,initialRules,0); + BoardHistory hist(board,nextPla,initialRules,0,false); cout << "----------------------------------------" << endl; cout << "Black makes 3 moves in a row" << endl; if(i >= 3) { @@ -1188,7 +1188,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1206,7 +1206,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1225,7 +1225,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1243,7 +1243,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1262,7 +1262,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1296,7 +1296,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1332,7 +1332,7 @@ ooxooxo cout << "---------------------------------------------------" << endl; cout << rules.toString() << endl; Board board(origBoard); - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); testScoring(board,hist,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C7",board),P_WHITE,NULL); @@ -1412,7 +1412,7 @@ ooxooxo Player nextPla; BoardHistory hist; Rules rules = sgf->getRulesOrFailAllowUnspecified(rulesToUse); - sgf->setupInitialBoardAndHist(rules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(rules, board, nextPla, hist, false); int nnXLen = 9; int nnYLen = 9; diff --git a/cpp/tests/testownership.cpp b/cpp/tests/testownership.cpp index 8354be9cb8..f487148cfb 100644 --- a/cpp/tests/testownership.cpp +++ b/cpp/tests/testownership.cpp @@ -41,7 +41,7 @@ void Tests::runOwnershipTests(const string& configFile, const string& modelFile) auto runOnBoard = [&](const Board& board, const Rules& rules) { Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); int64_t numVisits = 100; vector ownership = PlayUtils::computeOwnership(bot,board,hist,nextPla,numVisits); cout << "=================================================================================" << endl; diff --git a/cpp/tests/testpassalivesuicide.cpp b/cpp/tests/testpassalivesuicide.cpp new file mode 100644 index 0000000000..e209aac1e8 --- /dev/null +++ b/cpp/tests/testpassalivesuicide.cpp @@ -0,0 +1,303 @@ +#include "../tests/tests.h" +#include "../tests/testsearchcommon.h" + +#include + +#include "../book/book.h" +#include "../neuralnet/nneval.h" +#include "../program/setup.h" +#include "../search/search.h" + +using namespace std; +using namespace TestCommon; + +//Tests for BoardHistory::alwaysComputePassAliveUnderSuicideRules and its plumbing. +//Prints only a single completion line on success - all checks are testAsserts. +void Tests::runPassAliveSuicideModeTests() { + //A position where pass-alive computation differs between suicide-legal and suicide-illegal modes. + //Under suicide-illegal computation, the three white stones are pass-dead inside black + //pass-alive territory (an ecosystem of mutually-supporting black chains). Under suicide-legal + //computation, none of the black chains are pass-alive at all. + Board board = Board::parseBoard(4,5,R"%%( +...x +xx.. +oxxx +oox. +.x.x +)%%"); + + Rules rules = Rules::parseRules("chinese"); + testAssert(!rules.multiStoneSuicideLegal); + + //Sanity check that this position really does discriminate the two computations. + { + Color areaNoSuicide[Board::MAX_ARR_SIZE]; + Color areaSuicide[Board::MAX_ARR_SIZE]; + board.calculateArea(areaNoSuicide,false,false,false,false); + board.calculateArea(areaSuicide,false,false,false,true); + Loc whiteLoc = Location::getLoc(0,2,board.x_size); + testAssert(board.colors[whiteLoc] == C_WHITE); + testAssert(areaNoSuicide[whiteLoc] == C_BLACK); + testAssert(areaSuicide[whiteLoc] == C_EMPTY); + } + + //Basic flag behavior and effect on scoring + { + BoardHistory hist(board,P_BLACK,rules,0,false); + testAssert(!hist.alwaysComputePassAliveUnderSuicideRules); + testAssert(!hist.suicideLegalForPassAlive()); + + BoardHistory histFlagged(board,P_BLACK,rules,0,false); + histFlagged.setAlwaysComputePassAliveUnderSuicideRules(true); + testAssert(histFlagged.alwaysComputePassAliveUnderSuicideRules); + testAssert(histFlagged.suicideLegalForPassAlive()); + + //The flag changes the situation-and-rules hash exactly when the rules don't already have suicide legal + Hash128 hashOff = BoardHistory::getSituationRulesAndKoHash(board,hist,P_BLACK,0.5); + Hash128 hashOn = BoardHistory::getSituationRulesAndKoHash(board,histFlagged,P_BLACK,0.5); + testAssert(hashOff != hashOn); + + //And changes area scoring on this position + BoardHistory histScore(board,P_BLACK,rules,0,false); + Board boardCopy = board; + histScore.endAndScoreGameNow(boardCopy); + BoardHistory histScoreFlagged(board,P_BLACK,rules,0,false); + histScoreFlagged.setAlwaysComputePassAliveUnderSuicideRules(true); + Board boardCopy2 = board; + histScoreFlagged.endAndScoreGameNow(boardCopy2); + testAssert(histScore.isScored && histScoreFlagged.isScored); + testAssert(histScore.finalWhiteMinusBlackScore != histScoreFlagged.finalWhiteMinusBlackScore); + + //And changes territory scoring too (the countTerritoryAreaScoreWhiteMinusBlack path) + Rules japRules = Rules::parseRules("japanese"); + testAssert(!japRules.multiStoneSuicideLegal); + BoardHistory histTerrScore(board,P_BLACK,japRules,0,false); + Board boardCopy3 = board; + histTerrScore.endAndScoreGameNow(boardCopy3); + BoardHistory histTerrScoreFlagged(board,P_BLACK,japRules,0,false); + histTerrScoreFlagged.setAlwaysComputePassAliveUnderSuicideRules(true); + Board boardCopy4 = board; + histTerrScoreFlagged.endAndScoreGameNow(boardCopy4); + testAssert(histTerrScore.isScored && histTerrScoreFlagged.isScored); + testAssert(histTerrScore.finalWhiteMinusBlackScore != histTerrScoreFlagged.finalWhiteMinusBlackScore); + + //Copying and clear() preserve the flag + BoardHistory copied(histFlagged); + testAssert(copied.alwaysComputePassAliveUnderSuicideRules); + BoardHistory assigned; + assigned = histFlagged; + testAssert(assigned.alwaysComputePassAliveUnderSuicideRules); + BoardHistory cleared(histFlagged); + cleared.clear(board,P_BLACK,rules,0); + testAssert(cleared.alwaysComputePassAliveUnderSuicideRules); + testAssert(histFlagged.copyToInitial().alwaysComputePassAliveUnderSuicideRules); + } + + //When the rules already have suicide legal, the flag is a no-op for hashing and scoring + { + Rules tromp = Rules::parseRules("tromp-taylor"); + testAssert(tromp.multiStoneSuicideLegal); + BoardHistory hist(board,P_BLACK,tromp,0,false); + BoardHistory histFlagged(board,P_BLACK,tromp,0,false); + histFlagged.setAlwaysComputePassAliveUnderSuicideRules(true); + testAssert(hist.suicideLegalForPassAlive() && histFlagged.suicideLegalForPassAlive()); + Hash128 hashOff = BoardHistory::getSituationRulesAndKoHash(board,hist,P_BLACK,0.5); + Hash128 hashOn = BoardHistory::getSituationRulesAndKoHash(board,histFlagged,P_BLACK,0.5); + testAssert(hashOff == hashOn); + } + + //MiscNNInputParams override behavior for the nn cache hash + { + BoardHistory hist(board,P_BLACK,rules,0,false); + BoardHistory histFlagged(board,P_BLACK,rules,0,false); + histFlagged.setAlwaysComputePassAliveUnderSuicideRules(true); + + MiscNNInputParams noOverride; + MiscNNInputParams forceOn; + forceOn.passAliveSuicideRulesOverride = 1; + MiscNNInputParams forceOff; + forceOff.passAliveSuicideRulesOverride = 0; + + testAssert(!noOverride.getSuicideLegalForPassAlive(hist)); + testAssert(noOverride.getSuicideLegalForPassAlive(histFlagged)); + testAssert(forceOn.getSuicideLegalForPassAlive(hist)); + testAssert(!forceOff.getSuicideLegalForPassAlive(histFlagged)); + + //Hash reflects the effective featurization: flag-off + force-on == flag-on + no-override, etc. + Hash128 offPlain = NNInputs::getHash(board,hist,P_BLACK,noOverride); + Hash128 onPlain = NNInputs::getHash(board,histFlagged,P_BLACK,noOverride); + Hash128 offForcedOn = NNInputs::getHash(board,hist,P_BLACK,forceOn); + Hash128 onForcedOff = NNInputs::getHash(board,histFlagged,P_BLACK,forceOff); + testAssert(offPlain != onPlain); + testAssert(offForcedOn == onPlain); + testAssert(onForcedOff == offPlain); + } + + //Search maintains the invariant that its root history's flag always matches what its params + //and nnEval resolve to, regardless of the history set into it. + { + Logger logger(nullptr,false,false); + NNEvaluator* nnEval = TestSearchCommon::startNNEval( + "",logger,"passAliveSuicideModeTest",NNPos::MAX_BOARD_LEN,NNPos::MAX_BOARD_LEN, + 0,true,false,false,true,false + ); + //With no loaded model, auto resolves to false + testAssert(!nnEval->modelPreferPassAliveUnderSuicideRules()); + + SearchParams params = SearchParams::forTestsV2(); + testAssert(params.alwaysComputePassAliveUnderSuicideRules == enabled_t::Auto); + + { + Search search(params,nnEval,&logger,"passAliveStampTestSeed"); + testAssert(!search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + testAssert(!Search::resolveAlwaysComputePassAliveUnderSuicideRules(params,nnEval)); + + //Setting a history with the flag on gets re-stamped to the search's own resolution + BoardHistory histFlagged(board,P_BLACK,rules,0,false); + histFlagged.setAlwaysComputePassAliveUnderSuicideRules(true); + search.setPosition(P_BLACK,board,histFlagged); + testAssert(!search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + + //Forcing the param stamps the flag on, even though the last set position had it off + SearchParams paramsOn = params; + paramsOn.alwaysComputePassAliveUnderSuicideRules = enabled_t::True; + testAssert(Search::resolveAlwaysComputePassAliveUnderSuicideRules(paramsOn,nnEval)); + search.setParams(paramsOn); + testAssert(search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + + //And even the no-clearing param setter keeps the invariant + search.setParamsNoClearing(params); + testAssert(!search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + search.setParamsNoClearing(paramsOn); + testAssert(search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + + //setPlayerAndClearHistory and setKomiIfNew preserve it too + search.setPlayerAndClearHistory(P_WHITE); + testAssert(search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + search.setKomiIfNew(5.5f); + testAssert(search.getRootHist().alwaysComputePassAliveUnderSuicideRules); + } + + nnEval->killServerThreads(); + delete nnEval; + } + + //Books record the pass-alive computation mode and stamp it on their histories. + //Mode-true books require book version >= 3 (so old binaries reject them cleanly) + { + Rules bookRules = Rules::parseRules("chinese"); + Board initialBoard(9,9); + BookParams bparams; + for(bool mode : {false,true}) { + Book book(Book::LATEST_BOOK_VERSION, initialBoard, bookRules, P_BLACK, 3, mode, bparams); + testAssert(book.alwaysComputePassAliveUnderSuicideRules == mode); + testAssert(book.getInitialHist().alwaysComputePassAliveUnderSuicideRules == mode); + + std::ostringstream saved; + book.saveToStream(saved); + { + std::istringstream headerIn(saved.str()); + testAssert(Book::readAlwaysComputePassAliveUnderSuicideRulesOfHeader(headerIn) == mode); + } + std::istringstream loadIn(saved.str()); + Book* loaded = Book::loadFromStream(loadIn); + testAssert(loaded->alwaysComputePassAliveUnderSuicideRules == mode); + testAssert(loaded->bookVersion == Book::LATEST_BOOK_VERSION); + testAssert(loaded->getInitialHist().alwaysComputePassAliveUnderSuicideRules == mode); + delete loaded; + } + + //Constructing a mode-true book at a pre-migration version is an error. + { + bool threw = false; + try { + Book book(2, initialBoard, bookRules, P_BLACK, 3, true, bparams); + } + catch(const StringError&) { + threw = true; + } + testAssert(threw); + } + + //A pre-migration book file (header key absent entirely, version 2) loads as mode false. + { + Book book(2, initialBoard, bookRules, P_BLACK, 3, false, bparams); + std::ostringstream saved; + book.saveToStream(saved); + + string contents = saved.str(); + const string key = "\"alwaysComputePassAliveUnderSuicideRules\":false,"; + size_t keyPos = contents.find(key); + testAssert(keyPos != string::npos); + contents.erase(keyPos, key.size()); + + { + std::istringstream headerIn(contents); + testAssert(!Book::readAlwaysComputePassAliveUnderSuicideRulesOfHeader(headerIn)); + } + std::istringstream loadIn(contents); + Book* loaded = Book::loadFromStream(loadIn); + testAssert(!loaded->alwaysComputePassAliveUnderSuicideRules); + testAssert(loaded->getInitialHist().alwaysComputePassAliveUnderSuicideRules == false); + delete loaded; + } + } + + //The nn cache cannot mix results across featurization modes: with suicide-illegal rules the two + //modes hash differently (distinct cache entries), and with suicide-legal rules the mode is a + //genuine no-op and deliberately shares cache entries. + { + Logger logger(nullptr,false,false); + NNEvaluator* nnEval = TestSearchCommon::startNNEval( + "",logger,"passAliveSuicideCacheTest",NNPos::MAX_BOARD_LEN,NNPos::MAX_BOARD_LEN, + 0,true,false,false,true,false + ); + + MiscNNInputParams noOverride; + MiscNNInputParams forceOn; + forceOn.passAliveSuicideRulesOverride = 1; + + auto sameOutputs = [](const NNOutput& a, const NNOutput& b) { + if(a.whiteWinProb != b.whiteWinProb || a.whiteLossProb != b.whiteLossProb || a.whiteScoreMean != b.whiteScoreMean) + return false; + for(int i = 0; ievaluate(board,hist,P_BLACK,noOverride,buf,false,false); + std::shared_ptr outPlain = std::move(buf.result); + nnEval->evaluate(board,hist,P_BLACK,forceOn,buf,false,false); + std::shared_ptr outForcedOn = std::move(buf.result); + nnEval->evaluate(board,hist,P_BLACK,noOverride,buf,false,false); + std::shared_ptr outPlainAgain = std::move(buf.result); + + //The debug-skip evaluator returns fresh random outputs on every cache miss, so distinct + //entries differ and a repeated query only matches if it hit the cache. + testAssert(!sameOutputs(*outPlain,*outForcedOn)); + testAssert(sameOutputs(*outPlain,*outPlainAgain)); + } + + //Suicide-legal rules: the override is a no-op and must share the cache entry. + { + Rules tromp = Rules::parseRules("tromp-taylor"); + BoardHistory hist(board,P_BLACK,tromp,0,false); + NNResultBuf buf; + nnEval->evaluate(board,hist,P_BLACK,noOverride,buf,false,false); + std::shared_ptr outPlain = std::move(buf.result); + nnEval->evaluate(board,hist,P_BLACK,forceOn,buf,false,false); + std::shared_ptr outForcedOn = std::move(buf.result); + testAssert(sameOutputs(*outPlain,*outForcedOn)); + } + + nnEval->killServerThreads(); + delete nnEval; + } + + cout << "Ran pass-alive suicide mode tests" << endl; +} diff --git a/cpp/tests/testrules.cpp b/cpp/tests/testrules.cpp index 7e3028ebd2..d4b3efb968 100644 --- a/cpp/tests/testrules.cpp +++ b/cpp/tests/testrules.cpp @@ -131,7 +131,7 @@ void Tests::runRulesTests() { rules.komi = 0.5f; rules.multiStoneSuicideLegal = true; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(1,1,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(2,2,board.x_size), P_WHITE, __LINE__); @@ -188,7 +188,7 @@ HASH: C5B7EC66E875EF237ADC456CEE8436EA rules.komi = 0.5f; rules.multiStoneSuicideLegal = true; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(1,1,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(2,2,board.x_size), P_WHITE, __LINE__); @@ -314,7 +314,7 @@ oooo.o Board board(baseBoard); Rules rules(baseRules); rules.koRule = Rules::KO_SIMPLE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(5,1,board.x_size), P_BLACK, __LINE__); out << "After black ko capture:" << endl; @@ -390,7 +390,7 @@ isResignation: 0 Board board(baseBoard); Rules rules(baseRules); rules.koRule = Rules::KO_POSITIONAL; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(5,1,board.x_size), P_BLACK, __LINE__); out << "After black ko capture:" << endl; @@ -474,7 +474,7 @@ Illegal: (5,1) X Board board(baseBoard); Rules rules(baseRules); rules.koRule = Rules::KO_SITUATIONAL; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(5,1,board.x_size), P_BLACK, __LINE__); out << "After black ko capture:" << endl; @@ -550,7 +550,7 @@ Illegal: (0,0) X testAssert(suc); Rules rules(baseRules); rules.koRule = Rules::KO_SPIGHT; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(5,1,board.x_size), P_BLACK, __LINE__); out << "After black ko capture:" << endl; @@ -677,7 +677,7 @@ xx.... Board board(baseBoard); Rules rules(baseRules); rules.koRule = koRulesToTest[i]; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(4,0,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -776,7 +776,7 @@ xoooxxoo rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(2,4,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(4,4,board.x_size), P_WHITE, __LINE__); @@ -815,7 +815,7 @@ ooooooo rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(3,1,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(1,2,board.x_size), P_WHITE, __LINE__); @@ -858,7 +858,7 @@ ooooooo rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(3,1,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(1,2,board.x_size), P_WHITE, __LINE__); @@ -889,7 +889,7 @@ ooooooo rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -936,7 +936,7 @@ Ko recap blocked at F5 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -1004,7 +1004,7 @@ Ko recap blocked at D3 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -1085,7 +1085,7 @@ HASH: 4F0DF41FC22ACBFAEBB9F5D2052C74DD rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -1236,7 +1236,7 @@ x.oxxxx rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichTaxRule]; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); out << "Score: " << finalScoreIfGameEndedNow(hist,board) << endl; makeMoveAssertLegal(hist, board, Location::getLoc(5,3,board.x_size), P_BLACK, __LINE__); @@ -1305,7 +1305,7 @@ x.oxxxx rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichTaxRule]; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); out << "Score: " << finalScoreIfGameEndedNow(hist,board) << endl; makeMoveAssertLegal(hist, board, Location::getLoc(5,3,board.x_size), P_BLACK, __LINE__); @@ -1374,7 +1374,7 @@ x.oxxxx rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichTaxRule]; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); out << "Score: " << finalScoreIfGameEndedNow(hist,board) << endl; makeMoveAssertLegal(hist, board, Location::getLoc(5,3,board.x_size), P_BLACK, __LINE__); @@ -1446,7 +1446,7 @@ x.oxxxx rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichTaxRule]; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); out << "Score: " << finalScoreIfGameEndedNow(hist,board) << endl; makeMoveAssertLegal(hist, board, Location::getLoc(5,3,board.x_size), P_BLACK, __LINE__); @@ -1520,7 +1520,7 @@ o.xoo.x rules.komi = -0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichTaxRule]; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); out << "Score: " << finalScoreIfGameEndedNow(hist,board) << endl; makeMoveAssertLegal(hist, board, Location::getLoc(6,5,board.x_size), P_WHITE, __LINE__); @@ -1590,7 +1590,7 @@ o.xoo.x rules.komi = -0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = taxRules[whichTaxRule]; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -1665,7 +1665,7 @@ Score: 8.5 rules.multiStoneSuicideLegal = false; rules.komi = 2.5f; rules.hasButton = buttonRule[whichRule]; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); out << "Score: " << finalScoreIfGameEndedNow(hist,board) << endl; makeMoveAssertLegal(hist, board, Location::getLoc(3,4,board.x_size), P_BLACK, __LINE__); @@ -1728,7 +1728,7 @@ Score: -3 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); Hash128 hasha; Hash128 hashb; Hash128 hashc; @@ -1880,7 +1880,7 @@ ooo.... rules.komi = 0.5f; rules.multiStoneSuicideLegal = true; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2004,7 +2004,7 @@ oo..... rules.komi = 0.5f; rules.multiStoneSuicideLegal = true; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -2050,7 +2050,7 @@ xxxxxxx rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -2109,7 +2109,7 @@ xxxo...oo { rules.scoringRule = Rules::SCORING_AREA; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); testAssert(hist.isGameFinished == true); @@ -2118,7 +2118,7 @@ xxxo...oo { rules.scoringRule = Rules::SCORING_AREA; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); testAssert(hist.isGameFinished == true); @@ -2127,7 +2127,7 @@ xxxo...oo { rules.scoringRule = Rules::SCORING_AREA; rules.taxRule = Rules::TAX_ALL; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); testAssert(hist.isGameFinished == true); @@ -2136,7 +2136,7 @@ xxxo...oo { rules.scoringRule = Rules::SCORING_TERRITORY; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2149,7 +2149,7 @@ xxxo...oo { rules.scoringRule = Rules::SCORING_TERRITORY; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2162,7 +2162,7 @@ xxxo...oo { rules.scoringRule = Rules::SCORING_TERRITORY; rules.taxRule = Rules::TAX_ALL; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2223,7 +2223,7 @@ xxxoxxxoo { rules.scoringRule = Rules::SCORING_AREA; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); testAssert(hist.isGameFinished == true); @@ -2232,7 +2232,7 @@ xxxoxxxoo { rules.scoringRule = Rules::SCORING_AREA; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); testAssert(hist.isGameFinished == true); @@ -2241,7 +2241,7 @@ xxxoxxxoo { rules.scoringRule = Rules::SCORING_AREA; rules.taxRule = Rules::TAX_ALL; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); testAssert(hist.isGameFinished == true); @@ -2250,7 +2250,7 @@ xxxoxxxoo { rules.scoringRule = Rules::SCORING_TERRITORY; rules.taxRule = Rules::TAX_NONE; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2263,7 +2263,7 @@ xxxoxxxoo { rules.scoringRule = Rules::SCORING_TERRITORY; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2276,7 +2276,7 @@ xxxoxxxoo { rules.scoringRule = Rules::SCORING_TERRITORY; rules.taxRule = Rules::TAX_ALL; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -2331,7 +2331,7 @@ xxo rules.taxRule = Rules::TAX_NONE; { - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); hist.printDebugInfo(out,board); @@ -2350,7 +2350,7 @@ xxo { out << "-----------------------" << endl; out << "Preventing encore" << endl; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__, true); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__, true); hist.printDebugInfo(out,board); @@ -2625,9 +2625,9 @@ Last moves pass pass pass pass rules.komi = 0.5f; rules.taxRule = Rules::TAX_SEKI; rules.multiStoneSuicideLegal = false; - stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0),P_BLACK,true); + stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0,false),P_BLACK,true); rules.multiStoneSuicideLegal = true; - stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0),P_BLACK,true); + stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 4 ..X. NPO PS0 E0 0000 0000 @@ -2769,11 +2769,11 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0),P_BLACK,false); - stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0),P_BLACK,false); + stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0,false),P_BLACK,false); + stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0,false),P_BLACK,false); rules.multiStoneSuicideLegal = true; - stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0),P_BLACK,false); - stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0),P_BLACK,false); + stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0,false),P_BLACK,false); + stressTest(emptyBoard22,BoardHistory(emptyBoard22,P_BLACK,rules,0,false),P_BLACK,false); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 4 X... NPO PS0 E0 0000 0000 @@ -2846,7 +2846,7 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - stressTest(koBoard71,BoardHistory(koBoard71,P_BLACK,rules,0),P_BLACK,true); + stressTest(koBoard71,BoardHistory(koBoard71,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 3 .O.OX.O NPX PS0 E0 0000000 0000000 @@ -3028,7 +3028,7 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0),P_BLACK,true); + stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 3 .X.. NPO PS0 E0 0000 0000 @@ -3080,7 +3080,7 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0),P_BLACK,true); + stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 4 X... NPO PS0 E0 0000 0000 @@ -3122,7 +3122,7 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0),P_BLACK,true); + stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 @@ -3172,7 +3172,7 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0),P_BLACK,true); + stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 3 .X.. NPO PS0 E0 0000 0000 @@ -3203,7 +3203,7 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_NONE; - stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0),P_BLACK,true); + stressTest(koBoard41,BoardHistory(koBoard41,P_BLACK,rules,0,false),P_BLACK,true); expected = R"%%( 5 .... NPX PS0 E0 0000 0000 4 ...X NPO PS0 E0 0000 0000 @@ -3233,7 +3233,7 @@ isResignation: 0 rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; baseRand.init("123"); - stressTest(koBoard71,BoardHistory(koBoard71,P_BLACK,rules,0),P_BLACK,false); + stressTest(koBoard71,BoardHistory(koBoard71,P_BLACK,rules,0,false),P_BLACK,false); expected = R"%%( 3 .O.OX.O NPX PS0 E0 0000000 0000000 4 .O.OXX. NPO PS0 E0 0000000 0000000 @@ -3287,8 +3287,8 @@ isResignation: 0 rules.komi = 0.5f; rules.multiStoneSuicideLegal = true; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); - BoardHistory hist2(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); + BoardHistory hist2(board,P_BLACK,rules,0,false); auto compareHists = [&]() { out << hist.moveHistory.size() << " " << hist2.moveHistory.size() << endl; @@ -3428,7 +3428,7 @@ XXXOO.OOO rules.komi = 0.5f; rules.multiStoneSuicideLegal = false; rules.taxRule = Rules::TAX_SEKI; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -3469,7 +3469,7 @@ HASH: 5C26A060FA78FD93FFF559C72BD7C6A4 int turnIdxToSetup = (int)sgf->moves.size(); Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdxToSetup); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdxToSetup, false); string expected = R"%%( HASH: EB867913318513FD9DE98EDE86AE8CE0 A B C D E F G H J K L M @@ -3548,7 +3548,7 @@ xoxx. rules.multiStoneSuicideLegal = false; rules.komi = 0.0f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(2,2,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -3587,7 +3587,7 @@ xoxx. rules.multiStoneSuicideLegal = false; rules.komi = 0.5f; rules.hasButton = true; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(2,2,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -3632,7 +3632,7 @@ xoxx. rules.multiStoneSuicideLegal = false; rules.komi = 0.0f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(4,3,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(4,5,board.x_size), P_WHITE, __LINE__); @@ -3665,7 +3665,7 @@ xoxx. rules.multiStoneSuicideLegal = false; rules.komi = 0.5f; rules.hasButton = true; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(4,3,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Location::getLoc(4,5,board.x_size), P_WHITE, __LINE__); @@ -3706,7 +3706,7 @@ xoxx. rules.multiStoneSuicideLegal = false; rules.komi = 0.5f; rules.hasButton = true; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Location::getLoc(2,2,board.x_size), P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -3745,7 +3745,7 @@ Illegal: (4,3) X rules.multiStoneSuicideLegal = false; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -3860,7 +3860,7 @@ Last moves pass pass pass J6 H9 H9 J6 rules.multiStoneSuicideLegal = false; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -3975,7 +3975,7 @@ Last moves pass pass pass J6 H9 H9 J7 rules.multiStoneSuicideLegal = false; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); @@ -4134,7 +4134,7 @@ Illegal: (8,3) X rules.multiStoneSuicideLegal = true; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -4307,7 +4307,7 @@ Last moves pass pass H7 G9 J6 H8 G8 J7 rules.multiStoneSuicideLegal = true; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -4645,7 +4645,7 @@ Last moves pass pass H7 G9 J6 H8 H8 J6 G8 J7 F9 H7 F9 H8 H7 pass rules.multiStoneSuicideLegal = true; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -4784,7 +4784,7 @@ Last moves pass pass pass pass H7 G9 J6 H8 H8 rules.multiStoneSuicideLegal = true; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -5011,7 +5011,7 @@ Last moves pass pass H7 G9 J6 H8 G8 H7 G8 J7 F9 rules.multiStoneSuicideLegal = true; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -5143,7 +5143,7 @@ Last moves pass pass pass pass H7 G9 F9 H8 rules.multiStoneSuicideLegal = true; rules.komi = 6.5f; rules.hasButton = false; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_BLACK, __LINE__); makeMoveAssertLegal(hist, board, Board::PASS_LOC, P_WHITE, __LINE__); @@ -5283,9 +5283,9 @@ Last moves pass pass pass pass H7 G9 F9 H7 for(int j = 0; jgetRulesOrFailAllowUnspecified(defaultRules); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, + Search::resolveAlwaysComputePassAliveUnderSuicideRules(bot->getSearch()->searchParams, bot->getSearch()->nnEvaluator)); hist.setKomi(overrideKomi); runBotOnPosition(bot,board,nextPla,hist,opts); } diff --git a/cpp/tests/testsearchmisc.cpp b/cpp/tests/testsearchmisc.cpp index 6ba122ac33..216173e5d6 100644 --- a/cpp/tests/testsearchmisc.cpp +++ b/cpp/tests/testsearchmisc.cpp @@ -29,7 +29,7 @@ void Tests::runNNOnTinyBoard(const string& modelFile, bool inputsNHWC, bool useN Player nextPla = P_WHITE; Rules rules = Rules::getTrompTaylorish(); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); const bool logToStdout = true; const bool logToStderr = false; @@ -73,7 +73,7 @@ void Tests::runNNSymmetries(const string& modelFile, bool inputsNHWC, bool useNH Player nextPla = P_BLACK; Rules rules = Rules::getTrompTaylorish(); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); const bool logToStdout = true; const bool logToStderr = false; @@ -132,7 +132,7 @@ void Tests::runNNOnManyPoses(const string& modelFile, bool inputsNHWC, bool useN Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, false); nnEval->evaluate(board,hist,nextPla,nnInputParams,buf,skipCache,includeOwnerMap); winProbs.push_back(buf.result->whiteWinProb); @@ -215,7 +215,7 @@ void Tests::runNNBatchingTest(const string& modelFile, bool inputsNHWC, bool use initialRules.hasButton = initialRules.scoringRule == Rules::SCORING_AREA && rand.nextBool(0.5); initialRules.whiteHandicapBonusRule = rand.nextBool(0.5) ? Rules::WHB_ZERO : rand.nextBool(0.5) ? Rules::WHB_N : Rules::WHB_N_MINUS_ONE; initialRules.komi = 7.5f + rand.nextInt(-10,10) * 0.5f; - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, turnIdx, false); items.emplace_back(board,hist,nextPla); } }; diff --git a/cpp/tests/testsearchnonn.cpp b/cpp/tests/testsearchnonn.cpp index 8c4fd5f12e..21221dbe83 100644 --- a/cpp/tests/testsearchnonn.cpp +++ b/cpp/tests/testsearchnonn.cpp @@ -56,7 +56,7 @@ void Tests::runNNLessSearchTests() { ......... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->runWholeSearch(nextPla); @@ -138,7 +138,7 @@ ooooooo ...o... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { //-------------------------------------- @@ -206,7 +206,7 @@ o..oo.x )%%"); Player nextPla = P_BLACK; Rules rules = Rules::getTrompTaylorish(); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("B5",board),nextPla,NULL); nextPla = getOpp(nextPla); hist.makeBoardMoveAssumeLegal(board,Location::ofString("pass",board),nextPla,NULL); @@ -379,7 +379,7 @@ o..o.oo Player nextPla = P_WHITE; Rules rules = Rules::getTrompTaylorish(); rules.multiStoneSuicideLegal = false; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { cout << "First with no pruning" << endl; @@ -441,7 +441,7 @@ o..o.oo ......... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->runWholeSearch(nextPla); @@ -512,7 +512,7 @@ o..o.oo ......... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->runWholeSearch(nextPla); @@ -553,7 +553,7 @@ o..o.oo ......... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setRootSymmetryPruningOnly({0,3,4,7}); @@ -595,7 +595,7 @@ o..o.oo ......... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setRootSymmetryPruningOnly({0,3,4,7}); @@ -652,7 +652,7 @@ xx......x } Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setRootSymmetryPruningOnly({0,3,4,7}); @@ -730,7 +730,7 @@ xx......x } Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setRootSymmetryPruningOnly({0,3,4,7}); @@ -808,7 +808,7 @@ xx......x } Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setRootSymmetryPruningOnly({0,3,4,7}); @@ -878,7 +878,7 @@ xx......x ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->runWholeSearch(nextPla); @@ -979,7 +979,7 @@ xxxxooo .xxxooo )%%"); Player nextPla = P_WHITE; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search2->setPosition(nextPla,board,hist); @@ -1069,7 +1069,7 @@ o.oo.oo .oooooo )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1140,7 +1140,7 @@ oo.oxxxxxxxxoo ooooo.oooooooo )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1205,7 +1205,7 @@ ooooo.oooooooo ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1260,7 +1260,7 @@ ooooo.oooooooo ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1316,7 +1316,7 @@ ooooo.oooooooo ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1370,7 +1370,7 @@ xxx...xxx xxxxxxxxx )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1484,7 +1484,7 @@ xxxxxxxxx ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1636,7 +1636,7 @@ ooooooo .o.oo.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { //-------------------------------------- @@ -1732,7 +1732,7 @@ oo..o..oo avoidMoveUntilByLoc[Board::PASS_LOC] = 3; Player nextPla = P_WHITE; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setAvoidMoveUntilByLoc(avoidMoveUntilByLoc,avoidMoveUntilByLoc); @@ -1800,7 +1800,7 @@ oo..o..oo avoidMoveUntilByLoc[Board::PASS_LOC] = 3; Player nextPla = P_WHITE; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setAvoidMoveUntilByLoc(avoidMoveUntilByLoc,avoidMoveUntilByLoc); @@ -1848,7 +1848,7 @@ oo..o..oo avoidMoveUntilByLoc[Board::PASS_LOC] = 10; Player nextPla = P_WHITE; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); search->setPosition(nextPla,board,hist); search->setAvoidMoveUntilByLoc(avoidMoveUntilByLoc,vector()); @@ -1907,7 +1907,7 @@ oo..o..oo ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -1974,7 +1974,7 @@ oo..o..oo ....... )%%"); Player nextPla = P_WHITE; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2041,7 +2041,7 @@ oxooox. .ooox.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2108,7 +2108,7 @@ oxooox. .ooox.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2147,7 +2147,7 @@ oxooox. .ooox.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2186,7 +2186,7 @@ oxooox. .ooox.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2225,7 +2225,7 @@ oxooox. .ooox.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2264,7 +2264,7 @@ xxoxx x.x.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2334,7 +2334,7 @@ xxoxx x.x.x )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2399,7 +2399,7 @@ x.x.x ............. )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); PrintTreeOptions options; options = options.maxDepth(1); @@ -2575,7 +2575,7 @@ x.x.x ....... )%%"); Player nextPla = P_BLACK; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); // Search 1: params A. search->setPosition(nextPla,board,hist); @@ -2642,7 +2642,7 @@ x.x.x BoardHistory hist; ExtraBlackAndKomi extraBlackAndKomi; OtherGameProperties otherGameProps; - gameInit.createGame(board,pla,hist,extraBlackAndKomi,NULL,PlaySettings(),otherGameProps,NULL); + gameInit.createGame(board,pla,hist,extraBlackAndKomi,NULL,PlaySettings(),otherGameProps,NULL,false); boardSizeDistribution[std::make_pair(board.x_size,board.y_size)] += 1; } for(int x = 2; x<=8; x += 2) { diff --git a/cpp/tests/testsearchv3.cpp b/cpp/tests/testsearchv3.cpp index 97f933196e..02af1924d0 100644 --- a/cpp/tests/testsearchv3.cpp +++ b/cpp/tests/testsearchv3.cpp @@ -28,7 +28,7 @@ static void runOwnershipAndMisc(NNEvaluator* nnEval, NNEvaluator* nnEval11, NNEv Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 40); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 40, false); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -72,7 +72,7 @@ static void runOwnershipAndMisc(NNEvaluator* nnEval, NNEvaluator* nnEval11, NNEv Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 43); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 43, false); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -255,7 +255,7 @@ static void runOwnershipAndMisc(NNEvaluator* nnEval, NNEvaluator* nnEval11, NNEv ....o.. ....... )%%"); - BoardHistory histA(boardA,nextPla,rules,0); + BoardHistory histA(boardA,nextPla,rules,0,false); Board boardB = Board::parseBoard(11,7,R"%%( ........... @@ -266,7 +266,7 @@ static void runOwnershipAndMisc(NNEvaluator* nnEval, NNEvaluator* nnEval11, NNEv ........... ........... )%%"); - BoardHistory histB(boardB,nextPla,rules,0); + BoardHistory histB(boardB,nextPla,rules,0,false); SearchParams params; params.maxVisits = 200; @@ -319,7 +319,7 @@ o..o..oxo ....x.oox ......ox. )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("H8",board),nextPla,NULL); nextPla = P_BLACK; @@ -355,7 +355,7 @@ xx.o.o.o. .xxo.o.o. ..xo.o.o. )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Board::PASS_LOC,nextPla,NULL); nextPla = P_WHITE; @@ -412,7 +412,7 @@ xx.o.o.o. ......... ......... )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params; params.maxVisits = 200; @@ -455,7 +455,7 @@ xx..xoooo ..x...ox. )%%"); board.numWhiteCaptures = 3; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); MiscNNInputParams nnInputParams; NNResultBuf buf; @@ -495,7 +495,7 @@ xx..xoooo ..x...ox. )%%"); board.numWhiteCaptures = 3; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); MiscNNInputParams nnInputParams; NNResultBuf buf; diff --git a/cpp/tests/testsearchv8.cpp b/cpp/tests/testsearchv8.cpp index 431ba103ca..7eb883918d 100644 --- a/cpp/tests/testsearchv8.cpp +++ b/cpp/tests/testsearchv8.cpp @@ -26,7 +26,7 @@ static void runV8TestsSize9(NNEvaluator* nnEval, NNEvaluator* nnEval9, NNEvaluat Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 3); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 3, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; @@ -62,7 +62,7 @@ static void runV8TestsRandomSym(NNEvaluator* nnEval, NNEvaluator* nnEval19Exact, Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 11); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 11, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; @@ -96,7 +96,7 @@ static void runV8TestsRandomSym(NNEvaluator* nnEval, NNEvaluator* nnEval19Exact, Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 8); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 8, false); SearchParams params = SearchParams::forTestsV1(); params.rootNumSymmetriesToSample = 8; @@ -131,7 +131,7 @@ static void runV8TestsRandomSym(NNEvaluator* nnEval, NNEvaluator* nnEval19Exact, Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 8); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 8, false); SearchParams paramsA = SearchParams::forTestsV1(); SearchParams paramsB = SearchParams::forTestsV1(); @@ -215,7 +215,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) const Player startPla = P_WHITE; const Rules rules = Rules::getTrompTaylorish(); - const BoardHistory hist(board,startPla,rules,0); + const BoardHistory hist(board,startPla,rules,0,false); SearchParams baseParams = SearchParams::forTestsV1(); baseParams.maxVisits = 400; baseParams.maxVisitsPondering = 600; @@ -484,7 +484,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 400; @@ -532,7 +532,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 24); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 24, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; params.antiMirror = true; @@ -547,7 +547,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 32); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 32, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; params.antiMirror = true; @@ -562,7 +562,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 124); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 124, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; params.antiMirror = true; @@ -587,7 +587,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 29); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 29, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; params.antiMirror = true; @@ -602,7 +602,7 @@ static void runV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFailAllowUnspecified(Rules::getTrompTaylorish()); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 83); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 83, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 200; params.antiMirror = true; @@ -630,7 +630,7 @@ static void runMoreV8Tests(NNEvaluator* nnEval, Logger& logger) Player nextPla; BoardHistory hist; Rules initialRules = sgf->getRulesOrFail(); - sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 8); + sgf->setupBoardAndHistAssumeLegal(initialRules, board, nextPla, hist, 8, false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 20; @@ -695,7 +695,7 @@ oxxxooxoooo Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { cout << "Without root ending bonus pts===================" << endl; cout << endl; @@ -720,7 +720,7 @@ oxxxooxoooo Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); rules.hasButton = true; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { cout << "Without root ending bonus pts===================" << endl; cout << endl; @@ -744,7 +744,7 @@ oxxxooxoooo Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { cout << "Without root ending bonus pts===================" << endl; cout << endl; @@ -769,7 +769,7 @@ oxxxooxoooo Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Chinese"); rules.hasButton = true; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { cout << "Without root ending bonus pts===================" << endl; cout << endl; @@ -793,7 +793,7 @@ oxxxooxoooo Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { cout << "Without root ending bonus pts===================" << endl; cout << endl; @@ -818,7 +818,7 @@ oxxxooxoooo Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,2); + BoardHistory hist(board,nextPla,rules,2,false); { cout << "Without root ending bonus pts===================" << endl; cout << endl; @@ -874,7 +874,7 @@ xxxx.xxoxxx Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { AsyncBot* bot = new AsyncBot(params2, nnEval, &logger, "async bot ending bonus points seed"); runBotOnPosition(bot, board, nextPla, hist, opts); @@ -899,7 +899,7 @@ xxxx.xxoxxx ......... ......... )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 400; @@ -939,7 +939,7 @@ xxxx.xxoxxx ......... ......... )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 10000; @@ -995,7 +995,7 @@ xxxx.xxoxxx Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams paramsFast = SearchParams::forTestsV1(); paramsFast.maxVisits = 5; @@ -1151,7 +1151,7 @@ xxxx.xxoxxx Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams paramsBase = SearchParams::forTestsV1(); paramsBase.maxVisits = 500; @@ -1289,7 +1289,7 @@ oooxxox.. { Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "Base, white to play" << endl; @@ -1303,7 +1303,7 @@ oooxxox.. { Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "Fill dame before pass, white to play" << endl; @@ -1318,7 +1318,7 @@ oooxxox.. { Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "Base, black to play" << endl; @@ -1332,7 +1332,7 @@ oooxxox.. { Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "Fill dame before pass, black to play" << endl; @@ -1370,7 +1370,7 @@ oooo.o.oo Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); rules.komi = 14; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "White to play" << endl; @@ -1389,7 +1389,7 @@ oooo.o.oo { Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "White to play" << endl; @@ -1431,7 +1431,7 @@ oooo.o.oo { Rules rules = Rules::parseRules("Japanese"); rules.komi = 8; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); cout << "===================================================================" << endl; cout << "White to play" << endl; @@ -1468,7 +1468,7 @@ o....xo.. Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Chinese"); rules.komi = 4; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Board::PASS_LOC,nextPla,NULL); nextPla = P_WHITE; @@ -1502,7 +1502,7 @@ o....xo.. Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); rules.komi = 7; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Board::PASS_LOC,nextPla,NULL); nextPla = P_BLACK; @@ -1550,7 +1550,7 @@ o....xo.. Player nextPlaBase = P_BLACK; Rules rules = Rules::parseRules("Japanese"); rules.komi = 6.5; - BoardHistory histBase(boardBase,nextPlaBase,rules,0); + BoardHistory histBase(boardBase,nextPlaBase,rules,0,false); SearchParams paramsBase = SearchParams::forTestsV1(); paramsBase.maxVisits = 1000; @@ -1677,7 +1677,7 @@ o....xo.. Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); rules.komi = 6.5; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params0 = SearchParams::forTestsV1(); params0.maxVisits = 1000; @@ -1767,7 +1767,7 @@ o....xo.. Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); rules.komi = 6.5; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params0 = SearchParams::forTestsV1(); params0.maxVisits = 1000; @@ -1824,7 +1824,7 @@ o....xo.. Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Japanese"); rules.komi = 25.5; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params0 = SearchParams::forTestsV1(); params0.maxVisits = 1000; @@ -1884,7 +1884,7 @@ ooox..o oxxxxxx xx..... )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 100; @@ -1922,7 +1922,7 @@ static void runMoreV8TestsRandomizedNNEvals(NNEvaluator* nnEval, Logger& logger) Player nextPla = P_BLACK; Rules rules = Rules::parseRules("AGA"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.rootNumSymmetriesToSample = 8; @@ -2020,7 +2020,7 @@ static void runV8SearchMultithreadTest(NNEvaluator* nnEval, Logger& logger) Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); rules.komi = 8.5; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 16000; @@ -2112,7 +2112,7 @@ xoxxoo........o.x.. Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); rules.komi = 6.5; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV1(); params.maxVisits = 8000; diff --git a/cpp/tests/testsearchv9.cpp b/cpp/tests/testsearchv9.cpp index 2bc4533c43..a1d5860cca 100644 --- a/cpp/tests/testsearchv9.cpp +++ b/cpp/tests/testsearchv9.cpp @@ -89,7 +89,7 @@ xx...x.o..x.. )%%"); Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); { SearchParams params = SearchParams::forTestsV2(); @@ -138,7 +138,7 @@ o.ox..oox { Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 75; @@ -155,7 +155,7 @@ o.ox..oox { Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 75; @@ -172,7 +172,7 @@ o.ox..oox { Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 75; @@ -189,7 +189,7 @@ o.ox..oox { Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 75; @@ -261,7 +261,7 @@ o.ox..oox { Rules rules = Rules::parseRules("Japanese"); rules.koRule = Rules::KO_SPIGHT; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("G3",board),P_BLACK,NULL); hist.makeBoardMoveAssumeLegal(board,Location::ofString("G1",board),P_WHITE,NULL); hist.makeBoardMoveAssumeLegal(board,Location::ofString("G2",board),P_BLACK,NULL); @@ -285,7 +285,7 @@ o.ox..oox { Rules rules = Rules::parseRules("Japanese"); rules.koRule = Rules::KO_SPIGHT; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("G3",board),P_BLACK,NULL); hist.makeBoardMoveAssumeLegal(board,Location::ofString("G1",board),P_WHITE,NULL); hist.makeBoardMoveAssumeLegal(board,Location::ofString("G2",board),P_BLACK,NULL); @@ -322,7 +322,7 @@ o.ox..oox ......... ......... )%%"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); vector avoidMoveUntilByLoc(Board::MAX_ARR_SIZE); avoidMoveUntilByLoc[Location::ofString("D5",board)] = 1; @@ -381,7 +381,7 @@ xoo..... cout << "Area scoring no friendly pass ok" << endl; Rules rules = Rules::parseRules("Chinese"); rules.friendlyPassOk = false; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 50; @@ -398,7 +398,7 @@ xoo..... cout << "Area scoring yes friendly pass ok" << endl; Rules rules = Rules::parseRules("Chinese"); rules.friendlyPassOk = true; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 50; @@ -415,7 +415,7 @@ xoo..... cout << "Area scoring no friendly pass ok but pass hacks" << endl; Rules rules = Rules::parseRules("Chinese"); rules.friendlyPassOk = false; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); SearchParams params = SearchParams::forTestsV2(); params.maxVisits = 50; @@ -445,7 +445,7 @@ o.....oo )%%"); Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Chinese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("E5",board),P_WHITE,NULL); nextPla = getOpp(nextPla); @@ -504,7 +504,7 @@ oo...ooo )%%"); Player nextPla = P_WHITE; Rules rules = Rules::parseRules("Japanese"); - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("E4",board),P_WHITE,NULL); nextPla = getOpp(nextPla); @@ -558,7 +558,7 @@ oo...ooo Player nextPla = P_BLACK; Rules rules = Rules::parseRules("Japanese"); rules.komi = -4; - BoardHistory hist(board,nextPla,rules,0); + BoardHistory hist(board,nextPla,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("A1",board),P_BLACK,NULL); hist.makeBoardMoveAssumeLegal(board,Location::ofString("B2",board),P_WHITE,NULL); hist.makeBoardMoveAssumeLegal(board,Location::ofString("C3",board),P_BLACK,NULL); @@ -592,7 +592,7 @@ oo...ooo Rules rules = Rules::parseRules("Chinese"); rules.friendlyPassOk = false; rules.komi = 5.5; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("E5",board),P_BLACK,NULL); Player nextPla = P_WHITE; @@ -626,7 +626,7 @@ xxxxxxxxx Rules rules = Rules::parseRules("Chinese"); rules.friendlyPassOk = false; rules.komi = 7.5; - BoardHistory hist(board,P_WHITE,rules,0); + BoardHistory hist(board,P_WHITE,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("pass",board),P_WHITE,NULL); Player nextPla = P_BLACK; @@ -696,7 +696,7 @@ x.ooxxxxx Rules rules = Rules::parseRules("Chinese"); rules.friendlyPassOk = false; rules.komi = 7.5; - BoardHistory hist(board,P_BLACK,rules,0); + BoardHistory hist(board,P_BLACK,rules,0,false); hist.makeBoardMoveAssumeLegal(board,Location::ofString("pass",board),P_BLACK,NULL); Player nextPla = P_WHITE; diff --git a/cpp/tests/testsgf.cpp b/cpp/tests/testsgf.cpp index 3843cd1f7d..6bd06079f7 100644 --- a/cpp/tests/testsgf.cpp +++ b/cpp/tests/testsgf.cpp @@ -26,7 +26,7 @@ void Tests::runSgfTests() { Rules rules; Player pla; rules = sgf->getRulesOrFailAllowUnspecified(rules); - sgf->setupInitialBoardAndHist(rules,board,pla,hist); + sgf->setupInitialBoardAndHist(rules,board,pla,hist,false); out << "placements" << endl; for(int i = 0; i < sgf->placements.size(); i++) { @@ -43,7 +43,7 @@ void Tests::runSgfTests() { out << "pla " << PlayerIO::playerToString(pla) << endl; hist.printDebugInfo(out,board); - sgf->setupBoardAndHistAssumeLegal(rules,board,pla,hist,sgf->moves.size()); + sgf->setupBoardAndHistAssumeLegal(rules,board,pla,hist,sgf->moves.size(),false); out << "Final board hist " << endl; out << "pla " << PlayerIO::playerToString(pla) << endl; hist.printDebugInfo(out,board); @@ -59,7 +59,7 @@ void Tests::runSgfTests() { Rules rules2; Player pla2; rules2 = sgf2->getRulesOrFail(); - sgf->setupBoardAndHistAssumeLegal(rules2,board2,pla2,hist2,sgf2->moves.size()); + sgf->setupBoardAndHistAssumeLegal(rules2,board2,pla2,hist2,sgf2->moves.size(),false); testAssert(rules2 == rules); testAssert(board2.pos_hash == board.pos_hash); testAssert(hist2.moveHistory.size() == hist.moveHistory.size()); diff --git a/cpp/tests/testsymmetries.cpp b/cpp/tests/testsymmetries.cpp index f686f9269b..c959e56a85 100644 --- a/cpp/tests/testsymmetries.cpp +++ b/cpp/tests/testsymmetries.cpp @@ -819,7 +819,7 @@ void Tests::runBoardSymmetryTests() { }; auto computeAndPrintMarkedSymDupArea = [&out,&printMarkedSymDupArea](const Board& board, Player pla, const std::vector* onlySymmetries) { - BoardHistory hist(board,pla,Rules::getTrompTaylorish(),0); + BoardHistory hist(board,pla,Rules::getTrompTaylorish(),0,false); bool isSymDupLoc[Board::MAX_ARR_SIZE]; vector validSymmetries; vector avoidMoves; diff --git a/cpp/tests/testtime.cpp b/cpp/tests/testtime.cpp index cad91e757e..16f31c429f 100644 --- a/cpp/tests/testtime.cpp +++ b/cpp/tests/testtime.cpp @@ -17,7 +17,7 @@ void Tests::runTimeControlsTests() { ......... ......... )%%"); - BoardHistory hist9Early(board9Early,P_BLACK,Rules(),0); + BoardHistory hist9Early(board9Early,P_BLACK,Rules(),0,false); Board board9Late = Board::parseBoard(9,9,R"%%( ..xoo..x. @@ -30,7 +30,7 @@ oox.ox... .o..ox.x. ...oxxx.. )%%"); - BoardHistory hist9Late(board9Late,P_BLACK,Rules(),0); + BoardHistory hist9Late(board9Late,P_BLACK,Rules(),0,false); Board board19Early = Board::parseBoard(19,19,R"%%( @@ -54,7 +54,7 @@ oox.ox... ................... ................... )%%"); - BoardHistory hist19Early(board19Early,P_BLACK,Rules(),0); + BoardHistory hist19Early(board19Early,P_BLACK,Rules(),0,false); Board board19Late = Board::parseBoard(19,19,R"%%( A B C D E F G H J K L M N O P Q R S T @@ -78,7 +78,7 @@ oox.ox... 2 . O . O X . X O O X1X . . . . X X O O 1 . . O . . X .2X3. O . . . . . . . X . )%%"); - BoardHistory hist19Late(board19Late,P_BLACK,Rules(),0); + BoardHistory hist19Late(board19Late,P_BLACK,Rules(),0,false); auto tryTimeControlsOnBoard = [](const string& s, const TimeControls& timeControls, const Board& board, const BoardHistory& hist, double lagBuffer) { double minTime; diff --git a/cpp/tests/testtrainingwrite.cpp b/cpp/tests/testtrainingwrite.cpp index fa5b202cd4..1c37f8c18b 100644 --- a/cpp/tests/testtrainingwrite.cpp +++ b/cpp/tests/testtrainingwrite.cpp @@ -59,6 +59,103 @@ static NNEvaluator* startNNEval( return nnEval; } +//Directly test that addRow records the reanalysis info in the expected global target channels. +static void runReanalysisRowChannelsTest() { + cout << "Running reanalysis row channels test" << endl; + + int inputsVersion = 3; + int maxRows = 4; + int nnXLen = 5; + int nnYLen = 5; + TrainingWriteBuffers buffers( + inputsVersion, maxRows, NNInputs::NUM_FEATURES_SPATIAL_V3, NNInputs::NUM_FEATURES_GLOBAL_V3, nnXLen, nnYLen, false + ); + + Board board(5,5); + Player nextPla = P_BLACK; + Rules rules = Rules::getTrompTaylorish(); + BoardHistory hist(board,nextPla,rules,0,false); + + vector policyTarget; + policyTarget.push_back(PolicyTargetMove(Board::PASS_LOC,1)); + vector whiteValueTargets(1); + vector whiteQValueTargets(1); + NNRawStats nnRawStats; + nnRawStats.whiteWinLoss = 0.0; + nnRawStats.whiteScoreMean = 0.0; + nnRawStats.policyEntropy = 0.0; + Rand rand("runReanalysisRowChannelsTest"); + + auto addRowWith = [&](const ReanalysisData& reanalysisData) { + buffers.addRow( + board,hist,nextPla, + hist,hist, + 0, + 1.0f, + 100, + &policyTarget, + NULL, + 0.5, 1.0, 1.0, + whiteValueTargets, + whiteQValueTargets, + 0, + 1.0f, + 1.0f, + 1.0f, + nnRawStats, + NULL,NULL,NULL,NULL,NULL, + false, + 0, + 0.5, + C_EMPTY, + 0.0, + Hash128(), + vector(), + false, + 0, + FinishedGameData::MODE_NORMAL, + NULL, + rand, + reanalysisData + ); + }; + + //Row 0: an ordinary row, not reanalyzed + addRowWith(ReanalysisData()); + //Row 1: a reanalyzed row + ReanalysisData reanalysisData; + reanalysisData.wasReanalyzed = true; + reanalysisData.usedOutcomeTargets = false; + reanalysisData.selectionPolicySurprise = 0.25f; + reanalysisData.selectionValueSurprise = 0.125f; + reanalysisData.originalNumVisits = 137; + addRowWith(reanalysisData); + + int numGlobalChannels = 80; + const float* row0 = buffers.globalTargetsNC.data + 0 * numGlobalChannels; + const float* row1 = buffers.globalTargetsNC.data + 1 * numGlobalChannels; + testAssert(buffers.globalTargetsNC.getActualDataLen(2) == 2 * numGlobalChannels); + + testAssert(row0[63] == 3.0f); + testAssert(row0[64] == 0.0f); + testAssert(row0[65] == 0.0f); + testAssert(row0[66] == 0.0f); + testAssert(row0[67] == 0.0f); + + testAssert(row1[63] == 3.0f); + testAssert(row1[64] == 1.0f); + testAssert(row1[65] == 0.25f); + testAssert(row1[66] == 0.125f); + testAssert(row1[67] == 137.0f); + + for(int c = 68; c<80; c++) { + testAssert(row0[c] == 0.0f); + testAssert(row1[c] == 0.0f); + } + + cout << "Reanalysis row channels test passed" << endl; +} + void Tests::runTrainingWriteTests() { bool inputsNHWC = true; bool useNHWC = false; @@ -67,6 +164,8 @@ void Tests::runTrainingWriteTests() { cout << "Running training write tests" << endl; NeuralNet::globalInitialize(); + runReanalysisRowChannelsTest(); + int maxRows = 256; double firstFileMinRandProp = 1.0; int debugOnlyWriteEvery = 5; @@ -100,7 +199,7 @@ void Tests::runTrainingWriteTests() { Board initialBoard(boardXLen,boardYLen); Player initialPla = P_BLACK; int initialEncorePhase = 0; - BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase); + BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase,false); ExtraBlackAndKomi extraBlackAndKomi; extraBlackAndKomi.extraBlack = 0; @@ -187,6 +286,145 @@ void Tests::runTrainingWriteTests() { rules = Rules::getSimpleTerritory(); run("testtrainingwrite-simpleterritory-sgf-c",rules,0.5,inputsVersion,9,1,9,1,true); + //Reanalysis of cheap-search positions + //(reanalysis with reduceVisits is tested in runMoreSelfplayTestsWithNN instead, since with the neural-netless + //random evals here the winrate never gets extreme enough for reduceVisits to trigger) + auto runReanalyze = [&]( + const string& seedBase, + bool useOutcomeTargets, + double policySurpriseDataWeight, + double valueSurpriseDataWeight, + bool useSearchValueSurprise + ) { + int inputsVsn = 3; + int nnXLen = 5; + int nnYLen = 5; + //Write every row rather than every 5th, so that the reanalyzed rows all show up in the test output. + TrainingDataWriter dataWriter(&cout,inputsVsn, maxRows, firstFileMinRandProp, nnXLen, nnYLen, 1, seedBase+"dwriter"); + + NNEvaluator* nnEval = startNNEval("/dev/null",seedBase+"nneval",logger,0,inputsNHWC,useNHWC,false); + + SearchParams params; + params.maxVisits = 80; + params.drawEquivalentWinsForWhite = 0.5; + + MatchPairer::BotSpec botSpec; + botSpec.botIdx = 0; + botSpec.botName = string("test"); + botSpec.nnEval = nnEval; + botSpec.baseParams = params; + + Rules gameRules = Rules::getTrompTaylorish(); + Board initialBoard(5,5); + Player initialPla = P_BLACK; + int initialEncorePhase = 0; + BoardHistory initialHist(initialBoard,initialPla,gameRules,initialEncorePhase,false); + + ExtraBlackAndKomi extraBlackAndKomi; + extraBlackAndKomi.extraBlack = 0; + extraBlackAndKomi.komiMean = gameRules.komi; + extraBlackAndKomi.komiStdev = 0; + bool doEndGameIfAllPassAlive = true; + bool clearBotBeforeSearch = true; + int maxMovesPerGame = 40; + auto shouldStop = []() noexcept { return false; }; + WaitableFlag* shouldPause = nullptr; + PlaySettings playSettings; + playSettings.initGamesWithPolicy = true; + playSettings.policyInitAreaProp = 0.04; + playSettings.sidePositionProb = 0.10; + playSettings.forSelfPlay = true; + playSettings.cheapSearchProb = 0.6; + playSettings.cheapSearchVisits = 20; + playSettings.cheapSearchTargetWeight = 0.0f; + playSettings.policySurpriseDataWeight = policySurpriseDataWeight; + playSettings.valueSurpriseDataWeight = valueSurpriseDataWeight; + playSettings.useSearchValueSurprise = useSearchValueSurprise; + playSettings.useReanalyze = true; + playSettings.reanalyzeProp = 0.5; + playSettings.reanalyzePolicySurpriseWeight = 1.0; + playSettings.reanalyzeValueSurpriseWeight = 1.0; + playSettings.reanalyzeSurpriseExponent = 1.0; + playSettings.reanalyzeUseOutcomeTargets = useOutcomeTargets; + //Lead estimation should apply to reanalyzed positions regardless of whether they use outcome targets + playSettings.estimateLeadProb = 0.5; + playSettings.estimateLeadVisits = 5; + + Rand rand(seedBase+"play"); + OtherGameProperties otherGameProps; + FinishedGameData* gameData = Play::runGame( + initialBoard,initialPla,initialHist,extraBlackAndKomi, + botSpec,botSpec, + seedBase+"search", + doEndGameIfAllPassAlive, clearBotBeforeSearch, + logger, false, false, + maxMovesPerGame, shouldStop, + shouldPause, + playSettings, otherGameProps, + rand, + nullptr, + nullptr + ); + + cout << "seedBase: " << seedBase << endl; + cout << gameData->startHist.getRecentBoard(0) << endl; + gameData->endHist.printDebugInfo(cout,gameData->endHist.getRecentBoard(0)); + + //Verify the reanalysis bookkeeping is consistent + size_t numMoves = gameData->targetWeightByTurn.size(); + testAssert(gameData->reanalysisByTurn.size() == numMoves); + int numReanalyzed = 0; + for(size_t i = 0; ireanalysisByTurn[i]; + if(reanalysisData.wasReanalyzed) { + numReanalyzed += 1; + testAssert(reanalysisData.usedOutcomeTargets == useOutcomeTargets); + //Reanalyzed positions redo the search from scratch with full visits + testAssert(gameData->policyTargetsByTurn[i].unreducedNumVisits == params.maxVisits); + //And get recorded with the weight a full-search turn would get + if(policySurpriseDataWeight == 0.0 && valueSurpriseDataWeight == 0.0) + testAssert(gameData->targetWeightByTurnUnrounded[i] == 1.0f); + else + testAssert(gameData->targetWeightByTurnUnrounded[i] > 0.0f); + } + } + cout << "Reanalyzed " << numReanalyzed << " of " << numMoves << " turns" << endl; + for(size_t i = 0; ireanalysisByTurn[i]; + cout << "turn " << i + << " weight " << gameData->targetWeightByTurnUnrounded[i] + << " visits " << gameData->policyTargetsByTurn[i].unreducedNumVisits; + if(reanalysisData.wasReanalyzed) { + cout << " reanalyzed selectionPolicySurprise " << reanalysisData.selectionPolicySurprise + << " selectionValueSurprise " << reanalysisData.selectionValueSurprise + << " originalNumVisits " << reanalysisData.originalNumVisits; + testAssert(reanalysisData.originalNumVisits > 0); + //Sanity bound: cheap searches don't clear the tree, so they can inherit a subtree of up to just + //under maxVisits visits from the preceding full search, and their maxPlayouts cap can add at most + //cheapSearchVisits new playouts on top of whatever was inherited. + testAssert(reanalysisData.originalNumVisits <= params.maxVisits + playSettings.cheapSearchVisits); + } + cout << endl; + } + + //Also exercise the SGF output, which should show v= rv= on reanalyzed moves + WriteSgf::writeSgf(cout,"Black","White",gameData->endHist,gameData,false,false); + cout << endl; + + dataWriter.writeGame(*gameData); + dataWriter.flushIfNonempty(); + + delete gameData; + delete nnEval; + cout << endl; + }; + + runReanalyze("testtrainingwrite-reanalyze-outcome",true,0.0,0.0,false); + runReanalyze("testtrainingwrite-reanalyze-searchonly",false,0.5,0.1,false); + //Same as the previous but with value surprise computed from each turn's own search rather than the + //smoothed future game result, for both the data weighting and the reanalyze selection. + runReanalyze("testtrainingwrite-reanalyze-searchvaluesurprise",false,0.5,0.1,true); + NeuralNet::globalCleanup(); } @@ -229,7 +467,7 @@ void Tests::runSelfplayInitTestsWithNN(const string& modelFile) { Board initialBoard(11,11); Player initialPla = P_BLACK; int initialEncorePhase = 0; - BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase); + BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase,false); ExtraBlackAndKomi extraBlackAndKomi; extraBlackAndKomi.extraBlack = numExtraBlack; @@ -384,7 +622,8 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { bool testValueSurpriseWeight, bool testHint, bool testResign, - bool testScaleDataWeight + bool testScaleDataWeight, + bool testSearchValueSurprise ) { nnEval->clearCache(); nnEval->clearStats(); @@ -427,7 +666,7 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { } - BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase); + BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase,false); if(testHint) initialHist.setInitialTurnNumber(10); @@ -460,6 +699,7 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { playSettings.valueSurpriseDataWeight = 0.15; playSettings.noResolveTargetWeights = true; } + playSettings.useSearchValueSurprise = testSearchValueSurprise; if(testResign) { playSettings.allowResignation = true; playSettings.resignThreshold = -0.9; @@ -478,6 +718,8 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { cout << "====================================================================================================" << endl; cout << "====================================================================================================" << endl; cout << "seedBase: " << seedBase << endl; + if(testSearchValueSurprise) + cout << "Rerunning the same game with useSearchValueSurprise=true - only the data weights should differ" << endl; Rand rand(seedBase+"play"); OtherGameProperties otherGameProps; @@ -527,16 +769,183 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { cout << endl; }; - run("testasym!",Rules::getTrompTaylorish(),true,false,false,false,false,false,false); - run("test lead!",Rules::getTrompTaylorish(),false,true,false,false,false,false,false); + run("testasym!",Rules::getTrompTaylorish(),true,false,false,false,false,false,false,false); + run("test lead!",Rules::getTrompTaylorish(),false,true,false,false,false,false,false,false); Rules r = Rules::getTrompTaylorish(); r.hasButton = true; - run("test lead int button!",r,false,true,false,false,false,false,false); - run("test surprise!",Rules::getTrompTaylorish(),false,false,true,false,false,false,false); - run("test value surprise!",Rules::getTrompTaylorish(),false,false,false,true,false,false,false); - run("test hint!",Rules::getTrompTaylorish(),false,false,false,false,true,false,false); - run("test resign!",Rules::getTrompTaylorish(),false,false,false,false,false,true,false); - run("test scale data weight!",Rules::getTrompTaylorish(),false,false,false,false,false,false,true); + run("test lead int button!",r,false,true,false,false,false,false,false,false); + run("test surprise!",Rules::getTrompTaylorish(),false,false,true,false,false,false,false,false); + run("test value surprise!",Rules::getTrompTaylorish(),false,false,false,true,false,false,false,false); + //Same seeds and settings as the previous, so it replays the identical game, but with value surprise for + //the data weighting computed from each turn's own search rather than the smoothed future game result. + //The recorded rows should be identical except for the row weights. + run("test value surprise!",Rules::getTrompTaylorish(),false,false,false,true,false,false,false,true); + run("test hint!",Rules::getTrompTaylorish(),false,false,false,false,true,false,false,false); + run("test resign!",Rules::getTrompTaylorish(),false,false,false,false,false,true,false,false); + run("test scale data weight!",Rules::getTrompTaylorish(),false,false,false,false,false,false,true,false); + + //Test reanalysis of cheap-search positions interacting with reduceVisits. Requires a real neural net so that + //the winrate actually gets extreme enough for reduceVisits to trigger - we play with an absurd komi so that + //the game is lopsided from the start. With policySurpriseDataWeight > 0, also exercises that reanalyzed rows + //whose weight was reduced are still eligible for the excess-policy-surprise inclusion. + auto runReanalyzeReduceVisits = [&](const string& seedBase, double policySurpriseDataWeight) { + nnEval->clearCache(); + nnEval->clearStats(); + + SearchParams params; + params.maxVisits = 100; + params.drawEquivalentWinsForWhite = 0.5; + + MatchPairer::BotSpec botSpec; + botSpec.botIdx = 0; + botSpec.botName = string("test"); + botSpec.nnEval = nnEval; + botSpec.baseParams = params; + + Rules rules = Rules::getTrompTaylorish(); + rules.komi = 60.0f; + Board initialBoard(11,11); + Player initialPla = P_BLACK; + int initialEncorePhase = 0; + BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase,false); + + ExtraBlackAndKomi extraBlackAndKomi; + extraBlackAndKomi.extraBlack = 0; + extraBlackAndKomi.komiMean = rules.komi; + extraBlackAndKomi.komiStdev = 0; + + bool doEndGameIfAllPassAlive = true; + bool clearBotBeforeSearch = true; + int maxMovesPerGame = 25; + auto shouldStop = []() noexcept { return false; }; + WaitableFlag* shouldPause = nullptr; + PlaySettings playSettings; + playSettings.initGamesWithPolicy = true; + playSettings.policyInitAreaProp = 0.04; + playSettings.forSelfPlay = true; + playSettings.cheapSearchProb = 0.6; + playSettings.cheapSearchVisits = 20; + playSettings.cheapSearchTargetWeight = 0.0f; + playSettings.reduceVisits = true; + playSettings.reduceVisitsThreshold = 0.8; + playSettings.reduceVisitsThresholdLookback = 3; + playSettings.reducedVisitsMin = 10; + playSettings.reducedVisitsWeight = 0.1f; + playSettings.policySurpriseDataWeight = policySurpriseDataWeight; + playSettings.useReanalyze = true; + playSettings.reanalyzeProp = 0.5; + playSettings.reanalyzePolicySurpriseWeight = 1.0; + playSettings.reanalyzeValueSurpriseWeight = 1.0; + playSettings.reanalyzeSurpriseExponent = 1.0; + playSettings.reanalyzeUseOutcomeTargets = true; + + string searchRandSeed = seedBase+"search"; + Search* bot = new Search(botSpec.baseParams, botSpec.nnEval, &logger, searchRandSeed); + + cout << "====================================================================================================" << endl; + cout << "seedBase: " << seedBase << endl; + + Rand rand(seedBase+"play"); + OtherGameProperties otherGameProps; + FinishedGameData* gameData = Play::runGame( + initialBoard,initialPla,initialHist,extraBlackAndKomi, + botSpec,botSpec, + bot,bot, + doEndGameIfAllPassAlive, clearBotBeforeSearch, + logger, false, false, + maxMovesPerGame, shouldStop, + shouldPause, + playSettings, otherGameProps, + rand, + nullptr, + nullptr + ); + + gameData->endHist.printDebugInfo(cout,gameData->endHist.getRecentBoard(0)); + + size_t numMoves = gameData->targetWeightByTurn.size(); + testAssert(gameData->reanalysisByTurn.size() == numMoves); + int numReanalyzed = 0; + int numReanalyzedWithReducedVisits = 0; + int numReanalyzedWithStrongReduction = 0; + for(size_t i = 0; ireanalysisByTurn[i]; + if(reanalysisData.wasReanalyzed) { + numReanalyzed += 1; + int64_t visits = gameData->policyTargetsByTurn[i].unreducedNumVisits; + float weight = gameData->targetWeightByTurnUnrounded[i]; + //Reanalyzed positions get the same reduceVisits treatment a full-search turn would have gotten, + //never dropping below the configured minimums. + testAssert(visits >= playSettings.reducedVisitsMin && visits <= params.maxVisits); + if(policySurpriseDataWeight == 0.0) { + //Without surprise-based redistribution, the weight is exactly the reduceVisits-attenuated weight + testAssert(weight >= playSettings.reducedVisitsWeight - 0.0001f && weight <= 1.0f); + if(visits < params.maxVisits) { + numReanalyzedWithReducedVisits += 1; + testAssert(weight < 1.0f); + } + if(visits <= params.maxVisits * 3 / 4 && weight <= 0.75f) + numReanalyzedWithStrongReduction += 1; + } + else { + //Surprise-based redistribution can move weight in either direction, including above 1, but the + //non-redistributed share of the reduceVisits-attenuated weight is always retained. + testAssert(weight >= (1.0 - policySurpriseDataWeight) * playSettings.reducedVisitsWeight - 0.0001); + if(visits < params.maxVisits) + numReanalyzedWithReducedVisits += 1; + if(visits <= params.maxVisits * 3 / 4) + numReanalyzedWithStrongReduction += 1; + } + } + } + //The game is lopsided from the start, so reduceVisits should actually trigger on some reanalyzed turns, + //including substantially and not just marginally. + testAssert(numReanalyzed > 0); + testAssert(numReanalyzedWithReducedVisits > 0); + testAssert(numReanalyzedWithStrongReduction > 0); + + //The surprise-based redistribution should exactly preserve the total weight of the game's turns. + //Every weighted turn here was searched with a freshly cleared tree, so its pre-redistribution weight can + //be reconstructed by inverting the reduceVisits interpolation from its visit count; cheap non-reanalyzed + //turns have zero weight both before and after. + { + double sumFinalWeights = 0.0; + double sumPreWeights = 0.0; + for(size_t i = 0; itargetWeightByTurnUnrounded[i]; + sumFinalWeights += weight; + if(weight > 0.0) { + double visits = (double)gameData->policyTargetsByTurn[i].unreducedNumVisits; + double visitReductionProp = ((double)params.maxVisits - visits) / ((double)params.maxVisits - (double)playSettings.reducedVisitsMin); + sumPreWeights += 1.0 + visitReductionProp * ((double)playSettings.reducedVisitsWeight - 1.0); + } + } + //Tolerance accounts for inverting through the integer rounding of the reduced visit counts + testAssert(std::abs(sumFinalWeights - sumPreWeights) < 0.01 * (double)numMoves + 0.01); + } + + cout << "Reanalyzed " << numReanalyzed << " of " << numMoves << " turns, " + << numReanalyzedWithReducedVisits << " with reduced visits, " + << numReanalyzedWithStrongReduction << " strongly reduced" << endl; + for(size_t i = 0; ireanalysisByTurn[i]; + cout << "turn " << i + << " weight " << gameData->targetWeightByTurnUnrounded[i] + << " visits " << gameData->policyTargetsByTurn[i].unreducedNumVisits; + if(reanalysisData.wasReanalyzed) + cout << " reanalyzed selectionPolicySurprise " << reanalysisData.selectionPolicySurprise + << " selectionValueSurprise " << reanalysisData.selectionValueSurprise + << " originalNumVisits " << reanalysisData.originalNumVisits; + cout << endl; + } + + delete gameData; + delete bot; + cout << endl; + }; + + runReanalyzeReduceVisits("test reanalyze reducevisits!",0.0); + runReanalyzeReduceVisits("test reanalyze reducevisits surprise!",0.5); //Test lead specifically on a final position auto testLeadOnBoard = [&]( @@ -554,7 +963,7 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { rules.komi = komi; Player pla = P_BLACK; - BoardHistory hist(board,pla,rules,0); + BoardHistory hist(board,pla,rules,0,false); int compensateKomiVisits = 50; OtherGameProperties otherGameProps; double lead = PlayUtils::computeLead(bot,bot,board,hist,pla,compensateKomiVisits,otherGameProps); @@ -590,7 +999,7 @@ void Tests::runMoreSelfplayTestsWithNN(const string& modelFile) { Board initialBoard(11,11); Player initialPla = P_BLACK; int initialEncorePhase = 0; - BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase); + BoardHistory initialHist(initialBoard,initialPla,rules,initialEncorePhase,false); ExtraBlackAndKomi extraBlackAndKomi; extraBlackAndKomi.extraBlack = 0; @@ -1012,7 +1421,7 @@ xxxxxxxx. Board board; Player nextPla; BoardHistory hist; - sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist); + sgf->setupInitialBoardAndHist(initialRules, board, nextPla, hist, false); for(size_t i = 0; imoves.size(); - sgf->setupBoardAndHistAssumeLegal(rules,initialBoard,initialPla,initialHist,turnIdx); + sgf->setupBoardAndHistAssumeLegal(rules,initialBoard,initialPla,initialHist,turnIdx,false); bool doEndGameIfAllPassAlive = true; bool clearBotAfterSearch = true; @@ -2899,9 +3308,9 @@ ox....... oox.x.... .o....... )%%"); - BoardHistory hist(board,P_BLACK,Rules::parseRules("tromp-taylor"),0); + BoardHistory hist(board,P_BLACK,Rules::parseRules("tromp-taylor"),0,false); testStatuses(board,hist,P_BLACK); - BoardHistory hist2(board,P_WHITE,Rules::parseRules("tromp-taylor"),0); + BoardHistory hist2(board,P_WHITE,Rules::parseRules("tromp-taylor"),0,false); testStatuses(board,hist2,P_WHITE); } //The neural net that we're using for this test actually produces a lot of nonsense because it doesn't @@ -2918,9 +3327,9 @@ ooxxx.o.. xo.ox.xoo .xxox.xx. )%%"); - BoardHistory hist(board,P_WHITE,Rules::parseRules("tromp-taylor"),0); + BoardHistory hist(board,P_WHITE,Rules::parseRules("tromp-taylor"),0,false); testStatuses(board,hist,P_WHITE); - BoardHistory hist2(board,P_WHITE,Rules::parseRules("japanese"),0); + BoardHistory hist2(board,P_WHITE,Rules::parseRules("japanese"),0,false); testStatuses(board,hist2,P_WHITE); } @@ -2933,3 +3342,152 @@ xo.ox.xoo NeuralNet::globalCleanup(); cout << "Done" << endl; } + +void Tests::runPassAliveSuicideGameTests() { + bool inputsNHWC = true; + bool useNHWC = false; + TestCommon::overrideForBackends(inputsNHWC, useNHWC); + + cout << "Running pass-alive-under-suicide-rules game and training write tests" << endl; + NeuralNet::globalInitialize(); + + const bool logToStdout = true; + const bool logToStderr = false; + const bool logTime = false; + Logger logger(nullptr, logToStdout, logToStderr, logTime); + + Rules rules = Rules::parseRules("chinese"); + testAssert(!rules.multiStoneSuicideLegal); + + //Runs a full game with the given per-bot alwaysComputePassAliveUnderSuicideRules settings. + //The nnEval is a debugSkipNeuralNet eval, which declares no support, so Auto resolves to false. + auto runGameWithModes = [&](const string& seedBase, enabled_t modeB, enabled_t modeW, bool forSelfPlay, const Rules& gameRules) { + NNEvaluator* nnEval = startNNEval("/dev/null",seedBase+"nneval",logger,0,inputsNHWC,useNHWC,false); + + SearchParams paramsB; + paramsB.maxVisits = 100; + paramsB.drawEquivalentWinsForWhite = 0.5; + paramsB.alwaysComputePassAliveUnderSuicideRules = modeB; + SearchParams paramsW = paramsB; + paramsW.alwaysComputePassAliveUnderSuicideRules = modeW; + + MatchPairer::BotSpec botSpecB; + botSpecB.botIdx = 0; + botSpecB.botName = string("botB"); + botSpecB.nnEval = nnEval; + botSpecB.baseParams = paramsB; + MatchPairer::BotSpec botSpecW; + botSpecW.botIdx = forSelfPlay ? 0 : 1; + botSpecW.botName = forSelfPlay ? string("botB") : string("botW"); + botSpecW.nnEval = nnEval; + botSpecW.baseParams = paramsW; + + Board initialBoard(7,7); + Player initialPla = P_BLACK; + int initialEncorePhase = 0; + BoardHistory initialHist(initialBoard,initialPla,gameRules,initialEncorePhase,false); + + ExtraBlackAndKomi extraBlackAndKomi; + extraBlackAndKomi.extraBlack = 0; + extraBlackAndKomi.komiMean = gameRules.komi; + extraBlackAndKomi.komiStdev = 0; + bool doEndGameIfAllPassAlive = true; + bool clearBotBeforeSearch = true; + int maxMovesPerGame = 60; + auto shouldStop = []() noexcept { return false; }; + WaitableFlag* shouldPause = nullptr; + PlaySettings playSettings; + if(forSelfPlay) { + playSettings.initGamesWithPolicy = true; + playSettings.policyInitAreaProp = 0.04; + playSettings.sidePositionProb = 0.10; + playSettings.forSelfPlay = true; + } + Rand rand(seedBase+"play"); + OtherGameProperties otherGameProps; + FinishedGameData* gameData = Play::runGame( + initialBoard,initialPla,initialHist,extraBlackAndKomi, + botSpecB,botSpecW, + seedBase+"search", + doEndGameIfAllPassAlive, clearBotBeforeSearch, + logger, false, false, + maxMovesPerGame, shouldStop, + shouldPause, + playSettings, otherGameProps, + rand, + nullptr, + nullptr + ); + delete nnEval; + return gameData; + }; + + //Selfplay game with the mode forced on for both bots. The game-level history records the mode, + //adjudication and featurization run under suicide-mode pass-alive computation, and every training + //row records it in globalTargetsNC channel 68. + { + int maxRows = 256; + double firstFileMinRandProp = 1.0; + int debugOnlyWriteEvery = 5; + int inputsVersion = 7; + TrainingDataWriter dataWriter(&cout,inputsVersion, maxRows, firstFileMinRandProp, 7, 7, debugOnlyWriteEvery, "passalivesuicidedwriter"); + FinishedGameData* gameData = runGameWithModes("passalive-forcedtrue", enabled_t::True, enabled_t::True, true, rules); + cout << "seedBase: passalive-forcedtrue" << endl; + cout << "Game-level alwaysComputePassAliveUnderSuicideRules: " << gameData->endHist.alwaysComputePassAliveUnderSuicideRules << endl; + testAssert(gameData->startHist.alwaysComputePassAliveUnderSuicideRules); + testAssert(gameData->endHist.alwaysComputePassAliveUnderSuicideRules); + gameData->endHist.printDebugInfo(cout,gameData->endHist.getRecentBoard(0)); + dataWriter.writeGame(*gameData); + dataWriter.flushIfNonempty(); + delete gameData; + } + + //Territory-scoring (japanese) game with the mode forced on. The game may be truncated by the + //move cap before reaching game-level territory scoring - in-search territory/encore logic still + //runs under the mode, and the direct scoring difference is unit-tested in testpassalivesuicide.cpp. + { + Rules japRules = Rules::parseRules("japanese"); + testAssert(!japRules.multiStoneSuicideLegal); + FinishedGameData* gameData = runGameWithModes("passalive-territory", enabled_t::True, enabled_t::True, true, japRules); + cout << "seedBase: passalive-territory" << endl; + cout << "Game-level alwaysComputePassAliveUnderSuicideRules: " << gameData->endHist.alwaysComputePassAliveUnderSuicideRules << endl; + testAssert(gameData->startHist.alwaysComputePassAliveUnderSuicideRules); + testAssert(gameData->endHist.alwaysComputePassAliveUnderSuicideRules); + gameData->endHist.printDebugInfo(cout,gameData->endHist.getRecentBoard(0)); + delete gameData; + } + + //Match-style game where only one bot uses the mode: game-level adjudication uses the AND of the + //two bots' resolutions, so it stays off even though botB's own searches use the mode. + { + FinishedGameData* gameData = runGameWithModes("passalive-mixed", enabled_t::True, enabled_t::False, false, rules); + cout << "seedBase: passalive-mixed" << endl; + cout << "Game-level alwaysComputePassAliveUnderSuicideRules: " << gameData->endHist.alwaysComputePassAliveUnderSuicideRules << endl; + testAssert(!gameData->startHist.alwaysComputePassAliveUnderSuicideRules); + testAssert(!gameData->endHist.alwaysComputePassAliveUnderSuicideRules); + gameData->endHist.printDebugInfo(cout,gameData->endHist.getRecentBoard(0)); + delete gameData; + } + + //With a net that does not declare support, Auto must be behaviorally identical to explicit False. + { + FinishedGameData* gameDataAuto = runGameWithModes("passalive-identity", enabled_t::Auto, enabled_t::Auto, true, rules); + FinishedGameData* gameDataFalse = runGameWithModes("passalive-identity", enabled_t::False, enabled_t::False, true, rules); + testAssert(!gameDataAuto->endHist.alwaysComputePassAliveUnderSuicideRules); + testAssert(!gameDataFalse->endHist.alwaysComputePassAliveUnderSuicideRules); + testAssert(gameDataAuto->endHist.moveHistory.size() == gameDataFalse->endHist.moveHistory.size()); + for(size_t i = 0; iendHist.moveHistory.size(); i++) { + testAssert(gameDataAuto->endHist.moveHistory[i].loc == gameDataFalse->endHist.moveHistory[i].loc); + testAssert(gameDataAuto->endHist.moveHistory[i].pla == gameDataFalse->endHist.moveHistory[i].pla); + } + testAssert(gameDataAuto->endHist.getRecentBoard(0).pos_hash == gameDataFalse->endHist.getRecentBoard(0).pos_hash); + testAssert(gameDataAuto->endHist.winner == gameDataFalse->endHist.winner); + testAssert(gameDataAuto->endHist.finalWhiteMinusBlackScore == gameDataFalse->endHist.finalWhiteMinusBlackScore); + cout << "Auto with a non-declaring net produced a game identical to explicit False" << endl; + delete gameDataAuto; + delete gameDataFalse; + } + + NeuralNet::globalCleanup(); + cout << "Done" << endl; +} diff --git a/cpp/tests/tinymodel.cpp b/cpp/tests/tinymodel.cpp index 80d5bcd7bf..5e7c66ba47 100644 --- a/cpp/tests/tinymodel.cpp +++ b/cpp/tests/tinymodel.cpp @@ -117,7 +117,7 @@ NNEvaluator* TinyModelTest::runTinyModelTest(const string& baseDir, Logger& logg const Player nextPla = P_BLACK; const Rules rules = Rules::getTrompTaylorish(); - const BoardHistory hist(board,nextPla,rules,0); + const BoardHistory hist(board,nextPla,rules,0,false); auto runOneTest = [&]() { MiscNNInputParams nnInputParams; @@ -278,7 +278,7 @@ NNEvaluator* TinyModelTest::runTinyModelTest(const string& baseDir, Logger& logg const Player nextPla = P_BLACK; const Rules rules = Rules::getTrompTaylorish(); - const BoardHistory hist(board,nextPla,rules,0); + const BoardHistory hist(board,nextPla,rules,0,false); auto runOneTest = [&]() { MiscNNInputParams nnInputParams; @@ -426,7 +426,7 @@ NNEvaluator* TinyModelTest::runTinyModelTest(const string& baseDir, Logger& logg const Player nextPla = P_BLACK; const Rules rules = Rules::getTrompTaylorish(); - const BoardHistory hist(board,nextPla,rules,0); + const BoardHistory hist(board,nextPla,rules,0,false); auto runOneTest = [&]() { MiscNNInputParams nnInputParams; diff --git a/docs/Analysis_Engine.md b/docs/Analysis_Engine.md index 7976bf65d3..5ebc67b40d 100644 --- a/docs/Analysis_Engine.md +++ b/docs/Analysis_Engine.md @@ -79,7 +79,7 @@ Explanation of fields (including some optional fields not present in the above q * See the documentation of `kata-get-rules` and `kata-set-rules` in [GTP Extensions](./GTP_Extensions.md) for a description of supported rules. * Some older neural net versions of KataGo do not support some rules options. If this is the case, then a warning will be issued and the rules will automatically be converted to the nearest rules that the neural net does support. - * `komi (integer or half-integer)`: Optional but HIGHLY recommended. Specify the komi for the game. If not specified, KataGo will guess a default value, generally 7.5 for area scoring, but 6.5 if using territory scoring, and 7.0 if area scoring with a button. Values of komi outside of [-150,150] are not supported. + * `komi (integer or half-integer)`: Optional but HIGHLY recommended. Specify the komi for the game. If not specified, KataGo will guess a default value, generally 7.5 for area scoring, but 6.5 if using territory scoring, and 7.0 if area scoring with a button. Values of komi outside of [-400,400] are not supported. * `whiteHandicapBonus (0|N|N-1)`: Optional. See `kata-get-rules` in [GTP Extensions](./GTP_Extensions.md) for what these mean. Can be used to override the handling of handicap bonus, taking precedence over `rules`. E.g. if you want `chinese` rules but with different compensation for handicap stones than Chinese rules normally use. You could also always specify this as 0 and do any adjustment you like on your own, by reporting an appropriate `komi`. * `boardXSize (integer)`: Required. The width of the board. Sizes > 19 are NOT supported unless KataGo has been compiled to support them (cpp/game/board.h, MAX_LEN = 19). KataGo's official neural nets have also not been trained for larger boards, but should work fine for mildly larger sizes (21,23,25). * `boardYSize (integer)`: Required. The height of the board. Sizes > 19 are NOT supported unless KataGo has been compiled to support them (cpp/game/board.h, MAX_LEN = 19). KataGo's official neural nets have also not been trained for larger boards, but should work fine for mildly larger sizes (21,23,25). @@ -100,7 +100,7 @@ Explanation of fields (including some optional fields not present in the above q * `moves` - an array of move locations to prohibit, such as `["C3","Q4","pass"]` * `untilDepth` - a positive integer, indicating the ply such that moves are prohibited before that ply. * Multiple dicts can specify different `untilDepth` for different sets of moves. The behavior is unspecified if a move is specified more than once with different `untilDepth`. - * `allowMoves (list of dicts)`: Optional. Same as `avoidMoves` except prohibits all moves EXCEPT the moves specified. Currently, the list of dicts must also be length 1. + * `allowMoves (list of dicts)`: Optional. Same as `avoidMoves` except prohibits all moves EXCEPT the moves specified. At most one dict may be specified per player (so the list may contain at most two dicts, one for `"B"` and one for `"W"`). * `overrideSettings (object)`: Optional. Specify any number of `"paramName":value` entries in this object to override those params from command line `CONFIG_FILE` for this query. Most search parameters can be overriden: `cpuctExploration`, `winLossUtilityFactor`, etc. Some notable parameters include: * `playoutDoublingAdvantage (float)`. A value of PDA from -3 to 3 will adjust KataGo's evaluation to assume that the opponent is NOT of equal strength/compte, but rather that the current player has 2^(PDA) times as many playouts as the opponent. Dynamic versions of this are used to significant effect in handicap games in GTP mode, see [GTP example config](../cpp/configs/gtp_example.cfg). * `wideRootNoise (float)`. See documentation for this parameter in [the example config](../cpp/configs/analysis_example.cfg) diff --git a/docs/GTP_Extensions.md b/docs/GTP_Extensions.md index 671313ae63..04c1e83c72 100644 --- a/docs/GTP_Extensions.md +++ b/docs/GTP_Extensions.md @@ -188,8 +188,10 @@ In addition to a basic set of [GTP commands](https://www.lysator.liu.se/~gunnar/ * A GTP controller should be prepared that when it cancels a search, it's possible that the search has just finished at the same time, and reports a real move rather than `play cancelled`. Unlike `kata-genmove_analyze`, since this command doesn't change the board state, this race should hopefully not be hard for a controller to handle. * The same note about pondering as for `kata-search` and `kata-search_cancellable` applies here. GTP controllers should reply with the `play` command confirming the move they wish to make as soon as possible. - * `kata-raw-nn SYMMETRY` + * `kata-raw-nn [COLOR] SYMMETRY [OPTIMISM]` * `SYMMETRY` should be an integer from 0-7 or "all". + * `COLOR` is optional and should be `b`/`black` or `w`/`white`. If specified, it must come before `SYMMETRY`, and the raw evaluation is performed as if it were that player's turn to move (similar to how `genmove COLOR` specifies the player). If omitted, the current player to move is used. + * `OPTIMISM` is optional and, if specified, must come after `SYMMETRY`. It is a value from 0 to 1 that overrides the policy optimism used for the evaluation. If omitted, the configured `rootPolicyOptimism` is used. * Reports the result of a raw neural net evaluation from KataGo, or multiple raw evaluations in the case of "all". * Output format is of the form `symmetry ...`, possibly with additional whitespace or newlines between any tokens. In the case of "all", multiple such outputs of this form are concatenated together. * Possible keys are currently @@ -209,9 +211,10 @@ In addition to a basic set of [GTP commands](https://www.lysator.liu.se/~gunnar/ ``` Any consumers of this data should attempt to be robust to any pattern of whitespace within the output, as well as possibly the future addition of new keys and values. The ordering of the keys is also not guaranteed - consumers should be capable of handling any permutation of them. - * `kata-raw-human-nn SYMMETRY` + * `kata-raw-human-nn [COLOR] SYMMETRY` * Similar to `kata-raw-nn`, but uses the human SL model for evaluation. * `SYMMETRY` should be an integer from 0-7 or "all". + * `COLOR` is optional and behaves as in `kata-raw-nn`. * This command is only available if a human SL model was provided using the `-human-model` command line option. Typically, this should be a model like `b18c384nbt-humanv0.bin.gz`. * **Output format differences from `kata-raw-nn`:** * Reports `whiteScore` instead of `whiteLead`. diff --git a/docs/releasepackaging/README.txt b/docs/releasepackaging/README.txt new file mode 100644 index 0000000000..9237191ee5 --- /dev/null +++ b/docs/releasepackaging/README.txt @@ -0,0 +1,101 @@ +KataGo v1.17.2 +https://github.com/lightvector/KataGo + +For neural nets from the latest run, download from here: +https://katagotraining.org/ +For nets from earlier runs, see: +https://katagoarchive.org/ + +For the human SL net (b18c384nbt-humanv0.bin.gz), it was released with: +https://github.com/lightvector/KataGo/releases/tag/v1.15.0 + +For differences between this version and older versions, see releases page at +https://github.com/lightvector/KataGo/releases/ + +On Linux, depending on versions of your libraries and some issues with the libzip library, there may sometimes be problems +getting the precompiled executables to work. However, on Linux, KataGo is usually relatively straighforward to compile from source. +See: https://github.com/lightvector/KataGo/blob/master/Compiling.md + +----------------------------------------------------- +USAGE: +----------------------------------------------------- +KataGo is just an engine and does not have its own graphical interface. So generally you will want to use KataGo along with a GUI or analysis program. +(https://github.com/lightvector/KataGo#guis) + +FIRST: Run a command like this to make sure KataGo is working, with the neural net file you downloaded. On OpenCL, it will also tune for your GPU. + +./katago benchmark # if you have default_gtp.cfg and default_model.bin.gz +./katago benchmark -model .bin.gz # if you have default_gtp.cfg +./katago benchmark -model .bin.gz -config gtp_custom.cfg # use this .bin.gz neural net and this .cfg file + +It will tell you a good number of threads. Edit your .cfg file and set "numSearchThreads" to that many to get best performance. + +OR: Run this command to have KataGo generate a custom gtp config for you based on answering some questions: + +./katago genconfig -model .bin.gz -output gtp_custom.cfg + +NEXT: A command like this will run KataGo's engine. This is the command to give to your [GUI or analysis program](#guis) so that it can run KataGo. + +./katago gtp # if you have default_gtp.cfg and default_model.bin.gz +./katago gtp -model .bin.gz # if you have default_gtp.cfg +./katago gtp -model .bin.gz -config gtp_custom.cfg # use this .bin.gz neural net and this .cfg file + +You may need to specify different paths when entering KataGo's command for a GUI program, e.g.: + +path/to/katago gtp -model path/to/.bin.gz +path/to/katago gtp -model path/to/.bin.gz -config path/to/gtp_custom.cfg + +KataGo should be able to work with any GUI program that supports GTP, as well as any analysis program that supports Leela Zero's `lz-analyze` command, such as Lizzie (https://github.com/featurecat/lizzie) or Sabaki (https://sabaki.yichuanshen.de/). + +----------------------------------------------------- +HUMAN-STYLE PLAY AND ANALYSIS: +----------------------------------------------------- + +You can also have KataGo imitate human play if you download the human SL model b18c384nbt-humanv0.bin.gz from https://github.com/lightvector/KataGo/releases/tag/v1.15.0, and run a command like the following, providing both a normal model and the human SL model: + +./katago.exe gtp -model .bin.gz -human-model b18c384nbt-humanv0.bin.gz -config gtp_human5k_example.cfg + +The gtp_human5k_example.cfg configures KataGo to imitate 5-kyu-level players. You can change it to imitate other ranks too, as well as to do many more things, including making KataGo play in a human style but still at a strong level or analyze in interesting ways. Read the config file itself for documentation on some of these possibilities! + +And see also this guide to using the human SL model, which is written from the perspective of the JSON-based analysis engine mentioned below, but is also applicable to gtp as well. +https://github.com/lightvector/KataGo/blob/master/docs/Analysis_Engine.md#human-sl-analysis-guide + +----------------------------------------------------- +OTHER THINGS YOU CAN DO: +----------------------------------------------------- + +Run a JSON-based analysis engine (https://github.com/lightvector/KataGo/blob/master/docs/Analysis_Engine.md) that can do efficient batched evaluations for a backend Go service: + +./katago analysis -model .gz -config .cfg + +Run a high-performance match engine that will play a pool of bots against each other sharing the same GPU batches and CPUs with each other: + +./katago match -config .cfg -log-file match.log -sgf-output-dir + +Force OpenCL tuner to re-tune: + +./katago tuner -config .cfg + +Print version: + +./katago version + +----------------------------------------------------- +TUNING FOR PERFORMANCE: +----------------------------------------------------- +You will very likely want to tune some of the parameters in `default_gtp.cfg` for your system for good performance, including the number of threads, fp16 usage, NN cache size, pondering settings, and so on. You can also adjust things like KataGo's resign threshold or utility function. Most of the relevant parameters should be be reasonably well documented directly inline in that config. + +There are other a few notes about usage and performance at : https://github.com/lightvector/KataGo + +----------------------------------------------------- +TROUBLESHOOTING: +----------------------------------------------------- +Some common issues are described here: +https://github.com/lightvector/KataGo#common-causes-of-errors + +Or, feel free to hop into the Computer Go discord chat, which has become a general chatroom for a variety of computer Go hobbyists and users, and which you can often find people willing to help. +https://discord.gg/fhDHgfk + + + + diff --git a/python/benchmark_fresh_model.py b/python/benchmark_fresh_model.py index 3dce4fe754..1fd1117b3c 100644 --- a/python/benchmark_fresh_model.py +++ b/python/benchmark_fresh_model.py @@ -4,18 +4,23 @@ import argparse import time import math +from collections import defaultdict import numpy as np import torch import torch._dynamo torch._dynamo.config.recompile_limit = 32 import torch.nn +import torch.distributed +import torch.multiprocessing from torch.amp import autocast, GradScaler from katago.train import modelconfigs from katago.train.model_pytorch import Model from katago.train.metrics_pytorch import Metrics from katago.train import data_processing_pytorch +from katago.train import trainloop_helpers +from katago.train.metrics_logging import accumulate_metrics def main(): @@ -39,11 +44,23 @@ def main(): parser.add_argument('-no-compile', help='Do not torch.compile', action='store_true') parser.add_argument('-use-tf32-matmul', help='Reduce float32 precision for speed on some gpus', action='store_true') parser.add_argument('-use-amp', help='Use automatic mixed precision (fp16 autocast + GradScaler) for training benchmark', action='store_true') + parser.add_argument('-use-bf16', help='Use bf16 AMP (autocast, no GradScaler) for trainloop benchmark. Mutually exclusive with -use-amp', action='store_true') parser.add_argument('-use-fp16', help='Cast model to fp16 for forward-only benchmark (inference only, no training)', action='store_true') parser.add_argument('-forward-only', help='Only benchmark the forward pass, skip training benchmarks', action='store_true') parser.add_argument('-override-config', help='Override model config params, e.g. "gab_d1=16,tab_num_freqs=8"', type=str, default=None) + parser.add_argument('-mode', help='phases = existing phase-attribution benchmark, trainloop = replicate the full train.py per-batch step for realistic throughput', choices=['phases', 'trainloop'], default='phases') + parser.add_argument('-multi-gpus', help='Comma-separated GPU ids for DDP trainloop benchmark, e.g. "0,1". Only valid with -mode trainloop', type=str, default=None) + parser.add_argument('-master-port', help='Localhost port for DDP', type=int, default=23456) + parser.add_argument('-print-every', help='Emulated train loss print interval in batches for trainloop mode', type=int, default=100) + parser.add_argument('-attn-logit-penalty-cap', help='Enable the attention logit bound penalty as in train.py, for benchmarking its overhead (trainloop mode)', type=float, default=None) + parser.add_argument('-attn-logit-penalty-coeff', help='Coeff for -attn-logit-penalty-cap', type=float, default=1e-3) + parser.add_argument('-attn-logit-penalty-batch-frac', help='Fraction of the batch to compute the penalty on, as in train.py', type=float, default=1.0) args = vars(parser.parse_args()) + if args["mode"] == "trainloop": + run_trainloop_benchmark(args) + return + model_kind = args["model_kind"] optimizer_kind = args["optimizer"] batch_size = args["batch_size"] @@ -85,41 +102,7 @@ def main(): model_config = modelconfigs.config_of_name[model_kind].copy() # Apply config overrides - if override_config_str: - for kv in override_config_str.split(","): - kv = kv.strip() - if not kv: - continue - key, val_str = kv.split("=", 1) - key = key.strip() - val_str = val_str.strip() - if key in model_config: - orig = model_config[key] - if isinstance(orig, bool): - model_config[key] = val_str.lower() in ("true", "1", "yes") - elif isinstance(orig, int): - model_config[key] = int(val_str) - elif isinstance(orig, float): - model_config[key] = float(val_str) - elif isinstance(orig, str): - model_config[key] = val_str - else: - import json - model_config[key] = json.loads(val_str) - print(f"Config override: {key} = {model_config[key]} (was {orig})") - else: - # New key: infer type from value string - if val_str.lower() in ("true", "false"): - model_config[key] = val_str.lower() == "true" - else: - try: - model_config[key] = int(val_str) - except ValueError: - try: - model_config[key] = float(val_str) - except ValueError: - model_config[key] = val_str - print(f"Config override (new): {key} = {model_config[key]}") + apply_config_overrides(model_config, override_config_str) print(f"Model kind: {model_kind}") print(f"Optimizer: {optimizer_kind}") @@ -279,6 +262,300 @@ def main(): print() +def apply_config_overrides(model_config, override_config_str): + if not override_config_str: + return + for kv in override_config_str.split(","): + kv = kv.strip() + if not kv: + continue + key, val_str = kv.split("=", 1) + key = key.strip() + val_str = val_str.strip() + if key in model_config: + orig = model_config[key] + if isinstance(orig, bool): + model_config[key] = val_str.lower() in ("true", "1", "yes") + elif isinstance(orig, int): + model_config[key] = int(val_str) + elif isinstance(orig, float): + model_config[key] = float(val_str) + elif isinstance(orig, str): + model_config[key] = val_str + else: + import json + model_config[key] = json.loads(val_str) + print(f"Config override: {key} = {model_config[key]} (was {orig})") + else: + # New key: infer type from value string + if val_str.lower() in ("true", "false"): + model_config[key] = val_str.lower() == "true" + else: + try: + model_config[key] = int(val_str) + except ValueError: + try: + model_config[key] = float(val_str) + except ValueError: + model_config[key] = val_str + print(f"Config override (new): {key} = {model_config[key]}") + + +def build_train_param_groups(raw_model): + """Build optimizer param groups mirroring train.py's get_param_groups. + Same group partition and use_muon assignment. Fixed nominal lr/wd since only throughput is measured here).""" + reg_dict = {} + raw_model.add_reg_dict(reg_dict) + param_groups = [] + num_reg_dict_params = 0 + for group_name in reg_dict: + if len(reg_dict[group_name]) > 0: + is_muon_suitable = group_name in ("normal", "normal_attn", "normal_gab", "gab_mlp", "tab_module") + param_groups.append({ + "params": reg_dict[group_name], + "group_name": group_name, + "lr": 1e-4, + "weight_decay": 1e-5, + "use_muon": is_muon_suitable, + }) + num_reg_dict_params += len(reg_dict[group_name]) + num_params = len(list(raw_model.parameters())) + assert num_params == num_reg_dict_params, "Reg dict does not have entries for all params in model" + return param_groups + + +def make_optimizer(optimizer_kind, param_groups, world_size, ns_steps, use_polar_express): + if optimizer_kind == "adam": + return torch.optim.AdamW(param_groups, lr=1e-4) + elif optimizer_kind in ("muon", "aurora"): + from muon.muon import MuonWithAuxAdam, SingleDeviceMuonWithAuxAdam + use_aurora = optimizer_kind == "aurora" + if world_size > 1: + return MuonWithAuxAdam(param_groups, adjust_lr_fn="match_rms_adamw", use_aurora=use_aurora, ns_steps=ns_steps, use_polar_express=use_polar_express) + else: + return SingleDeviceMuonWithAuxAdam(param_groups, adjust_lr_fn="match_rms_adamw", use_aurora=use_aurora, ns_steps=ns_steps, use_polar_express=use_polar_express) + else: + return torch.optim.SGD(param_groups, lr=1e-4, momentum=0.9) + + +def run_trainloop_benchmark(args): + if args["forward_only"] or args["use_fp16"]: + raise ValueError("-mode trainloop is a training benchmark; -forward-only / -use-fp16 are not supported") + if args["use_amp"] and args["use_bf16"]: + raise ValueError("-use-amp and -use-bf16 are mutually exclusive") + if args["multi_gpus"] is not None: + gpu_ids = [int(x) for x in args["multi_gpus"].split(",")] + else: + gpu_ids = [args["gpu"]] + world_size = len(gpu_ids) + args = dict(args) + args["gpu_ids"] = gpu_ids + + if world_size > 1: + torch.multiprocessing.spawn( + trainloop_worker, + nprocs=world_size, + args=(world_size, args), + ) + else: + trainloop_worker(0, 1, args) + + +def trainloop_worker(rank, world_size, args): + gpu_ids = args["gpu_ids"] + device = torch.device(f"cuda:{gpu_ids[rank]}") + torch.cuda.set_device(device) + + def rank0print(*a, **kw): + if rank == 0: + print(*a, **kw, flush=True) + + if world_size > 1: + os.environ['MASTER_ADDR'] = 'localhost' + os.environ['MASTER_PORT'] = str(args["master_port"]) + torch.distributed.init_process_group("nccl", rank=rank, world_size=world_size) + + if args["use_tf32_matmul"]: + torch.set_float32_matmul_precision('high') + rank0print("float32 matmul precision: high (TF32)") + torch.backends.cudnn.benchmark = True + trainloop_helpers.maybe_enable_compiled_autograd() + + model_kind = args["model_kind"] + batch_size = args["batch_size"] + pos_len = args["pos_len"] + use_amp = args["use_amp"] + use_bf16 = args["use_bf16"] + use_autocast = use_amp or use_bf16 + amp_dtype = torch.bfloat16 if use_bf16 else torch.float16 + no_compile = args["no_compile"] + num_iters = args["num_iters"] + warmup_iters = args["warmup_iters"] + print_every = args["print_every"] + + assert model_kind in modelconfigs.config_of_name, f"Unknown model kind: {model_kind}" + model_config = modelconfigs.config_of_name[model_kind].copy() + apply_config_overrides(model_config, args["override_config"]) + + rank0print(f"Trainloop benchmark: model={model_kind} optimizer={args['optimizer']} " + f"batch_size={batch_size}/gpu world_size={world_size} amp={use_amp} bf16={use_bf16} " + f"compile={not no_compile} iters={num_iters} warmup={warmup_iters}") + + # Fixed seed so loss trajectories are comparable across benchmark variants. + torch.manual_seed(20260718) + raw_model = Model(model_config, pos_len) + raw_model.initialize() + raw_model.to(device) + total_params = sum(p.numel() for p in raw_model.parameters()) + rank0print(f"Total parameters: {total_params:,}") + + attn_logit_penalty_cap = args["attn_logit_penalty_cap"] + attn_logit_penalty_coeff = args["attn_logit_penalty_coeff"] + if attn_logit_penalty_cap is not None: + raw_model.attn_logit_penalty_cap = attn_logit_penalty_cap + raw_model.attn_logit_penalty_batch_frac = args["attn_logit_penalty_batch_frac"] + rank0print(f"Attention logit penalty enabled: cap={attn_logit_penalty_cap} coeff={attn_logit_penalty_coeff} " + f"batch_frac={args['attn_logit_penalty_batch_frac']}") + + ddp_model = trainloop_helpers.wrap_model_for_training(raw_model, device, world_size, no_compile) + + param_groups = build_train_param_groups(raw_model) + optimizer = make_optimizer(args["optimizer"], param_groups, world_size, args["ns_steps"], args["use_polar_express"]) + use_muonlike = args["optimizer"] in ("muon", "aurora") + + metrics_obj = Metrics(world_size, raw_model) + batch = load_batch(args["data"], batch_size, pos_len, model_config, device) + + model_norms_only_at_print = trainloop_helpers.get_model_norms_only_at_print() + training_metrics_fn = trainloop_helpers.make_training_metrics_fn(metrics_obj, no_compile, model_norms_only_at_print) + + scaler = GradScaler("cuda") if use_amp else None + step_norm_tracker = trainloop_helpers.StepNormTracker(optimizer) + gnorm_watcher = trainloop_helpers.GnormWatcher() + running_sums = defaultdict(float) + running_weights = defaultdict(float) + + raw_model.train() + + # Matches train.py's cap structure for muon/adamw. + # Value only matters in that it should essentially never clip during a throughput benchmark. + gnorm_cap = (11000.0 if use_muonlike or args["optimizer"] == "adam" else 5500.0) * math.sqrt((batch_size * world_size) / 256.0) + + def one_batch(batch_count): + # Matches train.py: the print-batch extras run when the post-increment batch count hits the print interval. + is_print_batch = (batch_count + 1) % print_every == 0 + + optimizer.zero_grad(set_to_none=True) + if use_autocast: + with autocast("cuda", dtype=amp_dtype): + model_outputs = ddp_model( + batch["binaryInputNCHW"], + batch["globalInputNC"], + ) + else: + model_outputs = ddp_model( + batch["binaryInputNCHW"], + batch["globalInputNC"], + ) + postprocessed = raw_model.postprocess_output(model_outputs) + metrics = training_metrics_fn( + raw_model, + postprocessed, + extra_outputs=None, + batch=batch, + is_training=True, + soft_policy_weight_scale=1.0, + disable_optimistic_policy=False, + meta_kata_only_soft_policy=False, + value_loss_scale=1.0, + td_value_loss_scales=[0.4, 1.0, 1.0], + seki_loss_scale=0.35, + variance_time_loss_scale=0.5, + main_loss_scale=1.0, + intermediate_loss_scale=0.5 if raw_model.get_has_intermediate_head() else None, + include_model_norms=not model_norms_only_at_print, + ) + if model_norms_only_at_print and is_print_batch: + metrics.update(metrics_obj.get_model_norm_metrics(raw_model)) + + # DDP averages loss across instances, so to preserve LR as per-sample lr, we scale by world size. + loss = metrics["loss_sum"] * world_size + + # Attention logit bound penalty, mirroring train.py. + if attn_logit_penalty_cap is not None: + attn_pen_sum = raw_model.attn_logit_penalty_per_sample.mean() * batch_size + metrics["alogitpen_sum"] = attn_pen_sum.detach() + metrics["alogitubmax_batch"] = raw_model.attn_logit_ub_batch_max + loss = loss + attn_logit_penalty_coeff * attn_pen_sum * world_size + + if scaler is not None: + scaler.scale(loss).backward() + scaler.unscale_(optimizer) + else: + loss.backward() + + trainloop_helpers.clip_gradients_and_record(ddp_model, gnorm_cap, metrics, batch_size) + + step_norm_tracker.capture(ddp_model, is_print_batch=is_print_batch) + if scaler is not None: + scaler.step(optimizer) + scaler.update() + else: + optimizer.step() + step_norm_tracker.record(ddp_model, metrics) + + metrics = trainloop_helpers.detensorify_metrics(metrics) + gnorm_watcher.observe(metrics, gnorm_cap=gnorm_cap) + accumulate_metrics(running_sums, running_weights, metrics, batch_size, decay=0.999, new_weight=1.0) + return metrics + + rank0print("Warming up (includes compilation) ...") + t_warm_start = time.perf_counter() + for i in range(warmup_iters): + one_batch(i) + torch.cuda.synchronize() + if world_size > 1: + torch.distributed.barrier() + t_warm_end = time.perf_counter() + rank0print(f"Warmup took {t_warm_end - t_warm_start:.1f} s") + + torch.cuda.reset_peak_memory_stats() + iter_times = [] + t_prev = time.perf_counter() + t0 = t_prev + metrics = None + for i in range(num_iters): + metrics = one_batch(warmup_iters + i) + t_now = time.perf_counter() + iter_times.append(t_now - t_prev) + t_prev = t_now + torch.cuda.synchronize() + if world_size > 1: + torch.distributed.barrier() + t1 = time.perf_counter() + + peak_mem = torch.cuda.max_memory_allocated() / (1024.0 ** 3) + if rank == 0: + total = t1 - t0 + samples_per_sec = num_iters * batch_size * world_size / total + print() + print("=" * 80) + print("TRAINLOOP THROUGHPUT") + print("=" * 80) + print_timing_stats("Per-iter", iter_times) + print(f" Total: {total:.3f} s for {num_iters} iters") + print(f" Throughput: {samples_per_sec:,.1f} samples/s " + f"(batch {batch_size} x world_size {world_size})") + print(f" Peak GPU memory (rank 0): {peak_mem:.2f} GiB") + print(f" Final loss_sum: {metrics['loss_sum']:.2f}") + print(f" Bad-gnorm batches: {gnorm_watcher.total_bad}/{gnorm_watcher.total_observed} " + f"({gnorm_watcher.total_nonfinite} nonfinite, {gnorm_watcher.total_extreme} extreme, " + f"max consecutive {gnorm_watcher.max_consecutive_bad})") + + if world_size > 1: + torch.distributed.destroy_process_group() + + def load_batch(data_path, batch_size, pos_len, model_config, device): """Load a single batch from an npz file.""" num_bin_features = modelconfigs.get_num_bin_input_features(model_config) diff --git a/python/export_model_pytorch.py b/python/export_model_pytorch.py index 8d8937a93c..5567e66468 100644 --- a/python/export_model_pytorch.py +++ b/python/export_model_pytorch.py @@ -21,6 +21,7 @@ from katago.train import modelconfigs from katago.train.model_pytorch import Model, ResBlock, NestedBottleneckResBlock, TransformerAttentionBlock, TransformerFFNBlock, NestedBottleneckTransformerBlock +from katago.train.model_pytorch import compute_attn_logit_dataless_bounds from katago.train.load_model import load_model #Command and args------------------------------------------------------------------- @@ -38,6 +39,8 @@ parser.add_argument('-use-swa', help='Use SWA model', action="store_true", required=False) parser.add_argument('-export-14-as-15', help='Export model version 14 as 15', action="store_true", required=False) parser.add_argument('-export-15-or-16-as-17', help='Export model version 15 or 16 as 17', action="store_true", required=False) +parser.add_argument('-attn-logit-bound-limit', help='Refuse to export if the data-free attention logit bound of any layer exceeds this (inference backends mask off-board keys with -3e4 in fp16, so genuine logits must stay well below that)', type=float, default=2.5e4, required=False) +parser.add_argument('-ignore-attn-logit-bound', help='Export anyway when the attention logit bound limit is exceeded', action="store_true", required=False) args = vars(parser.parse_args()) @@ -87,6 +90,32 @@ def main(args): model, swa_model, other_state_dict = load_model(checkpoint_file, use_swa, device="cpu", verbose=True) model_config = model.config + # ATTN LOGIT BOUND GUARD ------------------------------------------------------- + # Data-free certification that attention logits can never approach the additive mask + # constants the inference backends use for off-board keys (-3e4 in fp16 backends). + # See compute_attn_logit_dataless_bounds for the derivation and its tightness. + model_to_export = swa_model if swa_model is not None else model + attn_logit_bounds = compute_attn_logit_dataless_bounds(model_to_export) + if len(attn_logit_bounds) > 0: + top = sorted(attn_logit_bounds.items(), key=lambda kv: -kv[1])[:5] + logging.info( + f"Data-free attention logit bound, max over {len(attn_logit_bounds)} layers: " + + ", ".join(f"{n}={v:.0f}" for n, v in top) + ) + worst_name, worst = top[0] + if worst > args["attn_logit_bound_limit"]: + msg = ( + f"Attention logit bound of layer {worst_name} is {worst:.0f}, exceeding the export limit " + f"{args['attn_logit_bound_limit']:.0f}. Logits of this magnitude threaten the correctness of the " + f"additive off-board masking constants in fp16 inference backends (-3e4). The bound is data-free " + f"and usually several times above actual logit magnitudes - measure the actual logits and/or " + f"consider train.py -attn-logit-penalty-cap. Use -ignore-attn-logit-bound to export anyway." + ) + if args["ignore_attn_logit_bound"]: + logging.warning("WARNING (-ignore-attn-logit-bound): " + msg) + else: + raise Exception(msg) + # WRITING MODEL ---------------------------------------------------------------- extension = ".bin" mode = "wb" @@ -120,6 +149,15 @@ def writestr(s): if model.trunk_final_rmsnorm: logging.warn("Autoupgrading v15 or v16 model to v17 due to trunk rmsnorm") version = 17 + elif model_config.get("always_compute_pass_alive_under_suicide_rules"): + logging.warn("Autoupgrading v15 or v16 model to v17 due to always_compute_pass_alive_under_suicide_rules") + version = 17 + + if model_config.get("always_compute_pass_alive_under_suicide_rules") and version < 17: + raise Exception( + "always_compute_pass_alive_under_suicide_rules is set but model would be exported as version " + + str(version) + " < 17, which can technically represent it but we're not outputting in practice" + ) writeln(model_name) writeln(version) @@ -149,6 +187,13 @@ def writestr(s): else: writeln(0) + # preferPassAliveUnderSuicideRules: 1 if the model expects pass-alive area input features + # to be computed as if multi-stone suicide were always legal, regardless of the actual + # suicide rule. Only version 17+ engines parse nonzero values here (checked above). + if model_config.get("always_compute_pass_alive_under_suicide_rules"): + writeln(1) + else: + writeln(0) # Write some dummy placeholders for future features writeln(0) writeln(0) @@ -156,7 +201,6 @@ def writestr(s): writeln(0) writeln(0) writeln(0) - writeln(0) def write_weights(weights): diff --git a/python/katago/train/data_processing_pytorch.py b/python/katago/train/data_processing_pytorch.py index ff1dbff7ba..d0f8dfe4c9 100644 --- a/python/katago/train/data_processing_pytorch.py +++ b/python/katago/train/data_processing_pytorch.py @@ -10,6 +10,21 @@ from ..train import modelconfigs +# Needs to be kept in sync with GLOBAL_TARGET_NUM_CHANNELS in trainingwrite.cpp C++ code among other places. +# Data format version 2 files (recorded in channel 63 of each row) had only 64 channels; they are zero-padded +# up to this width when loading, which correctly encodes "not reanalyzed" for the version 3 channels. +GLOBAL_TARGETS_NC_CHANNELS = 80 + +def pad_global_targets_nc(globalTargetsNC: np.ndarray) -> np.ndarray: + """Zero-pad older-format globalTargetsNC rows up to the current channel count.""" + num_channels = globalTargetsNC.shape[1] + if num_channels == GLOBAL_TARGETS_NC_CHANNELS: + return globalTargetsNC + assert num_channels < GLOBAL_TARGETS_NC_CHANNELS, f"globalTargetsNC has {num_channels} channels, more than the expected {GLOBAL_TARGETS_NC_CHANNELS}" + padded = np.zeros((globalTargetsNC.shape[0], GLOBAL_TARGETS_NC_CHANNELS), dtype=globalTargetsNC.dtype) + padded[:, :num_channels] = globalTargetsNC + return padded + def read_npz_training_data( npz_files, batch_size: int, @@ -58,7 +73,7 @@ def select_rank_rows(arr): binaryInputNCHWPacked = select_rank_rows(npz["binaryInputNCHWPacked"]) globalInputNC = select_rank_rows(npz["globalInputNC"]) policyTargetsNCMove = select_rank_rows(npz["policyTargetsNCMove"]).astype(np.float32) - globalTargetsNC = select_rank_rows(npz["globalTargetsNC"]) + globalTargetsNC = pad_global_targets_nc(select_rank_rows(npz["globalTargetsNC"])) scoreDistrN = select_rank_rows(npz["scoreDistrN"]).astype(np.float32) valueTargetsNCHW = select_rank_rows(npz["valueTargetsNCHW"]).astype(np.float32) if include_meta: diff --git a/python/katago/train/metrics_pytorch.py b/python/katago/train/metrics_pytorch.py index 2d723fd26a..a80989ae51 100644 --- a/python/katago/train/metrics_pytorch.py +++ b/python/katago/train/metrics_pytorch.py @@ -2,6 +2,7 @@ import math from ..train.model_pytorch import EXTRA_SCORE_DISTR_RADIUS, Model, compute_gain, ExtraOutputs, MetadataEncoder +from ..train.trainloop_helpers import env_flag import torch import torch.nn @@ -36,20 +37,43 @@ def __init__(self, world_size: int, raw_model: Model): self.scoremean_multiplier = raw_model.scoremean_multiplier self.score_belief_offset_vector = raw_model.value_head.score_belief_offset_vector - self.moving_unowned_proportion_sum = 0.0 - self.moving_unowned_proportion_weight = 0.0 + # Keeping the seki moving average on the model device avoids a per-batch + # GPU->CPU sync in the training loss and lets the loss be torch.compiled. + self.seki_ema_on_device = env_flag("KATAGO_SEKI_EMA_ON_DEVICE", default=True) + if self.seki_ema_on_device: + metric_device = self.score_belief_offset_vector.device + self.moving_unowned_proportion_sum = torch.zeros([], device=metric_device, dtype=torch.float32) + self.moving_unowned_proportion_weight = torch.zeros([], device=metric_device, dtype=torch.float32) + else: + self.moving_unowned_proportion_sum = 0.0 + self.moving_unowned_proportion_weight = 0.0 def state_dict(self): + # Checkpoints always store plain floats regardless of where the moving + # average lives at runtime. + moving_sum = self.moving_unowned_proportion_sum + moving_weight = self.moving_unowned_proportion_weight + if isinstance(moving_sum, torch.Tensor): + moving_sum = moving_sum.item() + if isinstance(moving_weight, torch.Tensor): + moving_weight = moving_weight.item() return dict( - moving_unowned_proportion_sum = self.moving_unowned_proportion_sum, - moving_unowned_proportion_weight = self.moving_unowned_proportion_weight, + moving_unowned_proportion_sum = moving_sum, + moving_unowned_proportion_weight = moving_weight, ) def load_state_dict(self, state_dict: Dict[str,Any]): - if isinstance(state_dict["moving_unowned_proportion_sum"],torch.Tensor): - self.moving_unowned_proportion_sum = state_dict["moving_unowned_proportion_sum"].item() + moving_sum = state_dict["moving_unowned_proportion_sum"] + moving_weight = state_dict["moving_unowned_proportion_weight"] + if isinstance(moving_sum, torch.Tensor): + moving_sum = moving_sum.item() + if isinstance(moving_weight, torch.Tensor): + moving_weight = moving_weight.item() + if self.seki_ema_on_device: + self.moving_unowned_proportion_sum.fill_(moving_sum) + self.moving_unowned_proportion_weight.fill_(moving_weight) else: - self.moving_unowned_proportion_sum = state_dict["moving_unowned_proportion_sum"] - self.moving_unowned_proportion_weight = state_dict["moving_unowned_proportion_weight"] + self.moving_unowned_proportion_sum = moving_sum + self.moving_unowned_proportion_weight = moving_weight def loss_policy_player_samplewise(self, pred_logits, target_probs, weight, global_weight): assert pred_logits.shape[1:] == (self.policy_len,) @@ -185,10 +209,15 @@ def loss_seki_samplewise(self, pred_logits, target, target_ownership, weight, ma unowned_proportion = torch.mean(unowned_proportion * weight) if is_training: if not skip_moving_update: - self.moving_unowned_proportion_sum *= 0.998 - self.moving_unowned_proportion_weight *= 0.998 - self.moving_unowned_proportion_sum += unowned_proportion.item() - self.moving_unowned_proportion_weight += 1.0 + if self.seki_ema_on_device: + with torch.no_grad(): + self.moving_unowned_proportion_sum.mul_(0.998).add_(unowned_proportion.detach()) + self.moving_unowned_proportion_weight.mul_(0.998).add_(1.0) + else: + self.moving_unowned_proportion_sum *= 0.998 + self.moving_unowned_proportion_weight *= 0.998 + self.moving_unowned_proportion_sum += unowned_proportion.item() + self.moving_unowned_proportion_weight += 1.0 moving_unowned_proportion = self.moving_unowned_proportion_sum / self.moving_unowned_proportion_weight seki_weight_scale = 8.0 * 0.005 / (0.005 + moving_unowned_proportion) else: @@ -321,6 +350,12 @@ def get_model_norms(raw_model): return norms + @staticmethod + def get_model_norm_metrics(raw_model): + """Model norm metrics in the naming used by the training metrics dict.""" + norms = Metrics.get_model_norms(raw_model) + return {f"norm_{group_name}_batch": value for group_name, value in norms.items()} + def get_specific_norms_and_gradient_stats(self,raw_model): with torch.no_grad(): params = {} @@ -403,6 +438,7 @@ def metrics_dict_batchwise( variance_time_loss_scale, main_loss_scale, intermediate_loss_scale, + include_model_norms=True, ): results = self.metrics_dict_batchwise_single_heads_output( raw_model, @@ -417,6 +453,7 @@ def metrics_dict_batchwise( seki_loss_scale=seki_loss_scale, variance_time_loss_scale=variance_time_loss_scale, is_intermediate=False, + include_model_norms=include_model_norms, ) if main_loss_scale is not None: results["loss_sum"] = main_loss_scale * results["loss_sum"] @@ -449,6 +486,12 @@ def metrics_dict_batchwise( results["I"+key] = value results["loss_sum"] = results["loss_sum"] + intermediate_loss_scale * iresults["loss_sum"] + # Only the aggregate loss participates in backward. Keeping every + # logging component attached makes autograd treat dozens of metrics + # as differentiable outputs and retain their graphs until logging. + for key, value in results.items(): + if key != "loss_sum" and isinstance(value, torch.Tensor): + results[key] = value.detach() return results def metrics_dict_batchwise_single_heads_output( @@ -465,6 +508,7 @@ def metrics_dict_batchwise_single_heads_output( seki_loss_scale, variance_time_loss_scale, is_intermediate, + include_model_norms=True, ): ( policy_logits, @@ -894,8 +938,6 @@ def metrics_dict_batchwise_single_heads_output( global_weight, ) - norms = self.get_model_norms(raw_model) - extra_results = { "wsum": weight * self.world_size, "nsamp": nsamples * self.world_size, @@ -904,8 +946,8 @@ def metrics_dict_batchwise_single_heads_output( "sekiweightscale_sum": seki_weight_scale * weight, } - for group_name in norms: - extra_results[f"norm_{group_name}_batch"] = norms[group_name] + if include_model_norms: + extra_results.update(self.get_model_norm_metrics(raw_model)) for key,value in extra_results.items(): results[key] = value diff --git a/python/katago/train/model_pytorch.py b/python/katago/train/model_pytorch.py index d21c1a00ae..3240420651 100644 --- a/python/katago/train/model_pytorch.py +++ b/python/katago/train/model_pytorch.py @@ -15,6 +15,13 @@ from torch.amp import autocast from ..train import modelconfigs +from ..train.trainloop_helpers import env_flag + +# Under AMP, cast the small cos/sin rotation tables to the input dtype before the +# batch-sized Q/K rotation, instead of promoting the batch-sized rotation +# intermediates to FP32. The trigonometric functions themselves remain FP32. +# Set the environment variable to 0 for a full-FP32 rotation regression comparison. +LEARNED_ROPE_CAST_TO_INPUT_DTYPE = env_flag("KATAGO_LEARNED_ROPE_CAST_TO_INPUT_DTYPE", default=True) EXTRA_SCORE_DISTR_RADIUS = 60 @@ -282,6 +289,10 @@ def __init__( self.running_avg_momentum = config["bnorm_running_avg_momentum"] self.fixup_use_gamma = fixup_use_gamma self.is_last_batchnorm = is_last_batchnorm + # May be set to True externally (see Model transformer_skip_redundant_masks) + # when everything downstream of this norm is sound without zeroing + # off-board values. Not a checkpointed quantity. + self.skip_mask = False self.gamma_weight_decay_center_1 = config.get("gamma_weight_decay_center_1",False) self.use_gamma = ( ("bnorm_use_gamma" in config and config["bnorm_use_gamma"]) or @@ -381,22 +392,35 @@ def _compute_bnorm_values(self, x, mask, mask_sum: float): return zeromean_x, mean, std def apply_gamma_beta_scale_mask(self, x, mask): + # x is either NCHW (params broadcast as (1,C,1,1)) + # or NSC (params broadcast as (1,1,C)) + # mask matches correspondingly. + if x.dim() == 3: + beta = self.beta.reshape(1, 1, -1) + gamma = self.gamma.reshape(1, 1, -1) if self.gamma is not None else None + else: + beta = self.beta + gamma = self.gamma + if self.scale is not None: - if self.gamma is not None: + if gamma is not None: if self.gamma_weight_decay_center_1: - return (x * ((self.gamma+1.0) * self.scale) + self.beta) * mask + out = x * ((gamma+1.0) * self.scale) + beta else: - return (x * (self.gamma * self.scale) + self.beta) * mask + out = x * (gamma * self.scale) + beta else: - return (x * self.scale + self.beta) * mask + out = x * self.scale + beta else: - if self.gamma is not None: + if gamma is not None: if self.gamma_weight_decay_center_1: - return (x * (self.gamma+1.0) + self.beta) * mask + out = x * (gamma+1.0) + beta else: - return (x * self.gamma + self.beta) * mask + out = x * gamma + beta else: - return (x + self.beta) * mask + out = x + beta + if self.skip_mask: + return out + return out * mask def forward(self, x, mask, mask_sum_hw, mask_sum: float): @@ -661,19 +685,24 @@ def add_brenorm_clippage(self, upper_rclippage, lower_rclippage, dclippage): def forward(self, x, mask, mask_sum_hw, mask_sum: float, extra_outputs: Optional[ExtraOutputs], block_shared_data: Optional[Dict[str, Any]] = None): """ Parameters: - x: NCHW - mask: N1HW + x: NCHW, with mask N1HW, or NSC sequence layout (1x1 conv only), with mask NS1 mask_sum_hw: N111 mask_sum: scalar - Returns: NCHW + Returns: same layout as x """ out = x out = self.norm(out, mask=mask, mask_sum_hw=mask_sum_hw, mask_sum=mask_sum) out = self.act(out) # print("TENSOR AFTER NORMACT") # print(out) - if self.convpool is not None: + if x.dim() == 3: + # Sequence layout: a 1x1 convolution is a linear map over channels. + assert self.convpool is None and self.conv1x1 is None + weight = self.conv.weight + assert weight.shape[2] == 1 and weight.shape[3] == 1 + out = torch.nn.functional.linear(out, weight.reshape(weight.shape[0], weight.shape[1])) + elif self.convpool is not None: out = self.convpool(out, mask=mask, mask_sum_hw=mask_sum_hw, mask_sum=mask_sum, extra_outputs=extra_outputs) else: if self.conv1x1 is not None: @@ -1286,6 +1315,9 @@ def _rotate(x, cos, sin): if cos.dim() == 3: cos = cos.unsqueeze(0) # (1, S, H, P) sin = sin.unsqueeze(0) + if LEARNED_ROPE_CAST_TO_INPUT_DTYPE: + cos = cos.to(dtype=x.dtype) + sin = sin.to(dtype=x.dtype) out = torch.stack([x0 * cos - x1 * sin, x0 * sin + x1 * cos], dim=-1) return out.reshape(B, S, H, D).type_as(x) @@ -1317,6 +1349,42 @@ def compute_gab_fourier_features(dr, dc, freqs): GAB_TEMPLATES = "gab_templates" TAB_KQ = "tab_kq" REGISTER_STATE = "register_state" +FLEX_BLOCK_MASK = "flex_block_mask" +# When present in block_shared_data (training-time attention logit penalty), each attention layer +# appends its per-(batch,head) differentiable upper bound on pre-mask attention logit magnitude. +ATTN_LOGIT_UB = "attn_logit_ub" + + +_flex_attention_compiled = None + +def get_flex_attention_fn(): + """flex_attention, compiled on first use. When called inside an outer + torch.compile region, dynamo traces through to the flex_attention HOP. + In eager mode the compiled wrapper avoids flex's slow decomposed fallback.""" + global _flex_attention_compiled + if _flex_attention_compiled is None: + from torch.nn.attention.flex_attention import flex_attention + _flex_attention_compiled = torch.compile(flex_attention, dynamic=False) + return _flex_attention_compiled + + +def build_flex_attention_block_mask(mask): + """Build a flex-attention BlockMask for the board key-padding mask. + + mask: N1HW (or N11S) float 0/1 mask. The result is shared by every + attention layer in the forward pass. Only key positions are masked. + Off-board query rows produce garbage exactly like the additive-mask path. + """ + from torch.nn.attention.flex_attention import create_block_mask + batch_size = mask.shape[0] + seq_len = mask.numel() // batch_size + mask_bs = mask.reshape(batch_size, seq_len) > 0.5 + + def mask_mod(b, h, q_idx, kv_idx): + return mask_bs[b, kv_idx] + + return create_block_mask(mask_mod, batch_size, None, seq_len, seq_len, device=mask.device) + @dataclass class RegisterState: @@ -1976,6 +2044,38 @@ def forward(self, x, mask, mask_sum_hw, mask_sum: float, extra_outputs: Optional return out +# Hack for measuring attention logit ranges +# ATTN_LOGIT_STATS_CAPTURE = None +# def _capture_attn_logit_stats(store, name, q, k, scale, mask, batch_size, seq_len): +# with torch.no_grad(): +# qn = torch.linalg.vector_norm(q.float(), dim=-1) # (B, H, S) +# kn = torch.linalg.vector_norm(k.float(), dim=-1) +# ub = scale * qn.amax(dim=-1) * kn.amax(dim=-1) # (B, H) +# ub_entry = store.setdefault("UB:" + name, [ub.amax(), ub.mean(), torch.zeros_like(ub.mean())]) +# ub_entry[0] = torch.maximum(ub_entry[0], ub.amax()) +# ub_entry[1] = ub_entry[1] + ub.mean() +# ub_entry[2] = ub_entry[2] + 1.0 +# logits = torch.matmul(q.float(), k.float().transpose(-2, -1)) * scale # (B,H,S,S) +# min_all = logits.amin() +# max_all = logits.amax() +# if mask is not None: +# offboard_pair = (mask.reshape(batch_size, 1, 1, seq_len) * mask.reshape(batch_size, 1, seq_len, 1)) == 0 +# logits.masked_fill_(offboard_pair, float("-inf")) +# max_on = logits.amax() +# logits.masked_fill_(offboard_pair, float("inf")) +# min_on = logits.amin() +# else: +# min_on, max_on = min_all, max_all +# entry = store.get(name) +# if entry is None: +# store[name] = [min_all, max_all, min_on, max_on] +# else: +# entry[0] = torch.minimum(entry[0], min_all) +# entry[1] = torch.maximum(entry[1], max_all) +# entry[2] = torch.minimum(entry[2], min_on) +# entry[3] = torch.maximum(entry[3], max_on) + + class TransformerAttentionBlock(torch.nn.Module): """Self-attention half of a transformer block, with its own residual connection. @@ -2188,10 +2288,17 @@ def forward(self, x, mask, mask_sum_hw, mask_sum:float, extra_outputs: Optional[ mask_sum: scalar Returns: NCHW or NC1S (residual only, caller is responsible for adding to trunk) + + Alternatively accepts NSC sequence layout (with mask NS1) and returns NSC. """ - batch_size, channels, height, width = x.shape - seq_len = height * width - x_in = x.view(batch_size, channels, -1).permute(0, 2, 1) + input_was_seq = x.dim() == 3 + if input_was_seq: + batch_size, seq_len, channels = x.shape + x_in = x + else: + batch_size, channels, height, width = x.shape + seq_len = height * width + x_in = x.view(batch_size, channels, -1).permute(0, 2, 1) x_norm = self.norm1(x_in) @@ -2249,10 +2356,28 @@ def forward(self, x, mask, mask_sum_hw, mask_sum:float, extra_outputs: Optional[ if self.use_gab or self.use_tab: template_bias, extra_kq = self._compute_gab_bias(x_norm, mask, mask_sum_hw, block_shared_data) - if mask is not None: + # If attention weights are requested, force the manual path so we can capture them. + wants_attn_weights = ( + extra_outputs is not None + and self.name+".attn_weights" in extra_outputs.requested + ) + + # A shared flex-attention block mask (see build_flex_attention_block_mask) + # replaces the additive -inf mask when no extra bias terms are involved. + flex_block_mask = None + if ( + block_shared_data is not None + and FLEX_BLOCK_MASK in block_shared_data + and template_bias is None + and extra_kq is None + and not wants_attn_weights + ): + flex_block_mask = block_shared_data[FLEX_BLOCK_MASK] + + if mask is not None and flex_block_mask is None: # For inline registers, mask is N11S and already includes register positions - # (always 1.0), so seq_len already covers them. - mask_flat = mask.view(batch_size, 1, 1, seq_len) + # (always 1.0), so seq_len already covers them. For sequence layout, mask is NS1. + mask_flat = mask.reshape(batch_size, 1, 1, seq_len) attn_mask = torch.zeros_like(mask_flat, dtype=q.dtype) attn_mask.masked_fill_(mask_flat == 0, float('-inf')) else: @@ -2282,13 +2407,48 @@ def forward(self, x, mask, mask_sum_hw, mask_sum:float, extra_outputs: Optional[ k = torch.cat([k, extra_k], dim=-1) # (B, H, S, d_head + D_extra) # v stays (B, H, S, d_head), scaled_dot_product_attention supports differing channels for v than q/k - # If attention weights are requested, force the manual path so we can capture them. - wants_attn_weights = ( - extra_outputs is not None - and self.name+".attn_weights" in extra_outputs.requested - ) + # Hack: record pre-mask logit min/max when capture is enabled + # (see the commented-out ATTN_LOGIT_STATS_CAPTURE block above the class). + # if ATTN_LOGIT_STATS_CAPTURE is not None: + # _capture_attn_logit_stats( + # ATTN_LOGIT_STATS_CAPTURE, self.name, q, k, scale, mask, batch_size, seq_len + # ) + + # Training-time attention logit penalty (see Model.attn_logit_penalty_cap): record the + # differentiable per-(batch,head) upper bound on pre-mask attention logit magnitude, + # scale * max_i ||q_i|| * max_j ||k_j|| >= max_ij |scale * q_i . k_j|. + # The max deliberately includes off-board garbage positions, since inference backends + # compute logits at those positions too before masking, and their magnitudes are what + # constrain the fp16-safe additive mask bias constants. (Correct for the extra_kq/gab/tab + # path too: there q is pre-multiplied by the true scale and `scale` is 1.0.) + # + # Cost notes: computed on only the first `num_batch_items` samples + # (see attn_logit_penalty_batch_frac) since the hinge dynamics are slow enough that subsampled + # gradients suffice, and the dominant cost is the extra backward through every layer's + # q/k. The explicit .float() BEFORE squaring is required for correctness, not just + # accumulation: an fp16 square overflows to inf at |q| >= 256 (hot-layer components are + # already ~65) regardless of any fp32 accumulator, and eager would hit that even though + # inductor's fused kernels happen to compute fp16 pointwise math in fp32 registers. Under + # torch.compile the cast fuses into the reduction prologue, so no fp32 copy of q/k is + # materialized. The sqrt happens after the position amax. + if block_shared_data is not None and ATTN_LOGIT_UB in block_shared_data: + ub_state = block_shared_data[ATTN_LOGIT_UB] + nb = ub_state["num_batch_items"] + qs = q[:nb].float() + ks = k[:nb].float() + ub_qnorm2 = (qs * qs).sum(dim=-1) # (B', H, S) + ub_knorm2 = (ks * ks).sum(dim=-1) # (B', H, S) + ub_state["ubs"].append( + scale * torch.sqrt(ub_qnorm2.amax(dim=-1) * ub_knorm2.amax(dim=-1)) # (B', H) + ) - if not wants_attn_weights: + if flex_block_mask is not None: + attn_output = get_flex_attention_fn()( + q, k, v, + block_mask=flex_block_mask, + scale=scale, + ) + elif not wants_attn_weights: attn_output = torch.nn.functional.scaled_dot_product_attention( q, k, v, attn_mask=attn_mask, @@ -2313,7 +2473,10 @@ def forward(self, x, mask, mask_sum_hw, mask_sum:float, extra_outputs: Optional[ attn_output = attn_output.view(batch_size, seq_len, self.num_heads * self.v_head_dim) attn_output = self.out_proj(attn_output) - result = attn_output.permute(0, 2, 1).view(batch_size, channels, height, width) + if input_was_seq: + result = attn_output + else: + result = attn_output.permute(0, 2, 1).view(batch_size, channels, height, width) if extra_outputs is not None: extra_outputs.report(self.name+".out", result) return result @@ -2388,10 +2551,17 @@ def forward(self, x, mask, mask_sum_hw, mask_sum:float, extra_outputs: Optional[ mask_sum: scalar Returns: NCHW (residual only, caller is responsible for adding to trunk) + + Alternatively accepts NSC sequence layout and returns NSC. """ - batch_size, channels, height, width = x.shape - seq_len = height * width - x_in = x.view(batch_size, channels, -1).permute(0, 2, 1) + input_was_seq = x.dim() == 3 + if input_was_seq: + batch_size, seq_len, channels = x.shape + assert not self.use_depthwise_conv, "Sequence layout does not support depthwise conv in FFN" + else: + batch_size, channels, height, width = x.shape + seq_len = height * width + x_in = x if input_was_seq else x.view(batch_size, channels, -1).permute(0, 2, 1) xn = self.norm(x_in) @@ -2410,7 +2580,10 @@ def forward(self, x, mask, mask_sum_hw, mask_sum:float, extra_outputs: Optional[ x1 = x1_spatial.view(batch_size, self.ffn_dim, -1).permute(0, 2, 1) x1 = self.ffn_linear2(x1) - result = x1.permute(0, 2, 1).view(batch_size, channels, height, width) + if input_was_seq: + result = x1 + else: + result = x1.permute(0, 2, 1).view(batch_size, channels, height, width) if extra_outputs is not None: extra_outputs.report(self.name+".out", result) @@ -2805,6 +2978,58 @@ def _block_kind_uses_tab(block_kind: str) -> bool: return _BLOCK_KIND_FLAGS[base][1] +# Block kinds whose trunk computation involves only 1x1 convolutions plus +# attention/FFN sublayers, so the trunk can run in NSC sequence layout and +# per-block mask multiplications are skippable (see Model.__init__). +_TRANSFORMER_SEQ_LAYOUT_KINDS = frozenset([ + "attnrope", + "ffnsg", + "bottlenest2transformerrope", + "bottlenest2transformerropesg", + "bottlenest3transformerropesg", +]) + + +def compute_attn_logit_dataless_bounds(model) -> Dict[str, float]: + """Rigorous data-free upper bound on pre-mask attention logit magnitude, per attention layer. + + For each TransformerAttentionBlock: norm1 is RMSNorm, so each position's normed input has + ||x_norm|| <= sqrt(C) * max|gamma| (the epsilon only tightens this), the q/k projections + amplify by at most their per-head top singular values, and RoPE (fixed or learnable) is a + norm-preserving rotation. So per query head h (kv head h // n_rep): + |logit| <= scale * sigma_max(W_q,h) * sigma_max(W_k,h//n_rep) * C * max|gamma|^2 + With qk-norm the per-head RMSNorms bound the head vectors directly instead: + |logit| <= scale * d_head * max|gamma_qnorm| * max|gamma_knorm| + The layer bound is the max over heads. Holds for ANY input (including off-board garbage), + with no data needed. Does NOT include the extra additive logit terms of gab/tab blocks. + Measured tightness vs actual logits: ~4-7x on layers that exercise their capacity (attention + sinks), up to ~200x on layers that don't; see python/tmp/attn_logit_stats/. + + Inference backends mask off-board keys with large negative additive constants (-3e4 in fp16; + see cpp/neuralnet/cudahelpers.cu and onnxmodelbuilder.cpp), which is correct as long as + genuine logit magnitudes stay well below that scale - this bound certifies it from weights alone. + """ + bounds = {} + with torch.no_grad(): + for _, block in model.named_modules(): + if isinstance(block, TransformerAttentionBlock): + scale = 1.0 / math.sqrt(block.q_head_dim) + if block.use_qk_norm: + gq = block.q_norm.weight.abs().max().item() + gk = block.k_norm.weight.abs().max().item() + bounds[block.name] = scale * block.q_head_dim * gq * gk + continue + gamma = block.norm1.weight.abs().max().item() + d = block.q_head_dim + wq = block.q_proj.weight + wk = block.k_proj.weight + sq = [torch.linalg.svdvals(wq[h * d:(h + 1) * d, :].float())[0].item() for h in range(block.num_heads)] + sk = [torch.linalg.svdvals(wk[h * d:(h + 1) * d, :].float())[0].item() for h in range(block.num_kv_heads)] + best = max(sq[h] * sk[h // block.n_rep] for h in range(block.num_heads)) + bounds[block.name] = scale * best * block.c_main * gamma * gamma + return bounds + + class Model(torch.nn.Module): def __init__(self, config: modelconfigs.ModelConfig, pos_len: int): super(Model, self).__init__() @@ -3200,6 +3425,61 @@ def __init__(self, config: modelconfigs.ModelConfig, pos_len: int): self.rw_reg_readout_act = act(self.activation, inplace=False) self.rw_reg_readout_proj2 = torch.nn.Linear(self.c_trunk, self.c_trunk, bias=False) + # Optional optimizations for pure transformer trunks where every + # block is built from 1x1 convolutions plus attention/FFN sublayers: + # + # - transformer_seq_layout ("NHWC"): keep the whole trunk in NSC sequence layout + # so each attention/FFN sublayer avoids a pair of NCHW <-> NSC transposes. + # The trunk converts to NSC once after the input conv and back to NCHW before trunk-final norm. + # - transformer_skip_redundant_masks: skip the off-board mask multiply in + # each transformer bottleneck's p/q NormMask. + # Sound because attention already excludes off-board keys via its own attention mask, + # every other trunk op is pointwise across positions (1x1 convs, RMSNorms, FFN linears), + # and the trunk-final norms compute masked statistics and re-mask their output before any head + # or pooling reads the trunk. + # Off-board trunk values become nonzero garbage, which is fine. + # + # Neither changes any parameter or on-board output. Both can be toggled freely for an existing checkpoint. + trunk_is_plain_transformer = ( + all(bk[1] in _TRANSFORMER_SEQ_LAYOUT_KINDS for bk in self.block_kind) + and not self.use_trunk_channel_gate + and not self.use_trunk_residual_backout + and not self.use_rw_registers + ) + self.transformer_seq_layout = ( + env_flag("KATAGO_TRANSFORMER_NHWC", default=True) and trunk_is_plain_transformer + ) + self.transformer_skip_redundant_masks = ( + env_flag("KATAGO_TRANSFORMER_SKIP_REDUNDANT_MASKS", default=True) + and trunk_is_plain_transformer + and not config.get("transformer_ffn_depthwise_conv", False) + ) + if self.transformer_skip_redundant_masks: + for block in self.blocks: + if isinstance(block, NestedBottleneckTransformerBlock): + block.normactconvp.norm.skip_mask = True + block.normactconvq.norm.skip_mask = True + # Flex-attention with a block mask built once per forward, instead of the + # additive -inf attention bias whose handling roughly doubles the cost of + # the mem-efficient SDPA backend. Same masking semantics (keys only). + self.use_flex_attention = ( + env_flag("KATAGO_FLEX_ATTENTION", default=True) and trunk_is_plain_transformer + ) + + # Training-time attention logit penalty. Not part of the model config: set externally + # (e.g. by train.py from -attn-logit-penalty-cap) before any torch.compile wrapping. + # When set to a float cap, each forward stores: + # self.attn_logit_penalty_per_sample: (B',) sum over attention layers of + # mean over heads of relu(logit_upper_bound - cap), differentiable (linear hinge), + # over the first B' = ceil(B * attn_logit_penalty_batch_frac) batch items. + # self.attn_logit_ub_batch_max: 0-dim detached max of the bound over all layers/samples/heads. + # See TransformerAttentionBlock for the bound definition (includes off-board positions). + # attn_logit_penalty_batch_frac < 1 computes the penalty on a fixed slice of the batch, + # cutting its (mostly-backward) cost proportionally at the price of gradient variance, + # which the slow hinge dynamics tolerate. The compiled/DDP graph stays static. + self.attn_logit_penalty_cap = None + self.attn_logit_penalty_batch_frac = 1.0 + if self.trunk_final_rmsnorm: spatial = config.get("trunk_rmsnorm_spatial", False) cgroup_size = config.get("rmsnorm_spatial_cgroup_size", None) if spatial else None @@ -3477,6 +3757,11 @@ def forward( if self.tab_module is not None: tab_keys, tab_queries = self.tab_module(out, mask) block_shared_data[TAB_KQ] = TABKeyQueryData(keys=tab_keys, queries=tab_queries) + if self.use_flex_attention: + block_shared_data[FLEX_BLOCK_MASK] = build_flex_attention_block_mask(mask) + if self.attn_logit_penalty_cap is not None: + pen_batch_items = max(1, int(math.ceil(mask.shape[0] * self.attn_logit_penalty_batch_frac))) + block_shared_data[ATTN_LOGIT_UB] = {"num_batch_items": pen_batch_items, "ubs": []} if self.use_rw_registers: # Compute board geometry from mask for register tokens. # mask: (B, 1, H, W) @@ -3543,6 +3828,17 @@ def forward( else: backout = None + # For pure transformer trunks, optionally run the whole trunk in NSC + # sequence layout, converting once here and once before the final norm. + seq_layout = self.transformer_seq_layout + if seq_layout: + seq_B, seq_C, seq_H, seq_W = out.shape + # Learnable RoPE position arithmetic inside blocks assumes the full + # pos_len x pos_len grid. + assert seq_H == self.pos_len and seq_W == self.pos_len + out = out.view(seq_B, seq_C, seq_H * seq_W).transpose(1, 2).contiguous() + mask = mask.view(seq_B, seq_H * seq_W, 1) + if self.has_intermediate_head: count = 0 for i, block in enumerate(self.blocks[:self.intermediate_head_blocks]): @@ -3563,7 +3859,10 @@ def forward( count += 1 iout = out - if self.inline_registers and self.use_rw_registers: + if seq_layout: + # Restore NCHW for the intermediate head. The trunk itself stays NSC. + iout = out.transpose(1, 2).reshape(out.shape[0], self.c_trunk, orig_H, orig_W) + elif self.inline_registers and self.use_rw_registers: # Split off registers and restore NCHW for intermediate head board_hw = orig_H * orig_W iout = iout[:, :, :, :board_hw].view(iout.shape[0], self.c_trunk, orig_H, orig_W) @@ -3660,6 +3959,19 @@ def forward( out = out_board.view(out.shape[0], self.c_trunk, orig_H, orig_W) out = out + rw_readout.unsqueeze(-1).unsqueeze(-1) # broadcast to NCHW + if seq_layout: + out = out.transpose(1, 2).reshape(out.shape[0], self.c_trunk, orig_H, orig_W) + + if self.attn_logit_penalty_cap is not None: + ub_list = block_shared_data[ATTN_LOGIT_UB]["ubs"] + assert len(ub_list) > 0, "attn_logit_penalty_cap set but model has no attention layers" + ubs = torch.stack(ub_list) # (num_attn_layers, B', H) + excess = torch.nn.functional.relu(ubs - self.attn_logit_penalty_cap) + # Linear hinge: constant-magnitude pull on offending heads regardless of how far + # above the cap they currently are, gentler than a squared hinge for large excesses. + self.attn_logit_penalty_per_sample = excess.mean(dim=2).sum(dim=0) # (B',) + self.attn_logit_ub_batch_max = ubs.detach().amax() + # Use original mask for final norm and heads (NCHW format) out = self.norm_trunkfinal(out, mask=orig_mask, mask_sum_hw=orig_mask_sum_hw, mask_sum=orig_mask_sum) out = self.act_trunkfinal(out) diff --git a/python/katago/train/trainloop_helpers.py b/python/katago/train/trainloop_helpers.py new file mode 100644 index 0000000000..ca80ae60f3 --- /dev/null +++ b/python/katago/train/trainloop_helpers.py @@ -0,0 +1,467 @@ +""" +Helpers shared between train.py and benchmark_fresh_model.py for the per-batch +training step, so that throughput benchmarks measure the same code that real +training runs. + +Optimization toggles are controlled by environment variables. +Set to "0" to disable an optimization. + +KATAGO_COMPILE_MODE (default "default"): + torch.compile mode for the model and compiled loss. + "max-autotune-no-cudagraphs" trades minutes of extra compile/tuning time for a few percent throughput. + It retunes per GPU model, per batch size, so it should be re-measured on each machine. +KATAGO_MODEL_NORMS_ONLY_AT_PRINT (default 1): + Compute model norm metrics only on logging batches instead of every batch. +KATAGO_COMPILE_TRAINING_LOSS (default 1): + torch.compile the loss/metrics computation separately from the model. +KATAGO_DDP_STATIC_GRAPH (default 1): enable DDP static-graph mode. +KATAGO_DDP_GRADIENT_AS_BUCKET_VIEW (default 1): + Gradients are views of DDP reduction buckets, saving a copy. +KATAGO_DDP_BROADCAST_BUFFERS (default depends on norm kind): + Skip DDP's per-forward buffer broadcast for plain batch norm, where training-mode + forwards do not consume the running statistics. Batch renorm does consume + them and keeps broadcasts. +KATAGO_DDP_ALIGN_CONV1X1_WEIGHT_STRIDES (default 1): + Match 1x1 convolution parameter strides with the layout produced by CUDA convolution backward so + DDP bucket views do not need a re-strided copy. +KATAGO_STEP_NORMS_ONLY_AT_PRINT (default 1): + Compute the empirical step-norm metrics (which require cloning all parameters and syncing) only on logging batches. +KATAGO_DEFER_GNORM_SYNC (default 1): + Record the clipped gradient norm as a tensor and convert to a float only at end-of-batch metric collection, + instead of forcing a GPU sync between backward and optimizer step. +""" + +import logging +import math +import os +from collections import defaultdict + +import torch +from torch.nn.parallel import DistributedDataParallel + + +def env_flag(name: str, default: bool) -> bool: + """Read a boolean environment flag, accepting only the exact values 0 and 1.""" + value = os.environ.get(name) + if value is None: + return default + if value == "0": + return False + if value == "1": + return True + raise ValueError(f"Environment variable {name} must be exactly '0' or '1', got {value!r}") + + +_ALLOWED_COMPILE_MODES = ( + "default", + "max-autotune-no-cudagraphs", + "max-autotune", +) + + +def get_compile_mode() -> str: + mode = os.environ.get("KATAGO_COMPILE_MODE", "default") + if mode in _ALLOWED_COMPILE_MODES: + return mode + allowed = "|".join(_ALLOWED_COMPILE_MODES) + raise ValueError(f"Environment variable KATAGO_COMPILE_MODE must be one of {allowed}, got {mode!r}") + + +@torch.no_grad() +def align_conv1x1_weight_strides_for_ddp(raw_model) -> int: + """Match the layout produced by convolution backward for 1x1 weights. + + CUDA convolution backward commonly returns a logically contiguous [out, in, 1, 1] gradient with strides [in, 1, in, in]. + PyTorch's default parameter allocation uses [in, 1, 1, 1] instead. + Both layouts address exactly the same storage because the last dimensions have size 1, + but DDP otherwise warns and copies into a differently-strided bucket view. + + Must be called before the optimizer captures parameter references. + """ + aligned_count = 0 + for module in raw_model.modules(): + if not isinstance(module, torch.nn.Conv2d): + continue + weight = module.weight + if ( + weight is None + or weight.ndim != 4 + or tuple(weight.shape[2:]) != (1, 1) + ): + continue + in_channels_per_group = weight.shape[1] + desired_stride = ( + in_channels_per_group, + 1, + in_channels_per_group, + in_channels_per_group, + ) + if weight.stride() == desired_stride: + continue + aligned_weight = torch.empty_strided( + weight.shape, + desired_stride, + dtype=weight.dtype, + device=weight.device, + ) + aligned_weight.copy_(weight) + module.weight = torch.nn.Parameter( + aligned_weight, + requires_grad=weight.requires_grad, + ) + aligned_count += 1 + return aligned_count + + +def wrap_model_for_training(raw_model, device, world_size: int, no_compile: bool): + """Apply torch.compile and DDP without changing ownership of raw_model. + + Must be called before the optimizer is constructed because 1x1 conv stride alignment can replace Parameter objects. + """ + compile_mode = None if no_compile else get_compile_mode() + if world_size <= 1: + logging.info( + f"Training model wrapper: single GPU, compile={not no_compile}, " + f"compile_mode={compile_mode}, DDP environment flags ignored" + ) + if no_compile: + return raw_model + return torch.compile(raw_model, mode=compile_mode) + + static_graph = env_flag("KATAGO_DDP_STATIC_GRAPH", default=True) + gradient_as_bucket_view = env_flag("KATAGO_DDP_GRADIENT_AS_BUCKET_VIEW", default=True) + align_conv1x1_weight_strides = env_flag("KATAGO_DDP_ALIGN_CONV1X1_WEIGHT_STRIDES", default=True) + aligned_conv1x1_count = ( + align_conv1x1_weight_strides_for_ddp(raw_model) + if align_conv1x1_weight_strides + else 0 + ) + # Plain batch norm uses the current batch during training, so synchronizing + # its running statistics before every forward does not affect gradients or + # rank 0's checkpointed statistics. Batch renorm does consume its running + # statistics in the training forward and therefore keeps DDP's behavior. + norm_kind = raw_model.get_norm_kind() + broadcast_buffers = env_flag( + "KATAGO_DDP_BROADCAST_BUFFERS", + default=norm_kind in ("brenorm", "fixbrenorm"), + ) + # Dynamo's DDPOptimizer splits the compiled graph at DDP bucket boundaries + # to overlap communication with backward compute. With the flex-attention + # HOP in the graph, certain split layouts (seen on nbt3 models, torch 2.10-2.11) + # SILENTLY CORRUPT GRADIENTS. Disable graph splitting whenever flex + # attention is active. This also is fast or faster than splitting + # on these models. Non-flex models keep the PyTorch default behavior. + uses_flex_attention = bool(getattr(raw_model, "use_flex_attention", False)) + optimize_ddp = env_flag("KATAGO_DYNAMO_OPTIMIZE_DDP", default=not uses_flex_attention) + if not no_compile: + if uses_flex_attention and optimize_ddp: + logging.warning( + "KATAGO_DYNAMO_OPTIMIZE_DDP=1 with flex attention under DDP is known to " + "silently corrupt gradients on some models. Only use this for debugging, and " + "watch for nonfinite gnorm warnings." + ) + torch._dynamo.config.optimize_ddp = optimize_ddp + logging.info( + f"Training model wrapper: DDP world_size={world_size}, compile={not no_compile}, " + f"compile_mode={compile_mode}, static_graph={static_graph}, " + f"gradient_as_bucket_view={gradient_as_bucket_view}, " + f"broadcast_buffers={broadcast_buffers}, aligned_conv1x1_weights={aligned_conv1x1_count}, " + f"dynamo_optimize_ddp={optimize_ddp if not no_compile else 'n/a'}" + ) + + ddp_kwargs = { + "device_ids": [device], + "broadcast_buffers": broadcast_buffers, + } + if static_graph: + ddp_kwargs["static_graph"] = True + if gradient_as_bucket_view: + ddp_kwargs["gradient_as_bucket_view"] = True + + if no_compile: + return DistributedDataParallel(raw_model, **ddp_kwargs) + + compiled_model = torch.compile(raw_model, mode=compile_mode) + return DistributedDataParallel(compiled_model, **ddp_kwargs) + + +def maybe_enable_compiled_autograd(): + """Experimental: capture the backward pass (including DDP hooks) with + compiled autograd for additional fusion. Off by default.""" + if env_flag("KATAGO_COMPILED_AUTOGRAD", default=False): + torch._dynamo.config.compiled_autograd = True + logging.info("Compiled autograd enabled") + + +def get_model_norms_only_at_print() -> bool: + return env_flag("KATAGO_MODEL_NORMS_ONLY_AT_PRINT", default=True) + + +def make_training_metrics_fn(metrics_obj, no_compile: bool, model_norms_only_at_print: bool): + """Return the (possibly torch.compiled) training metrics/loss function.""" + compile_requested = env_flag("KATAGO_COMPILE_TRAINING_LOSS", default=True) + compile_training_loss = compile_requested and not no_compile + if compile_requested and not compile_training_loss: + logging.info("Disabling compiled training loss because no_compile is set") + if not compile_training_loss: + return metrics_obj.metrics_dict_batchwise + if not model_norms_only_at_print: + raise ValueError( + "KATAGO_COMPILE_TRAINING_LOSS=1 requires KATAGO_MODEL_NORMS_ONLY_AT_PRINT=1 " + "so the compiled result structure is fixed" + ) + if not metrics_obj.seki_ema_on_device: + raise ValueError( + "KATAGO_COMPILE_TRAINING_LOSS=1 requires KATAGO_SEKI_EMA_ON_DEVICE=1 " + "to avoid a per-step Python scalar guard" + ) + logging.info(f"Compiling training loss with mode={get_compile_mode()}") + return torch.compile(metrics_obj.metrics_dict_batchwise, mode=get_compile_mode(), dynamic=False) + + +def clip_gradients_and_record(ddp_model, gnorm_cap, metrics, batch_size): + """Clip gradients by global norm and record gnorm metrics. + + With KATAGO_DEFER_GNORM_SYNC=1 the gnorm stays a tensor here so the CPU can + enqueue the optimizer step without waiting for backward to finish. + The conversion to float (and the finite-ness filtering) happens in detensorify_metrics at end of batch. + """ + gnorm_tensor = torch.nn.utils.clip_grad_norm_(ddp_model.parameters(), gnorm_cap).detach() + if env_flag("KATAGO_DEFER_GNORM_SYNC", default=True): + metrics["gnorm_batch"] = gnorm_tensor + metrics["exgnorm_sum"] = torch.clamp(gnorm_tensor - gnorm_cap, min=0.0) * batch_size + else: + gnorm = gnorm_tensor.cpu().item() + if math.isfinite(gnorm) and abs(gnorm < 1e30): + metrics["gnorm_batch"] = gnorm + exgnorm = max(0.0, gnorm - gnorm_cap) + metrics["exgnorm_sum"] = exgnorm * batch_size + + +class StepNormTracker: + """Tracks the empirical optimizer step vector length (overall and per group). + + capture() is called before optimizer.step() and record() after, filling + step_norm metrics. With KATAGO_STEP_NORMS_ONLY_AT_PRINT=1 the (expensive) + parameter cloning and comparison runs only on logging batches. + When it does run, the per-group sums are collected with a single GPU sync rather than + one sync per parameter tensor. + """ + + def __init__(self, optimizer): + # Build a mapping from parameter id to group name once. + self.param_to_group = {} + for param_group in optimizer.param_groups: + group_name = param_group["group_name"] + for param in param_group["params"]: + self.param_to_group[id(param)] = group_name + self.only_at_print = env_flag("KATAGO_STEP_NORMS_ONLY_AT_PRINT", default=True) + self.old_params = None + + def capture(self, ddp_model, is_print_batch=True): + if self.only_at_print and not is_print_batch: + self.old_params = None + return + old_params = {} + for name, param in ddp_model.named_parameters(): + if param.requires_grad: + old_params[name] = param.data.detach().clone() + self.old_params = old_params + + def record(self, ddp_model, metrics): + if self.old_params is None: + return + with torch.no_grad(): + group_sums = {} + for name, param in ddp_model.named_parameters(): + if param.requires_grad: + param_diff_squared = torch.sum(torch.square(param.data - self.old_params[name])) + group_name = self.param_to_group.get(id(param), "unknown") + if group_name in group_sums: + group_sums[group_name] += param_diff_squared + else: + group_sums[group_name] = param_diff_squared + + group_names = list(group_sums.keys()) + # One GPU->CPU sync for all groups instead of one per parameter. + group_values = torch.stack([group_sums[name] for name in group_names]).cpu().tolist() + + metrics["step_norm_batch"] = math.sqrt(sum(group_values)) + for group_name, norm_squared in zip(group_names, group_values): + metrics[f"step_norm_{group_name}_batch"] = math.sqrt(norm_squared) + self.old_params = None + + +class GnormWatcherError(RuntimeError): + """Raised by GnormWatcher to halt a run whose gradients are persistently nonfinite.""" + pass + + +class GnormWatcher: + """Halts the run when the gradient norm looks persistently pathological. + + A batch is "bad" when its gradient norm is nonfinite OR extremely large + The magnitude signal matters: in the dynamo-DDPOptimizer + flex-attention + gradient-corruption bug, gradients are finite but too large. + + Triggers: + - consecutive: >= consecutive_warn_threshold bad batches in a row, armed + only after the first good batch. GradScaler calibration produces an + unbroken nonfinite run from the very first batch and must not false-positive. + - startup: no good batch at all within the first startup_good_limit + observations. Calibration runs end long before that. + - rate: >= rate_warn_fraction of the last rate_window batches bad. + + Raises GnormWatcherError so the run cannot silently continue. + Setting KATAGO_GNORM_WATCHER_HALT=0 makes it warn instead. + + All ranks compute the same post-allreduce gradient norm, so under DDP every + rank raises at the same batch. + """ + + def __init__(self, consecutive_warn_threshold=8, rate_window=100, rate_warn_fraction=0.25, + extreme_cap_factor=50.0, startup_good_limit=30): + self.consecutive_warn_threshold = consecutive_warn_threshold + self.rate_window = rate_window + self.rate_warn_fraction = rate_warn_fraction + self.extreme_cap_factor = extreme_cap_factor + self.startup_good_limit = startup_good_limit + self.halt_on_trigger = env_flag("KATAGO_GNORM_WATCHER_HALT", default=True) + self.window = [] # ring buffer of 0/1 bad flags + self.window_pos = 0 + self.consecutive_bad = 0 + self.max_consecutive_bad = 0 + self.total_observed = 0 + self.total_bad = 0 + self.total_nonfinite = 0 + self.total_extreme = 0 + self.seen_good = False + self.observations_at_last_warning = None + + def _trigger(self, message): + message = message + " Training is likely diverging or gradients are being corrupted." + if self.halt_on_trigger: + message = message + " Halting the run (set KATAGO_GNORM_WATCHER_HALT=0 to only warn)." + logging.error(message) + raise GnormWatcherError(message) + # Warn-only mode: at most one warning per half rate-window, to avoid + # log spam while remaining very visible in a limping run. + if ( + self.observations_at_last_warning is not None + and self.total_observed - self.observations_at_last_warning < self.rate_window // 2 + ): + return + self.observations_at_last_warning = self.total_observed + logging.warning(message) + + def observe(self, detensorified_metrics, gnorm_cap=None): + gnorm = detensorified_metrics.get("gnorm_batch") + nonfinite = gnorm is None + extreme = ( + not nonfinite + and gnorm_cap is not None + and gnorm > self.extreme_cap_factor * gnorm_cap + ) + bad = nonfinite or extreme + self.total_observed += 1 + if bad: + self.total_bad += 1 + if nonfinite: + self.total_nonfinite += 1 + else: + self.total_extreme += 1 + self.consecutive_bad += 1 + self.max_consecutive_bad = max(self.max_consecutive_bad, self.consecutive_bad) + else: + self.consecutive_bad = 0 + self.seen_good = True + + if len(self.window) < self.rate_window: + self.window.append(1 if bad else 0) + else: + self.window[self.window_pos] = 1 if bad else 0 + self.window_pos = (self.window_pos + 1) % self.rate_window + + detail = ( + f"({self.total_nonfinite} nonfinite + {self.total_extreme} extreme " + f"(>{self.extreme_cap_factor:g}x the clip cap) out of {self.total_observed} batches" + + (f" latest gnorm {gnorm:.4g} vs cap {gnorm_cap:.4g}" if extreme else "") + + ")" + ) + if self.seen_good and self.consecutive_bad >= self.consecutive_warn_threshold: + self._trigger( + f"GNORM WATCHER: gradient norm has been nonfinite or extremely large for " + f"{self.consecutive_bad} consecutive batches {detail}." + ) + elif not self.seen_good and self.total_observed >= self.startup_good_limit: + self._trigger( + f"GNORM WATCHER: no healthy gradient norm in the first " + f"{self.total_observed} batches {detail}." + ) + elif len(self.window) >= self.rate_window: + bad_fraction = sum(self.window) / len(self.window) + if bad_fraction >= self.rate_warn_fraction: + self._trigger( + f"GNORM WATCHER: gradient norm nonfinite or extremely large in " + f"{100.0 * bad_fraction:.0f}% of the last {len(self.window)} batches " + f"{detail}, max consecutive {self.max_consecutive_bad}." + ) + + +def detensorify_metrics(metrics): + """Convert tensor metrics to floats with a single GPU sync. + + Also drops the gnorm metrics when nonfinite (they can legitimately be inf + for a batch whose FP16 gradients overflowed and whose step was skipped), + matching the historical behavior of excluding such batches. + """ + ret = {} + tensor_keys = [] + for key in metrics: + value = metrics[key] + if isinstance(value, torch.Tensor): + tensor_keys.append(key) + else: + ret[key] = value + if len(tensor_keys) > 0: + stacked = torch.stack([metrics[key].detach().reshape([]).float() for key in tensor_keys]).cpu().tolist() + for key, value in zip(tensor_keys, stacked): + ret[key] = value + if "gnorm_batch" in ret and not (math.isfinite(ret["gnorm_batch"]) and ret["gnorm_batch"] < 1e30): + del ret["gnorm_batch"] + ret.pop("exgnorm_sum", None) + return ret + + +def get_local_validation_model(training_model, raw_model, world_size: int): + """Return a local forward module that cannot initiate DDP collectives. + + Validation runs on rank 0 only. Forwarding through the DDP wrapper there + would trigger collectives (e.g. buffer broadcasts) that other ranks never + join. The common compile-before-DDP path preserves the compiled local + module here, while bypassing DDP's forward-time work. + """ + if world_size <= 1: + return training_model + + current = training_model + visited = set() + while id(current) not in visited: + visited.add(id(current)) + if isinstance(current, DistributedDataParallel): + return current.module + original_module = getattr(current, "_orig_mod", None) + if original_module is None or original_module is current: + break + current = original_module + + # Unknown wrappers are not safe to call from rank 0 alone. + return raw_model + + +def set_snapshot_metrics(metric_sums, metric_weights, metrics, keys): + """Store point-in-time metrics without depending on moving-average weight.""" + for key in keys: + if key in metrics: + metric_sums[key] = metrics[key] + metric_weights[key] = 1.0 diff --git a/python/muon/muon.py b/python/muon/muon.py index 1b51f2eb69..14296803cb 100644 --- a/python/muon/muon.py +++ b/python/muon/muon.py @@ -1,9 +1,25 @@ +import logging +import os +from dataclasses import dataclass from itertools import repeat +from typing import List, Sequence, Tuple import torch import torch.distributed as dist +def _env_flag(name: str, default: bool) -> bool: + """Read a boolean environment flag, accepting only the exact values 0 and 1.""" + value = os.environ.get(name) + if value is None: + return default + if value == "0": + return False + if value == "1": + return True + raise ValueError(f"Environment variable {name} must be exactly '0' or '1', got {value!r}") + + def zeropower_via_newtonschulz5(G, steps: int): """ Newton-Schulz iteration to compute the zeroth power / orthogonalization of G. We opt to use a @@ -220,7 +236,347 @@ def adam_update(grad, buf1, buf2, step, betas, eps): return buf1c / (buf2c.sqrt() + eps) -class MuonWithAuxAdam(torch.optim.Optimizer): +# Compiled variants used by the batched Newton-Schulz path. +# The number of distinct (batch, rows, cols) shapes per model is small, so per-shape compilation settles quickly. +# These functions accept stacked (B, m, n) input since the underlying implementations already support batched matrices. +zeropower_via_newtonschulz5_compiled = torch.compile(zeropower_via_newtonschulz5) +zeropower_via_polar_express_compiled = torch.compile(zeropower_via_polar_express) + + +DEFAULT_DISTRIBUTED_BUCKET_CAP_BYTES = 16 * 1024 * 1024 + + +@dataclass(frozen=True) +class _MuonBucketSegment: + param_index: int + param_offset: int + packed_offset: int + numel: int + + +@dataclass(frozen=True) +class _MuonFlatBucketPlan: + collective_numel: int + owner_numels: Tuple[int, ...] + segments_by_owner: Tuple[Tuple[_MuonBucketSegment, ...], ...] + + +@dataclass +class _MuonDistributedLayout: + params: Tuple[torch.Tensor, ...] + buckets: Tuple[_MuonFlatBucketPlan, ...] + send_buffer: torch.Tensor + gathered_buffer: torch.Tensor + + +def _build_muon_flat_bucket_plan( + owner_param_numels: Sequence[Sequence[Tuple[int, int]]], + bucket_cap_numel: int, +) -> Tuple[_MuonFlatBucketPlan, ...]: + """Build equal-sized all-gather buckets from one parameter stream per owner. + + Each input item is ``(param_index, numel)``. + A parameter may be split across buckets, but every element appears exactly once and in parameter-stream order. + The collective size of a bucket is the largest owner payload in that bucket. + Shorter owner payloads are padded by the caller. + """ + if bucket_cap_numel <= 0: + raise ValueError(f"bucket_cap_numel must be positive, got {bucket_cap_numel}") + if len(owner_param_numels) <= 0: + raise ValueError("owner_param_numels must contain at least one owner") + + normalized_streams: List[Tuple[Tuple[int, int], ...]] = [] + for stream in owner_param_numels: + normalized_stream = [] + for param_index, numel in stream: + if param_index < 0: + raise ValueError(f"param_index must be nonnegative, got {param_index}") + if numel < 0: + raise ValueError(f"parameter numel must be nonnegative, got {numel}") + if numel > 0: + normalized_stream.append((param_index, numel)) + normalized_streams.append(tuple(normalized_stream)) + + stream_indices = [0 for _ in normalized_streams] + param_offsets = [0 for _ in normalized_streams] + buckets: List[_MuonFlatBucketPlan] = [] + + while any(stream_indices[owner] < len(normalized_streams[owner]) for owner in range(len(normalized_streams))): + owner_numels: List[int] = [] + segments_by_owner: List[Tuple[_MuonBucketSegment, ...]] = [] + + for owner, stream in enumerate(normalized_streams): + packed_offset = 0 + owner_segments: List[_MuonBucketSegment] = [] + while packed_offset < bucket_cap_numel and stream_indices[owner] < len(stream): + param_index, param_numel = stream[stream_indices[owner]] + param_offset = param_offsets[owner] + take = min(param_numel - param_offset, bucket_cap_numel - packed_offset) + assert take > 0 + owner_segments.append(_MuonBucketSegment( + param_index=param_index, + param_offset=param_offset, + packed_offset=packed_offset, + numel=take, + )) + packed_offset += take + param_offset += take + if param_offset == param_numel: + stream_indices[owner] += 1 + param_offsets[owner] = 0 + else: + param_offsets[owner] = param_offset + + owner_numels.append(packed_offset) + segments_by_owner.append(tuple(owner_segments)) + + collective_numel = max(owner_numels) + assert collective_numel > 0 + buckets.append(_MuonFlatBucketPlan( + collective_numel=collective_numel, + owner_numels=tuple(owner_numels), + segments_by_owner=tuple(segments_by_owner), + )) + + return tuple(buckets) + + +class _MuonWithAuxAdamBase(torch.optim.Optimizer): + """Shared implementation for the single-device and distributed variants. + + Optimization toggles (set the environment variable to 0 to disable for + debugging or exact regression comparison against the historical kernels): + KATAGO_MUON_BATCHED_NS (default 1): stack Muon updates with the same + matrix shape (up to KATAGO_MUON_NS_BATCH_SIZE, default 32) into a single + compiled Newton-Schulz iteration rather than one launch sequence per + parameter. Same update equations, but not bitwise identical to the + scalar launches. + KATAGO_AUX_ADAM_FOREACH (default 1): use torch._foreach multi-tensor + kernels for the auxiliary Adam parameter groups. + """ + def __init__(self, param_groups, adjust_lr_fn="match_rms_adamw", adam_betas=(0.95, 0.995), adam_eps=1e-6, + use_normuon=False, normuon_beta2=0.95, normuon_eps=1e-8, + use_aurora=False, aurora_pp_iterations=2, aurora_pp_beta=0.5, aurora_eps=1e-7, + ns_steps=5, use_polar_express=False, sort_muon_params=False): + self.use_normuon = use_normuon + self.normuon_beta2 = normuon_beta2 + self.normuon_eps = normuon_eps + self.use_aurora = use_aurora + self.aurora_pp_iterations = aurora_pp_iterations + self.aurora_pp_beta = aurora_pp_beta + self.aurora_eps = aurora_eps + self.ns_steps = ns_steps + self.use_polar_express = use_polar_express + # Aurora's data-dependent preconditioning loop stays on the scalar path. + self.use_batched_muon_ns = _env_flag("KATAGO_MUON_BATCHED_NS", default=True) and not use_aurora + self.use_foreach_aux_adam = _env_flag("KATAGO_AUX_ADAM_FOREACH", default=True) + self.muon_ns_batch_size = int(os.environ.get("KATAGO_MUON_NS_BATCH_SIZE", "32")) + if self.muon_ns_batch_size <= 0: + raise ValueError(f"KATAGO_MUON_NS_BATCH_SIZE must be positive, got {self.muon_ns_batch_size}") + if self.use_batched_muon_ns: + logging.info(f"Muon: using batched Newton-Schulz with batch size {self.muon_ns_batch_size}") + if self.use_foreach_aux_adam: + logging.info("Muon: using foreach kernels for auxiliary Adam parameter groups") + for group in param_groups: + assert "use_muon" in group + if group["use_muon"]: + if sort_muon_params: + group["params"] = sorted(group["params"], key=lambda x: x.size(), reverse=True) + # defaults + group["lr"] = group.get("lr", 0.02) + group["momentum"] = group.get("momentum", 0.95) + group["weight_decay"] = group.get("weight_decay", 0) + group["adjust_lr_fn"] = group.get("adjust_lr_fn", adjust_lr_fn) + else: + # defaults + group["lr"] = group.get("lr", 3e-4) + group["betas"] = group.get("betas", adam_betas) + group["eps"] = group.get("eps", adam_eps) + group["weight_decay"] = group.get("weight_decay", 0) + super().__init__(param_groups, dict()) + + def _ensure_muon_state(self, p): + if p.grad is None: + # continue + p.grad = torch.zeros_like(p) # Force synchronization + state = self.state[p] + if len(state) == 0: + state["momentum_buffer"] = torch.zeros_like(p) + if self.use_normuon: + state["normuon_v"] = torch.zeros(p.shape[0], device=p.device, dtype=p.dtype) + return state + + def _step_muon_param_scalar(self, group, p): + state = self._ensure_muon_state(p) + if self.use_aurora: + update = aurora_update( + p.grad, state["momentum_buffer"], + ns_steps=self.ns_steps, + beta=group["momentum"], adjust_lr_fn=group["adjust_lr_fn"], + pp_iterations=self.aurora_pp_iterations, + pp_beta=self.aurora_pp_beta, eps=self.aurora_eps, + use_polar_express=self.use_polar_express, + ) + else: + update = muon_update( + p.grad, state["momentum_buffer"], + ns_steps=self.ns_steps, + beta=group["momentum"], adjust_lr_fn=group["adjust_lr_fn"], + normuon_v=state.get("normuon_v"), + normuon_beta2=self.normuon_beta2, normuon_eps=self.normuon_eps, + use_polar_express=self.use_polar_express, + ) + p.mul_(1 - group["lr"] * group["weight_decay"]) + p.add_(update.reshape(p.shape), alpha=-group["lr"]) + + def _step_muon_params_batched(self, group, param_indices): + """Same equations as the scalar path, but Newton-Schulz iterations for + same-shape matrices are launched as one batched computation, and the + elementwise momentum/Nesterov/scale/weight-decay/apply passes use + multi-tensor (foreach / stacked) kernels. + + Per-parameter momentum/Nesterov mutation semantics are preserved. + Only independent computations are regrouped. + """ + params = group["params"] + chosen = [] + for param_index in param_indices: + p = params[param_index] + state = self._ensure_muon_state(p) + chosen.append((p, state)) + if len(chosen) == 0: + return + + # Momentum + Nesterov for all parameters in a few multi-tensor launches, + # matching muon_update: momentum.lerp_(grad, 1-beta); grad.lerp_(momentum, beta). + grads = [p.grad for p, state in chosen] + momenta = [state["momentum_buffer"] for p, state in chosen] + torch._foreach_lerp_(momenta, grads, 1 - group["momentum"]) + torch._foreach_lerp_(grads, momenta, group["momentum"]) + + entries_by_shape = {} + for p, state in chosen: + update = p.grad + matrix = update.view(len(update), -1) if update.ndim == 4 else update + assert matrix.ndim == 2 + # Normalize orientation to rows <= cols so that transposed shape pairs share a batch. + # Zeropower of the transpose is the transpose of zeropower, so this is equivalent to the scalar path. + was_transposed = matrix.shape[0] > matrix.shape[1] + normalized = matrix.mT if was_transposed else matrix + key = (normalized.device, normalized.dtype, normalized.shape[0], normalized.shape[1]) + entries_by_shape.setdefault(key, []).append((p, normalized, was_transposed, state)) + + apply_params = [] + apply_updates = [] + for entries in entries_by_shape.values(): + for chunk_begin in range(0, len(entries), self.muon_ns_batch_size): + chunk = entries[chunk_begin:chunk_begin + self.muon_ns_batch_size] + stacked = torch.stack([entry[1] for entry in chunk], dim=0) + if self.use_polar_express: + orthogonalized = zeropower_via_polar_express_compiled(stacked, steps=self.ns_steps) + else: + orthogonalized = zeropower_via_newtonschulz5_compiled(stacked, steps=self.ns_steps) + + if not self.use_normuon and group["adjust_lr_fn"] == "match_rms_adamw": + # The adjust-lr scale depends only on the (shared) matrix + # shape, so scale the whole stacked chunk in one launch, + # in parameter dtype for the foreach apply below. + m, n = orthogonalized.shape[-2], orthogonalized.shape[-1] + scale = (0.1825 if self.use_polar_express else 0.2) * max(m, n)**0.5 + scaled = orthogonalized.to(chunk[0][0].dtype) * scale + for (p, _, was_transposed, state), update in zip(chunk, scaled.unbind(dim=0)): + if was_transposed: + update = update.mT + apply_params.append(p) + apply_updates.append(update.reshape(p.shape)) + continue + + for (p, _, was_transposed, state), update in zip(chunk, orthogonalized.unbind(dim=0)): + if was_transposed: + update = update.mT + normuon_v = state.get("normuon_v") + if normuon_v is not None: + assert group["adjust_lr_fn"] == "match_rms_adamw", \ + f"NorMuon requires adjust_lr_fn='match_rms_adamw', got '{group['adjust_lr_fn']}'" + normuon_v.lerp_(update.square().mean(dim=-1).to(normuon_v.dtype), 1 - self.normuon_beta2) + update = update / (normuon_v.sqrt().unsqueeze(-1) + self.normuon_eps) + update = update * (0.1825 * (update.size(-2) * update.size(-1))**0.5 / (update.norm() + 1e-30)) + elif group["adjust_lr_fn"] == "match_rms_adamw": + if self.use_polar_express: + update = update * (0.1825 * max(update.size(-2), update.size(-1))**0.5) + else: + update = update * (0.2 * max(update.size(-2), update.size(-1))**0.5) + elif group["adjust_lr_fn"] == "original": + update = update * (max(1, update.size(-2) / update.size(-1))**0.5) + else: + raise AssertionError(f"Unexpected value adjust_lr_fn={group['adjust_lr_fn']}") + apply_params.append(p) + apply_updates.append(update.reshape(p.shape).to(p.dtype)) + + torch._foreach_mul_(apply_params, 1 - group["lr"] * group["weight_decay"]) + torch._foreach_add_(apply_params, apply_updates, alpha=-group["lr"]) + + def _step_muon_group(self, group, param_indices): + if self.use_batched_muon_ns: + self._step_muon_params_batched(group, param_indices) + else: + for param_index in param_indices: + self._step_muon_param_scalar(group, group["params"][param_index]) + + def _ensure_adam_state(self, p): + if p.grad is None: + # continue + p.grad = torch.zeros_like(p) # Force synchronization + state = self.state[p] + if len(state) == 0: + state["exp_avg"] = torch.zeros_like(p) + state["exp_avg_sq"] = torch.zeros_like(p) + state["step"] = 0 + return state + + def _step_adam_group(self, group): + if self.use_foreach_aux_adam: + self._step_adam_group_foreach(group) + return + for p in group["params"]: + state = self._ensure_adam_state(p) + state["step"] += 1 + update = adam_update(p.grad, state["exp_avg"], state["exp_avg_sq"], + state["step"], group["betas"], group["eps"]) + p.mul_(1 - group["lr"] * group["weight_decay"]) + p.add_(update, alpha=-group["lr"]) + + def _step_adam_group_foreach(self, group): + """Update an auxiliary Adam group with one multi-tensor launch per operation. + Same update equations as adam_update.""" + entries_by_step = {} + for p in group["params"]: + state = self._ensure_adam_state(p) + state["step"] += 1 + entries_by_step.setdefault(state["step"], []).append(( + p, p.grad, state["exp_avg"], state["exp_avg_sq"], + )) + + beta1, beta2 = group["betas"] + adam_lr = group["lr"] + for step, entries in entries_by_step.items(): + params, grads, exp_avgs, exp_avg_sqs = map(list, zip(*entries)) + torch._foreach_lerp_(exp_avgs, grads, 1 - beta1) + grads_sq = torch._foreach_mul(grads, grads) + torch._foreach_lerp_(exp_avg_sqs, grads_sq, 1 - beta2) + + bias_correction1 = 1 - beta1**step + bias_correction2_sqrt = (1 - beta2**step) ** 0.5 + denominators = torch._foreach_sqrt(exp_avg_sqs) + torch._foreach_div_(denominators, bias_correction2_sqrt) + torch._foreach_add_(denominators, group["eps"]) + updates = torch._foreach_div(exp_avgs, denominators) + + torch._foreach_mul_(params, 1 - adam_lr * group["weight_decay"]) + torch._foreach_add_(params, updates, alpha=-adam_lr / bias_correction1) + + +class MuonWithAuxAdam(_MuonWithAuxAdamBase): """ Distributed Muon variant that can be used for all parameters in the network, since it runs an internal AdamW for the parameters that are not compatible with Muon. The user must manually @@ -230,6 +586,10 @@ class MuonWithAuxAdam(torch.optim.Optimizer): The point of this class is to allow the user to have a single optimizer in their code, rather than having both a Muon and an Adam which each need to be stepped. + Muon parameter ownership is sharded round-robin across ranks. + After each step the updated parameters are synchronized in reusable flat buckets + (one all-gather per ~16 MiB bucket) rather than one collective per parameter. + Set use_normuon=True to enable NorMuon (neuron-wise normalized Muon), which adds row-wise adaptive learning rates after orthogonalization. See https://arxiv.org/abs/2510.05491 @@ -257,32 +617,203 @@ class MuonWithAuxAdam(torch.optim.Optimizer): def __init__(self, param_groups, adjust_lr_fn="match_rms_adamw", adam_betas=(0.95, 0.995), adam_eps=1e-6, use_normuon=False, normuon_beta2=0.95, normuon_eps=1e-8, use_aurora=False, aurora_pp_iterations=2, aurora_pp_beta=0.5, aurora_eps=1e-7, - ns_steps=5, use_polar_express=False): - self.use_normuon = use_normuon - self.normuon_beta2 = normuon_beta2 - self.normuon_eps = normuon_eps - self.use_aurora = use_aurora - self.aurora_pp_iterations = aurora_pp_iterations - self.aurora_pp_beta = aurora_pp_beta - self.aurora_eps = aurora_eps - self.ns_steps = ns_steps - self.use_polar_express = use_polar_express - for group in param_groups: - assert "use_muon" in group - if group["use_muon"]: - group["params"] = sorted(group["params"], key=lambda x: x.size(), reverse=True) - # defaults - group["lr"] = group.get("lr", 0.02) - group["momentum"] = group.get("momentum", 0.95) - group["weight_decay"] = group.get("weight_decay", 0) - group["adjust_lr_fn"] = group.get("adjust_lr_fn", adjust_lr_fn) - else: - # defaults - group["lr"] = group.get("lr", 3e-4) - group["betas"] = group.get("betas", adam_betas) - group["eps"] = group.get("eps", adam_eps) - group["weight_decay"] = group.get("weight_decay", 0) - super().__init__(param_groups, dict()) + ns_steps=5, use_polar_express=False, + distributed_bucket_cap_bytes=DEFAULT_DISTRIBUTED_BUCKET_CAP_BYTES): + self.distributed_bucket_cap_bytes = int(distributed_bucket_cap_bytes) + if self.distributed_bucket_cap_bytes <= 0: + raise ValueError(f"distributed_bucket_cap_bytes must be positive, got {distributed_bucket_cap_bytes}") + self._muon_distributed_layouts = None + super().__init__( + param_groups, adjust_lr_fn=adjust_lr_fn, adam_betas=adam_betas, adam_eps=adam_eps, + use_normuon=use_normuon, normuon_beta2=normuon_beta2, normuon_eps=normuon_eps, + use_aurora=use_aurora, aurora_pp_iterations=aurora_pp_iterations, + aurora_pp_beta=aurora_pp_beta, aurora_eps=aurora_eps, + ns_steps=ns_steps, use_polar_express=use_polar_express, + sort_muon_params=True, + ) + + def _initialize_muon_distributed_layouts(self): + world_size = dist.get_world_size() + + # Insertion order follows parameter traversal and is therefore identical + # across ranks even though each rank's CUDA device index is different. + layout_builders = {} + for group in self.param_groups: + if not group["use_muon"]: + continue + for local_index, param in enumerate(group["params"]): + if not param.is_contiguous(): + raise ValueError( + "Distributed Muon parameter synchronization requires contiguous parameters, " + f"got shape={tuple(param.shape)} stride={param.stride()}" + ) + key = (param.device, param.dtype) + if key not in layout_builders: + layout_builders[key] = { + "params": [], + "owner_param_numels": [[] for _ in range(world_size)], + } + builder = layout_builders[key] + param_index = len(builder["params"]) + builder["params"].append(param) + owner = local_index % world_size + builder["owner_param_numels"][owner].append((param_index, param.numel())) + + layouts = [] + total_buckets = 0 + total_workspace_bytes = 0 + for builder in layout_builders.values(): + params = tuple(builder["params"]) + if len(params) <= 0: + continue + element_size = params[0].element_size() + bucket_cap_numel = max(1, self.distributed_bucket_cap_bytes // element_size) + buckets = _build_muon_flat_bucket_plan( + builder["owner_param_numels"], + bucket_cap_numel, + ) + if len(buckets) <= 0: + continue + max_collective_numel = max(bucket.collective_numel for bucket in buckets) + send_buffer = torch.empty( + max_collective_numel, + dtype=params[0].dtype, + device=params[0].device, + ) + gathered_buffer = torch.empty( + world_size * max_collective_numel, + dtype=params[0].dtype, + device=params[0].device, + ) + layouts.append(_MuonDistributedLayout( + params=params, + buckets=buckets, + send_buffer=send_buffer, + gathered_buffer=gathered_buffer, + )) + total_buckets += len(buckets) + total_workspace_bytes += (world_size + 1) * max_collective_numel * element_size + + self._muon_distributed_layouts = tuple(layouts) + logging.info( + "Muon DDP flat parameter synchronization: %d bucket(s), %.1f MiB reusable workspace per rank", + total_buckets, + total_workspace_bytes / (1024.0 * 1024.0), + ) + + def state_dict_for_checkpoint(self): + """Full optimizer state dict including Muon states owned by other ranks. + + Muon momentum (and NorMuon second-moment) buffers are sharded: each rank + only steps params[rank::world_size] within each Muon group, so a plain + rank-0 state_dict() would silently drop the other ranks' buffers and + they would reinitialize to zero on resume. This gathers every rank's + owned Muon states onto rank 0. + + COLLECTIVE: every rank must call this at the same point. Returns the + complete state dict on rank 0 and None on other ranks. + """ + optimizer_state_dict = self.state_dict() + rank = dist.get_rank() + world_size = dist.get_world_size() + + local_muon_state = {} + for group in optimizer_state_dict["param_groups"]: + if not group.get("use_muon", False): + continue + for local_index, param_id in enumerate(group["params"]): + if local_index % world_size != rank: + continue + if param_id not in optimizer_state_dict["state"]: + continue + state = optimizer_state_dict["state"][param_id] + local_muon_state[param_id] = { + key: (value.detach().cpu() if isinstance(value, torch.Tensor) else value) + for key, value in state.items() + } + + gathered_muon_state = [None for _ in range(world_size)] if rank == 0 else None + dist.gather_object(local_muon_state, gathered_muon_state, dst=0) + if rank != 0: + return None + for rank_state in gathered_muon_state: + if rank_state is None: + continue + for param_id, state in rank_state.items(): + optimizer_state_dict["state"][param_id] = state + return optimizer_state_dict + + def load_state_dict_for_checkpoint(self, state_dict): + """Load a checkpoint produced by state_dict_for_checkpoint, keeping only + the locally-owned Muon states on this rank. Because the checkpoint holds + every rank's Muon states, resuming with a different world size works as + long as the parameter groups and their ordering are unchanged.""" + rank = dist.get_rank() + world_size = dist.get_world_size() + muon_non_local_param_ids = set() + for group in state_dict["param_groups"]: + if not group.get("use_muon", False): + continue + for local_index, param_id in enumerate(group["params"]): + if local_index % world_size != rank: + muon_non_local_param_ids.add(param_id) + filtered_state = { + param_id: state + for param_id, state in state_dict["state"].items() + if param_id not in muon_non_local_param_ids + } + self.load_state_dict({ + "state": filtered_state, + "param_groups": state_dict["param_groups"], + }) + + def _synchronize_muon_parameters(self): + if self._muon_distributed_layouts is None: + self._initialize_muon_distributed_layouts() + + rank = dist.get_rank() + world_size = dist.get_world_size() + for layout in self._muon_distributed_layouts: + for bucket in layout.buckets: + collective_numel = bucket.collective_numel + owner_numel = bucket.owner_numels[rank] + send = layout.send_buffer[:collective_numel] + + local_parts = [ + layout.params[segment.param_index].detach().view(-1)[ + segment.param_offset:segment.param_offset + segment.numel + ] + for segment in bucket.segments_by_owner[rank] + ] + if len(local_parts) == 1: + send[:owner_numel].copy_(local_parts[0]) + elif len(local_parts) > 1: + torch.cat(local_parts, dim=0, out=send[:owner_numel]) + else: + assert owner_numel == 0 + if owner_numel < collective_numel: + send[owner_numel:].zero_() + + gathered = layout.gathered_buffer[:world_size * collective_numel] + dist.all_gather_into_tensor(gathered, send) + gathered_by_owner = gathered.view(world_size, collective_numel) + + destination_parts = [] + source_parts = [] + for owner in range(world_size): + if owner == rank: + continue + for segment in bucket.segments_by_owner[owner]: + destination_parts.append( + layout.params[segment.param_index].view(-1)[ + segment.param_offset:segment.param_offset + segment.numel + ] + ) + source_parts.append( + gathered_by_owner[owner, segment.packed_offset:segment.packed_offset + segment.numel] + ) + if len(destination_parts) > 0: + torch._foreach_copy_(destination_parts, source_parts) @torch.no_grad() def step(self, closure=None): @@ -292,62 +823,24 @@ def step(self, closure=None): with torch.enable_grad(): loss = closure() + rank = dist.get_rank() + world_size = dist.get_world_size() for group in self.param_groups: if group["use_muon"]: - params = group["params"] - params_pad = params + [torch.empty_like(params[-1])] * (dist.get_world_size() - len(params) % dist.get_world_size()) - for base_i in range(len(params))[::dist.get_world_size()]: - if base_i + dist.get_rank() < len(params): - p = params[base_i + dist.get_rank()] - if p.grad is None: - # continue - p.grad = torch.zeros_like(p) # Force synchronization - state = self.state[p] - if len(state) == 0: - state["momentum_buffer"] = torch.zeros_like(p) - if self.use_normuon: - state["normuon_v"] = torch.zeros(p.shape[0], device=p.device, dtype=p.dtype) - if self.use_aurora: - update = aurora_update( - p.grad, state["momentum_buffer"], - ns_steps=self.ns_steps, - beta=group["momentum"], adjust_lr_fn=group["adjust_lr_fn"], - pp_iterations=self.aurora_pp_iterations, - pp_beta=self.aurora_pp_beta, eps=self.aurora_eps, - use_polar_express=self.use_polar_express, - ) - else: - update = muon_update( - p.grad, state["momentum_buffer"], - ns_steps=self.ns_steps, - beta=group["momentum"], adjust_lr_fn=group["adjust_lr_fn"], - normuon_v=state.get("normuon_v"), - normuon_beta2=self.normuon_beta2, normuon_eps=self.normuon_eps, - use_polar_express=self.use_polar_express, - ) - p.mul_(1 - group["lr"] * group["weight_decay"]) - p.add_(update.reshape(p.shape), alpha=-group["lr"]) - dist.all_gather(params_pad[base_i:base_i + dist.get_world_size()], params_pad[base_i + dist.get_rank()]) + # Round-robin ownership matching the historical layout. All + # ranks must agree on this assignment; parameters this rank + # does not own are filled in by the flat synchronization below. + param_indices = range(rank, len(group["params"]), world_size) + self._step_muon_group(group, param_indices) else: - for p in group["params"]: - if p.grad is None: - # continue - p.grad = torch.zeros_like(p) # Force synchronization - state = self.state[p] - if len(state) == 0: - state["exp_avg"] = torch.zeros_like(p) - state["exp_avg_sq"] = torch.zeros_like(p) - state["step"] = 0 - state["step"] += 1 - update = adam_update(p.grad, state["exp_avg"], state["exp_avg_sq"], - state["step"], group["betas"], group["eps"]) - p.mul_(1 - group["lr"] * group["weight_decay"]) - p.add_(update, alpha=-group["lr"]) + self._step_adam_group(group) + + self._synchronize_muon_parameters() return loss -class SingleDeviceMuonWithAuxAdam(torch.optim.Optimizer): +class SingleDeviceMuonWithAuxAdam(_MuonWithAuxAdamBase): """ Non-distributed variant of MuonWithAuxAdam. """ @@ -355,30 +848,14 @@ def __init__(self, param_groups, adjust_lr_fn="match_rms_adamw", adam_betas=(0.9 use_normuon=False, normuon_beta2=0.95, normuon_eps=1e-8, use_aurora=False, aurora_pp_iterations=2, aurora_pp_beta=0.5, aurora_eps=1e-7, ns_steps=5, use_polar_express=False): - self.use_normuon = use_normuon - self.normuon_beta2 = normuon_beta2 - self.normuon_eps = normuon_eps - self.use_aurora = use_aurora - self.aurora_pp_iterations = aurora_pp_iterations - self.aurora_pp_beta = aurora_pp_beta - self.aurora_eps = aurora_eps - self.ns_steps = ns_steps - self.use_polar_express = use_polar_express - for group in param_groups: - assert "use_muon" in group - if group["use_muon"]: - # defaults - group["lr"] = group.get("lr", 0.02) - group["momentum"] = group.get("momentum", 0.95) - group["weight_decay"] = group.get("weight_decay", 0) - group["adjust_lr_fn"] = group.get("adjust_lr_fn", adjust_lr_fn) - else: - # defaults - group["lr"] = group.get("lr", 3e-4) - group["betas"] = group.get("betas", adam_betas) - group["eps"] = group.get("eps", adam_eps) - group["weight_decay"] = group.get("weight_decay", 0) - super().__init__(param_groups, dict()) + super().__init__( + param_groups, adjust_lr_fn=adjust_lr_fn, adam_betas=adam_betas, adam_eps=adam_eps, + use_normuon=use_normuon, normuon_beta2=normuon_beta2, normuon_eps=normuon_eps, + use_aurora=use_aurora, aurora_pp_iterations=aurora_pp_iterations, + aurora_pp_beta=aurora_pp_beta, aurora_eps=aurora_eps, + ns_steps=ns_steps, use_polar_express=use_polar_express, + sort_muon_params=False, + ) @torch.no_grad() def step(self, closure=None): @@ -390,49 +867,8 @@ def step(self, closure=None): for group in self.param_groups: if group["use_muon"]: - for p in group["params"]: - if p.grad is None: - # continue - p.grad = torch.zeros_like(p) # Force synchronization - state = self.state[p] - if len(state) == 0: - state["momentum_buffer"] = torch.zeros_like(p) - if self.use_normuon: - state["normuon_v"] = torch.zeros(p.shape[0], device=p.device, dtype=p.dtype) - if self.use_aurora: - update = aurora_update( - p.grad, state["momentum_buffer"], - ns_steps=self.ns_steps, - beta=group["momentum"], adjust_lr_fn=group["adjust_lr_fn"], - pp_iterations=self.aurora_pp_iterations, - pp_beta=self.aurora_pp_beta, eps=self.aurora_eps, - use_polar_express=self.use_polar_express, - ) - else: - update = muon_update( - p.grad, state["momentum_buffer"], - ns_steps=self.ns_steps, - beta=group["momentum"], adjust_lr_fn=group["adjust_lr_fn"], - normuon_v=state.get("normuon_v"), - normuon_beta2=self.normuon_beta2, normuon_eps=self.normuon_eps, - use_polar_express=self.use_polar_express, - ) - p.mul_(1 - group["lr"] * group["weight_decay"]) - p.add_(update.reshape(p.shape), alpha=-group["lr"]) + self._step_muon_group(group, range(len(group["params"]))) else: - for p in group["params"]: - if p.grad is None: - # continue - p.grad = torch.zeros_like(p) # Force synchronization - state = self.state[p] - if len(state) == 0: - state["exp_avg"] = torch.zeros_like(p) - state["exp_avg_sq"] = torch.zeros_like(p) - state["step"] = 0 - state["step"] += 1 - update = adam_update(p.grad, state["exp_avg"], state["exp_avg_sq"], - state["step"], group["betas"], group["eps"]) - p.mul_(1 - group["lr"] * group["weight_decay"]) - p.add_(update, alpha=-group["lr"]) + self._step_adam_group(group) return loss diff --git a/python/quantize_vitisai.py b/python/quantize_vitisai.py deleted file mode 100644 index a023b3281c..0000000000 --- a/python/quantize_vitisai.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python3 -"""Quantize a KataGo FP32 ONNX graph to INT8 QDQ for the VitisAI (AMD Ryzen AI NPU) execution -provider, for use with katago.exe's ONNX backend (onnxProvider=vitisai). - -Offline tool -- katago.exe does NOT invoke this automatically. Requires `amd-quark` (AMD's ONNX -quantizer, providing the `quark.onnx` module, bundled with the Ryzen AI / VitisAI SDK), `onnx`, -and `numpy`. - -Typical usage: first export an FP32 ONNX graph from a .bin.gz KataGo model (`katago exportonnx`), -sample calibration data from real games (`katago dumpcalibrationdata`), then run: - - python quantize_vitisai.py --input model-fp32.onnx --calibration calib.npz --output model-int8.onnx -""" -import argparse -import sys - -import numpy as np -import onnx - - -def load_calibration(npz_path): - data = np.load(npz_path) - return data["binaryInputNCHW"], data["globalInputNC"] - - -def classify_input_name(name): - lname = name.lower() - if "mask" in lname: - return "mask" - if "spatial" in lname: - return "spatial" - if "global" in lname: - return "global" - if "meta" in lname: - return "meta" - return None - - -class KataGoCalibrationDataReader: - """Feeds calibration rows sampled by KataGo's dumpcalibrationdata. - binaryInputNCHW has shape [N, spatialChannels, H, W] where channel 0 is the on-board mask - (KataGo convention); globalInputNC has shape [N, globalChannels]. These get mapped onto - whatever the graph's actual input names are (InputSpatial/InputMask/InputGlobal/InputMeta by - default, but matched generically here by substring in case of custom names). - """ - - def __init__(self, spatial, global_, input_names): - self.spatial = spatial - self.global_ = global_ - self.input_names = input_names - self.idx = 0 - self.n = spatial.shape[0] - - def get_next(self): - if self.idx >= self.n: - return None - i = self.idx - self.idx += 1 - feed = {} - if "spatial" in self.input_names: - feed[self.input_names["spatial"]] = self.spatial[i : i + 1] - if "mask" in self.input_names: - feed[self.input_names["mask"]] = self.spatial[i : i + 1, 0:1] - if "global" in self.input_names: - g = self.global_[i : i + 1] - feed[self.input_names["global"]] = g.reshape(g.shape[0], g.shape[1], 1, 1) - if "meta" in self.input_names: - feed[self.input_names["meta"]] = np.zeros(self.input_names["meta_shape"], dtype=np.float32) - return feed - - def rewind(self): - self.idx = 0 - - -def build_input_map(model): - input_names = {} - for inp in model.graph.input: - role = classify_input_name(inp.name) - if role is None: - print(f'[quantize_vitisai] warning: unrecognized graph input "{inp.name}", ignoring', flush=True) - continue - input_names[role] = inp.name - if role == "meta": - dims = [d.dim_value if d.dim_value > 0 else 1 for d in inp.type.tensor_type.shape.dim] - input_names["meta_shape"] = tuple(dims) - return input_names - - -def quantize(input_path, output_path, reader): - # Preferred path: quark's high-level ModelQuantizer with the XINT8 preset config, which is - # AMD's own recommended power-of-2-scale INT8 scheme for Ryzen AI NPU CNN deployment. - try: - from quark.onnx import XINT8_QCONFIG, ModelQuantizer - - print("[quantize_vitisai] using quark.onnx ModelQuantizer with XINT8_QCONFIG preset", flush=True) - quantizer = ModelQuantizer(XINT8_QCONFIG) - result = quantizer.quantize_model( - model_input=input_path, - model_output=output_path, - calibration_data_reader=reader, - ) - if result is not None and not _file_nonempty(output_path): - onnx.save(result, output_path) - return - except ImportError as e: - print(f"[quantize_vitisai] quark.onnx ModelQuantizer/XINT8_QCONFIG unavailable ({e}), " - f"falling back to quark.onnx.quantize_static", flush=True) - - # Fallback: the lower-level quantize_static function. XINT8_QCONFIG (the preferred path above) - # is int8 with POWER-OF-2 scaling and MinMSE calibration (quark.onnx.quantization.config.spec. - # XInt8Spec) -- NOT the same as generic int8 with float32 scaling and MinMax calibration, which - # is quark's own *default* if calibrate_method/scale type are left unspecified here. Using the - # wrong scale representation produces a QDQ graph the VitisAI DPU compiler's pattern-matcher - # does not recognize as fusable, so activation_type/weight_type alone are not sufficient -- - # calibrate_method must explicitly be quark's PowerOfTwoMethod, not onnxruntime's CalibrationMethod. - reader.rewind() - import quark.onnx as qo - from onnxruntime.quantization import QuantFormat, QuantType - from quark.onnx.calibration import PowerOfTwoMethod - - qo.quantize_static( - model_input=input_path, - model_output=output_path, - calibration_data_reader=reader, - quant_format=QuantFormat.QDQ, - calibrate_method=PowerOfTwoMethod.MinMSE, - activation_type=QuantType.QInt8, - weight_type=QuantType.QInt8, - enable_npu_cnn=True, - ) - - -def _file_nonempty(path): - try: - import os - - return os.path.exists(path) and os.path.getsize(path) > 0 - except OSError: - return False - - -def main(): - parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument("--input", required=True, help="Input FP32 ONNX model path") - parser.add_argument("--calibration", required=True, help="Calibration .npz path (binaryInputNCHW, globalInputNC)") - parser.add_argument("--output", required=True, help="Output INT8 QDQ ONNX model path") - args = parser.parse_args() - - print(f"[quantize_vitisai] loading model: {args.input}", flush=True) - model = onnx.load(args.input) - - input_names = build_input_map(model) - printable = {k: v for k, v in input_names.items() if k != "meta_shape"} - print(f"[quantize_vitisai] graph inputs mapped: {printable}", flush=True) - if "spatial" not in input_names or "global" not in input_names: - print("[quantize_vitisai] ERROR: could not find InputSpatial/InputGlobal in the graph", flush=True) - sys.exit(1) - - print(f"[quantize_vitisai] loading calibration data: {args.calibration}", flush=True) - spatial, global_ = load_calibration(args.calibration) - print(f"[quantize_vitisai] calibration: {spatial.shape[0]} positions", flush=True) - - reader = KataGoCalibrationDataReader(spatial, global_, input_names) - - try: - quantize(args.input, args.output, reader) - except Exception as e: # noqa: BLE001 -- deliberately broad: any failure must be reported, not swallowed - print(f"[quantize_vitisai] ERROR: quantization failed: {e}", flush=True) - import traceback - - traceback.print_exc() - sys.exit(1) - - if not _file_nonempty(args.output): - print(f"[quantize_vitisai] ERROR: expected output {args.output} was not created", flush=True) - sys.exit(1) - - print(f"[quantize_vitisai] wrote {args.output}", flush=True) - - -if __name__ == "__main__": - main() diff --git a/python/refresh_batchnorm_stats.py b/python/refresh_batchnorm_stats.py new file mode 100644 index 0000000000..56c96194ff --- /dev/null +++ b/python/refresh_batchnorm_stats.py @@ -0,0 +1,387 @@ +#!/usr/bin/python3 +""" +Refresh (exactly recompute) the batchnorm running statistics of a checkpoint over +a sample of shuffled data, for both the plain model and the SWA model, and write +out a new checkpoint that is otherwise identical. + +Why: batchnorm running_mean/running_std are an EWMA over recent training batches, so they lag +the current weights' true statistics. This inflates eval-mode losses in a way that varies +erratically from checkpoint to checkpoint. + +This affects SWA too, and AveragedModel copies the raw model's instantaneous buffers +rather than averaging them. + +This script run forwards in train mode while accumulating the exact masked population +mean/variance of each batchnorm layer's input. Then overwrites running_mean with the pooled mean +and running_std with sqrt(pooled_var + epsilon), matching the convention that +running_std is an EWMA of sqrt(batch_var + epsilon). + +Also evaluates losses on the same data in various modes, paired on identical batches, +printing full losses in the same format as train.py and a small summary table: +* train mode (batch stats), +* eval mode with the original stored stats +* eval mode with the refreshed stats +""" +import sys +import os +import math +import argparse +import logging +import hashlib +import datetime +from collections import defaultdict + +import torch +from torch.optim.swa_utils import AveragedModel + +from katago.train import modelconfigs +from katago.train.model_pytorch import Model, NormMask, ExtraOutputs +from katago.train.metrics_pytorch import Metrics +from katago.train import data_processing_pytorch +from katago.train.load_model import load_checkpoint, load_model_state_dict, load_swa_model_state_dict +from katago.train.metrics_logging import accumulate_metrics, log_metrics +from katago.train.trainloop_helpers import detensorify_metrics + +# Match train.py's defaults so the reported aggregate "loss" is comparable. +SOFT_POLICY_WEIGHT_SCALE = 8.0 +VALUE_LOSS_SCALE = 0.6 +TD_VALUE_LOSS_SCALES = [0.6, 0.6, 0.6] +SEKI_LOSS_SCALE = 1.0 +VARIANCE_TIME_LOSS_SCALE = 1.0 + +SUMMARY_TABLE_KEYS = ["p0loss", "p0sopt", "vloss", "tdvloss1", "leadloss", "oloss"] + + +def find_batchnorm_modules(model): + return [(name, module) for name, module in model.named_modules() + if isinstance(module, NormMask) and module.is_using_batchnorm] + + +def get_bn_buffers(model): + return {name: buf for name, buf in model.named_buffers() if "running_" in name} + + +def snapshot_bn_buffers(model): + return {name: buf.detach().clone() for name, buf in get_bn_buffers(model).items()} + + +def load_bn_buffers(model, values): + # values may cover only a subset of the buffers (e.g. fresh stats cover + # running_mean/running_std but not brenorm's auxiliary buffers). + with torch.no_grad(): + for name, buf in get_bn_buffers(model).items(): + if name in values: + buf.copy_(values[name]) + + +def compute_fresh_stats(model, bn_modules, make_reader, forward_fn, num_batches, device): + """ + Exact masked population mean/std of each batchnorm layer's input, from train-mode forwards. + Returns {module_name: (mean, std)} as buffer-style dicts keyed like snapshot_bn_buffers. + Restores the model's original buffers (train mode forwards update them as a side effect). + """ + accum = { + name: {"s1": None, "s2": None, "n": torch.zeros((), dtype=torch.float64, device=device)} + for name, _ in bn_modules + } + handles = [] + + def make_hook(name): + def hook(module, args, kwargs): + x = args[0] if len(args) > 0 else kwargs["x"] + mask = kwargs["mask"] if "mask" in kwargs else args[1] + mask_sum = kwargs["mask_sum"] if "mask_sum" in kwargs else args[3] + xf = x.float() + b1 = torch.sum(xf * mask, dim=(0, 2, 3)).double() + b2 = torch.sum(torch.square(xf) * mask, dim=(0, 2, 3)).double() + a = accum[name] + if a["s1"] is None: + a["s1"], a["s2"] = b1, b2 + else: + a["s1"] += b1 + a["s2"] += b2 + a["n"] += float(mask_sum) + return hook + + for name, module in bn_modules: + handles.append(module.register_forward_pre_hook(make_hook(name), with_kwargs=True)) + + orig_buffers = snapshot_bn_buffers(model) + model.train() + count = 0 + with torch.no_grad(): + for batch in make_reader(): + if count >= num_batches: + break + forward_fn(model, batch) + count += 1 + for handle in handles: + handle.remove() + load_bn_buffers(model, orig_buffers) + model.eval() + assert count > 0, "No data batches read for stats" + + fresh = {} + for name, module in bn_modules: + a = accum[name] + mean = (a["s1"] / a["n"]).float() + var = (a["s2"] / a["n"]).float() - torch.square(mean) + std = torch.sqrt(var.clamp(min=0.0) + module.epsilon) + fresh[name + ".running_mean"] = mean + fresh[name + ".running_std"] = std + rm = module.running_mean.float() + rs = module.running_std.float() + logging.info( + f" {name}: refreshed from {count} batches, |fresh_mean - old_mean| avg = " + f"{(mean - rm).abs().mean().item():.5f} (mean scale {rm.abs().mean().item():.4f}), " + f"fresh/old std ratio mean = {(std / rs).mean().item():.4f} " + f"min = {(std / rs).min().item():.4f} max = {(std / rs).max().item():.4f}" + ) + return fresh + + +def log_input_checkpoint_info(path, state_dict): + """Log identifying info about the original checkpoint being refreshed.""" + st = os.stat(path) + sha = hashlib.sha256() + with open(path, "rb") as f: + for chunk in iter(lambda: f.read(1024 * 1024), b""): + sha.update(chunk) + mtime = datetime.datetime.fromtimestamp(st.st_mtime).astimezone().isoformat(timespec="seconds") + logging.info(f"Input checkpoint: {path}") + logging.info(f" size = {st.st_size} bytes ({st.st_size / 1024**3:.3f} GiB)") + logging.info(f" mtime = {mtime}") + logging.info(f" sha256 = {sha.hexdigest()}") + train_state = state_dict.get("train_state") + if not isinstance(train_state, dict): + logging.info(" train_state: (not present in checkpoint)") + return + for key in ["global_step_samples", "total_num_data_rows", "window_start_data_row_idx"]: + value = train_state.get(key, "(not present)") + logging.info(f" train_state.{key} = {value}") + + +def main(args): + checkpoint_file = args["checkpoint"] + output_ckpt = args["output_ckpt"] + log_file = output_ckpt + ".bnrefresh.log" + + logging.root.handlers = [] + logging.basicConfig( + level=logging.INFO, + format="%(message)s", + handlers=[ + logging.StreamHandler(stream=sys.stdout), + logging.FileHandler(log_file, mode="w"), + ], + ) + logging.info(str(sys.argv)) + + npzdir = args["npzdir"] + pos_len = args["pos_len"] + batch_size = args["batch_size"] + num_stats_batches = args["num_stats_batches"] + num_loss_batches = args["num_loss_batches"] + use_fp16 = args["use_fp16"] + gpu_idx = args["gpu_idx"] + + assert not os.path.exists(output_ckpt), f"Output already exists: {output_ckpt}" + + if gpu_idx is not None: + torch.cuda.set_device(gpu_idx) + device = torch.device("cuda", gpu_idx) + elif torch.cuda.is_available(): + device = torch.device("cuda") + else: + logging.warning("WARNING: No GPU, using CPU") + device = torch.device("cpu") + torch.set_float32_matmul_precision("high") + torch.backends.cudnn.benchmark = True + + val_files = sorted(os.path.join(npzdir, f) for f in os.listdir(npzdir) if f.endswith(".npz")) + assert len(val_files) > 0, f"No npz files in {npzdir}" + + # Load the checkpoint once; keep the raw state dict around for the final save. + state_dict = load_checkpoint(checkpoint_file) + log_input_checkpoint_info(checkpoint_file, state_dict) + if "config" in state_dict: + model_config = state_dict["config"] + else: + import json + config_file = os.path.join(os.path.dirname(checkpoint_file), "model.config.json") + logging.info(f"No config in checkpoint, so loading from: {config_file}") + with open(config_file, "r") as f: + model_config = json.load(f) + + model = Model(model_config, pos_len) + model.initialize() + model.load_state_dict(load_model_state_dict(state_dict)) + model.to(device) + model.eval() + + swa_model = None + if "swa_model" in state_dict: + swa_wrapper = AveragedModel(model, device=device) + swa_wrapper.load_state_dict(load_swa_model_state_dict(state_dict)) + swa_model = swa_wrapper.module + swa_model.eval() + else: + logging.info("Checkpoint has no swa_model, refreshing plain model only") + + models = [("plain", model)] + ([("swa", swa_model)] if swa_model is not None else []) + + bn_modules_by_model = {} + for mlabel, m in models: + bn_modules = find_batchnorm_modules(m) + assert len(bn_modules) > 0, "Model has no batchnorm layers, nothing to refresh" + bn_modules_by_model[mlabel] = bn_modules + logging.info(f"Batchnorm layers to refresh: {[name for name, _ in bn_modules_by_model['plain']]}") + + metrics_obj = Metrics(1, model) + has_meta = model.get_has_metadata_encoder() + has_intermediate = model.get_has_intermediate_head() + + def make_reader(): + return data_processing_pytorch.read_npz_training_data( + val_files, batch_size, world_size=1, rank=0, pos_len=pos_len, + device=device, randomize_symmetries=False, include_meta=has_meta, + model_config=model_config, + ) + + def forward_fn(m, batch): + extra_outputs = ExtraOutputs([]) + with torch.autocast("cuda", enabled=use_fp16): + return m( + batch["binaryInputNCHW"], + batch["globalInputNC"], + input_meta=(batch["metadataInputNC"] if has_meta else None), + extra_outputs=extra_outputs, + ) + + def batch_metrics(m, batch): + model_outputs = forward_fn(m, batch) + postprocessed = m.postprocess_output(model_outputs) + return metrics_obj.metrics_dict_batchwise( + m, postprocessed, ExtraOutputs([]), batch, + is_training=False, + soft_policy_weight_scale=SOFT_POLICY_WEIGHT_SCALE, + disable_optimistic_policy=False, + meta_kata_only_soft_policy=False, + value_loss_scale=VALUE_LOSS_SCALE, + td_value_loss_scales=TD_VALUE_LOSS_SCALES, + seki_loss_scale=SEKI_LOSS_SCALE, + variance_time_loss_scale=VARIANCE_TIME_LOSS_SCALE, + main_loss_scale=1.0, + intermediate_loss_scale=(1.0 if has_intermediate else None), + ) + + # Compute the refreshed statistics. + orig_buffers = {} + fresh_buffers = {} + for mlabel, m in models: + logging.info(f"Computing fresh batchnorm stats for {mlabel} model over {num_stats_batches} batches of {batch_size}:") + orig_buffers[mlabel] = snapshot_bn_buffers(m) + fresh_buffers[mlabel] = compute_fresh_stats( + m, bn_modules_by_model[mlabel], make_reader, forward_fn, num_stats_batches, device + ) + + # Evaluate losses under all conditions, paired on identical batches. + conditions = [("trainmode", "train"), ("evalmode-orig", "orig"), ("evalmode-refreshed", "fresh")] + if num_loss_batches > 0: + sums = defaultdict(lambda: defaultdict(float)) + weights = defaultdict(lambda: defaultdict(float)) + num_batches = 0 + with torch.no_grad(): + for batch in make_reader(): + if num_batches >= num_loss_batches: + break + for mlabel, m in models: + for clabel, ckind in conditions: + if ckind == "train": + m.train() + else: + m.eval() + load_bn_buffers(m, fresh_buffers[mlabel] if ckind == "fresh" else orig_buffers[mlabel]) + metrics = detensorify_metrics(batch_metrics(m, batch)) + key = (mlabel, clabel) + accumulate_metrics(sums[key], weights[key], metrics, batch_size, decay=1.0, new_weight=1.0) + if ckind == "train": + # Undo buffer EWMA updates from the train-mode forward + load_bn_buffers(m, orig_buffers[mlabel]) + m.eval() + num_batches += 1 + if num_batches % 25 == 0: + logging.info(f"Evaluated losses on {num_batches}/{num_loss_batches} batches") + + logging.info("") + logging.info(f"Losses on {num_batches * batch_size} samples from {npzdir}:") + for mlabel, _ in models: + for clabel, _ in conditions: + key = (mlabel, clabel) + logging.info(f"----- {mlabel} model, {clabel} -----") + log_metrics(sums[key], weights[key], {}, None) + + def fmt_summary_table(keys, label): + avail = [k for k in keys if any((k + "_sum") in sums[key] for key in sums)] + if not avail: + return + logging.info("") + logging.info(f"Summary ({label}):") + header = f"{'condition':>28} " + " ".join(f"{k:>9}" for k in avail) + logging.info(header) + for mlabel, _ in models: + for clabel, _ in conditions: + key = (mlabel, clabel) + row = f"{mlabel + ' ' + clabel:>28} " + for k in avail: + sk = k + "_sum" + row += f"{sums[key][sk] / weights[key][sk]:9.5f} " if weights[key][sk] > 0 else f"{'n/a':>9} " + logging.info(row) + + fmt_summary_table(SUMMARY_TABLE_KEYS, "main heads") + if has_intermediate: + fmt_summary_table(["I" + k for k in SUMMARY_TABLE_KEYS], "intermediate heads - on -bnh models these are the batchnorm-normalized heads") + + # Ensure the in-memory models are left with refreshed buffers (not needed for + # the save below, which edits the raw state dict, but tidy if this is imported). + for mlabel, m in models: + load_bn_buffers(m, fresh_buffers[mlabel]) + + # Write the output checkpoint: identical except for the batchnorm buffers. + def strip_prefixes(key): + while key.startswith("module.") or key.startswith("_orig_mod."): + key = key[len("module."):] if key.startswith("module.") else key[len("_orig_mod."):] + return key + + def overwrite_bn_keys(raw_sd, fresh, what): + num_replaced = 0 + for raw_key in raw_sd: + clean = strip_prefixes(raw_key) + if clean in fresh: + raw_sd[raw_key] = fresh[clean].detach().to(raw_sd[raw_key].dtype).cpu() + num_replaced += 1 + assert num_replaced == len(fresh), \ + f"Expected to replace {len(fresh)} buffers in {what} but replaced {num_replaced}" + logging.info(f"Replaced {num_replaced} batchnorm buffers in {what}") + + overwrite_bn_keys(state_dict["model"], fresh_buffers["plain"], "model") + if swa_model is not None: + overwrite_bn_keys(state_dict["swa_model"], fresh_buffers["swa"], "swa_model") + + torch.save(state_dict, output_ckpt) + logging.info(f"Wrote checkpoint with refreshed batchnorm stats to: {output_ckpt}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('-checkpoint', help='Checkpoint file to refresh', required=True) + parser.add_argument('-output-ckpt', help='Path to write the refreshed checkpoint', required=True) + parser.add_argument('-npzdir', help='Directory with shuffled npz data to compute stats and losses on', required=True) + parser.add_argument('-pos-len', help='Spatial length of expected training data', type=int, default=19, required=False) + parser.add_argument('-batch-size', help='Batch size for stats and loss evaluation', type=int, default=256, required=False) + parser.add_argument('-num-stats-batches', help='Number of batches for computing fresh stats', type=int, default=200, required=False) + parser.add_argument('-num-loss-batches', help='Number of batches for the loss comparison, 0 to skip it', type=int, default=200, required=False) + parser.add_argument('-use-fp16', help='Run forwards under fp16 autocast, matching training with -use-fp16', action="store_true", required=False) + parser.add_argument('-gpu-idx', help='GPU idx', type=int, required=False) + main(vars(parser.parse_args())) diff --git a/python/shuffle.py b/python/shuffle.py index 589657fd94..25c11680e0 100755 --- a/python/shuffle.py +++ b/python/shuffle.py @@ -4,6 +4,7 @@ import sys import os import argparse +import shlex import traceback import math import time @@ -24,13 +25,18 @@ # Needs to be kept in sync with QVALUE_SPATIAL_TARGET_NUM_CHANNELS in trainingwrite.cpp C++ code among other places. EXPECTED_Q_VALUE_TARGETS_NCMOVE_CHANNELS = 3 +# Needs to be kept in sync with GLOBAL_TARGET_NUM_CHANNELS in trainingwrite.cpp C++ code among other places. +# Data format version 2 files (recorded in channel 63 of each row) had only 64 channels; they are zero-padded +# up to this width when shuffling, which correctly encodes "not reanalyzed" for the version 3 channels. +GLOBAL_TARGETS_NC_CHANNELS = 80 + # Empirically measured per-row sizes for 19x19 data, used only for the rough resource-cost # estimates printed by -dry-run-print-resource-cost (and informationally on normal runs). # binaryInputNCHWPacked 1012, globalInputNC 76, policyTargetsNCMove 1448, -# globalTargetsNC 256, scoreDistrN 842, valueTargetsNCHW 1805 (sum = 5439, "required") +# globalTargetsNC 320, scoreDistrN 842, valueTargetsNCHW 1805 (sum = 5503, "required") # + qValueTargetsNCMove 2172, + metadataInputNC 768 when those are included. -UNCOMPRESSED_BYTES_PER_ROW_REQUIRED_19 = 5439 +UNCOMPRESSED_BYTES_PER_ROW_REQUIRED_19 = 5503 UNCOMPRESSED_BYTES_PER_ROW_QVALUES_19 = 2172 UNCOMPRESSED_BYTES_PER_ROW_META_19 = 768 # Whole-file (large npz) compressed size as a fraction of uncompressed, measured on @@ -142,6 +148,16 @@ def save_output_npz( **save_dict ) +def pad_global_targets_nc(globalTargetsNC: np.ndarray) -> np.ndarray: + """Zero-pad older-format globalTargetsNC rows up to the current channel count.""" + num_channels = globalTargetsNC.shape[1] + if num_channels == GLOBAL_TARGETS_NC_CHANNELS: + return globalTargetsNC + assert num_channels < GLOBAL_TARGETS_NC_CHANNELS, f"globalTargetsNC has {num_channels} channels, more than the expected {GLOBAL_TARGETS_NC_CHANNELS}" + padded = np.zeros((globalTargetsNC.shape[0], GLOBAL_TARGETS_NC_CHANNELS), dtype=globalTargetsNC.dtype) + padded[:, :num_channels] = globalTargetsNC + return padded + def load_and_accumulate_input_contents( input_file: str, binaryInputNCHWPackedList: list[np.ndarray], @@ -161,7 +177,7 @@ def load_and_accumulate_input_contents( binaryInputNCHWPackedList.append(npz["binaryInputNCHWPacked"]) globalInputNCList.append(npz["globalInputNC"]) policyTargetsNCMoveList.append(npz["policyTargetsNCMove"]) - globalTargetsNCList.append(npz["globalTargetsNC"]) + globalTargetsNCList.append(pad_global_targets_nc(npz["globalTargetsNC"])) scoreDistrNList.append(npz["scoreDistrN"]) valueTargetsNCHWList.append(npz["valueTargetsNCHW"]) if metadataInputNCList is not None: @@ -785,6 +801,9 @@ def __exit__(self, exception_type, exception_val, trace): optional_args.add_argument('-exclude-qvalues', action="store_true", required=False, help='Exclude Q-value targets (for backwards compatibility with pre-v1.16)') args = parser.parse_args() + + print("Command: %s" % shlex.join(sys.argv), flush=True) + dirs = args.dirs min_rows = args.min_rows max_rows = args.max_rows diff --git a/python/train.py b/python/train.py index 678b4e2666..c05697817e 100755 --- a/python/train.py +++ b/python/train.py @@ -2,6 +2,7 @@ import sys import os import argparse +import re import traceback import random import math @@ -43,6 +44,7 @@ from katago.utils.training_data_generator import TrainingDataGenerator from katago.train import load_model from katago.train import data_processing_pytorch +from katago.train import trainloop_helpers from katago.train.metrics_logging import accumulate_metrics, log_metrics, clear_metric_nonfinite # HANDLE COMMAND AND ARGS ------------------------------------------------------------------- @@ -81,6 +83,7 @@ optional_args.add_argument('-lr-scale', help='LR multiplier on the hardcoded schedule', type=float, required=False) optional_args.add_argument('-lr-scale-auto', help='LR auto scaling', required=False, action='store_true') optional_args.add_argument('-lr-scale-auto2', help='LR auto scaling 2', required=False, type=float) + optional_args.add_argument('-lr-schedule', help="Explicit piecewise-constant LR scale schedule as (global_step_samples,lr_scale) points, e.g. '(0,12.0),(20M,9.0),(40M,6.0)'. Must start at (0,...); each point sets the LR scale from that sample count onward. Counts accept K/M/B suffixes. Mutually exclusive with -lr-scale/-lr-scale-auto/-lr-scale-auto2.", required=False, type=str) optional_args.add_argument('-head-lr-factor', help='LR factor for output head weights', type=float, required=False, default=0.5) optional_args.add_argument('-noreg-lr-factor', help='LR factor for noreg params (biases, norms)', type=float, required=False, default=1.0) optional_args.add_argument('-muon-adam-lr-factor', help='LR factor for muon-ineligible (adam) params when using muon', type=float, required=False, default=1.0) @@ -105,7 +108,8 @@ optional_args.add_argument('-use-polar-express', help='Use Polar Express iteration instead of standard NS5 for muon/normuon/aurora', required=False, action='store_true') optional_args.add_argument('-multi-gpus', help='Use multiple gpus, comma-separated device ids', required=False) - optional_args.add_argument('-use-fp16', help='Use fp16 training', required=False, action='store_true') + optional_args.add_argument('-use-fp16', help='Use fp16 AMP training (with gradient scaler)', required=False, action='store_true') + optional_args.add_argument('-use-bf16', help='Use bf16 AMP training (no gradient scaler). Mutually exclusive with -use-fp16', required=False, action='store_true') optional_args.add_argument('-no-compile', help='Do not torch.compile', required=False, action='store_true') optional_args.add_argument('-use-tf32-matmul', help='Reduce float32 precision for speed on some gpus', required=False, action='store_true') @@ -133,6 +137,9 @@ optional_args.add_argument('-brenorm-target-dmax', type=float, help='Gradually adjust brenorm dmax to this value', required=False) optional_args.add_argument('-brenorm-adjustment-scale', type=float, help='How many samples to adjust brenorm params all but 1/e of the way to target', required=False) + optional_args.add_argument('-attn-logit-penalty-cap', type=float, help='Penalize attention layers whose per-head logit upper bound (scale * max||q|| * max||k||, incl off-board positions) exceeds this. None = disabled.', required=False) + optional_args.add_argument('-attn-logit-penalty-coeff', type=float, default=1e-3, help='Loss coeff for the attention logit bound penalty (linear hinge, mean over heads, sum over layers, per sample)', required=False) + optional_args.add_argument('-attn-logit-penalty-batch-frac', type=float, default=1.0, help='Compute the attention logit penalty on only this fraction of each batch (cuts its cost proportionally, adds gradient variance)', required=False) optional_args.add_argument('-soft-policy-weight-scale', type=float, default=8.0, help='Soft policy loss coeff', required=False) optional_args.add_argument('-disable-optimistic-policy', help='Disable optimistic policy', required=False, action='store_true') optional_args.add_argument('-meta-kata-only-soft-policy', help='Mask soft policy on non-kata rows using sgfmeta', required=False, action='store_true') @@ -147,6 +154,39 @@ args = vars(parser.parse_args()) +def parse_sample_count(s): + """Parse a sample-count token like '0', '20M', '1.5B', '250K' into an int.""" + s = s.strip() + mult = 1.0 + if s and s[-1] in "kK": + mult = 1e3; s = s[:-1] + elif s and s[-1] in "mM": + mult = 1e6; s = s[:-1] + elif s and s[-1] in "bBgG": + mult = 1e9; s = s[:-1] + return int(round(float(s) * mult)) + +def parse_lr_schedule(schedule_str): + """Parse an explicit LR schedule string into a sorted list of (samples, lr_scale) points. + + Format: a sequence of '(samples,lr_scale)' points separated by ',' or ';', e.g. + '(0,12.0),(20M,9.0),(40M,6.0)'. Sample counts accept K/M/B suffixes. The schedule is + piecewise-constant: at global_step_samples >= a point's sample count, the LR scale becomes + that point's value, until the next point. Must start at samples == 0 and have strictly + increasing sample thresholds. + """ + points = [] + for m in re.finditer(r"\(\s*([0-9.eE+\-kKmMbBgG]+)\s*,\s*([0-9.eE+\-]+)\s*\)", schedule_str): + points.append((parse_sample_count(m.group(1)), float(m.group(2)))) + if not points: + raise ValueError(f"Could not parse any (samples,lr_scale) points from -lr-schedule: {schedule_str!r}") + if points[0][0] != 0: + raise ValueError(f"-lr-schedule must start at samples 0, got first point at {points[0][0]}") + for i in range(1, len(points)): + if points[i][0] <= points[i-1][0]: + raise ValueError(f"-lr-schedule sample thresholds must be strictly increasing: {points}") + return points + def get_longterm_checkpoints_dir(traindir): return os.path.join(traindir,"longterm_checkpoints") @@ -304,6 +344,7 @@ def _main_impl(rank: int, world_size: int, args, multi_gpu_device_ids, readpipes lr_scale = args["lr_scale"] lr_scale_auto = args["lr_scale_auto"] lr_scale_auto2 = args["lr_scale_auto2"] + lr_schedule = parse_lr_schedule(args["lr_schedule"]) if args["lr_schedule"] is not None else None head_lr_factor = args["head_lr_factor"] noreg_lr_factor = args["noreg_lr_factor"] muon_adam_lr_factor = args["muon_adam_lr_factor"] @@ -332,6 +373,11 @@ def _main_impl(rank: int, world_size: int, args, multi_gpu_device_ids, readpipes raise ValueError("-use-polar-express can only be used with muon or normuon or aurora optimizer") optimizer_name = "Aurora" if use_aurora else "NorMuon" if use_normuon else "Muon" if use_muon else "AdamW" if use_adamw else "SGD" use_fp16 = args["use_fp16"] + use_bf16 = args["use_bf16"] + if use_fp16 and use_bf16: + raise ValueError("-use-fp16 and -use-bf16 are mutually exclusive") + use_amp = use_fp16 or use_bf16 + amp_dtype = torch.bfloat16 if use_bf16 else torch.float16 no_compile = args["no_compile"] use_tf32_matmul = args["use_tf32_matmul"] @@ -359,6 +405,9 @@ def _main_impl(rank: int, world_size: int, args, multi_gpu_device_ids, readpipes brenorm_avg_momentum = args["brenorm_avg_momentum"] brenorm_adjustment_scale = args["brenorm_adjustment_scale"] + attn_logit_penalty_cap = args["attn_logit_penalty_cap"] + attn_logit_penalty_coeff = args["attn_logit_penalty_coeff"] + attn_logit_penalty_batch_frac = args["attn_logit_penalty_batch_frac"] soft_policy_weight_scale = args["soft_policy_weight_scale"] disable_optimistic_policy = args["disable_optimistic_policy"] meta_kata_only_soft_policy = args["meta_kata_only_soft_policy"] @@ -374,6 +423,10 @@ def _main_impl(rank: int, world_size: int, args, multi_gpu_device_ids, readpipes lr_scale = 1.0 if lr_scale_auto or lr_scale_auto2 is not None: assert lr_scale == 1.0, "Cannot specify both lr_scale and lr_scale_auto" + if lr_schedule is not None: + assert lr_scale == 1.0, "Cannot specify both -lr-scale and -lr-schedule" + assert not lr_scale_auto and lr_scale_auto2 is None, "Cannot specify -lr-schedule together with -lr-scale-auto/-lr-scale-auto2" + logging.info("Using explicit -lr-schedule: " + ", ".join(f"(samples>={s}: scale {v})" for s, v in lr_schedule)) assert not (not datadir and not latestdatadir), "Must specify one of -datadir and -latestdatadir" assert not (datadir and latestdatadir), "Must specify only one of -datadir and -latestdatadir" @@ -499,6 +552,16 @@ def lr_scale_auto_factor(train_state): if train_state["global_step_samples"] < 600000000: return 0.08 * lr_scale_auto2 return 0.05 * lr_scale_auto2 + elif lr_schedule is not None: + # Piecewise-constant: use the value of the last point whose threshold <= current samples. + samples = train_state["global_step_samples"] + scale = lr_schedule[0][1] + for (thresh, val) in lr_schedule: + if samples >= thresh: + scale = val + else: + break + return scale else: return 1.0 @@ -513,14 +576,24 @@ def get_checkpoint_prev_path(i): return os.path.join(traindir,f"checkpoint_prev{i}.ckpt") NUM_SHORTTERM_CHECKPOINTS_TO_KEEP = 4 - def save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics, path=None): + def save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics, path=None, skip_optimizer=False): if gnorm_stats_debug: logging.warning("Skipping save since debugging gnorm stats") return + optimizer_state_dict = None + if not skip_optimizer: + if hasattr(optimizer, "state_dict_for_checkpoint"): + # Collective: gathers the Muon states sharded across DDP ranks, + # so when skip_optimizer is False, every rank must call save() + # at the same point. Returns None on nonzero ranks. + optimizer_state_dict = optimizer.state_dict_for_checkpoint() + elif rank == 0: + optimizer_state_dict = optimizer.state_dict() if rank == 0: state_dict = {} state_dict["model"] = ddp_model.state_dict() - state_dict["optimizer"] = optimizer.state_dict() + if optimizer_state_dict is not None: + state_dict["optimizer"] = optimizer_state_dict state_dict["metrics"] = metrics_obj.state_dict() state_dict["running_metrics"] = { k: dict(v) if isinstance(v, defaultdict) else v @@ -731,11 +804,12 @@ def load(): raw_model.initialize() raw_model.to(device) - compiled_model = raw_model if no_compile else torch.compile(raw_model, mode="default") - if world_size > 1: - ddp_model = torch.nn.parallel.DistributedDataParallel(compiled_model, device_ids=[device]) - else: - ddp_model = compiled_model + if attn_logit_penalty_cap is not None: + raw_model.attn_logit_penalty_cap = attn_logit_penalty_cap + raw_model.attn_logit_penalty_batch_frac = attn_logit_penalty_batch_frac + # Applies torch.compile and DDP options. + # Must run before the optimizer is constructed since it may replace Parameter objects. + ddp_model = trainloop_helpers.wrap_model_for_training(raw_model, device, world_size, no_compile) swa_model = None if rank == 0 and swa_scale is not None: @@ -821,11 +895,12 @@ def load(): raw_model.load_state_dict(model_state_dict) raw_model.to(device) - compiled_model = raw_model if no_compile else torch.compile(raw_model, mode="default") - if world_size > 1: - ddp_model = torch.nn.parallel.DistributedDataParallel(compiled_model, device_ids=[device]) - else: - ddp_model = compiled_model + if attn_logit_penalty_cap is not None: + raw_model.attn_logit_penalty_cap = attn_logit_penalty_cap + raw_model.attn_logit_penalty_batch_frac = attn_logit_penalty_batch_frac + # Applies torch.compile and DDP options. + # Must run before the optimizer is constructed since it may replace Parameter objects. + ddp_model = trainloop_helpers.wrap_model_for_training(raw_model, device, world_size, no_compile) swa_model = None if rank == 0 and swa_scale is not None: @@ -869,16 +944,18 @@ def load(): old_optimizer_name = train_state.get("optimizer_name","SGD") if old_optimizer_name == optimizer_name: try: - optimizer.load_state_dict(state_dict["optimizer"]) + if hasattr(optimizer, "load_state_dict_for_checkpoint"): + optimizer.load_state_dict_for_checkpoint(state_dict["optimizer"]) + else: + optimizer.load_state_dict(state_dict["optimizer"]) except ValueError as e: logging.info(f"WARNING: Failed to load optimizer state dict: {e}, dropping old optimizer state") train_state["optimizer_name"] = optimizer_name else: train_state["optimizer_name"] = optimizer_name logging.info(f"WARNING: Optimizer name {old_optimizer_name} in checkpoint but we are set to use {optimizer_name} now, dropping old optimizer state") - else: - logging.info("WARNING: Optimizer not found in state dict, using fresh optimizer") + logging.info("WARNING: Optimizer not found in state dict (e.g. a skip_optimizer save), using fresh optimizer") train_state["optimizer_name"] = optimizer_name return (model_config, ddp_model, raw_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics) @@ -1269,15 +1346,6 @@ def get_files_for_subepoch(): return None # METRICS ----------------------------------------------------------------------------------- - def detensorify_metrics(metrics): - ret = {} - for key in metrics: - if isinstance(metrics[key], torch.Tensor): - ret[key] = metrics[key].detach().cpu().item() - else: - ret[key] = metrics[key] - return ret - if rank == 0: train_metrics_out = open(os.path.join(traindir,"metrics_train.json"),"a") val_metrics_out = open(os.path.join(traindir,"metrics_val.json"),"a") @@ -1320,10 +1388,20 @@ def detensorify_metrics(metrics): running_metrics["weights"] = defaultdict(float,running_metrics["weights"]) torch.backends.cudnn.benchmark = True + trainloop_helpers.maybe_enable_compiled_autograd() + + model_norms_only_at_print = trainloop_helpers.get_model_norms_only_at_print() + logging.info(f"model_norms_only_at_print {model_norms_only_at_print}") + training_metrics_fn = trainloop_helpers.make_training_metrics_fn(metrics_obj, no_compile, model_norms_only_at_print) + step_norm_tracker = trainloop_helpers.StepNormTracker(optimizer) + gnorm_watcher = trainloop_helpers.GnormWatcher() + scaler = None if use_fp16: logging.info("Training in FP16! Creating scaler") scaler = GradScaler("cuda") + elif use_bf16: + logging.info("Training in BF16 AMP without gradient scaling.") else: logging.info("Training in FP32.") @@ -1390,7 +1468,7 @@ def detensorify_metrics(metrics): logging.info(f"Training dir: {traindir}") logging.info(f"Export dir: {exportdir}") logging.info("Export cycle counter = " + str(train_state["export_cycle_counter"])) - if use_fp16: + if scaler is not None: logging.info(f"Current grad scale: {scaler.get_scale()}") lr_right_now, normal_weight_decay_right_now = update_and_return_lr_and_wd(log_if="always") @@ -1447,8 +1525,8 @@ def detensorify_metrics(metrics): # if raw_model.get_has_metadata_encoder(): # extra_outputs = ExtraOutputs([MetadataEncoder.OUTMEAN_KEY,MetadataEncoder.OUTLOGVAR_KEY]) - if use_fp16: - with autocast("cuda"): + if use_amp: + with autocast("cuda", dtype=amp_dtype): # Note: output heads are already in fp32 despite autocast model_outputs = ddp_model( batch["binaryInputNCHW"], @@ -1464,8 +1542,11 @@ def detensorify_metrics(metrics): extra_outputs=extra_outputs, ) + # The print-batch extras below run when the post-increment batch count hits the print interval. + is_print_batch = (batch_count_this_epoch + 1) % print_train_loss_every_batches == 0 + postprocessed = raw_model.postprocess_output(model_outputs) - metrics = metrics_obj.metrics_dict_batchwise( + metrics = training_metrics_fn( raw_model, postprocessed, extra_outputs, @@ -1480,13 +1561,26 @@ def detensorify_metrics(metrics): variance_time_loss_scale=variance_time_loss_scale, main_loss_scale=main_loss_scale, intermediate_loss_scale=intermediate_loss_scale, + include_model_norms=not model_norms_only_at_print, ) + if model_norms_only_at_print and is_print_batch: + metrics.update(metrics_obj.get_model_norm_metrics(raw_model)) # DDP averages loss across instances, so to preserve LR as per-sample lr, we scale by world size. loss = metrics["loss_sum"] * world_size + # Attention logit bound penalty (kept out of loss_sum so the main loss stays comparable + # across runs; logged as its own metrics). mean * batch_size rather than sum: with + # attn-logit-penalty-batch-frac < 1 the penalty is computed on a slice of the batch, + # and this keeps it an unbiased estimate of the full-batch sum (coeff meaning unchanged). + if attn_logit_penalty_cap is not None: + attn_pen_sum = raw_model.attn_logit_penalty_per_sample.mean() * batch_size + metrics["alogitpen_sum"] = attn_pen_sum.detach() + metrics["alogitubmax_batch"] = raw_model.attn_logit_ub_batch_max + loss = loss + attn_logit_penalty_coeff * attn_pen_sum * world_size + # Reduce gradients across DDP - if use_fp16: + if scaler is not None: scaler.scale(loss).backward() scaler.unscale_(optimizer) else: @@ -1518,12 +1612,7 @@ def detensorify_metrics(metrics): # Loosen gradient clipping as we shift to smaller learning rates gnorm_cap = gnorm_cap / math.sqrt(max(0.0000001,get_effective_lr_scale(train_state))) - gnorm = torch.nn.utils.clip_grad_norm_(ddp_model.parameters(), gnorm_cap).detach().cpu().item() - - if math.isfinite(gnorm) and abs(gnorm < 1e30): - metrics["gnorm_batch"] = gnorm - exgnorm = max(0.0, gnorm - gnorm_cap) - metrics["exgnorm_sum"] = exgnorm * batch_size + trainloop_helpers.clip_gradients_and_record(ddp_model, gnorm_cap, metrics, batch_size) metrics["pslr_batch"] = lr_right_now metrics["wdnormal_batch"] = normal_weight_decay_right_now @@ -1539,55 +1628,25 @@ def detensorify_metrics(metrics): metrics["window_end_batch"] = train_state["total_num_data_rows"] # Store parameters to later calculate empirical step vector length - old_params = {} - for name, param in ddp_model.named_parameters(): - if param.requires_grad: - old_params[name] = param.data.detach().clone() + step_norm_tracker.capture(ddp_model, is_print_batch=is_print_batch) - if use_fp16: + if scaler is not None: scaler.step(optimizer) scaler.update() else: optimizer.step() # Empirical step vector length (overall and per parameter group) - with torch.no_grad(): - step_norm_squared = 0.0 - step_norm_squared_per_group = defaultdict(float) - - # Build a mapping from parameter id to group name - param_to_group = {} - for param_group in optimizer.param_groups: - group_name = param_group["group_name"] - for param in param_group["params"]: - param_to_group[id(param)] = group_name - - param_idx = 0 - for name, param in ddp_model.named_parameters(): - if param.requires_grad: - param_diff_squared = torch.sum(torch.square(param.data - old_params[name])).cpu().item() - step_norm_squared += param_diff_squared - - # Add to per-group tracking - group_name = param_to_group.get(id(param), "unknown") - step_norm_squared_per_group[group_name] += param_diff_squared - - param_idx += 1 - - step_norm = math.sqrt(step_norm_squared) - metrics["step_norm_batch"] = step_norm + step_norm_tracker.record(ddp_model, metrics) - # Store per-group step norms - for group_name, norm_squared in step_norm_squared_per_group.items(): - metrics[f"step_norm_{group_name}_batch"] = math.sqrt(norm_squared) - - del model_outputs, postprocessed, loss, old_params + del model_outputs, postprocessed, loss batch_count_this_epoch += 1 train_state["train_steps_since_last_reload"] += batch_size * world_size train_state["global_step_samples"] += batch_size * world_size - metrics = detensorify_metrics(metrics) + metrics = trainloop_helpers.detensorify_metrics(metrics) + gnorm_watcher.observe(metrics, gnorm_cap=gnorm_cap) if lookahead_k is not None and lookahead_print: # Only accumulate metrics when lookahead is synced if lookahead_print is True @@ -1601,6 +1660,21 @@ def detensorify_metrics(metrics): if batch_count_this_epoch % print_train_loss_every_batches == 0: + # Norms computed only on this print batch are snapshots; + # store them with weight 1 so logging cannot divide 0 by 0 + # (e.g. when lookahead_print gives surrounding batches zero + # accumulation weight). + if model_norms_only_at_print: + trainloop_helpers.set_snapshot_metrics( + running_metrics["sums"], running_metrics["weights"], metrics, + [key for key in metrics if key.startswith("norm_") and key.endswith("_batch")], + ) + if step_norm_tracker.only_at_print: + trainloop_helpers.set_snapshot_metrics( + running_metrics["sums"], running_metrics["weights"], metrics, + [key for key in metrics if key.startswith("step_norm_") and key.endswith("_batch")], + ) + if model_config["norm_kind"] == "brenorm" or model_config["norm_kind"] == "fixbrenorm": metrics["brn_rmax"] = train_state["brenorm_rmax"] metrics["brn_dmax"] = train_state["brenorm_dmax"] @@ -1684,8 +1758,9 @@ def detensorify_metrics(metrics): if len(val_files) == 0: logging.info("No validation files, skipping validation step") else: + validation_model = trainloop_helpers.get_local_validation_model(ddp_model, raw_model, world_size) with torch.no_grad(): - ddp_model.eval() + validation_model.eval() val_metric_sums = defaultdict(float) val_metric_weights = defaultdict(float) val_samples = 0 @@ -1701,16 +1776,16 @@ def detensorify_metrics(metrics): include_meta=raw_model.get_has_metadata_encoder(), model_config=model_config ): - if use_fp16: - with autocast("cuda"): + if use_amp: + with autocast("cuda", dtype=amp_dtype): # Note: output heads are already in fp32 despite autocast - model_outputs = ddp_model( + model_outputs = validation_model( batch["binaryInputNCHW"], batch["globalInputNC"], input_meta=(batch["metadataInputNC"] if raw_model.get_has_metadata_encoder() else None), ) else: - model_outputs = ddp_model( + model_outputs = validation_model( batch["binaryInputNCHW"], batch["globalInputNC"], input_meta=(batch["metadataInputNC"] if raw_model.get_has_metadata_encoder() else None), @@ -1733,7 +1808,7 @@ def detensorify_metrics(metrics): main_loss_scale=main_loss_scale, intermediate_loss_scale=intermediate_loss_scale, ) - metrics = detensorify_metrics(metrics) + metrics = trainloop_helpers.detensorify_metrics(metrics) accumulate_metrics(val_metric_sums, val_metric_weights, metrics, batch_size, decay=1.0, new_weight=1.0) val_samples += batch_size if max_val_samples is not None and val_samples > max_val_samples: @@ -1747,7 +1822,7 @@ def detensorify_metrics(metrics): log_metrics(val_metric_sums, val_metric_weights, metrics, val_metrics_out) t1 = time.perf_counter() logging.info(f"Validation took {t1-t0} seconds") - ddp_model.train() + validation_model.train() if rank == 0: logging.info("Export cycle counter = " + str(train_state["export_cycle_counter"])) @@ -1780,10 +1855,22 @@ def detensorify_metrics(metrics): else: os.mkdir(savepathtmp) logging.info("SAVING MODEL FOR EXPORT TO: " + savepath) - save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics, path=os.path.join(savepathtmp,"model.ckpt")) + # skip_optimizer: export only needs weights, and this save runs on + # rank 0 only so it must not trigger the optimizer-state collective. + save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics, path=os.path.join(savepathtmp,"model.ckpt"), skip_optimizer=True) time.sleep(2) os.rename(savepathtmp,savepath) + # Rejoin all ranks before the final save. The save below is called by every rank and, + # with a sharded optimizer like Muon, performs a collective (state_dict_for_checkpoint's + # gather) that every rank must enter together. Validation and export above run on rank 0 + # only, so without this barrier the non-zero ranks would reach the collective immediately + # and sit inside an NCCL op waiting for rank 0, hitting the ~600s NCCL watchdog timeout and + # aborting the job on any epoch where rank 0's validation/export takes that long. This is a + # CPU-side multiprocessing.Barrier (no NCCL timeout), so the non-zero ranks idle here + # harmlessly instead. No-op when barrier is None (single-GPU / non-DDP training). + safe_barrier(barrier,rank) + # Finally save, now after validation and exports are done save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics) @@ -1797,7 +1884,9 @@ def detensorify_metrics(metrics): if now - last_longterm_checkpoint_save_time >= datetime.timedelta(hours=12): last_longterm_checkpoint_save_time = now dated_name = datetime.datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S") - save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics, path=os.path.join(longterm_checkpoints_dir,f"{dated_name}.ckpt")) + # skip_optimizer: archival checkpoint, and this save runs on rank 0 + # only so it must not trigger the optimizer-state collective. + save(ddp_model, swa_model, optimizer, metrics_obj, running_metrics, train_state, last_val_metrics, path=os.path.join(longterm_checkpoints_dir,f"{dated_name}.ckpt"), skip_optimizer=True) train_metrics_out.close() val_metrics_out.close() From edd1b06947c6c563655675181de645f2ae65179b Mon Sep 17 00:00:00 2001 From: Looong01 Date: Fri, 14 Aug 2026 14:00:36 +0000 Subject: [PATCH 29/37] Fix slowdown and Compiling.md --- Compiling.md | 24 ++- cpp/configs/analysis_example.cfg | 3 +- cpp/configs/gtp_example.cfg | 10 +- cpp/neuralnet/cudaandrocmbackend.inc | 261 ++++++++++++++++++++++++--- 4 files changed, 263 insertions(+), 35 deletions(-) diff --git a/Compiling.md b/Compiling.md index c601ceff07..5fc0ebd319 100644 --- a/Compiling.md +++ b/Compiling.md @@ -33,7 +33,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the OpenCL backend, a modern GPU that supports OpenCL 1.2 or greater, or else something like [this](https://software.intel.com/en-us/opencl-sdk) for CPU. But if using CPU, Eigen should be better. * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. - * If using the ROCm backend, ROCm 6.4 or later (https://rocm.docs.amd.com/projects/install-on-linux/en/latest/) and a GPU capable of supporting it. Install the ROCm developer packages, not just the ROCm runtime packages. + * If using the ROCm backend, ROCm 7.x (https://rocm.docs.amd.com/en/latest/install/rocm.html) and a GPU capable of supporting it. Install the ROCm developer packages, not just the ROCm runtime packages. * If using the Eigen backend, Eigen3. With Debian packages, (i.e. apt or apt-get), this should be `libeigen3-dev`. * zlib, libzip. With Debian packages (i.e. apt or apt-get), these should be `zlib1g-dev`, `libzip-dev`. * If you want to do self-play training and research, probably Google perftools `libgoogle-perftools-dev` for TCMalloc or some other better malloc implementation. For unknown reasons, the allocation pattern in self-play with large numbers of threads and parallel games causes a lot of memory fragmentation under glibc malloc that will eventually run your machine out of memory, but better mallocs handle it fine. @@ -56,7 +56,13 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using OpenCL, you will want to verify that KataGo is picking up the correct device when you run it (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). * **ROCm backend (Linux) - additional notes:** - * Install ROCm following the [official guide](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/). Install the full developer stack (not just runtime): `sudo apt install rocm-dev miopen-hip-dev hipblas-dev rocblas-dev`. + * Install ROCm following the [official guide](https://rocm.docs.amd.com/en/latest/install/rocm.html). On the guide's selector panel, choose your Device family, your GPU, your Operating system and its version, Use case = **Compute**, and Installation method = the system package manager (e.g. `apt` on Ubuntu). **If you have ROCm 7.2.4 or older installed, please uninstall it before proceeding** (the guide documents `sudo amdgpu-uninstall` for that). + * Install the prerequisite libraries, then the ROCm 7.14 packages (developer stack, not just the runtime): + ``` + sudo apt install libatomic1 libquadmath0 + sudo apt install amdrocm7.14 amdrocm-core-dev7.14 amdrocm-developer-tools7.14 amdrocm-opencl7.14 amdrocm-core-sdk7.14 + ``` + * Verify the installation with `amd-smi` (it should report the ROCm version and list your GPU); `rocminfo` works too. * Build: ``` cd KataGo/cpp @@ -154,13 +160,13 @@ As also mentioned in the instructions below but repeated here for visibility, if * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). - * **ROCm backend (Windows) - building via AMD TheRock:** - * The ROCm (MIOpen) backend supports Windows via [AMD TheRock](https://github.com/ROCm/TheRock) (tested with TheRock 7.13 / ROCm 7.13, RX 7900 XTX / gfx1100), including transformer/attention models (model version 17+) and the optional Composable Kernel (CK) fused-attention fast path. + * **ROCm backend (Windows):** + * The ROCm (MIOpen) backend supports Windows, including transformer/attention models (model version 17+) and the optional Composable Kernel (CK) fused-attention fast path. * **Prerequisites:** - * Download [AMD TheRock](https://github.com/ROCm/TheRock) and extract it to e.g. `C:\TheRock\build`, adjusting the paths below if you extract elsewhere. + * Install ROCm for Windows following the [official guide](https://rocm.docs.amd.com/en/latest/install/rocm.html). On the guide's selector panel, choose your Device family, your GPU, and Operating system = **Windows**, then follow the method it presents (the tarball method gives a system-wide install with all components, HIP/MIOpen/clang toolchain included). **If you have ROCm 7.2.4 or older installed, please uninstall it before proceeding.** * Install **Visual Studio Build Tools or Community** with the "Desktop development with C++" workload, for the MSVC toolchain and Windows SDK the HIP compiler needs. A **v143 toolset (MSVC 14.3x or 14.4x)** must be among the installed toolsets - newer toolsets alone (14.5x+) are not accepted by the HIP clang compatibility check. If more than one is installed side by side, `CMakeLists.txt` automatically probes them at configure time and picks a compatible one itself (see "Fully automatic" below), no manual toolset selection needed. * Install [Ninja](https://ninja-build.org) build tool: `winget install Ninja-build.Ninja`. - * Set the following **system environment variables** (via System Properties -> Advanced -> Environment Variables): + * Set the following **system environment variables** (via System Properties -> Advanced -> Environment Variables), adjusting the paths if you extracted the tarball elsewhere: ``` HIP_PATH=C:/TheRock/build HIP_PLATFORM=amd @@ -185,12 +191,12 @@ As also mentioned in the instructions below but repeated here for visibility, if install are needed beyond the prerequisites above. `CMakeLists.txt` handles the rest of the Windows-specific setup automatically at configure/build time: * **MSVC toolset selection:** if more than one MSVC toolset is installed side by side, a - newer one can conflict with TheRock's bundled clang (newer MSVC STL headers are not yet + newer one can conflict with the HIP clang (newer MSVC STL headers are not yet compatible with it). `CMakeLists.txt` finds the installed v143-family toolsets via `vswhere` and probes each with a real compile until one works, with no user action needed. - * **zlib:** TheRock's Windows package ships `zlib.h` but (as of 7.13) no longer ships a - linkable `.lib`. `CMakeLists.txt` automatically bootstraps a local + * **zlib:** if the ROCm Windows package on your system ships `zlib.h` but no + linkable `.lib`, `CMakeLists.txt` automatically bootstraps a local [vcpkg](https://github.com/microsoft/vcpkg) clone under `/deps/vcpkg` (this needs internet access and `git` on `PATH` the first time; subsequent reconfigures reuse the same local install) and builds zlib through it, via the diff --git a/cpp/configs/analysis_example.cfg b/cpp/configs/analysis_example.cfg index 1b18627421..f66105a198 100644 --- a/cpp/configs/analysis_example.cfg +++ b/cpp/configs/analysis_example.cfg @@ -281,7 +281,8 @@ nnRandomize = true # force a particular behavior you can uncomment these lines and change them to "true" or "false", # e.g. if FP16 is giving an error or too much numerical inaccuracy on your card. # rocmUseFP16 = auto -# rocmUseNHWC = auto # Uses NHWC tensor layout. Default: auto - NHWC with FP16 on GPUs where NHWC convolutions are faster (CDNA), else NCHW; transformers always NHWC. +# rocmUseNHWC = auto # Uses NHWC tensor layout. Default: auto - NCHW for convnets on all GPUs (MIOpen's NCHW conv solvers are its most mature path); transformers always use NHWC regardless. +# rocmUse1x1Matmul = auto # Whether 1x1 NHWC convs run as a hipBLAS GEMM instead of a MIOpen conv. auto = GEMM whenever the layout allows; recommended (MIOpen's NHWC conv solvers are slow on some GPUs, and FP16 GEMMs use FP32 accumulation). # OpenCL-specific GPU settings-------------------------------------- diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index 1b89821387..3d0effac85 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -613,10 +613,14 @@ searchFactorWhenWinningThreshold = 0.95 # compiled without FP16 kernel support). If you want to force a particular # behavior you can uncomment these lines and change them to "true" or "false". # rocmUseFP16 = auto -# Uses NHWC tensor layout. Default: auto - NHWC when using FP16 on GPUs whose matrix -# instructions make NHWC convolutions faster (CDNA), otherwise NCHW; transformer models -# always use NHWC. +# Uses NHWC tensor layout. Default: auto - NCHW for convnets on all GPUs (MIOpen's NCHW +# conv solvers are its most mature path); transformer models always use NHWC regardless. # rocmUseNHWC = auto +# Whether 1x1 NHWC convolutions run as a hipBLAS GEMM instead of a MIOpen convolution. +# "auto" (default) uses the GEMM whenever the layout allows it. Recommended to leave on: +# MIOpen's NHWC conv solvers are slow on some GPUs (e.g. CK grouped-conv kernels on +# gfx1100), while the GEMM is both faster and uses FP32 accumulation for FP16. +# rocmUse1x1Matmul = auto # ------------------------------ # OpenCL GPU settings diff --git a/cpp/neuralnet/cudaandrocmbackend.inc b/cpp/neuralnet/cudaandrocmbackend.inc index dd56dbc65b..17860adc7d 100644 --- a/cpp/neuralnet/cudaandrocmbackend.inc +++ b/cpp/neuralnet/cudaandrocmbackend.inc @@ -343,21 +343,6 @@ static bool isCkFmhaSupportedArch(const hipDeviceProp_t& prop) { arch.compare(0, 5, "gfx94") == 0 || arch.compare(0, 5, "gfx95") == 0 || arch.compare(0, 5, "gfx11") == 0 || arch.compare(0, 5, "gfx12") == 0; } - -// Archs where MIOpen's NHWC FP16 convolutions (MFMA implicit GEMM) are known faster than NCHW, -// so NHWC mode "Auto" should enable NHWC when using FP16 - the analog of the CUDA backend -// enabling NHWC on tensor-core (Volta+) GPUs. Currently the CDNA/MFMA family only, where NHWC -// measured substantially faster on convnets. RDNA (WMMA) is unmeasured rather than known -// slower. Extend this list if NHWC measures faster there too, testable via rocmUseNHWC=true. -static bool isNhwcFp16PreferredArch(const hipDeviceProp_t& prop) { - std::string arch(prop.gcnArchName); - size_t colonPos = arch.find(':'); - if(colonPos != std::string::npos) - arch = arch.substr(0, colonPos); - return - arch == "gfx908" || arch == "gfx90a" || - arch.compare(0, 5, "gfx94") == 0 || arch.compare(0, 5, "gfx95") == 0; -} #endif @@ -466,6 +451,9 @@ struct CudaHandles { // the attempt (and its attention-bias materialization) entirely. Only touched by the single // server thread that owns this handle, hence no synchronization. bool fusedAttentionRuntimeDisabled; + // Controls whether 1x1 NHWC convs run as a hipBLAS GEMM (vs MIOpen). Auto = matmul iff FP16. + // True/False force the choice regardless of precision. + enabled_t use1x1MatmulMode; CudaHandles(int major, int minor, Logger* logger_, bool ckFmhaArchSupported_, bool disableFusedAttention_) : majorComputeCapability(major), @@ -473,7 +461,8 @@ struct CudaHandles { logger(logger_), ckFmhaArchSupported(ckFmhaArchSupported_), disableFusedAttention(disableFusedAttention_), - fusedAttentionRuntimeDisabled(false) + fusedAttentionRuntimeDisabled(false), + use1x1MatmulMode(enabled_t::Auto) { } @@ -1026,6 +1015,23 @@ struct ConvLayer { OwnedDesc convolutionDescriptor; std::unique_ptr> convolutionAlgorithms; //array of one for each batch size OwnedDeviceBuf filterBuf; + // A 1x1 conv is equivalent to a matmul. When use1x1Matmul is set we run it as a hipBLAS GEMM over + // batch*spatial tokens and build NO MIOpen objects. This is the default for 1x1 NHWC FP16 convs + // (see rocmUse1x1Matmul). matmulWeightBuf is [inC, outC] column-major (hipBLAS order); + // matmulSpatialSize is the spatial length. + bool use1x1Matmul; + int matmulSpatialSize; + OwnedDeviceBuf matmulWeightBuf; + // When MIOpen can only offer its naive direct-conv fallback for an NHWC conv (weak NHWC solver + // coverage), we instead re-express the conv as NCHW at runtime: transpose input, run the NCHW + // conv, transpose output back. Only ever set for NHWC-in/out convs. + bool useNchwFallback; + ByBatchSizeView nchwInputDescriptors; + ByBatchSizeView nchwOutputDescriptors; + OwnedDesc nchwFilterDescriptor; + OwnedDesc nchwConvolutionDescriptor; + std::unique_ptr> nchwConvolutionAlgorithms; + OwnedDeviceBuf nchwFilterBuf; ConvLayer() = delete; ConvLayer(const ConvLayer&) = delete; @@ -1066,11 +1072,102 @@ struct ConvLayer { testAssert(convXSize % 2 == 1); testAssert(convYSize % 2 == 1); + // A 1x1 conv is a matmul. MIOpen's NHWC conv solver coverage is weak on consumer GPUs in both + // FP16 and FP32 (e.g. on gfx1100 it picks CK grouped-conv WMMA kernels for FP16, ~2-4x slower + // per call than a GEMM with much more dispatch overhead, and falls back to its naive direct + // solver for some FP32 cases), while hipBLAS GEMM is fast - so on ROCm "auto" uses the GEMM + // whenever the layout allows it, regardless of precision. (The CUDA backend's FP32 exception + // was a cuDNN-specific benchmarking result and does not apply to MIOpen.) FP16 GEMMs use FP32 + // compute for accuracy, matching MatMulLayer. Supports NHWC only (the GEMM assumes + // channel-contiguous-per-position layout). + use1x1Matmul = false; + useNchwFallback = false; + if(convXSize == 1 && convYSize == 1 && useNHWCIn && useNHWCOut) { + enabled_t mode = cudaHandles->use1x1MatmulMode; + use1x1Matmul = (mode == enabled_t::True) || (mode == enabled_t::Auto); + } + matmulSpatialSize = use1x1Matmul ? (manager->nnYLen * manager->nnXLen) : 0; + + if(use1x1Matmul) { + // 1x1 conv weights are [outC, inC]. hipBLAS GEMM wants column-major, i.e. [inC, outC] in row-major notation. + // So transpose. No MIOpen objects are built. + vector wT((size_t)inChannels * outChannels); + for(int oc = 0; oc < outChannels; oc++) + for(int ic = 0; ic < inChannels; ic++) + wT[(size_t)oc + (size_t)ic * outChannels] = desc->weights[(size_t)oc * inChannels + ic]; + CudaUtils::mallocAndCopyToDevice(name + ":matmulW", wT, matmulWeightBuf.buf, useFP16); + return; + } + inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; + bool anyNaive = buildMiopenConvPath( + cudaHandles, name, desc, useFP16, useNHWCIn, useNHWCOut, filterNHWC, maxBatchSize, + inputDescriptors, outputDescriptors, filterDescriptor, convolutionDescriptor, + convolutionAlgorithms, filterBuf); + + // MIOpen's NHWC solver coverage is patchy (e.g. on gfx1100 a 3x3 NHWC FP16 stem conv falls all + // the way back to ConvDirectNaiveConvFwd). When that happens, try re-expressing the conv as + // NCHW - MIOpen's NCHW solver coverage is much better - at the cost of a pair of transposes + // around each call. + if(anyNaive && useNHWCIn && useNHWCOut) { + string convDescStr = Global::intToString(inChannels) + "->" + Global::intToString(outChannels) + + " " + Global::intToString(convYSize) + "x" + Global::intToString(convXSize); + nchwInputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,false); + nchwOutputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,false); + bool nchwNaive = buildMiopenConvPath( + cudaHandles, name + ":nchw", desc, useFP16, false, false, false, maxBatchSize, + nchwInputDescriptors, nchwOutputDescriptors, nchwFilterDescriptor, nchwConvolutionDescriptor, + nchwConvolutionAlgorithms, nchwFilterBuf); + if(!nchwNaive) { + useNchwFallback = true; + if(cudaHandles->logger != NULL) + cudaHandles->logger->write( + "ROCm backend: MIOpen offers only its naive direct-conv fallback for NHWC conv layer '" + + name + "' (" + convDescStr + "); re-expressing it as NCHW with per-call transposes instead"); + } + else if(cudaHandles->logger != NULL) + cudaHandles->logger->write( + "ROCm backend: WARNING: MIOpen offers only its naive direct-conv fallback for NHWC conv layer '" + + name + "' (" + convDescStr + "), and the NCHW alternative is naive too - expect reduced conv performance"); + } + else if(anyNaive && cudaHandles->logger != NULL) + cudaHandles->logger->write( + "ROCm backend: WARNING: MIOpen offers only its naive direct-conv fallback for conv layer '" + + name + "' - expect reduced conv performance"); + } + + // Builds all the MIOpen objects for one layout choice of this conv across batch sizes, uploads + // the (layout-transposed if needed) filter, and compiles the chosen solution per batch size. + // Returns true if MIOpen's chosen solution for ANY batch size is its naive direct-conv fallback. + static bool buildMiopenConvPath( + CudaHandles* cudaHandles, + const string& name, + const ConvLayerDesc* desc, + bool useFP16, + bool useNHWCIn, + bool useNHWCOut, + bool filterNHWC, + int maxBatchSize, + ByBatchSizeView& inputDescriptors, + ByBatchSizeView& outputDescriptors, + OwnedDesc& filterDescriptor, + OwnedDesc& convolutionDescriptor, + std::unique_ptr>& convolutionAlgorithms, + OwnedDeviceBuf& filterBuf + ) { + int convYSize = desc->convYSize; + int convXSize = desc->convXSize; + int dilationY = desc->dilationY; + int dilationX = desc->dilationX; + int paddingX = (convXSize / 2) * dilationX; + int paddingY = (convYSize / 2) * dilationY; + int inChannels = desc->inChannels; + int outChannels = desc->outChannels; + CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor.desc)); if(filterNHWC) { int lens[4] = {outChannels, inChannels, convYSize, convXSize}; @@ -1096,7 +1193,6 @@ struct ConvLayer { int yStride = 1; int xStride = 1; - CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor.desc)); CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( convolutionDescriptor, @@ -1115,6 +1211,7 @@ struct ConvLayer { convolutionAlgorithms = std::make_unique>(maxBatchSize); + bool anyNaive = false; for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; @@ -1144,6 +1241,11 @@ struct ConvLayer { if(returnedAlgoCount <= 0) throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); (*convolutionAlgorithms)[batchSize] = solutions[0]; + // MIOpen hands back its naive direct-conv solver (ConvDirectNaiveConvFwd, registered solver + // id 55) as the last-resort fallback, stamped with a sentinel time of 1000ms. The numeric id + // is not a public-stable API, so treat the sentinel time as the primary signal. + if(solutions[0].time >= 999.0f || solutions[0].solution_id == 55) + anyNaive = true; CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( cudaHandles->cudnn, filterDescriptor, @@ -1174,12 +1276,28 @@ struct ConvLayer { else CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf.buf,useFP16); + return anyNaive; } size_t requiredWorkspaceBytes( CudaHandles* cudaHandles, int batchSize ) const { + if(use1x1Matmul) + return 0; + if(useNchwFallback) { + size_t workspaceBytes = 0; + CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( + cudaHandles->cudnn, + nchwFilterDescriptor, + nchwInputDescriptors[batchSize], + nchwConvolutionDescriptor, + nchwOutputDescriptors[batchSize], + (*nchwConvolutionAlgorithms)[batchSize].solution_id, + &workspaceBytes + )); + return workspaceBytes; + } size_t workspaceBytes = 0; CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( cudaHandles->cudnn, @@ -1203,6 +1321,57 @@ struct ConvLayer { void* workspaceBuf, size_t workspaceBytes ) const { + if(use1x1Matmul) { + // out[outC, tokens] = W[outC, inC] x in[inC, tokens] + // where tokens = batchSize * spatial. NHWC buffers are [tokens, C] row-major = [C, tokens] column-major + // matching hipBLAS's expectation. Same as MatMulLayer. + int tokens = batchSize * matmulSpatialSize; + if(!usingFP16) { + const float alpha = 1.0f; + const float beta = accumulate ? 1.0f : 0.0f; + CUBLAS_ERR(name.c_str(),cublasSgemm( + cudaHandles->cublas, CUBLAS_OP_N, CUBLAS_OP_N, + outChannels, tokens, inChannels, + &alpha, (const float*)matmulWeightBuf.buf, outChannels, + (const float*)inputBuf, inChannels, + &beta, (float*)outputBuf, outChannels)); + } + else { +#if defined(hipblasVersionMajor) && hipblasVersionMajor >= 2 + // Use FP32 compute for the same accuracy reason as MatMulLayer (hipblasHgemm's FP16 + // compute costs real accuracy on transformer nets). + const float alpha = 1.0f; + const float beta = accumulate ? 1.0f : 0.0f; + CUBLAS_ERR(name.c_str(),hipblasGemmEx( + cudaHandles->cublas, + HIPBLAS_OP_N, + HIPBLAS_OP_N, + outChannels, + tokens, + inChannels, + &alpha, + matmulWeightBuf.buf, HIP_R_16F, outChannels, + inputBuf, HIP_R_16F, inChannels, + &beta, + outputBuf, HIP_R_16F, outChannels, + HIPBLAS_COMPUTE_32F, + HIPBLAS_GEMM_DEFAULT + )); +#else + // hipBLAS older than 2.0 (below ROCm 6.0, below the minimum Compiling.md documents): + // fall back to the FP16-compute spelling. + const cublas_half_t* alpha = (const cublas_half_t*)scratch->oneBuf; + const cublas_half_t* betaHalf = (const cublas_half_t*)(accumulate ? scratch->oneBuf : scratch->zeroBuf); + CUBLAS_ERR(name.c_str(),cublasHgemm( + cudaHandles->cublas, CUBLAS_OP_N, CUBLAS_OP_N, + outChannels, tokens, inChannels, + alpha, (const cublas_half_t*)matmulWeightBuf.buf, outChannels, + (const cublas_half_t*)inputBuf, inChannels, + betaHalf, (cublas_half_t*)outputBuf, outChannels)); +#endif + } + return; + } // miopenConvolutionForwardImmediate does NOT support alpha/beta (unlike cuDNN). // When accumulate=true, we need: outputBuf = conv(inputBuf) + outputBuf (residual skip // connection). Save outputBuf's contents to a scratch buffer, run the conv, then add back. @@ -1224,6 +1393,43 @@ struct ConvLayer { CUDA_ERR(name.c_str(), hipMemcpyAsync(accumBuf->buf, outputBuf, outputElts * elemSize, hipMemcpyDeviceToDevice)); } + if(useNchwFallback) { + // Re-expressed NCHW conv: transpose input NHWC->NCHW, run the conv, transpose the output + // back to NHWC. Buffers are max-batch-sized pool allocations, same as everywhere else here. + int xySize = nnXLen * nnYLen; + SizedBuf inNchw(scratch->allocator, scratch->getBufSizeXY(inChannels)); + SizedBuf outNchw(scratch->allocator, scratch->getBufSizeXY(outChannels)); + if(usingFP16) + customCudaCopyNHWCtoNCHW((const half*)inputBuf, (half*)inNchw.buf, batchSize, inChannels, xySize); + else + customCudaCopyNHWCtoNCHW((const float*)inputBuf, (float*)inNchw.buf, batchSize, inChannels, xySize); + CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( + cudaHandles->cudnn, + nchwFilterDescriptor, + nchwFilterBuf.buf, + nchwInputDescriptors[batchSize], + inNchw.buf, + nchwConvolutionDescriptor, + nchwOutputDescriptors[batchSize], + outNchw.buf, + workspaceBuf, + workspaceBytes, + (*nchwConvolutionAlgorithms)[batchSize].solution_id + )); + if(usingFP16) + customCudaCopyNCHWtoNHWC((const half*)outNchw.buf, (half*)outputBuf, batchSize, outChannels, xySize); + else + customCudaCopyNCHWtoNHWC((const float*)outNchw.buf, (float*)outputBuf, batchSize, outChannels, xySize); + if(accumulate) { + if(usingFP16) + customCudaAddTensorInplace((half*)outputBuf, (const half*)accumBuf->buf, (int)outputElts); + else + customCudaAddTensorInplace((float*)outputBuf, (const float*)accumBuf->buf, (int)outputElts); + } + CUDA_ERR(name.c_str(), hipPeekAtLastError()); + return; + } + CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( cudaHandles->cudnn, filterDescriptor, @@ -3885,6 +4091,8 @@ struct ComputeContext { enabled_t useFP16Mode; enabled_t useNHWCMode; bool disableFusedAttention; + // Whether 1x1 NHWC convs use the hipBLAS GEMM path. Auto = matmul iff FP16. + enabled_t use1x1MatmulMode; }; #endif @@ -3941,6 +4149,11 @@ ComputeContext* NeuralNet::createComputeContext( // the CUDA backend's cudaDisableGraphSDPA. Only meaningful for transformer models. bool disableFusedAttention = cfg.contains("rocmDisableFusedAttention") ? cfg.getBool("rocmDisableFusedAttention") : false; + // Mirrors the CUDA backend's cudaUse1x1Matmul. On ROCm this matters much more than on CUDA: + // MIOpen 7.x's NHWC FP16 conv solver coverage is weak (e.g. on gfx1100 it routes 1x1 convs to + // slow CK grouped-conv kernels), while hipBLAS GEMM is fast. + enabled_t use1x1MatmulMode = + cfg.contains("rocmUse1x1Matmul") ? cfg.getEnabled("rocmUse1x1Matmul") : enabled_t::Auto; ComputeContext* context = new ComputeContext(); context->nnXLen = nnXLen; @@ -3948,6 +4161,7 @@ ComputeContext* NeuralNet::createComputeContext( context->useFP16Mode = useFP16Mode; context->useNHWCMode = useNHWCMode; context->disableFusedAttention = disableFusedAttention; + context->use1x1MatmulMode = use1x1MatmulMode; return context; } #endif @@ -4025,6 +4239,8 @@ struct ComputeHandle { { cudaHandles = std::make_unique( majorComputeCapability,minorComputeCapability,logger,ckFmhaArchSupported,context->disableFusedAttention); + // Must be set before building the model: ConvLayer reads it at construction to pick the 1x1 conv path. + cudaHandles->use1x1MatmulMode = context->use1x1MatmulMode; model = std::make_unique( cudaHandles.get(), &(loadedModel->modelDesc), maxBatchSize, nnXLen, nnYLen, inputsUseNHWC, useFP16, useNHWC @@ -4172,11 +4388,12 @@ ComputeHandle* NeuralNet::createComputeHandle( logger->write("ROCm backend: this build was compiled without FP16 kernel support; using FP32"); } - // Mirror the CUDA backend's tensor-core rule: on archs whose matrix instructions make NHWC - // convolutions the fast path, NHWC "Auto" turns NHWC on together with FP16. Decided after the - // FP16-kernel check above so a build that just downgraded to FP32 does not also switch layouts. - if(context->useNHWCMode == enabled_t::Auto && useFP16 && isNhwcFp16PreferredArch(prop)) - useNHWC = true; + // ROCm defaults convnets to NCHW in "Auto" (unlike CUDA's tensor-core rule): MIOpen's NCHW + // solver coverage (Winograd / implicit GEMM / GEMM) is its most mature path on every arch we + // support, while its NHWC conv solvers are patchy (weak CK grouped-conv or outright naive + // fallbacks on e.g. gfx1100). NHWC is used only where it is forced (transformer models, below) + // or explicitly requested with rocmUseNHWC=true. + // (useNHWC stays false here unless rocmUseNHWC=true was set above.) // The transformer block implementation (attention/RoPE/FFN) only supports NHWC, since its channel // projections assume the channel dim is contiguous per spatial position. Force NHWC for transformer From 62cb2932bbc1007bb219393b1b4306599e6df72a Mon Sep 17 00:00:00 2001 From: Looong01 Date: Mon, 17 Aug 2026 17:25:01 +0000 Subject: [PATCH 30/37] Fix CDNA slowdown --- cpp/neuralnet/cudaandrocmbackend.inc | 40 +++++++++++++++++++++------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/cpp/neuralnet/cudaandrocmbackend.inc b/cpp/neuralnet/cudaandrocmbackend.inc index 17860adc7d..205a4c8197 100644 --- a/cpp/neuralnet/cudaandrocmbackend.inc +++ b/cpp/neuralnet/cudaandrocmbackend.inc @@ -57,6 +57,7 @@ #include "../core/simpleallocator.h" #include "../core/test.h" +#include #ifdef KATAGO_GPU_CUDA #include "../core/hash.h" #endif @@ -338,10 +339,29 @@ static bool isCkFmhaSupportedArch(const hipDeviceProp_t& prop) { size_t colonPos = arch.find(':'); // e.g. "gfx942:sramecc+:xnack-" if(colonPos != std::string::npos) arch = arch.substr(0, colonPos); + static constexpr std::string_view gfx908 = "gfx908"; + static constexpr std::string_view gfx90a = "gfx90a"; + static constexpr std::string_view gfx94 = "gfx94"; + static constexpr std::string_view gfx95 = "gfx95"; + static constexpr std::string_view gfx11 = "gfx11"; + static constexpr std::string_view gfx12 = "gfx12"; return - arch == "gfx908" || arch == "gfx90a" || - arch.compare(0, 5, "gfx94") == 0 || arch.compare(0, 5, "gfx95") == 0 || - arch.compare(0, 5, "gfx11") == 0 || arch.compare(0, 5, "gfx12") == 0; + arch == gfx908 || arch == gfx90a || + arch.compare(0, gfx94.size(), gfx94) == 0 || arch.compare(0, gfx95.size(), gfx95) == 0 || + arch.compare(0, gfx11.size(), gfx11) == 0 || arch.compare(0, gfx12.size(), gfx12) == 0; +} + +// Archs where MIOpen's NHWC convolutions are preferred in "Auto" mode. We enable NHWC +// automatically on the gfx9 family (CDNA/MI etc.), where NHWC measured faster on convnets. +// RDNA (gfx10/gfx11/gfx12) keeps NCHW as the "Auto" default because its NHWC solvers can +// fall back to naive implementations. Users can still force NHWC with rocmUseNHWC=true. +static bool isNhwcPreferredArch(const hipDeviceProp_t& prop) { + std::string arch(prop.gcnArchName); + size_t colonPos = arch.find(':'); + if(colonPos != std::string::npos) + arch = arch.substr(0, colonPos); + static constexpr std::string_view prefix = "gfx9"; + return arch.compare(0, prefix.size(), prefix) == 0; } #endif @@ -4373,7 +4393,7 @@ ComputeHandle* NeuralNet::createComputeHandle( bool useNHWC = false; if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) useFP16 = true; - if(context->useNHWCMode == enabled_t::True) + if(context->useNHWCMode == enabled_t::True || (context->useNHWCMode == enabled_t::Auto && isNhwcPreferredArch(prop))) useNHWC = true; // Every arch in the default CMAKE_HIP_ARCHITECTURES list supports packed FP16, so FP16 "Auto" @@ -4388,12 +4408,12 @@ ComputeHandle* NeuralNet::createComputeHandle( logger->write("ROCm backend: this build was compiled without FP16 kernel support; using FP32"); } - // ROCm defaults convnets to NCHW in "Auto" (unlike CUDA's tensor-core rule): MIOpen's NCHW - // solver coverage (Winograd / implicit GEMM / GEMM) is its most mature path on every arch we - // support, while its NHWC conv solvers are patchy (weak CK grouped-conv or outright naive - // fallbacks on e.g. gfx1100). NHWC is used only where it is forced (transformer models, below) - // or explicitly requested with rocmUseNHWC=true. - // (useNHWC stays false here unless rocmUseNHWC=true was set above.) + // ROCm "Auto" NHWC policy: on the gfx9 family (CDNA/MI etc.) we enable NHWC automatically, + // since MIOpen's NHWC solvers measured faster on convnets there. RDNA and newer (gfx10/gfx11/gfx12) + // keep NCHW in "Auto" because their NHWC solvers can fall back to naive implementations. + // NHWC is still forced for transformer models below and can always be requested with + // rocmUseNHWC=true. + // (useNHWC stays false here on non-gfx9 archs unless rocmUseNHWC=true was set above.) // The transformer block implementation (attention/RoPE/FFN) only supports NHWC, since its channel // projections assume the channel dim is contiguous per spatial position. Force NHWC for transformer From 5967a2ef39a9a55ce4697bc1e23469acbcb5aec1 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 18 Aug 2026 20:39:56 +0800 Subject: [PATCH 31/37] Add RyzenAI backend for AMD NPU, first push --- .gitignore | 2 + Compiling.md | 34 ++ README.md | 8 +- cpp/CMakeLists.txt | 322 +++++++++++++++++- cpp/configs/gtp_example.cfg | 47 +++ cpp/external/ryzenai_artifacts/README.md | 34 ++ .../bf16/npu1_1col/gemm_bf16_K1024.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1024.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K1088.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1088.xclbin | Bin 0 -> 35976 bytes .../bf16/npu1_1col/gemm_bf16_K1152.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1152.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K1216.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1216.xclbin | Bin 0 -> 36616 bytes .../bf16/npu1_1col/gemm_bf16_K128.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K128.xclbin | Bin 0 -> 24776 bytes .../bf16/npu1_1col/gemm_bf16_K1280.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1280.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K1344.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1344.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K1408.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1408.xclbin | Bin 0 -> 29896 bytes .../bf16/npu1_1col/gemm_bf16_K1472.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1472.xclbin | Bin 0 -> 36616 bytes .../bf16/npu1_1col/gemm_bf16_K1536.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1536.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K1728.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K1728.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K192.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K192.xclbin | Bin 0 -> 23560 bytes .../bf16/npu1_1col/gemm_bf16_K2304.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K2304.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K256.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K256.xclbin | Bin 0 -> 24328 bytes .../bf16/npu1_1col/gemm_bf16_K2880.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K2880.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K320.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K320.xclbin | Bin 0 -> 25096 bytes .../bf16/npu1_1col/gemm_bf16_K3456.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K3456.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K384.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K384.xclbin | Bin 0 -> 25864 bytes .../bf16/npu1_1col/gemm_bf16_K4032.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K4032.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K448.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K448.xclbin | Bin 0 -> 26632 bytes .../bf16/npu1_1col/gemm_bf16_K4608.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K4608.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K512.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K512.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K5184.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K5184.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K576.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K576.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K5760.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K5760.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K6336.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K6336.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_1col/gemm_bf16_K64.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K64.xclbin | Bin 0 -> 25352 bytes .../bf16/npu1_1col/gemm_bf16_K640.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K640.xclbin | Bin 0 -> 29896 bytes .../bf16/npu1_1col/gemm_bf16_K6912.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K6912.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K704.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K704.xclbin | Bin 0 -> 36616 bytes .../bf16/npu1_1col/gemm_bf16_K768.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K768.xclbin | Bin 0 -> 36104 bytes .../bf16/npu1_1col/gemm_bf16_K832.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K832.xclbin | Bin 0 -> 35976 bytes .../bf16/npu1_1col/gemm_bf16_K896.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K896.xclbin | Bin 0 -> 29896 bytes .../bf16/npu1_1col/gemm_bf16_K960.insts.bin | Bin 0 -> 660 bytes .../bf16/npu1_1col/gemm_bf16_K960.xclbin | Bin 0 -> 32776 bytes .../bf16/npu1_2col/gemm_bf16_K1024.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1024.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K1088.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1088.xclbin | Bin 0 -> 64136 bytes .../bf16/npu1_2col/gemm_bf16_K1152.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1152.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K1216.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1216.xclbin | Bin 0 -> 65416 bytes .../bf16/npu1_2col/gemm_bf16_K128.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K128.xclbin | Bin 0 -> 41736 bytes .../bf16/npu1_2col/gemm_bf16_K1280.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1280.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K1344.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1344.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K1408.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1408.xclbin | Bin 0 -> 51976 bytes .../bf16/npu1_2col/gemm_bf16_K1472.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1472.xclbin | Bin 0 -> 65416 bytes .../bf16/npu1_2col/gemm_bf16_K1536.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1536.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K1728.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K1728.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K192.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K192.xclbin | Bin 0 -> 39304 bytes .../bf16/npu1_2col/gemm_bf16_K2304.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K2304.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K256.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K256.xclbin | Bin 0 -> 40840 bytes .../bf16/npu1_2col/gemm_bf16_K2880.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K2880.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K320.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K320.xclbin | Bin 0 -> 42376 bytes .../bf16/npu1_2col/gemm_bf16_K3456.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K3456.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K384.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K384.xclbin | Bin 0 -> 43912 bytes .../bf16/npu1_2col/gemm_bf16_K4032.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K4032.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K448.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K448.xclbin | Bin 0 -> 45448 bytes .../bf16/npu1_2col/gemm_bf16_K4608.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K4608.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K512.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K512.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K5184.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K5184.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K576.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K576.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K5760.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K5760.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K6336.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K6336.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_2col/gemm_bf16_K64.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K64.xclbin | Bin 0 -> 42888 bytes .../bf16/npu1_2col/gemm_bf16_K640.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K640.xclbin | Bin 0 -> 51976 bytes .../bf16/npu1_2col/gemm_bf16_K6912.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K6912.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K704.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K704.xclbin | Bin 0 -> 65416 bytes .../bf16/npu1_2col/gemm_bf16_K768.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K768.xclbin | Bin 0 -> 64392 bytes .../bf16/npu1_2col/gemm_bf16_K832.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K832.xclbin | Bin 0 -> 64136 bytes .../bf16/npu1_2col/gemm_bf16_K896.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K896.xclbin | Bin 0 -> 51976 bytes .../bf16/npu1_2col/gemm_bf16_K960.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu1_2col/gemm_bf16_K960.xclbin | Bin 0 -> 57736 bytes .../bf16/npu1_4col/gemm_bf16_K1024.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1024.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K1088.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1088.xclbin | Bin 0 -> 120862 bytes .../bf16/npu1_4col/gemm_bf16_K1152.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1152.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K1216.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1216.xclbin | Bin 0 -> 123422 bytes .../bf16/npu1_4col/gemm_bf16_K128.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K128.xclbin | Bin 0 -> 76062 bytes .../bf16/npu1_4col/gemm_bf16_K1280.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1280.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K1344.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1344.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K1408.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1408.xclbin | Bin 0 -> 96542 bytes .../bf16/npu1_4col/gemm_bf16_K1472.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1472.xclbin | Bin 0 -> 123422 bytes .../bf16/npu1_4col/gemm_bf16_K1536.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1536.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K1728.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K1728.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K192.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K192.xclbin | Bin 0 -> 71197 bytes .../bf16/npu1_4col/gemm_bf16_K2304.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K2304.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K256.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K256.xclbin | Bin 0 -> 74270 bytes .../bf16/npu1_4col/gemm_bf16_K2880.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K2880.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K320.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K320.xclbin | Bin 0 -> 77342 bytes .../bf16/npu1_4col/gemm_bf16_K3456.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K3456.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K384.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K384.xclbin | Bin 0 -> 80414 bytes .../bf16/npu1_4col/gemm_bf16_K4032.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K4032.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K448.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K448.xclbin | Bin 0 -> 83486 bytes .../bf16/npu1_4col/gemm_bf16_K4608.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K4608.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K512.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K512.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K5184.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K5184.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K576.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K576.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K5760.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K5760.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K6336.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K6336.xclbin | Bin 0 -> 108062 bytes .../bf16/npu1_4col/gemm_bf16_K64.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K64.xclbin | Bin 0 -> 78366 bytes .../bf16/npu1_4col/gemm_bf16_K640.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K640.xclbin | Bin 0 -> 96542 bytes .../bf16/npu1_4col/gemm_bf16_K6912.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K6912.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K704.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K704.xclbin | Bin 0 -> 123422 bytes .../bf16/npu1_4col/gemm_bf16_K768.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K768.xclbin | Bin 0 -> 121374 bytes .../bf16/npu1_4col/gemm_bf16_K832.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K832.xclbin | Bin 0 -> 120862 bytes .../bf16/npu1_4col/gemm_bf16_K896.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K896.xclbin | Bin 0 -> 96542 bytes .../bf16/npu1_4col/gemm_bf16_K960.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu1_4col/gemm_bf16_K960.xclbin | Bin 0 -> 108062 bytes .../bf16/npu2_1col/gemm_bf16_K1024.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1024.xclbin | Bin 0 -> 23560 bytes .../bf16/npu2_1col/gemm_bf16_K1088.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1088.xclbin | Bin 0 -> 23880 bytes .../bf16/npu2_1col/gemm_bf16_K1152.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1152.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K1216.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1216.xclbin | Bin 0 -> 23816 bytes .../bf16/npu2_1col/gemm_bf16_K128.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K128.xclbin | Bin 0 -> 27592 bytes .../bf16/npu2_1col/gemm_bf16_K1280.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1280.xclbin | Bin 0 -> 23560 bytes .../bf16/npu2_1col/gemm_bf16_K1344.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1344.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K1408.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1408.xclbin | Bin 0 -> 22344 bytes .../bf16/npu2_1col/gemm_bf16_K1472.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1472.xclbin | Bin 0 -> 23816 bytes .../bf16/npu2_1col/gemm_bf16_K1536.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1536.xclbin | Bin 0 -> 23560 bytes .../bf16/npu2_1col/gemm_bf16_K1728.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K1728.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K192.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K192.xclbin | Bin 0 -> 22536 bytes .../bf16/npu2_1col/gemm_bf16_K2304.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K2304.xclbin | Bin 0 -> 23560 bytes .../bf16/npu2_1col/gemm_bf16_K256.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K256.xclbin | Bin 0 -> 23240 bytes .../bf16/npu2_1col/gemm_bf16_K2880.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K2880.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K320.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K320.xclbin | Bin 0 -> 23944 bytes .../bf16/npu2_1col/gemm_bf16_K3456.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K3456.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K384.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K384.xclbin | Bin 0 -> 24648 bytes .../bf16/npu2_1col/gemm_bf16_K4032.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K4032.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K448.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K448.xclbin | Bin 0 -> 25352 bytes .../bf16/npu2_1col/gemm_bf16_K4608.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K4608.xclbin | Bin 0 -> 23560 bytes .../bf16/npu2_1col/gemm_bf16_K512.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K512.xclbin | Bin 0 -> 26056 bytes .../bf16/npu2_1col/gemm_bf16_K5184.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K5184.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K576.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K576.xclbin | Bin 0 -> 26760 bytes .../bf16/npu2_1col/gemm_bf16_K5760.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K5760.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K6336.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K6336.xclbin | Bin 0 -> 22920 bytes .../bf16/npu2_1col/gemm_bf16_K64.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K64.xclbin | Bin 0 -> 24520 bytes .../bf16/npu2_1col/gemm_bf16_K640.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K640.xclbin | Bin 0 -> 27464 bytes .../bf16/npu2_1col/gemm_bf16_K6912.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K6912.xclbin | Bin 0 -> 23560 bytes .../bf16/npu2_1col/gemm_bf16_K704.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K704.xclbin | Bin 0 -> 28168 bytes .../bf16/npu2_1col/gemm_bf16_K768.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K768.xclbin | Bin 0 -> 28872 bytes .../bf16/npu2_1col/gemm_bf16_K832.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K832.xclbin | Bin 0 -> 23880 bytes .../bf16/npu2_1col/gemm_bf16_K896.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K896.xclbin | Bin 0 -> 22344 bytes .../bf16/npu2_1col/gemm_bf16_K960.insts.bin | Bin 0 -> 660 bytes .../bf16/npu2_1col/gemm_bf16_K960.xclbin | Bin 0 -> 22920 bytes .../gemm_swiglu_bf16_K1152.insts.bin | Bin 0 -> 660 bytes .../gemm_swiglu_bf16_K1152.xclbin | Bin 0 -> 26632 bytes .../gemm_swiglu_bf16_K512.insts.bin | Bin 0 -> 660 bytes .../gemm_swiglu_bf16_K512.xclbin | Bin 0 -> 29704 bytes .../gemm_swiglu_bf16_K768.insts.bin | Bin 0 -> 660 bytes .../gemm_swiglu_bf16_K768.xclbin | Bin 0 -> 32520 bytes .../bf16/npu2_2col/gemm_bf16_K1024.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1024.xclbin | Bin 0 -> 39384 bytes .../bf16/npu2_2col/gemm_bf16_K1088.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1088.xclbin | Bin 0 -> 40024 bytes .../bf16/npu2_2col/gemm_bf16_K1152.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1152.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K1216.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1216.xclbin | Bin 0 -> 39896 bytes .../bf16/npu2_2col/gemm_bf16_K128.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K128.xclbin | Bin 0 -> 47448 bytes .../bf16/npu2_2col/gemm_bf16_K1280.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1280.xclbin | Bin 0 -> 39384 bytes .../bf16/npu2_2col/gemm_bf16_K1344.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1344.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K1408.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1408.xclbin | Bin 0 -> 36952 bytes .../bf16/npu2_2col/gemm_bf16_K1472.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1472.xclbin | Bin 0 -> 39896 bytes .../bf16/npu2_2col/gemm_bf16_K1536.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1536.xclbin | Bin 0 -> 39384 bytes .../bf16/npu2_2col/gemm_bf16_K1728.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K1728.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K192.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K192.xclbin | Bin 0 -> 37336 bytes .../bf16/npu2_2col/gemm_bf16_K2304.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K2304.xclbin | Bin 0 -> 39384 bytes .../bf16/npu2_2col/gemm_bf16_K256.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K256.xclbin | Bin 0 -> 38744 bytes .../bf16/npu2_2col/gemm_bf16_K2880.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K2880.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K320.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K320.xclbin | Bin 0 -> 40152 bytes .../bf16/npu2_2col/gemm_bf16_K3456.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K3456.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K384.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K384.xclbin | Bin 0 -> 41560 bytes .../bf16/npu2_2col/gemm_bf16_K4032.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K4032.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K448.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K448.xclbin | Bin 0 -> 42968 bytes .../bf16/npu2_2col/gemm_bf16_K4608.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K4608.xclbin | Bin 0 -> 39384 bytes .../bf16/npu2_2col/gemm_bf16_K512.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K512.xclbin | Bin 0 -> 44376 bytes .../bf16/npu2_2col/gemm_bf16_K5184.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K5184.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K576.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K576.xclbin | Bin 0 -> 45784 bytes .../bf16/npu2_2col/gemm_bf16_K5760.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K5760.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K6336.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K6336.xclbin | Bin 0 -> 38104 bytes .../bf16/npu2_2col/gemm_bf16_K64.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K64.xclbin | Bin 0 -> 41304 bytes .../bf16/npu2_2col/gemm_bf16_K640.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K640.xclbin | Bin 0 -> 47192 bytes .../bf16/npu2_2col/gemm_bf16_K6912.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K6912.xclbin | Bin 0 -> 39384 bytes .../bf16/npu2_2col/gemm_bf16_K704.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K704.xclbin | Bin 0 -> 48600 bytes .../bf16/npu2_2col/gemm_bf16_K768.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K768.xclbin | Bin 0 -> 50008 bytes .../bf16/npu2_2col/gemm_bf16_K832.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K832.xclbin | Bin 0 -> 40024 bytes .../bf16/npu2_2col/gemm_bf16_K896.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K896.xclbin | Bin 0 -> 36952 bytes .../bf16/npu2_2col/gemm_bf16_K960.insts.bin | Bin 0 -> 1304 bytes .../bf16/npu2_2col/gemm_bf16_K960.xclbin | Bin 0 -> 38104 bytes .../gemm_swiglu_bf16_K1152.insts.bin | Bin 0 -> 1304 bytes .../gemm_swiglu_bf16_K1152.xclbin | Bin 0 -> 45528 bytes .../gemm_swiglu_bf16_K512.insts.bin | Bin 0 -> 1304 bytes .../gemm_swiglu_bf16_K512.xclbin | Bin 0 -> 51672 bytes .../gemm_swiglu_bf16_K768.insts.bin | Bin 0 -> 1304 bytes .../gemm_swiglu_bf16_K768.xclbin | Bin 0 -> 57304 bytes .../bf16/npu2_4col/gemm_bf16_K1024.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1024.xclbin | Bin 0 -> 71277 bytes .../bf16/npu2_4col/gemm_bf16_K1088.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1088.xclbin | Bin 0 -> 72558 bytes .../bf16/npu2_4col/gemm_bf16_K1152.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1152.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K1216.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1216.xclbin | Bin 0 -> 72302 bytes .../bf16/npu2_4col/gemm_bf16_K128.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K128.xclbin | Bin 0 -> 87406 bytes .../bf16/npu2_4col/gemm_bf16_K1280.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1280.xclbin | Bin 0 -> 71277 bytes .../bf16/npu2_4col/gemm_bf16_K1344.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1344.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K1408.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1408.xclbin | Bin 0 -> 66408 bytes .../bf16/npu2_4col/gemm_bf16_K1472.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1472.xclbin | Bin 0 -> 72302 bytes .../bf16/npu2_4col/gemm_bf16_K1536.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1536.xclbin | Bin 0 -> 71277 bytes .../bf16/npu2_4col/gemm_bf16_K1728.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K1728.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K192.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K192.xclbin | Bin 0 -> 67176 bytes .../bf16/npu2_4col/gemm_bf16_K2304.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K2304.xclbin | Bin 0 -> 71277 bytes .../bf16/npu2_4col/gemm_bf16_K256.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K256.xclbin | Bin 0 -> 69996 bytes .../bf16/npu2_4col/gemm_bf16_K2880.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K2880.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K320.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K320.xclbin | Bin 0 -> 72814 bytes .../bf16/npu2_4col/gemm_bf16_K3456.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K3456.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K384.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K384.xclbin | Bin 0 -> 75630 bytes .../bf16/npu2_4col/gemm_bf16_K4032.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K4032.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K448.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K448.xclbin | Bin 0 -> 78446 bytes .../bf16/npu2_4col/gemm_bf16_K4608.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K4608.xclbin | Bin 0 -> 71277 bytes .../bf16/npu2_4col/gemm_bf16_K512.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K512.xclbin | Bin 0 -> 81262 bytes .../bf16/npu2_4col/gemm_bf16_K5184.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K5184.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K576.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K576.xclbin | Bin 0 -> 84078 bytes .../bf16/npu2_4col/gemm_bf16_K5760.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K5760.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K6336.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K6336.xclbin | Bin 0 -> 68712 bytes .../bf16/npu2_4col/gemm_bf16_K64.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K64.xclbin | Bin 0 -> 75118 bytes .../bf16/npu2_4col/gemm_bf16_K640.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K640.xclbin | Bin 0 -> 86894 bytes .../bf16/npu2_4col/gemm_bf16_K6912.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K6912.xclbin | Bin 0 -> 71277 bytes .../bf16/npu2_4col/gemm_bf16_K704.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K704.xclbin | Bin 0 -> 89710 bytes .../bf16/npu2_4col/gemm_bf16_K768.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K768.xclbin | Bin 0 -> 92526 bytes .../bf16/npu2_4col/gemm_bf16_K832.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K832.xclbin | Bin 0 -> 72558 bytes .../bf16/npu2_4col/gemm_bf16_K896.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K896.xclbin | Bin 0 -> 66408 bytes .../bf16/npu2_4col/gemm_bf16_K960.insts.bin | Bin 0 -> 2592 bytes .../bf16/npu2_4col/gemm_bf16_K960.xclbin | Bin 0 -> 68712 bytes .../gemm_swiglu_bf16_K1152.insts.bin | Bin 0 -> 2592 bytes .../gemm_swiglu_bf16_K1152.xclbin | Bin 0 -> 83566 bytes .../gemm_swiglu_bf16_K512.insts.bin | Bin 0 -> 2592 bytes .../gemm_swiglu_bf16_K512.xclbin | Bin 0 -> 95854 bytes .../gemm_swiglu_bf16_K768.insts.bin | Bin 0 -> 2592 bytes .../gemm_swiglu_bf16_K768.xclbin | Bin 0 -> 107118 bytes .../bf16/npu2_8col/gemm_bf16_K1024.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1024.xclbin | Bin 0 -> 135502 bytes cpp/main.cpp | 4 + cpp/program/setup.cpp | 3 + 436 files changed, 449 insertions(+), 5 deletions(-) create mode 100644 cpp/external/ryzenai_artifacts/README.md create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1024.xclbin diff --git a/.gitignore b/.gitignore index 7799d05291..99b64501c2 100644 --- a/.gitignore +++ b/.gitignore @@ -92,3 +92,5 @@ cpp/build.ninja cpp/KataGoSwift.* cpp/include/KataGoSwift/KataGoSwift-swift.h cpp/external/katagocoreml/proto/ + +.claude \ No newline at end of file diff --git a/Compiling.md b/Compiling.md index abe7de36fc..e02d1f8452 100644 --- a/Compiling.md +++ b/Compiling.md @@ -63,6 +63,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the OpenCL backend, a modern GPU that supports OpenCL 1.2 or greater, or else something like [this](https://software.intel.com/en-us/opencl-sdk) for CPU. But if using CPU, Eigen should be better. * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. I'm unsure how version compatibility works with CUDA, there's a good chance that later versions than these work just as well, but they have not been tested. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. + * If using the RyzenAI backend, an AMD Ryzen AI processor with its NPU enabled, AMD's NPU driver, and the [XRT SDK for Windows](https://github.com/Xilinx/XRT). Nothing else - the NPU kernels ship with KataGo. See the RyzenAI notes below. * If using the Eigen backend, Eigen3, version 3.3.x. (http://eigen.tuxfamily.org/index.php?title=Main_Page#Download). * zlib. Easy way to build zlib on Windows is to use vcpkg. Run in Powershell: * git clone https://github.com/microsoft/vcpkg.git @@ -109,6 +110,39 @@ As also mentioned in the instructions below but repeated here for visibility, if * For MinGW it's recommended to configure the project in the following ways: * Use the default MinGW toolchain in [CLion IDE](https://www.jetbrains.com/clion/) (free for Non-Commercial use) * Use [MSYS2](https://www.msys2.org/) MinGW toolchain. Befor configuring, install gcc compiler using pacman package manager: `pacman -S mingw-w64-x86_64-gcc` + * **RyzenAI backend (Windows):** + * Runs the neural net on the NPU built into AMD Ryzen AI processors (XDNA1 as in Phoenix/Hawk Point, XDNA2 as in Strix). The compiled NPU kernels are committed to this repository, so there is no tuning step, no model conversion, and nothing to install beyond the two requirements below. + * Requirements: + * AMD's NPU driver, and the NPU enabled in the BIOS. `katago benchmark` reports which NPU it found, or says none was found. + * The [XRT SDK for Windows](https://github.com/Xilinx/XRT). CMake looks in `%XILINX_XRT%` and then `C:\Xilinx\XRT`; pass `-DXRT_ROOT=` if it lives elsewhere. + * Visual Studio Build Tools with the "Desktop development with C++" workload, and zlib (conda and vcpkg both ship one). + * Build. CMake locates the C++ toolchain, the XRT SDK and zlib itself, so an ordinary shell is enough - a Developer Command Prompt is *not* required: + ``` + cd cpp + mkdir build + cd build + cmake .. -G Ninja -DUSE_BACKEND=RYZENAI -DCMAKE_BUILD_TYPE=Release + cmake --build . --parallel + ``` + `ninja` works in place of `cmake --build .` if you have it on your PATH. If CMake cannot find something it names what and where to get it; `-DZLIB_ROOT=...` and `-DXRT_RUNTIME_DLL_DIR=...` override the search. + * The build directory runs as-is: `katago.exe`, the XRT runtime DLLs beside it, and the NPU kernels in a `ryzenai` subdirectory. Copy all three together if you move it. + * **Precision:** on XDNA2 the default is block floating point, which is faster; `ryzenaiDtype = bf16` in the config selects the more accurate format instead. XDNA1 only has bf16. Either way the NPU is not computing in fp32, so its outputs differ slightly from the CPU backends - enough to pick differently between two nearly-equal moves, not enough to matter for strength. + * **Regenerating the NPU kernels** - only needed for a network shape that has no kernel yet. The shipped set already covers every reduction dimension up to 6912, so most new models need nothing at all. Run katago with `-override-config ryzenaiShapeReport=true` to see what a model asks for; the log names any shape that fell back to the CPU. + * This needs the [mlir-aie](https://github.com/Xilinx/mlir-aie) toolchain, which is several gigabytes and is installed into a virtual environment of your choosing: + ``` + cd python\ryzenai_kernels + .\setup_env.ps1 -Prefix C:\Envs\mlir-aie # report the plan, download nothing + .\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute # install for real + ``` + `-Prefix` is required and has no default - any path works, e.g. `-Prefix D:\tools\mlir-aie`. Without `-Execute` the script only checks prerequisites and prints what it would do. + * Then generate. Artifacts land in `cpp/external/ryzenai_artifacts` in the layout the loader expects, intermediate build trees are cleaned up, and the next `cmake --build` copies everything next to `katago.exe`: + ``` + activate_iron.bat + python make_artifacts.py --list --for-model 512 8 # plan only + python make_artifacts.py --for-model 512 8 --ffn-hidden 768 # transformer + python make_artifacts.py --for-model 768 0 # convnet + ``` + The arguments are trunk channels, attention heads (0 for a convnet), and optionally board points (default 361, i.e. 19x19). `--ffn-hidden` is the FFN hidden width from the shape report; without it the SwiGLU activation runs unfused, which costs a few percent. * Done! You should now have a compiled `katago.exe` executable in your working directory. * Note: You may need to copy the ".dll" files corresponding to the various ".lib" (".a") files you compiled with into the directory containing katago.exe. * MinGW has different dlls. If you use pacman, the necessary dlls (`libbz2-1.dll`, `libzip.dll`, `libzstd.dll`, `liblzma-5.dll`) should be copied from MinGW bin directory (like `C:\msys64\mingw64\bin`). diff --git a/README.md b/README.md index 4ea665e7f5..32439a5739 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ * [GUIs](#guis) * [Windows and Linux](#windows-and-linux) * [MacOS](#macos) - * [OpenCL vs CUDA vs TensorRT vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-eigen) + * [OpenCL vs CUDA vs TensorRT vs RyzenAI vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-ryzenai-vs-eigen) * [How To Use](#how-to-use) * [Tuning for Performance](#tuning-for-performance) * [Common Questions and Issues](#common-questions-and-issues) @@ -85,8 +85,8 @@ The community also provides KataGo packages for [Homebrew](https://brew.sh) on M Use `brew install katago`. The latest config files and networks are installed in KataGo's `share` directory. Find them via `brew list --verbose katago`. A basic way to run katago will be `katago gtp -config $(brew list --verbose katago | grep 'gtp.*\.cfg') -model $(brew list --verbose katago | grep .gz | head -1)`. You should choose the Network according to the release notes here and customize the provided example config as with every other way of installing KataGo. -### OpenCL vs CUDA vs TensorRT vs Eigen -KataGo has four backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), and Eigen (CPU). (On macOS there is also a Metal backend, most easily obtained via homebrew - see above.) +### OpenCL vs CUDA vs TensorRT vs RyzenAI vs Eigen +KataGo has five backends, OpenCL (GPU), CUDA (GPU), TensorRT (GPU), RyzenAI (AMD NPU), and Eigen (CPU). (On macOS there is also a Metal backend, most easily obtained via homebrew - see above.) As of v1.17, KataGo supports transformer neural nets, which are generally much stronger for the same compute cost and which the main training run is switching to. Transformer models are more demanding on the GPU backend than the older convolutional nets, so the backend recommendations below matter more for them - in particular OpenCL is noticeably slower on transformers, and on NVIDIA the CUDNN and TensorRT versions make a large difference. @@ -95,12 +95,14 @@ The quick summary is: * **For often much better performance on NVIDIA GPUs, try TensorRT**, but you may need to install TensorRT from Nvidia. * Use Eigen with AVX2 if you don't have a GPU or if your GPU is too old/weak to work with OpenCL, and you just want a plain CPU KataGo. * Use Eigen without AVX2 if your CPU is old or on a low-end device that doesn't support AVX2. + * Use RyzenAI on a Ryzen AI laptop, if you would rather run on its NPU than on its integrated GPU or CPU. * The CUDA+CUDNN backend can also work well for NVIDIA GPUs. It has faster startup than TensorRT and is competitive on transformers if using CUDNN >= 9.8.0, though TensorRT 10.16 is often still slightly faster. More in detail: * OpenCL is a general GPU backend should be able to run with any GPUs or accelerators that support [OpenCL](https://en.wikipedia.org/wiki/OpenCL), including NVIDIA GPUs, AMD GPUs, as well CPU-based OpenCL implementations or things like Intel Integrated Graphics. This is the most general GPU version of KataGo and doesn't require a complicated install like CUDA does, so is most likely to work out of the box as long as you have a fairly modern GPU. **However, it also need to take some time when run for the very first time to tune itself.** For many systems, this will take 5-30 seconds, but on a few older/slower systems, may take many minutes or longer. Also, the quality of OpenCL implementations is sometimes inconsistent, particularly for Intel Integrated Graphics and for AMD GPUs that are older than several years, so it might not work for very old machines, as well as specific buggy newer AMD GPUs, see also [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers). OpenCL is not as optimized as the NVIDIA-specific backends and will generally be slower, particularly for transformer models. * CUDA is a GPU backend specific to NVIDIA GPUs (it will not work with AMD or Intel or any other GPUs) and requires installing [CUDA](https://developer.nvidia.com/cuda-zone) and [CUDNN](https://developer.nvidia.com/cudnn) and a modern NVIDIA GPU. For older convolutional nets, on many GPUs the OpenCL implementation can match or beat NVIDIA's own CUDA/CUDNN, with the exception of top-end NVIDIA GPUs that support FP16 and tensor cores. For transformer nets, CUDA+CUDNN clearly outperforms OpenCL, but you should use CUDNN >= 9.8.0 if at all possible - the older CUDNN 8.9.7 is a LOT slower on transformer models. Compared to TensorRT, CUDA+CUDNN has faster startup times and is often only slightly slower (and occasionally faster) on transformers. * TensorRT is similar to CUDA, but uses NVIDIA's TensorRT framework to run the neural network with more optimized kernels. For modern NVIDIA GPUs it should work whenever CUDA does, and will usually be the fastest backend, though it has much longer startup times on every launch. As of v1.17.0, TensorRT versions older than 10 are no longer supported. For transformer models, recent versions like CUDA 13 + TensorRT 10.16 are best, while older TensorRT versions can be outperformed by CUDA+CUDNN. + * RyzenAI is a backend for the *NPU* built into AMD Ryzen AI laptop processors (XDNA1 as in Phoenix/Hawk Point, XDNA2 as in Strix). It will not work with anything else - not AMD GPUs, and not older Ryzen chips without an NPU. It needs only AMD's NPU driver and the [XRT runtime](https://github.com/Xilinx/XRT); the compiled NPU kernels ship with KataGo, so there is no tuning step and no per-model setup. It reads `.bin.gz` models directly like every other backend. On a Strix laptop it runs roughly 5-11x faster than the Eigen CPU backend on the same machine, with the larger nets gaining the most, and it leaves the CPU almost entirely free for the search itself. Whether it beats that laptop's integrated GPU under OpenCL depends on the model and the machine, so run KataGo's benchmark with both if you want the best choice. Accuracy note: the NPU computes in bfloat16 or block floating point rather than fp32, which shifts the network's outputs slightly - enough to change the engine's choice between two moves it considers nearly equal, not enough to affect playing strength. See [Compiling.md](Compiling.md) for build instructions, and `ryzenaiDtype` in the example config to trade a little speed for more accuracy. * Eigen is a *CPU* backend that should work widely *without* needing a GPU or fancy drivers. Use this if you don't have a good GPU or really any GPU at all. It will be quite significantly slower than OpenCL or CUDA, but on a good CPU can still often get 10 to 20 playouts per second if using the smaller (15 or 20) block neural nets. Eigen can also be compiled with AVX2 and FMA support, which can provide a big performance boost for Intel and AMD CPUs from the last few years. However, it will not run at all on older CPUs (and possibly even some recent but low-power modern CPUs) that don't support these fancy vector instructions. For **any** implementation, it's recommended that you also tune the number of threads used if you care about optimal performance, as it can make a factor of 2-3 difference in the speed. See "Tuning for Performance" below. However, if you mostly just want to get it working, then the default untuned settings should also be still reasonable. diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index fb8bb130fa..7eb8eb6eaa 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,10 +1,184 @@ cmake_minimum_required(VERSION 3.18.2) + +#--------------------------- MSVC ENVIRONMENT BOOTSTRAP (Windows, pre-project) ----------------------------------------- +# +# Configuring with Ninja normally requires a Developer Command Prompt, because cl.exe reads +# INCLUDE/LIB/PATH that only vcvarsall.bat sets. Finding and applying that automatically lets a +# plain shell do the documented thing: +# +# cd cpp && mkdir build && cd build +# cmake .. -G Ninja -DUSE_BACKEND=RYZENAI -DCMAKE_BUILD_TYPE=Release && ninja +# +# Nothing here hardcodes an install path, edition or version. vswhere sits at a location Microsoft +# documents as stable, it reports where Visual Studio actually is, and the newest installed toolset +# wins. Running inside a Developer Command Prompt still works - the bootstrap sees the environment +# is already set up and does nothing. + +# Locate vswhere.exe via the Program Files env vars (its documented install location), so we never +# hardcode a drive letter or edition-specific path. +function(katago_win_find_vswhere out_var) + foreach(_pf_var "ProgramFiles(x86)" "ProgramFiles") + if(DEFINED ENV{${_pf_var}}) + file(TO_CMAKE_PATH "$ENV{${_pf_var}}" _pf) + set(_candidate "${_pf}/Microsoft Visual Studio/Installer/vswhere.exe") + if(EXISTS "${_candidate}") + set(${out_var} "${_candidate}" PARENT_SCOPE) + return() + endif() + endif() + endforeach() + set(${out_var} "" PARENT_SCOPE) +endfunction() + +# Apply the environment vcvarsall.bat would set into THIS cmake process, which is what every +# compiler check during this configure run needs (execute_process children inherit it). +function(katago_win_apply_vcvarsall vcvarsall_bat vcvars_ver) + # Generate a tiny .bat wrapper rather than passing the whole "call ... && set" pipeline as one + # execute_process COMMAND argument - CMake's argument quoting mangles a string that complex + # (embedded quotes plus '&&'), even though it works typed straight into a shell. + set(_bat_file "${CMAKE_BINARY_DIR}/_katago_vcvars_dump.bat") + set(_out_file "${CMAKE_BINARY_DIR}/_katago_vcvars_env.txt") + file(WRITE "${_bat_file}" "@echo off\r\ncall \"${vcvarsall_bat}\" x64 -vcvars_ver=${vcvars_ver} >NUL 2>NUL\r\nset\r\n") + execute_process(COMMAND cmd /c "${_bat_file}" OUTPUT_FILE "${_out_file}" RESULT_VARIABLE _rc) + if(NOT _rc EQUAL 0 OR NOT EXISTS "${_out_file}") + set(${out_var} 0 PARENT_SCOPE) + return() + endif() + # Read line by line with file(STRINGS) rather than splitting the raw output ourselves: INCLUDE, + # LIB and PATH contain semicolons, which a string(REPLACE "\n" ";") split would corrupt. + file(STRINGS "${_out_file}" _env_lines) + foreach(_line IN LISTS _env_lines) + if(_line MATCHES "^([A-Za-z_][A-Za-z0-9_().]*)=(.*)$") + set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") + endif() + endforeach() +endfunction() + +# Newest MSVC toolset across every Visual Studio install, as "|". +function(katago_win_find_newest_msvc out_var) + katago_win_find_vswhere(_vswhere) + if(NOT _vswhere) + set(${out_var} "" PARENT_SCOPE) + return() + endif() + execute_process( + COMMAND "${_vswhere}" -all -products * -property installationPath + OUTPUT_VARIABLE _raw OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + string(REPLACE "\r\n" "\n" _raw "${_raw}") + string(REPLACE "\n" ";" _install_paths "${_raw}") + + set(_best_ver "") + set(_best_bat "") + foreach(_install_path IN LISTS _install_paths) + if(_install_path STREQUAL "") + continue() + endif() + file(TO_CMAKE_PATH "${_install_path}" _install_path) + set(_vcvarsall "${_install_path}/VC/Auxiliary/Build/vcvarsall.bat") + if(NOT EXISTS "${_vcvarsall}") + continue() + endif() + # Version comes from the toolset directory name; require the C++ headers to actually be there, + # so a partially-installed toolset is not selected. + file(GLOB _tool_dirs "${_install_path}/VC/Tools/MSVC/*") + foreach(_t IN LISTS _tool_dirs) + if(IS_DIRECTORY "${_t}" AND EXISTS "${_t}/include/cmath") + get_filename_component(_ver "${_t}" NAME) + # Compare as versions, not strings: list(SORT) mis-orders e.g. 14.9 against 14.40. + if(_ver MATCHES "^[0-9]+\\.[0-9]+" AND (_best_ver STREQUAL "" OR _ver VERSION_GREATER _best_ver)) + set(_best_ver "${_ver}") + set(_best_bat "${_vcvarsall}") + endif() + endif() + endforeach() + endforeach() + if(_best_ver STREQUAL "") + set(${out_var} "" PARENT_SCOPE) + else() + set(${out_var} "${_best_ver}|${_best_bat}" PARENT_SCOPE) + endif() +endfunction() + +# Turn a semicolon-separated path list (the INCLUDE or LIB env var) into quoted compiler flags. +function(katago_win_pathlist_to_flags pathlist flagprefix out_var) + set(_flags "") + # Split as a plain string via regex: CMake's own ';' list handling would fight the semicolons + # already inside the path list. + string(REGEX MATCHALL "[^;]+" _dirs "${pathlist}") + foreach(_dir IN LISTS _dirs) + if(NOT _dir STREQUAL "") + set(_flags "${_flags} ${flagprefix}\"${_dir}\"") + endif() + endforeach() + set(${out_var} "${_flags}" PARENT_SCOPE) +endfunction() + +# CMAKE_HOST_WIN32, not WIN32: the latter is a result of platform detection inside project(), so +# it is still undefined this early. +# +# The guard asks whether the environment is usable, not whether a variable happens to exist: a +# stray empty or whitespace VCToolsInstallDir would otherwise make this skip the bootstrap and +# leave the build with no compiler at all. +set(_katago_vctools "$ENV{VCToolsInstallDir}") +set(_katago_include "$ENV{INCLUDE}") +string(STRIP "${_katago_vctools}" _katago_vctools) +string(STRIP "${_katago_include}" _katago_include) +if(CMAKE_HOST_WIN32 AND NOT CMAKE_CXX_COMPILER + AND (_katago_vctools STREQUAL "" OR _katago_include STREQUAL "")) + katago_win_find_newest_msvc(_katago_msvc) + if(_katago_msvc) + string(REPLACE "|" ";" _katago_msvc_list "${_katago_msvc}") + list(GET _katago_msvc_list 0 _katago_msvc_ver) + list(GET _katago_msvc_list 1 _katago_msvc_bat) + katago_win_apply_vcvarsall("${_katago_msvc_bat}" "${_katago_msvc_ver}") + message(STATUS "KataGo: using MSVC toolset ${_katago_msvc_ver} (found via vswhere)") + + # The environment applied above lasts only for this configure run. A later, separate `ninja` + # (or `cmake --build`) is a sibling process that inherits none of it, so cl.exe would be found + # by its baked-in full path and then fail on . Bake the resolved INCLUDE/LIB into + # flags below, once project() has created the variables to append them to. + katago_win_pathlist_to_flags("$ENV{INCLUDE}" "/I" _katago_msvc_incflags) + katago_win_pathlist_to_flags("$ENV{LIB}" "/LIBPATH:" _katago_msvc_libflags) + + # Visual Studio bundles Ninja, but only on the IDE's private PATH, so a plain shell asking for + # -G Ninja would otherwise need a separate install. + if(CMAKE_GENERATOR MATCHES "Ninja" AND NOT CMAKE_MAKE_PROGRAM) + find_program(_katago_ninja ninja) + if(NOT _katago_ninja) + get_filename_component(_vs_root "${_katago_msvc_bat}" DIRECTORY) + get_filename_component(_vs_root "${_vs_root}/../../.." ABSOLUTE) + set(_bundled "${_vs_root}/Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe") + if(EXISTS "${_bundled}") + set(CMAKE_MAKE_PROGRAM "${_bundled}" CACHE FILEPATH "" FORCE) + message(STATUS "KataGo: using Ninja bundled with Visual Studio: ${_bundled}") + endif() + endif() + endif() + else() + message(WARNING "KataGo: no Visual Studio C++ toolchain found via vswhere. Install the " + "\"Desktop development with C++\" workload, or configure from a Developer " + "Command Prompt.") + endif() +endif() +#----------------------------------------------------------------------------------------------------------------------- + if(USE_BACKEND STREQUAL "METAL") project(katago LANGUAGES CXX Swift) else() project(katago) endif() +# See the bootstrap block above: these carry the auto-detected toolchain's header and library +# search paths into the generated build files, so building later from a plain shell works. +if(_katago_msvc_incflags) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}${_katago_msvc_incflags}" CACHE STRING "" FORCE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}${_katago_msvc_incflags}" CACHE STRING "" FORCE) + foreach(_lk EXE SHARED MODULE) + set(CMAKE_${_lk}_LINKER_FLAGS "${CMAKE_${_lk}_LINKER_FLAGS}${_katago_msvc_libflags}" + CACHE STRING "" FORCE) + endforeach() +endif() + set(CMAKE_CXX_STANDARD 17) if(NOT CMAKE_CONFIGURATION_TYPES) @@ -44,7 +218,7 @@ endif() set(BUILD_DISTRIBUTED 0 CACHE BOOL "Build with http support for contributing to distributed training") set(USE_BACKEND CACHE STRING "Neural net backend") string(TOUPPER "${USE_BACKEND}" USE_BACKEND) -set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN METAL) +set_property(CACHE USE_BACKEND PROPERTY STRINGS "" CUDA TENSORRT OPENCL EIGEN METAL RYZENAI) set(USE_TCMALLOC 0 CACHE BOOL "Use TCMalloc") set(NO_GIT_REVISION 0 CACHE BOOL "Disable embedding the git revision into the compiled exe") @@ -164,8 +338,19 @@ elseif(USE_BACKEND STREQUAL "EIGEN") set(NEURALNET_BACKEND_SOURCES neuralnet/eigenbackend.cpp ) +elseif(USE_BACKEND STREQUAL "RYZENAI") + message(STATUS "-DUSE_BACKEND=RYZENAI, using AMD Ryzen AI NPU (XDNA/XDNA2) backend.") + set(NEURALNET_BACKEND_SOURCES + neuralnet/ryzenaibackend.cpp + neuralnet/ryzenaidevice.cpp + neuralnet/ryzenaikernel.cpp + neuralnet/ryzenaireference.cpp + neuralnet/ryzenaisequence.cpp + neuralnet/ryzenaishapes.cpp + neuralnet/ryzenaimatmul.cpp + ) elseif(USE_BACKEND STREQUAL "") - message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN to compile with the respective backend.${ColorReset}") + message(WARNING "${ColorBoldRed}WARNING: Using dummy neural net backend, intended for non-neural-net testing only, will fail on any code path requiring a neural net. To use neural net, specify -DUSE_BACKEND=CUDA or -DUSE_BACKEND=TENSORRT or -DUSE_BACKEND=OPENCL or -DUSE_BACKEND=EIGEN or -DUSE_BACKEND=RYZENAI to compile with the respective backend.${ColorReset}") set(NEURALNET_BACKEND_SOURCES neuralnet/dummybackend.cpp) else() message(FATAL_ERROR "Unrecognized backend: " ${USE_BACKEND}) @@ -535,6 +720,96 @@ elseif(USE_BACKEND STREQUAL "EIGEN") message(STATUS "Found Eigen3 at ${EIGEN3_INCLUDE_DIRS}") endif() endif() +elseif(USE_BACKEND STREQUAL "RYZENAI") + target_compile_definitions(katago PRIVATE USE_RYZENAI_BACKEND) + message(STATUS "RyzenAI backend: talks to the NPU directly through XRT.") + message(STATUS " It does NOT require the AMD Ryzen AI Software SDK, ONNX Runtime, or Python.") + message(STATUS " Build time needs the XRT SDK; run time needs only the NPU driver.") + + # ---- XRT SDK discovery ---- + # Nothing here hardcodes a path or a version. Resolution order: + # 1. -DXRT_ROOT=... given on the command line + # 2. the XILINX_XRT environment variable (set by XRT's own setup scripts on + # Linux, and by the Windows XRT SDK install step) + # 3. CMake's normal search paths + set(XRT_ROOT "" CACHE PATH "Root of the XRT SDK. Falls back to the XILINX_XRT environment variable.") + # Consult both every configure. Seeding the cache entry from the environment + # instead would stick on whatever the first configure saw, so installing the + # SDK afterwards would not be picked up without wiping the build directory. + set(_katago_xrt_hints "") + if(XRT_ROOT) + list(APPEND _katago_xrt_hints "${XRT_ROOT}") + endif() + if(DEFINED ENV{XILINX_XRT} AND NOT "$ENV{XILINX_XRT}" STREQUAL "") + list(APPEND _katago_xrt_hints "$ENV{XILINX_XRT}") + endif() + find_path(XRT_INCLUDE_DIR + NAMES xrt/xrt_device.h + HINTS ${_katago_xrt_hints} + PATH_SUFFIXES include + DOC "Directory containing xrt/xrt_device.h" + ) + find_library(XRT_COREUTIL_LIBRARY + NAMES xrt_coreutil + HINTS ${_katago_xrt_hints} + PATH_SUFFIXES lib lib64 + DOC "The xrt_coreutil library" + ) + if(NOT XRT_INCLUDE_DIR OR NOT XRT_COREUTIL_LIBRARY) + message(FATAL_ERROR "${ColorBoldRed}The XRT SDK was not found. Install it and either set the XILINX_XRT environment variable to its root or pass -DXRT_ROOT=. On Windows, download xrt_windows_sdk.zip from the Xilinx/XRT releases and extract its xrt_sdk/xrt directory; on Linux, install the XRT packages (typically /opt/xilinx/xrt).${ColorReset}") + endif() + message(STATUS " XRT include dir: ${XRT_INCLUDE_DIR}") + message(STATUS " XRT library: ${XRT_COREUTIL_LIBRARY}") + target_include_directories(katago SYSTEM PRIVATE "${XRT_INCLUDE_DIR}") + target_link_libraries(katago "${XRT_COREUTIL_LIBRARY}") + + # XRT's headers select std::any vs boost::any on __cplusplus. MSVC reports + # 199711L there unless told otherwise, which sends xrt/detail/any.h looking for + # a Boost that we do not ship. Set per-target so the compiler defaults CMake + # supplies (notably /EHsc) are left intact. + target_compile_options(katago PRIVATE $<$:/Zc:__cplusplus>) + + # ---- NPU kernel binaries (xclbin) ---- + # Shipped as build artifacts next to the executable, in a "ryzenai" subdir. + # The backend resolves them relative to the executable at run time, so a + # deployed install is just exe + dlls + this directory. + set(RYZENAI_ARTIFACT_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/ryzenai_artifacts") + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "$/ryzenai" + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${RYZENAI_ARTIFACT_SRC_DIR}" "$/ryzenai" + COMMENT "Copying RyzenAI NPU kernel artifacts next to katago" + ) + + if(WIN32) + # The XRT runtime DLLs ship with the NPU driver rather than with the SDK, so + # they are picked up from the Windows driver store. Located by globbing on + # top of %SystemRoot%, so neither a path nor a driver version is hardcoded. + # Override with -DXRT_RUNTIME_DLL_DIR= if the driver lives elsewhere. + set(XRT_RUNTIME_DLL_DIR "" CACHE PATH "Directory containing xrt_coreutil.dll. Auto-detected from the NPU driver store if empty.") + if(NOT XRT_RUNTIME_DLL_DIR) + file(GLOB _katago_xrt_driver_dirs + "$ENV{SystemRoot}/System32/DriverStore/FileRepository/*/xrt_coreutil.dll") + if(_katago_xrt_driver_dirs) + # Several driver revisions can coexist in the store; take the newest. + list(SORT _katago_xrt_driver_dirs COMPARE FILE_BASENAME ORDER DESCENDING) + list(GET _katago_xrt_driver_dirs 0 _katago_xrt_dll) + get_filename_component(XRT_RUNTIME_DLL_DIR "${_katago_xrt_dll}" DIRECTORY) + endif() + endif() + if(XRT_RUNTIME_DLL_DIR) + message(STATUS " XRT runtime DLLs: ${XRT_RUNTIME_DLL_DIR}") + file(GLOB _katago_xrt_runtime_dlls "${XRT_RUNTIME_DLL_DIR}/xrt_*.dll") + foreach(_katago_xrt_dll IN LISTS _katago_xrt_runtime_dlls) + add_custom_command(TARGET katago POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${_katago_xrt_dll}" "$" + ) + endforeach() + else() + message(WARNING "${ColorBoldRed}Could not locate xrt_coreutil.dll in the driver store. katago will need it on PATH at run time, or pass -DXRT_RUNTIME_DLL_DIR=.${ColorReset}") + endif() + endif() endif() if(USE_BIGGER_BOARDS_EXPENSIVE) @@ -545,6 +820,49 @@ if(NO_GIT_REVISION AND (NOT BUILD_DISTRIBUTED)) target_compile_definitions(katago PRIVATE NO_GIT_REVISION) endif() +# Windows has no system zlib, so a plain `cmake .. -G Ninja` would fail here even though a usable +# copy is almost always already on the machine - conda ships one, so does vcpkg. Look in the roots +# those tools advertise through the environment before giving up. Explicit -DZLIB_ROOT= still wins, +# and nothing here names a fixed drive, user or version. +if(CMAKE_HOST_WIN32 AND NOT ZLIB_ROOT AND NOT ZLIB_LIBRARY) + set(_katago_zlib_roots "") + if(DEFINED ENV{CONDA_PREFIX}) + file(TO_CMAKE_PATH "$ENV{CONDA_PREFIX}" _p) + list(APPEND _katago_zlib_roots "${_p}/Library") + endif() + if(DEFINED ENV{VCPKG_ROOT}) + file(TO_CMAKE_PATH "$ENV{VCPKG_ROOT}" _p) + list(APPEND _katago_zlib_roots "${_p}/installed/x64-windows") + endif() + if(DEFINED ENV{USERPROFILE}) + file(TO_CMAKE_PATH "$ENV{USERPROFILE}" _home) + # A base conda install is not "activated", so it exports no CONDA_PREFIX; its default location + # under the user profile is the only thing to go on. + foreach(_dist miniconda3 anaconda3 miniforge3 mambaforge) + list(APPEND _katago_zlib_roots "${_home}/${_dist}/Library") + endforeach() + endif() + foreach(_root IN LISTS _katago_zlib_roots) + if(EXISTS "${_root}/include/zlib.h") + # Prefer the import library for the DLL over the static one: KataGo links the rest of its + # dependencies dynamically here, and mixing runtimes is what produces the confusing + # duplicate-symbol failures at link time. + foreach(_cand zdll.lib zlib.lib z.lib) + if(EXISTS "${_root}/lib/${_cand}") + set(ZLIB_ROOT "${_root}" CACHE PATH "Root of a zlib install" FORCE) + set(ZLIB_INCLUDE_DIR "${_root}/include" CACHE PATH "" FORCE) + set(ZLIB_LIBRARY "${_root}/lib/${_cand}" CACHE FILEPATH "" FORCE) + message(STATUS "KataGo: using zlib from ${_root}") + break() + endif() + endforeach() + endif() + if(ZLIB_ROOT) + break() + endif() + endforeach() +endif() + find_package(ZLIB) if(ZLIB_FOUND) include_directories(${ZLIB_INCLUDE_DIRS}) diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index 7c3a8f8341..7188d8890f 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -546,6 +546,53 @@ searchFactorWhenWinningThreshold = 0.95 # Default: numSearchThreads # numEigenThreadsPerModel = X +# ------------------------------ +# RyzenAI (AMD NPU) settings +# ------------------------------ +# These only apply when using the RyzenAI version of KataGo (USE_BACKEND=RYZENAI). +# +# This backend talks to the NPU directly through XRT. You do NOT need to install +# the AMD Ryzen AI Software SDK, ONNX Runtime, or Python - at runtime only the +# NPU driver is required. + +# Directory containing the NPU kernel artifacts (*.xclbin). If unset, defaults +# to a "ryzenai" subdirectory next to the katago executable. +# ryzenaiArtifactDir = C:/path/to/ryzenai/artifacts + +# Directory for cached data derived from the model. If unset, follows KataGo's +# usual home data dir convention (see homeDataDir), in a "ryzenaicache" subdir. +# ryzenaiCacheDir = C:/path/to/cache + +# Numeric format requested for NPU kernels: auto, bf16, or bfp16. +# +# auto - bfp16 on XDNA2 (Strix and later), bf16 on XDNA1. This is the default. +# bfp16 - block floating point. Faster, and XDNA2 only. +# bf16 - more accurate, and the only format XDNA1 has. +# +# A single bfp16 matmul carries roughly 3% relative error against float32 where +# bf16 carries ~2e-5, but that is input quantisation and the accumulator is +# float32 either way, so it does not compound the way the per-matmul figure +# suggests: measured end to end over a whole evaluation, bfp16 lands within +# about 1.3-2x of bf16's deviation from the CPU reference, and the policy's top +# ten moves come out the same. Set bf16 explicitly if you would rather have the +# accuracy than the speed. +# ryzenaiDtype = auto + +# Set to true to fail hard if no NPU kernel artifacts are found, instead of +# falling back to the CPU reference forward path. +# ryzenaiForceNpuOnly = false + +# Set to true to log per-thread dispatch details. +# ryzenaiVerboseDispatch = false + +# For one NPU: optionally uncomment and change this if the device to use is guessed incorrectly. +# ryzenaiDeviceToUse = 0 + +# For multiple threads/devices: uncomment these and replace X and Y with the device ids. +# (AND also set numNNServerThreadsPerModel above) +# ryzenaiDeviceToUseThread0 = X +# ryzenaiDeviceToUseThread1 = Y + # =========================================================================== # Root move selection and biases # =========================================================================== diff --git a/cpp/external/ryzenai_artifacts/README.md b/cpp/external/ryzenai_artifacts/README.md new file mode 100644 index 0000000000..53473ceb7e --- /dev/null +++ b/cpp/external/ryzenai_artifacts/README.md @@ -0,0 +1,34 @@ +# RyzenAI NPU kernel artifacts + +Compiled AI Engine kernel binaries for the RyzenAI backend. Everything here is a +build product of the kernel sources in `../kernels/`, committed so that neither +end users nor people compiling KataGo need the AIE toolchain. + +CMake copies this whole directory next to `katago` as `ryzenai/` at build time, +and the backend resolves it relative to the running executable, so a deployed +install is just the executable, the XRT runtime DLLs, and this directory. + +## Layout + +``` +manifest.json ABI contract shared with cpp/neuralnet/ryzenai/manifest.h +bf16/*.xclbin bfloat16 kernels +``` + +## Status + +M2 first kernel landed: `bf16/gemm_bf16_M{M}K{K}N{N}.xclbin` + `.insts.bin` +for (M,K,N) in {(384,384,384), (384,512,512), (384,768,768)} — single-core +bf16×bf16→fp32 GEMM (64×64×64 tiles via mem tile), built by +`../kernels/build_kernels.py` from `../kernels/gemm_bf16.py`, verified on +hardware against numpy. These are per-shape AOT artifacts: M/K/N are baked +into each `.insts.bin`. The shape-independent form (runtime-generated +instruction stream per the "What an xclbin is parameterized by" section +below) is the M3 goal; `manifest.json` pins the ABI either way. + +## What an xclbin is parameterized by + +`(target device, core program, dataflow topology, compile-time tile sizes)` — +**not** by tensor shape. M/K/N, layer count and batch size all live in the +runtime instruction stream, so changing model, board size or batch size does +not require a different xclbin. diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1024.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..71d072e58309451bddaa93cf8c21a06571fd0e23 GIT binary patch literal 660 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 x#?=M)uEJ^}P3AHDzp literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ac7b26c04a32b3ab5dbbfd9ea972cecfea601615 GIT binary patch literal 35976 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 H+}iMe4B55* literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..607afdceb5633296ed6fe07dfd442ac0392c32c9 GIT binary patch literal 660 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 AjsO4v literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1216.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1216.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..96b4ef8f8776e7e15ea3f0e89a112b75cfbf99f8 GIT binary patch literal 36616 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 ZEKx3x>a~da-?whxac_brtfuvi{||XpkURhY literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..cb2d1c0301d25e119d6fa7ed0968a0c2b3988cba GIT binary patch literal 660 zcmbV~I}XAy42FNF6|fZ~28K%QzyY`c3><`kgQQXi4#2?>7b<@m8#NIxVX5(>jz2pI zq?m~SD*#sq(2Q~u?1I%sS68Gg?V=+RSd9TZE@<- z{z3ePzGkBR(vy~W+tXHinxGPMtz02-$~_o&k)#XT?uR*Ch0kYkRIbgDRH0KV*Ja$3 vaa$&Neo>xxV17sA)g7GkdA;sXW%Cvp*BkfGdHWydEtMPE8c#6v#mD#nT_YeE literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..986462c3b80ebee5966306917b632e289df9299d GIT binary patch literal 24776 zcmeHPdvIG-dOvztmLG|)gK;Ila#4&cSmVgg_!TTau_N1YoP^2U-Ht5FvaQ6Hw6?4y zFd>4nnZQDu(yogc9%iS*1WIWb=$5Yk5t&SyNmy_amLYV?xS5m*4Bau?#Uv1-e&?Qh zbkDt(3?^Z>Gpm!4?)Ux9?|kPw-+A0mj&%3A#|FK=3KUJ26(ex)g$H&cD5nPSJ3>?^ z8h+Q_D$6%ddg7Use^@&I+S~)4-q&yc-HVA247>mNDLKu+xwe)Vu&QX zfv-{k4*rOMbvAOPz2L^D2y|24vEBDO5sKUtYuJbeX^{^7CrE9Tmh8iOhj+d;_tFeP zdZk5x#BlI}D@RcoeljBK;JrkR5mUE->)zi_h@w~UTZG|2XIt)J8 zjvk9Y286U5Z9@2%^QM(RFQxqYAeb!qhhD%bcp^%ux+DllRLUa}naq zVZ&Of#?nmt4yQ~0Bx;jR+pOCVYeV}{j)7Q^M_}&NBM_!-X0`vM-S_Oh z<@uQRbhZ+WSQ{HLJHx{6rBuOAW(l_>b1lyETHmcRx4)TVj(naaOgESWEnXd#SbuV~ z1}TPT{NnN%Kck#+Qz`o6#OvFQApU%xk>^|TztEzIv;GrB|Ay9R+*uY*e4bjE@zGna zTxWMgVG%lPN3Ew)!$a96sI^l!Fl5mqbIrrt&o%a4WJh5izv7k*a9+F(=gEmB*rP({ z7vfIUpq@DjX+ zzsfRShSzR55kG~O@9V6YrLVL0cIv`un(zbH-wEsXp3;TGD17otmevUPZE3TI?!CHo z1G><0RUCn!O+(KV<~j!8-Q+;phOR98%Zny^Ms&`4X5HA?qW4WvVfqD=5VD!!l@G51 zcooj16x`BkZ7})&s{qZF{j3rhGkTE@kdyx$F~LrUnm0|TJ@+Hy4-7)+t@Z68+uA+o z3%-GGDL1A$%HTw`8XocdyFDe(xTo6SnIng*?L0s8xIs7boI&3cstCM0JM&};>Iprx zG!O45-#Z5HTlSuVGq7=6Kl-18fvK~ao={ESHh4Gw{i~?w-pt8)G{?PxZy$ZfK(aQ% zO=s~OnzK3z{1;90{n*=EkhN^-tY)sPp#T|6-ovdQ`^{^pC$}kh9_kxTqRXW_UIWST ztmag474#Q6mE8}$HobmMGiPlm9Q&Q=NWbP^t&V5QP84+(?|2=!8Mi?Y-{A^FCs>xQ|6FOdBsTV@_d}#eh zNs18KQrHtpzq{g+5PG|y!P;=o%m2I9dY2Y@G{MaeijZ5rUYM>Z5^^gG-M?@ZbmTVb z-OqlU-;rCVbL*csbxc&n|4 zIY;waLT$AbmmF(Pm|H@BRa<$&k=||Y2z95Gq_~e*^EyJ0Y8=xi@b&Q$z2k{)kc_>> zI=A81VD*sR@z_tz9l4wCDATlu9zIiygiyrXK3(@Bj1|0xQQvVFNZt94U2F0?rt4qC zT4!N;`|e)^~YfHYLq{=%;4w(eu3UG{`V+?dUmPcmiY?fp+vPuj9`=tLc1|cf)A4 zm*)qBLn#?Ja@tXl9|9SoroDV_K$r#@Mz6hmc0k8xtk<4;b-=AZ3i|o5@N7yZj=FaA zeAu1&yh+>nT3GlSL#A*9aEP(?=zLhmJD$@XJ{EREthJ->&I-RsS<~P`+;L<&dUjTL zEM<-Gpka*=hU+7SHTP@sko|DVT?S5QxgwoPWXy2(M6^aae!-+ig&g|eo#=(7uTupd zygr4qXg9nr!+A6euS;+a4Z>^Ts`C7aM4KSK9EX!4sld+KOwzfYkgW^pq5jIjH$=pU zDWJcv<3+L+=bCtae$W=ifDvV00mk_PLZoHAa|rD`O83ATU6rbUqlNk#-Z(rTy915I_nvL@L3#WF=H72qbu3uBeXCd0e z=E=A}tkXQ1>NHQLI?a=*j`&tsrKAvh%?L+Se2MmyI{Hwl8yP)YBhH0rYe|5oZWU#9gmU&cE7-Ea0gC-}SI^qV9){GF1;ZJ3U*%rP?0$Tmi{Gjbmz4={3o zk;9C9gpp?%`4}Td76tY-i*?Mjl|~03(MP`3NJ= zGV(D-jxh2(BQG%WA|u=FnwbB6jBJNBjMpvRcYVy-w!_@Zcyp|+9bzWq^4ua#K@8_W z#s%B7gAX!ajup@NU}I#S;oBJhd8S_*Glx9mr;S;=JTopEGcLs7oC24}%Q1Ek(=W&L z8%FYYkAO_aJImn57(Bw@^9;Vg;EN27n3!;kjF|XvOneYyhhyyU3~pm^JA?Nz_yB_k zB%J-5M~X)L8YV*XFqisy{1r?^S!mL)jmNhWK3)ona`B+PC>}pd_zEso{`)z7Sv>wM z;gdzqv;uxfJpKUT%RdZ~+JHZ~@%TL9OTYe;J6LGa8}K^U!{3N-5zi7y#?IinO#1gD zxKH4FBQCTq2Xq`n+>T@FvNf22f8Rvo4SQ`>@fP{3h_}cW`()n|$6MqRCz%F`<1O-6 z5pR*dLcF0K3W+z7X-qTe|CfvLR@UV}og8nuZh5?$R~c`SzlwN^d?s>4OdM~KuTeKh z9B+}oig=6s72*x`P)NLqtO1>@Z*q3xI{e)STxeYm=yJT}y5;fSw#s;m{8hwThsA)I%ZhCNhm_CjA|x7;j}=4%ErQO_4o*MkXu zU>v8Y*TVu`Z#kdD<*V1*0$tDCCvmJVU(d7De%tA|_SO4kmfCMS4felzKMqj)jW2=y z<>!fdzYkFRwJ(AF<$U#d!c+TIkH)pHKCcGod04z9ZhTszt%~&-rhMxUC@2sm`jZ z`!VPiscx65&PJX*62|dEntWg(A_JZw$)yZ#2OQ!pa`X&d3OHC0aU+A*0uD)$h-Wf* z72uG5h&adKdcffmkBIXOZUh|0F5-3u&jfspgjX>*2ROu7bH}@?Tb3be=(gEeX9aIP2v}SCgU97vV9ph0^W{) zo{85L;S>3HI#jJ$pC#_s#Y$%Em9f~?0xri~#ybI*V=LoEz~$J=cvS*C2XHxtGT#Ka z977rB0ne7k-u9V{>la%YKU-t|cLFZ24H-8AF8eRz_5^qi;If}GzW{LAPZ`%QZfE-4 z9`nZtxEvoD&jDPvPjK<>oqPvg z*2#Bru+EmYzMZ0~fyIW)o8*E9I*Dz{$JbE_3&8b8%b#U^?#z6*`Sj6GKd$N8c>3Cr zd*Dx8U=;VW?c|u;dhbW-B{Sz?-)IFXFpJ$BsxyC)4Ej`^`{m$mD zb_+k|@{LTv)!NhIs$?`&({(d^v5qq%>_{gz4h zsAt^elx}^N`ui>8uHF6#OFf*vrIvB8Pn2yS2V6n-DBw2Bfl|w;$2H^u*8P?q*NE2* z@ILa$P9Sdgj`&=`sR>WF$2SthO@^fcl@8DTmNCD34};R$Q00g(iJcx_56&@4a9JkX`Pv z7OzjTP*+hmWUF>n4c81+4pt5h!ceNKJcCsg)gG6pqI?MWZJxoY5om#1!xox^L=r#k zRNhJsuWtw{Yk=Dei6V%qXQx61NxPuRwy(m2hl0~CQLU~8E#TTe=68V=*vFo6XHa_Z zs;E2N{wZG&xD`Mgcj9`SQd;VN1Y{>pSD>z^y~o)GPZbp@Q*YS@-#a zPI2YnI{b+T$m#^Za^M?gYZF+GAB+k}zS;S4gT^d-x8LW(J1gW3?pMYG?<*V~QtyX- z2n!!R5jkPodG>*mv4D|i#&B_|OS>fomWykeZC)wbk4;958MisUiz<7sy0PZ?TpV|P z=iW(hzH@UtU90K+8)m;^h3T(ROn)5?8#DbQ6aJ|{Y?7BRf^u^BC07C7!OPa*A9xk0 oc0h9f{lD3NOb!D3i@7^iR}8OsFCzQzPcH8`5a$zCdvDwS0m5zWNB{r; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1280.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1280.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..ee181535b5a04a60926e10ddee62c3f67ac87f78 GIT binary patch literal 660 zcmbVK%MHRX41IP2919W$4wc#i1F!)-FaRTPU=M=S0|PJ^>O#dyZPbrI6+XnVYrjua zkXsS~8vsuRA;!Kt`(E}x5Y`BJiDV{kBg zUw2RM^o(|eWJut`jB0kiSAX68b$|W%W;Cq$xXzlL~d(a zRZEN_0WagLWPp8lQsO!Xy|P?z;**qgRerHv3$)S1Rndl(=#U;6&>sM*Ew(K=a97v% z*T$b4LC6RkgmQ@lLM3p;$3I72&7ctdZLDo=70d#Xs?D=VdIe#Q$nMq0p2Yd#{0EVb zr1JQEZhxPrn_`5NO@38B*okkkznwh_+{19=1SpTKO6lDw|h

=lE{%)bZGKN(UCVkOCLFYKHb_5 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 BAz%Oi literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e5a836569fb0a68e1af548f4263ad0b4358193de GIT binary patch literal 32776 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 Y`Q=f0EfVJ6H*Vi?FvT5KYj?~41Jz7_1^@s6 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..a6a10b0d538b944f6184153cd6668691bbabd3cc GIT binary patch literal 660 zcmbVKI}XAy41IP2j0K5-p;9|=0B!&ShhXf$L4wqQ18^U%fVfa`Qd_h^pb8Ih?Aq@W z73AhbzzV>P0lD_^Anf9;?n^y+4_qsNyJ{I*e32u~>3}6K`!NJ^6wa!rG8NJgz|#7X zy?q0Pjnq1c+B7xRNlSd^UXwz6)wESjI`@&*%1gpH0>9tlsJtW9 w1E^AYIpb}NH~I}T+nDV4ocn!aBrNmmGTvakfBJ1F`t`~iL`{0Zs7iju7Y-;QNB{r; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..852d75aa0747a88fc05c44308ef2c465c3b861f5 GIT binary patch literal 29896 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 D{Qx5{ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5aa967853eeecc3073f82e0b6d43673621eec4fb GIT binary patch literal 36616 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 Q*6lm)PjQFUvbFjD0Sn1@oB#j- literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K192.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..80f71c7b5c640823850f1b175fec37e4b4628c38 GIT binary patch literal 660 zcmbV~K@NgI3`Ktn(Txe3xNt!N3lHE8bm2X8;XyEA;Q>65M=)Fn|3Iq@iH10fnYMKL z{+|FzW+K1}z+C}`{dx*^Au9XScHINF0?@WthLT>nb$!<0N6PzQab&a-&l)3TEO21% zb)KnzgH#*l)``+J#XvooCL8fp)7CT%P*J!xu8=t79-O;~+J&;~b`H((`z?;fbsy0b wCb@BS#63GV_7DbP@1A?_xj*m7lHPP^bRZn5BgyQsW(02i=-6Qbhw(0a zC4}mthOgQiW%>F^eII{z>xo}A^*5WaXo!~R$iIWsQEx4J`0k+t zZ!A1FONbsUgj5L(LL6|#<1Z7h6^oMi+TG#vaVCyP-DXWfc?IwVmFZhvejMwgF~nlQ zFdqny1&4XrN4YG@5-#E=Y&$CYO@w?4PQ0=QUF10Eux3)j&2qk~{K%Wh&v4w^JN7^g zgdDxy#HyT<%6q*mfu_}w2Z>p5Bi6n70$+!g|n|*DQqrE zbiS$~i4#eXh8Cf&pP=-?JAj!{s{A(%S+pe=Y|WKmN|9Och`4d`$C_&F$I5#z9 zwz1JT&>BH)R<;VFBe-XiOG^MY?3T>t+d_*tv6Gd z4YbVWt*J7!p08*7k3-zQO-P*vZ)~f^G*cYEQta!VNyVPdH5hN0j~c>`az!P1xSzCl z>G}tYs)(hb&GZ9}>ku(wn=HA1Tl{3pgKyZ9pK_NCFzdf(PWsP$0v`OkufQw*9k}-N zO7gfR*H|>$qA8jsyNhN^;9AmFGl`P?|+)>@BcK{VixD8(2B+6E_b}GQ-`aJv?MJ9R|+i`;T(dMeF@IPu-bnO zX9QOH<JdE_Eti7_ZeLxK@z7wF4P(UzbS9-p@X07*-9>SVlSW{+C1`P zMTw^$Udwq%3nf{XMSY%$L$t4%it`Bvtl-<{DyX0vpM=7 zR1?mzUu6^gHwLy8G^P z#5>cnw~zey@$sp%8gIP8w-;WGfBgdS9xRw#A`2!Cw?p4NNGF?N6J0q+7HppK== zRYTk}4dH5yf2Lsz)boVaR(<^ZoHy>+Wv}waUumk>`{S-MDE-K`9DjUwg*U$8j=GEf z_?zX;w&pvZ|DR2^+q6)l8Mb;j{3W$p{4;fx{*wBN&<}&$&{O|a)>*Pc7t%jt z?wqM7p3-pHD-9=_>{TJH+uRv{B`1{Nz_ML4Y~(C$CCxWi@2KtY6rU<>i+4EdE_yb- zYH5pq&sqPfXG4#rGv1T8Ehlu+R@xbVRO6X>6|djjruTfm2P9)}l`drXIe2|Y?>X_H zrL&~*<{FJV{=n;1usRnl?wK9WLSLcv(CeFT1F5IXb7*5(=Sz>jf?Zz13b?>i0jClaG

FN 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1868d70d8c5405b9d0f4ea968f7926e71f83c63a GIT binary patch literal 660 zcmbV~F%H5o3`M`42*gy77#J$G0|(#+bl@Ni+=C)@U}WH6hzk`bu~Ab5s>qPUsq^3e zQ9*7-1grqu8IWxn55g|&>Qw5?d*E6D+*iwR#21-jpElUy<$f3XlYBy4ACu;N5WU74j$&*Ta^|Vz_15~zME0=^g#zQOokW5w|t&pLx59dA)L5aT8xKxRRgo1-3#V1^@s6 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d7da02d54fba2e05e305ca7a2f16513a4125b9f6 GIT binary patch literal 36104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K256.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K256.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..30ecaf4d825282e278420f5cc8399a66a19ef330 GIT binary patch literal 24328 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 TB60ow(d8Y-lYGK*?P~j9V5N%j literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2880.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2880.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..543f08d1854634137b0acc55441a78e51fe41dee GIT binary patch literal 660 zcmbV~u?@m75Jmr80u&ShiGl(tDHwnaNWmZ!3=*Ui3_#Bk3=*+W_)hLb90?TR!uC1m z|NgfEN#-KJ8o*rvZu`*)4q;dHrOkQ-ZaJWBz6wWr<<#|AgD)xXhe63`BwoFYl<|Oq zJ3r@|`Zq|mWo?}(+*1>&>SNY>GKsIA_U37Tinbf$3W-B*>D*`3F0@^@3uuPlZ*elN z=ZI8T?2M};?%BB^Z@Khqlk;B2c|RJRmgh}I+{(Fs=B+2@O^sX8P4|Mq6@SJzP1Peb literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..00adb8a7fe008183d3fd1dcb8d79fb4e0bfd06a8 GIT binary patch literal 32776 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

j0ft$eEe9F?!TEvXGvvUDP>u}<6R-vGo_T} z0KZZyGpCdl0AD1PSyIZ1frp2=2|BryvJ&7qsmz{Ib`S72scdITnSBBlGlS~^hdUkt=NQ}sIP_h> zT@0QD_zDTHWN2GF!;cyWcpZZm0}h)p0ncG@{p?x-&y^Bz%jav8zN!Np zVn)F24DJLxsfWQU0Z;ae!A*d}!>|QC1q|+*2j>7!`k#@{0X*3+2Dbp7^c#a00DhCy zZX1KUW_67H!gf}$trGBMl6>*!GHwQ3)-U5Gz+3Qfh!|I*yh#5+N7ifBWDE0kwu0$< zMbfuUz-6DycpKodZ)MyBxa?aQubcEN=l^_Mwb(fUlDJ-u$_Y>t~x7JDZaB zw*fB4hK!p4m+hBv*F1O*;If^vd;#FHoieVU-Nv-LEoqMlaM?dHo&&h7U&MvAa~4os z*kFPt`6=LCBCm&X2e2^iiu^v*LVaQ#=^2kQFMdZ|=Ecw0BF`SpT{{F;1Hp#J8{&z? z2SnXe9?wT5Yy!^LdVKx2ubmit=&pBP`=`jU%8L8XO!q^I3zT9zuP%Z9y869CgIv@< zJOaPpw9!^p>acPCpfA)H2o7wtjYj%!ciQUjTwWI*4(;~)B6lw5xVrG5H_{&(9zq7# zK7Tae^NS3yzR+-z0d|jnIOrebg5DwjMq6h`d$*^dy~V~2dV>R_@bfzxZ9W?p*%t<) zFFb0aS_H-Zy%B$~&);`@pEu&=px7fS^91@f+8lc~ILd5X|7g&MKRx9g1jxpXjP{Dk z%4~Niba{sdBpX6u=$+rjdHec?{Uak=N4x8n)IRT_)CsdR#;Dp`~=$bnUk_#$i0~DiB1`S-93!`C4DHzC$PLtg%XrpqE-|Bb@htXW2X7mTiWHAp~{ zi@hG;vqPzFJnI+*m?onKT)&eC)}aU5!yb6~Tq=D_r3dYU-I#F5KcGgn05(clVZVPjkce2G6$b4c*%xu#Nb3`G>q7>C$JbdB8U0-5naX)xhdoVjBts z1=<00*cg`v2t z+F4cQtS*BEu*BBt7vifsG{lNvklrnB;h@4jqoAm~6i;RAVLw-5>%1^H%w@8|&3z}hf{Mqnd}zZNP_C3hg$2ZdE2yBRi$K&JfmC=`g>E+}&B zE%#$raN8xY>z%-bz5513UeE&b*gxcnNIzUE@E%`iG#CNdau6KyU^#9nZ8bjxVGnLs zpscf{)6)#U$|;D9j`-0aVI}b3PQcwLG*yOv5+owt0YLEQJ_WYdJL3097d1h$QuHYF zcd>2wluh6-gCZ&#aAnY0R?hB2=*rJ!|FpI+mg>y%_z01?J&EszA-rUjwZ4G&( zI|djtxWy9?`IdqKlXo7%;Nq^p02_f_Vsm4|hZ!n0EfXU}Vx^qBoPc5bDxwNrGiU zOtaN11pUduNJ^%yj#p7->$tEDd9J$p`fIB$I_Iie$KhIx@s}C>@&$(9s~G+b=r(5f z2ZlqV;p8CC4T3Up@l&G!XYiaDyuneBG6U54_a`&|m^}#0FXrl4U9P-5re2H0`S+dM OcRZNp4y$Ez^Zx?`pMFaK literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d3da630d5b81dd037d71408e8031041061ce05e2 GIT binary patch literal 660 zcmbV~u?@m75JkT)7L)-g1x2K!U;s8C1p_bw1%m`B1q0Bt5@Mn7o!o(A2^8VN_FeAo z{ci;>TQ~=-0o(-ObzBdJUAWa_sJrZeYXwMOtwKsJ+=eY yJ|zzNt47&mFQ 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..25c6c244c13c9dc9aa7b81da709a4bfd9ee08a06 GIT binary patch literal 660 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%0DK` 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 Sn1A28eaC}o?y%anwEjQ7z=8h& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..4cea74c1851284e0f785a4349fe437306574e5a7 GIT binary patch literal 660 zcmbV~y$!-J5QU$A1Z6;?poo+d48R6ZFbD+$FoKa%FaQHF0%C!T5}utqa3X;suCRTV z^L_7GfpIfqfF*#N1$gY^VX%#-x=&@bJK$OYwyPGgWG`G&pET&^c|Qh64#H{n6jH$g z2bNmr?)4i?STmPS)T-&6H51W_CaHeav=L2%+gY*_t|2k!?v?a6*mW51sniK~9yh#Qpqr{89xUoYH1HR%PTD*lWwcNij~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K448.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K448.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..0707f3e46d178fd2c253b468ca1dbc6a14f83e0f GIT binary patch literal 26632 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 G$NvEpN2=-o literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4608.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4608.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d6e7641ee34834810abcc62c459ca9f920c8c3bb GIT binary patch literal 660 zcmbV~F%H5o3`M`w2-pgUfuT}6Z~$%q0|#N?AVKQD0XP`qLggp5QCbA5@Q~Q9?e`rO zQp`kv6@a?~==Syy?4#H8p`Pvl+-kse^)ja1l}D=60=qo>qjBWG3X7gfDw*KG%JRIu zeS?H8W35DEnu5=&sb$e?(&Sf7JJpmo=l({yLSoK68n-besY@uk?dEVLe!s;@xr6Qu vTq)O$xM$<0eb?48dEd*&zV8`nmhD@NxWTx8?%Ph>*DE(rO?ttoia+BE5d0y= literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4608.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K4608.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..55a138db2f497fdd4cab46f22bd7c545d4704ef3 GIT binary patch literal 36104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..db416b3191178e71bd1e01a37e97e6706b69282f GIT binary patch literal 660 zcma))F%H5o3`Kv^3dVxOz)-0fH~=?*frBt`kRWy702~Z)q4M3@RZ;{>1}AoHzi+E> z)yg?w3*hMiKBx0?ILa$bu3CQr9v$F^ZX+Rory27!!LFM1a@aCEm3eO^H4Ly}YjNJS zeS?d8`kIMgnqrbHT2zxpe`-3YrmQ+~cFJ`mrrfh}Ly}Bcl-&<&_y+%XaZ#?#k#(Wd xD%UT#SK~&hm^WEG@9k^exra1_&08(F(YRquGgCZoUpQ~A+(^Q>K_T&H`~cN)A&dY3 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K512.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K512.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c58a4085a5cc40d157eb5e6cf0ddaa235783955b GIT binary patch literal 36104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5184.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5184.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..23e8e4ed8708b9196940c12b143f418a6e03ff5e GIT binary patch literal 660 zcmbV~K@NgI3`KtnYT^b=Shyg8g$M8kvfv;tJjj@^@Bkjncp>NvZ5$@i5WARZOWXH5 z0hDctfCGRh1LDs1BAmU~&Y_-s0Uiy&V^jJR-{lB(T3}Z${oZ8c!ZM5AN-88F18d96 zo!d8%J4&pTXiZbOiK@ZPe%7SPubNJ(DQ=GaO1UJ&nA;h*HzlEqMD{T5zy*H4MX%gN xcLc7L%L(^tT)%HuS;y*qZ|T0D8DW;~ncC*NK|&f?k#Uj1w=fANT+O literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..78c066dcb3a8bc647283e478ed9e999d36e9fc10 GIT binary patch literal 32776 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2e39deb5edb6786a98749fd88cca99548bcce784 GIT binary patch literal 32776 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 QjoWwJo#qa!bz95-0VrC8`~Uy| literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5760.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5760.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..951456cf700d71c0ee16fec77afdf4a2281b26e3 GIT binary patch literal 660 zcmbV~u?@mN3`M`400l)rLWm+#QZN7;gn~gRC>Z0AQZN7mWF*8w!FOkiOC(T)i#yw~ z{k~5DWpg564dB6mxY3@3gZJtf>d6gouK@0=l~3_aj!>rscIDFVO-2qZv*@LyLJ~5t zw7lH8eFM3j#9E2kGz5&NG BA|?O; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ff1ab23931e2826b7631bb2396596a042f5032ac GIT binary patch literal 32776 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 P=k^`0|yCG2L?tC#1SekRGicnX(dpFhs1Vm zzwfA^EGGii03Hm8J6K0(f>#frp1cQc6~KM93MszI5$m+TE+_rLWaP*)i(X19Bq0M! z%ggQT8^~`Z)=Jc-smYUS@M$?{(&Sf7JJpmnr~XE{B*c_^Fz(%y#4ZxqZNC5)`27|~ z<&L@&aH(9LaL>jK`#yuBXtVddO!xiFh=Xk3Y{K=%{d3=T=Dtq3Uev@F465X3d;^nZ BB31wZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e401d9ab62c7593963924db1a170127f8208f094 GIT binary patch literal 32776 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 V<+Vtdf8V-&$9-w;u-dn^{Xa9%d9MHf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7974b11df5f663e37b818bab5c21a611621ba5fd GIT binary patch literal 660 zcmbV~K?=e!5Ji8IBJNah;iAwkJb*Va3lHMLgGA`U19&j;Li(qju}MKH4y2h$C-eTN zg$oPkfDM4V2bd1=a5zZT4y8W*5x6yge>H14@>f3kK5ekA;(ZB@EFxI-RMLtE99Y{q z_sZVEr5$VSL~ELQbanwqtPJ&4(_S?dH?v}^Tt{NgjmBMO&6Gvi9p%q*Ps%kP#S|8` wa%E7?JsVg2My@du(^>9i>Nk!9Bs0HZ;x`%hPru!dek*DazlrPfN%=Fr0oR2bdH?_b literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..dc9ced24abcc4f98ae7dc60ff53bec3d82244c45 GIT binary patch literal 25352 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..be203bdd9a6c041f84bad87c2dd9a28345781412 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6912.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K6912.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8f47a3626fd48f50b697e7bafe040dfe9f7656c9 GIT binary patch literal 660 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 BB1QlJ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..7712655920d320c5824f84cb9f6e421a4eec463b GIT binary patch literal 36616 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K768.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..ab0ad45d49ff1e3641674b7751aaef08bc102d90 GIT binary patch literal 660 zcmbV~!41MN3`M`w3XTPd1BXiOfdSY64h+J9Jt$HS48TAg0kKf|N$e^u0#*2s#IED_ ze^f}e5CPTz9uD9!##6BOr#hy(x&v^p0M}P5Uvf7tp-&rZ%X!}iM~))1?4_iF1r98& z&ONtpkY>wVJ5igaE@>v>Dp8YGziQg4rqS&r*(g^?Ou0wnj*SXsxBU{X!0)#>Dc5`? x$Z#x`>n7Z@aXa5OyxeTRmk+$H}=vDD&d;?PtAus>{ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K768.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5e449c44f60c7393437a52b08929fcc4ff1d0b06 GIT binary patch literal 36104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7f904f8cda3eefd10863303da6d272593f769912 GIT binary patch literal 660 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 Nu|LHQt8r7q{{iu1z6JmQ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..027e3f99d2cf4d878a13f00dd606c0287bc59c79 GIT binary patch literal 660 zcmbV~u?@m75Jmqv5tIRmf+A8S+ui3EypVf!xM z_x_y%$z~$J62Q#?yvFqqY{RXNq3&)ETr0qJ)gq+agea-Y;3%F z-95e2Gg|#&he{PYuHAX>>({Sezkc1*^E^8`;OXo1`HN5_ek|yLzxmk%`w$$bg7_OD z##0V|>u*%(>qmY3=f9i&{2xCb`EmB|oOfQH`KeZOq70be-0$t*9T*7o1$qv;`rSTK zGOecqdu2Hh&I9hjpfBhP__36q7E~DI^Y`glu0|Q|d!U0dO$qdD=E`{TRWIdOyUb2r z2Gc?}MOx&7HS$?|>X7CBN-oIM3dsCLS&p^K`k~jc3Q@v{k)|EHcC!+Ej>=6&Q6jgi zy{0va$i%DoEIZ)PofO<`r)Sm*u6&9@*X0}Q{pc=)Ca;S&tVD32f zqJiZ0d0oDKcaI!aSW_1M(jIscZ^(N;Ya|1qC*gz7{J|zU9&{5o+`P=S(w8P8U*mDF ztKR`FAan$5u>bXm$SUZNUI!CR+!gf==7mpoVlnyw-lE}=hBtFO)`>p}x(J$;=P*L; z=tdoyOhkLobZR2BMgNr_i3%W?z8wa^+WA$Qwfk~f<*M+pH+3j{S7hwBvuR_qU#E>d za5ZhL_EMU48a@{;r&;%1!BRP|gVZw-O#Lgg@DiquoziMgsU4KYJ$Qm}7tznb-9wD6bHt5j9q`0Ta5Wesyzd3pF-CQ)uOl!JGmWr(q;uo({ zyREDLEQ3-~SZ|VQzf6=SXA>y`{oIRtI96URSaXnIbrXdkEs@D$jM{eR7O3DuxPku_(olicog@bOd%200%iTlhIJVF?^(V#hPjvms zzFS^@zV-N7v^TWZT>MbWRVycnpQMdP>d{0r{%O5yUwLTk7*(-T*JS9Jfk?HMJ&f0% zQ+g6V)|7oPCo6C7w%&rSErMWtzG3{(^>?B52kTxef?6|@Qs21>annqqhs4m)jVy-9 z`ct4&#m^UO^1tot*P^|^5rA!_v16qcXTOxR5w2jBx8o}qo&hspIgX#>Zr!Pd|I6!F zU&2B$biojfp|L-$yK$lTkxqUo?_wrKBDY_OtTiV^*a~e;JQ>{|j8*-!FeaE+jb*@j zy>Zpp&9yjM_aZZ$8#+`P*26XO+yhq=&&__FDEZ;@`IW?TwU-j5eOD5t3zrk6Zup%4 zDpBf$&-A54tA$=`u?FjSq`Dzg+h{q1o#vMW4KcZO{5XZ`$2n$-{cLf9MPeOr<) z{J_A`X=d<&@naDf6y6;TRN0x{*`ZJ3ZvRmP^20mHv$sS9{x&cPl68QHlG*R$)F*2uYM+QJn z{{5r{kGm!Cx&<|4{HJ-NNeaEawjpF+xgUKgR*JQS<|Jo<2_4EaJ?i}zM?$7~f2qkk z0X>7mepVcN(qtHW)?{oA6%D*UKK4`sY7IR!I|bh-KRf~7+wOS}wT@QpY)AinXkhq^ zt~FHFwiCY1KYkgt-jO;q1*>|+ZJ?{|1W?CsgPr@#dpPp40-su@+Of4apuB?FGrEa_ z$}D7F{~@mZ#0RgS){N@lStzeOi7w>teg!D!G2N-$5@;`UYE?V5TK)6)U=LQA-S>OT zNW1PAdCp@6Z{{@R?*2K*rrZEN_y=sK`A5)lUS<8?ozJm@HMl)<%BnVuSzkJtX@{2c zoH_X)ZBCZ5OVx&zM(avqN1=%3LOStH(DA(TaFi?hS4%#zD^n~ zTMO+xtQ1Wd>=cUkZvnpZ!z4$*X z^ET>%^PJ; zY_aEh^bMBA&>IP!um~lkx*oG=t<9+1kiWUG-kE+pvo=&;QFPw9@=a@P=m!rguQ=VWabjN34w*AzY{5YZ^zlJde4i?1qdj&ldn?%5E4f$9@S-u7UM9 z@ANY-P85(nK6A4iPr$J`s6)-;E7rhw);r*dX0S!d*lP8Fz52ZOMQJ=C$#eJ-tN!>| zQFY?-|h`o<62)dRg>9Z}k_ZI;6u1DcE!RUZ5WW8oZ{z@Lq>B z3N-Xyf8k7rK}=bzKlO5l$9Nq0vtj92LMryUzV~d{llq)R-}FjY`U_L4Gy*vISbuyf zY!IE#>W`cVd%)NF-uK6)pCqiPbR(ftXE}amTzVp5h4i3lg%pPKqox)2=`xYyNWvzQ zAk|)!*DKm*Sc4o1(KSf27*V!>K7KdCuR%*%eAiD(|a*T&LG122Mt-W@Y__TD4a= z&z`$_MZG>xN2>We0d5cTEKk6AmM365%M&mjiFIHhJ*d7Kggr_=M4y^RpQw2=$FI_n zu^`Ik<{xU~`G4Y(Flq^|G-wCxpOSK@+>KG;`xVo{vn=! zi02>T`Ge}57G{YCuu7v!1$@9^(0Xg+}D6D)E*fblF}z<8D~z&!u%2mUt~ z_+1d}mlOv4n~Is8SR7$m;AoMf?Hujk=r)e-;OGI44s-MfM~`##367rR=qZk#=I9xj z#?OS{-z_i4GYW0zXa`5PadZbq4{&stqenP;oTE>0^dv`5ar87t&v3NEp^Mtz z#?cOlVH~%3-nDVD?SQdY@S12{2l!0Em9a&-tSBx3jSsBT0X8V|imyb@20KTKoV=a0 zU*y`gb7LrScG|hv6}f)dxqcxI7gV^?UxCwuxON4u-7vg{hxKbjekBj??>L8_;P6Qf zpW^Uo4xiz0#Q8+vXvFzP;QWI)Jp!jk1yN3Sn>`kk6orZK0Rd2i6tMV@+w)({KvD#f>`q7RGtPoR}19V$CB@$^6b?V z(HdY+Ml5-e%ERk})W>wS(S*m{2-ie>khMgnu`#$TmF3UjI)Sf^_+Vw}z+)%kdIDFr zN{1!z`;C~tVXiI9-$Z^H{wDIIP5x_se-n9XBv)a6e-rs-_?yTt;BP30gZi7&%%`dB zc}e1Lby+%;DgIW<=K8y4nf@m7%kVdm=R8Nr`Tb4gb=nH^`G z)&WoBo35R>3_tsd4_1~Ayy9=AY_7j|F4Nycei{BI^29d&Ykq$ddE5=vF~7fw{4)Ga z~BAC(HeTHwj`v5x-H;jMl;jRv?7mUxbgE zh~vRk&|rd&$~zE~-$Dg6-;PL)N*)3ZNUciV0l&5<_T>EvG|!c9h}5g) zng0A=#ngX$q){awX8Ii;gMK4QgTCUQsNi5_hQPoMp{(z<4itvUrhNOk?kt^NhUAc8&h6u z|1^_Ne=MfF)_#;A`_pnXro7gEk;!M>5>sAlzsT&#N(TA4hjzR~77v!>CB?%ui?{U8 zV#;gdZJNci@Y!5r0MW+tIMZMMR!sfc`7+M**S`hY7N3tDOn=o2pnvZApq=j>On=1- zpntBsc0Cc9{*uRH>esGU9c(?!-4@e7wUIhie1@5P-uGh4*GC#u^5aZCe_u@b#>nj| z`AH^kzc;45c72{^@+FVOl-JsiqW(M@Q(kMo$mFYTi7BtOUu5>!lR?GOuZwn>#sNq6;K1X_L#~;cvMS&$a#@9@tR8sWDz4|yl(hhlTf}8enzG%%r^;n* znzB^j@m(;kXV#RZ1HV!(6EtO6z~{(i7EM_$@bGdKqEpnAakyh1Tm(Goe@;Ff@Mym{ z+yZ#iZycTl_-eV`CJuMZ7&!aMc9z&y0(g=vpZkS^3xF&772FJX1Abf&#}$>Q^zRL* zRJS&b%-5M>uJ6TB-&O#w_*}u809Smg;AX%T-zs>?Ja{_biVqce3*d?m6-mE8CG zFBIH3Q^(m^7q!0$a3wYr+zhy4zk)mF!P5a(>{R5l09Wi(aO2D_uH9Wxd(40<{!#FB zz!m)zCu`>npmueW-=?(K_-wmlU4<22$baGl`hzkNUPf zgw;W?;p26BLLKn#Z!F8?@wr#V2HI40KV#qr<1n-~UYAY@><$d}V+PnRZ^-BIQU+L0U@*!6yWczL_x6c?cfWV5t+l1O-Br`vU=#b?{+?lY zefUp-t=__IvQF z^WA*_*~FpYPO7ZXcB@L4d$32gAus^F^V&prSJ$9-XlUoKyU*9{^A3{wL^G)I-3tcU z4^-I1KzH|$H;5TK=*d~BM zOEbaK>mC$unb!dSycR$wu?0nn1tq)_3Kw$%NGnb#E?U3|odM7_cNAn76e|X(MxhWI zSegq$0bker9_S1}L-V!{jl>*)!n*6#IyiXV)=TGUz39629lSel>t*w`e%<;G-I%xa z@_AY>zNWt8aCiGXUTz)2%MiClRNYD!7q)6t-Ks2PRktc@T-B}0@&`0q7TNlbUzQI~ zY9+D1Yrs~#Etr5NmwP?H?>c9?@!7yBz-cme!1X(N;5zKk{+$ne`Mh5Gu9qHcE9}O| z5&e4~Q7iG)9`5VE;ok+>Th~(CyxrB>+}^&U-Bn++yT-L^cTM~5`)os=UT?qKC13h% zTkf;U*{dI7iF?$5XNdfi=Kkh;&->hAG*06swfWDf}L z^7Z)L!Qnw~i`U;1#8tZG0}7qqgSCAD&wdVNrSbE3%L5P%d;Gq;hrP}95Do5fcUif& z%x#wsDBbPr_wEY1`v;)7u)LzItfJJuxfBW-y(GTc1O2=R4$?d577i-hH4KW13h=40 z6!vrZwpP61!SS1KYxW1dgWYbAch4TuIBRsiGgN7lw|jTgZodPx0J7K9SL^f38oJyS z<=$?u-RtQr^LjShHC~IwKb=AXP6(Soe5+b);0p?!Np3$)emlJ6K`%-|M}Aj&NT2S)Ea$l&5z4_sL@>i$5`MIr~6;X57> z)@}f7_b)P9<)AsXGscvEVbTFclF{|UNsJiu%Ypae|n10tcZk;;k8&}7} zwVc)$8U3OKhQCZT{F|}cxZ&>^3=9uM2YGG~6w<{n9tC&?&xyfrISMp0AU^;8-^@R5 f4+8UxyE>MYbuV}=qVw-Nx9_+=#vN9}_WJ(?c5-0} literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K960.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_1col/gemm_bf16_K960.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..a939cbed3c6714e0b10a56904cea0c4a1c6a7272 GIT binary patch literal 660 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 Xc~oDE#QFD)+jrcT;SQ@~Tl@b5?md6h literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1024.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7dd5a285e96f17d6e31db2040c8471a422075a22 GIT binary patch literal 1304 zcma)*L2kk@5Jmqu26cf%7hSMGBC0q5Hy{fR(gpXxm9pqDy6AyWFGRp zjPI0st;SW-gBj1dOaz@ N{@P3uF~1eD`~c*dM#}&I literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1024.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5492583229740978e09198a76eeeb1173814b462 GIT binary patch literal 64392 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 X!QG3FMcn@`xOvAN8CF;w+uHvRX?eG3 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..64919bdc4845bed4a936696ac4267652dee566f3 GIT binary patch literal 1304 zcmbW0J&wXK6oki)L0hcE78DdnSSt>&Hy}k0Lcu)@#F({H5KmGJE8nk^Q@&SDS=qW368~>k96TTo3eg zE9ZKy%-mhM3<5Qnxew-QCUc)UwoezMf3h;sh{JLQIzP>vCs)p( zO#;=K+bfru%QT{zWG-@NvYz}Nmn2tbt}Fc}ji^PxGg%+GZ~8q|`eoL8=_dZQp(|rz I-m=>K0_^le{{R30 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..82482b6f34286f98cc67a53d2fa712070edabed4 GIT binary patch literal 64136 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 W-eu<^?thovy5pWKPgq?ycm5wQ7psW? literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2dfe888ee3d43bb1863f763f1bdd901df33000be GIT binary patch literal 1304 zcmbW0y=}uV5QQHp+DH+=DN?vFU?K1T*+42>WQ-Kv!wR4xWkyJmK{A4og`DH*9!L>N zKv;#OvUZlp5t3Pm3H@M;JpL0mw0c4x(-ah(uzZcpw@ zwpiMd?=W6B@O%9KEsn;ekC}=TJLCF-`$}%~I|Od4_IoP*CJoi1-=^RWDrpmNT&V zdFEPjM+(j;Yyk~~I|mV`i%f=mJk zMZ!`%wqQ@|BfdB=VlqPoeGz5O{?Yp;c-|oKMd&1ov4~`uUN9ssg9?N>*Pi&7KC2&0X zOZrKOpgBc9m0JwFdgwhbd}8bRAHCT1#{B>IZf!Ua%G6wALU0K~X}#b-AR@ zWpW1wTKaU32EIYRH3yvh0B7#@@^4Wub?aHqT9r>~{nOA#$yL!tl~@S1_21yHz23d? z$%jS`{ou@VvxL~7gpg_`K}Z99)8j7_-!JEge|ER`_p1(-XwAk&?0gd=PvZC;&p$)! z(|ZbVARHPDj|WE41gOlWj!xpwdUjVOYr#j_AC?o7oOU|Q8NIu)%u4ad(ezt%(6qJR z2Q?6K2JCq2&*#${p+SlTMud7mub0w}*Y+#457-~j&J3Dl&~`*qo%FBBk|xiwkxH!} zP;Rjh&l+-wES8plANjvsPim7KByJ{Th*GYR-YRlveCw(|-t45*S)kHa z0d@WikSo1o`2WhFri9h*N)+4anLhxF`^iIH)*-tu(RumD)x>r7QkkpsQW>?>PtqkW zso|@fnNn zNn)q|sVY1A$ssaZ(|*f$)Jw(vFfr&qSKa4zOB8MVXeCG|?|X&y5!VlqXGjT)w1>zhM+p(}y$ZH!MdXYl zu?1Ea81WC&P!2PdMtX?#dBt+j=r4gaaZ?Zde5R>{t|buH+dNHAfA^af`b{R*Rnxex z$M=|X`#USXN6hP!u>Xv{I<3ygp;~Z^k_j246LhQ_mjiqjHl=63jvGWM!v4w z&wCvDe1&V%(y>q5FgwsJL`IwcBd{^1gTVP~t9lrezvf6Q8jD0@p`Ob#!GQ`-2 z{Xz1LGJl1a?r%)-{_Tu^|AjY7a?Jr+E3~pi8~@I4^ZiZLhvfLbG5fM>jQ<-I|1;)5 z%BIhO*_w`J_c{K~OKg8`A!nx3_gqPDwV%H#B802tC4I*`+x$nmlh2wdsF z)ec;TB-U6Gk6!(8!urrzYa&4sFI_HE?7+Wu&D<0Bzj@znMrwrDdqI7OP}$)eACz~TYm0L`)B^v>5qF|@V6QMD&encwy5%Em|xE5FDuEJ z?VqS8_I3M+6*w>bL()lC9%uA6b^5#l|k&VI7kI{Ud|TVK2`_LI5Ur;A8m{P9Z*@cGiu=Hc_+ zhh8OpGtK)4$bX-VO}%32i|_2;51;nG{tD^4zx3Dwtg3T+L0A7gAV(wYCR4A{$Xglx zm2+W$T6;6`Y`^r1<;?b`N@CykGkW$@Km97{tJphv4$7NeA{S~7eicy9Da+aF2BXifoF1@z-P3bw`-@w;st3$SnxAfQ?6-8xY_qSkcFgQuvyODceScSD?W<^PtR42p zp8#KXIy>TfPH!h2GdsgI7XQr7tx(Tr6;I8{b8~(1hP~eEzW57!>TUkGZ!?_zv28{E z_`Owq@wM-(d)*)ZQDu{->7FnB?*`AE3e@O?y)_*EirTIInYu0hiu$VH7Xp=?70tHb zssG&ES+Uz1w0+*$Ia5!1Hib98u=A-s-s+&z;p~jRP!vq4P_n}^YFAyY6-~F-?5=I^ zDL=ibHQwG>_j=EU7hSFKPc_!R*t53R)fw+yv#lsN?b*~B|G1@R=0*Db$!)ftPxk_{ z@2j>3i+>1OpRn~j^-))6#je}8TRP$&dAXYS<4IS?%fPM)!1~Rd zGkd;BsjjMyialT44yd@QV`dliOFX$5;)&!@6pB+P-0E8knXwlo8hza zhv12Bu*F|-w<`$tDxROH{<)$x!6!cIQcj;!{htL4?N*Mws`@_-7+Rnlc}2CVFQ2k> zeMJpIYn2NNL;fd<)=|$XM*u$#7`&!jcy-7>0~lJbTzF;3s;=9roc+pB&~_T=a|!>c zqEhO0<;b~2u=MjzrR%E+|6dfB`lo>pK2}aIB&=%B=aeVs6G8B`a^xp-{x1}*Zwe5{ zw=K@ougv+MDq8P;gH9K-ct>f!(?+Ts zqxxU=DkS+B&sYEr`->#gKtDwO;{0O{yURgtg1w0Y zxT>{r_UaYL4P7boUuxb8`4y+#L1HhZU3Me>TFCjkFznOFpet=F?<8jrdoP59ASMrPnM} zi`Y{c8N?M_b!EwB%6yv4rxl*>ey5FZzTO%6`qi<2X-;8D?pWs2WIj#*|AFiH|2)^o zC&+x7%%|~~ca8t=MB|A5f9Ja;pM0a@zs#q}e45Os$$T1(wKAV3^J&*NpT_fBB0uKT z@>_xy`7c3>{Fk7KTAz_mtIf!#nQ8KxnYJT(`FvWP%%{nGn#`xM|7%&A&s+W%fqCQ@ zm*x}X@6+V()3nI4{PQ^8rQ`ob{eOzgr^$Sp z%%{nG8jZCwpCj-9Kug z;r>w*4fl`g^z!+%0s3SZ`TR8b{Is|I{5QULeJ5l~cPYTKdX8V1n%%{ocr^)B1$>*oZ=cmc%r@f1w zpT_c8B0mPtPczXX|0T*r{!7sC{IraGT8o|^R`Bbh4d$oG)3=@QeDRICo|5@AnNO4XG?`D6 z`LyMC39BCYWj;;5k3hbUK)#PazK=k@j{p)zu;2e9cpm}JXNmk6JU=ZXpJt{-{!7Ti z^V2f&X|;NOjOWwLG~7RGDu??=b$a=HTAj?N$$Xm3r^$Spyx%j&`*-Q}(8}KtxawC` zGM^^j?hQ@-C*zTZ>6-&4Nd^AGX;o;;r= z@?-G)w2XY3nHKpkArH?_%gCqQs^`aeKFv(S{iCLGxPMfqm(QoUWj;;j(_}tP=F?<8 zP3F`1EU0VA@|MOtev2vJ?gi{*k z?Q6?uAE!l|NU8<3&%i3;dlB{_+>h`O!ZCys2u~wChwwbYNrV>=UPL&hVcx#_jP`Nb zXkRUApMlksfxQU(5bj5K2;msQ352H+o(lBq|Z5i$3w9&p>QTq(6 zrVQ*w*oSaG!b1qh5KbUGjqn`8^9UyqUO;#e;gp88`KRZkF>SPOKZRoc=~zt}d@sU2 zg!>U5LO6zS0^w=i#Cx|i{2&&!YaaEgnbD2BRqs~ z4B-UA(+JNYJdbb^;RS>j5l(5Cx34~OIEHWn;c0~D z5S~XkiSPo#iwLJQ%-eTcM*BEzwC`5bJ_D;M1A7tnA>5Df5W+Ep69`WuJcsZ+!byY| z5MD$$h47HiqT3%s*avF}4J>pG>_=;h4`P$SH)1HrGe2qax=xTse522OsIGp5eGuCX z{VjTI^Fhoo_(p6?l1iPw0GL)xZ2&!}-WFsJ-y?84jXnZBx;*I7~d#DOqD^*T_!1o^>%{E$HXIF0&o4)Ny^AMDiq0CwvBA;|w=r_Klc zx;*ID`Ji9tgMOV)P`wURuZs9y#P=b7KjIG|ehl%!Z+czeHywlDbbG*Wh;Pgz@SDL$ z_Jf@|AMDiifSo!Y?9};Sr_KjEbw1e1_#64qXSm2>XWwK2Y_cubIAMG)?zL^mChz0& zYQR&vAL~Ky((!Z_6e>#N}b*Z$7}Difr;KmoG9) z6SBD1R!rxh4X!!p!PW{5Q)6gZsrdhPxXz&09`q1p#>((@dsY@>xr5MuZn`nn*0 zGx-Ai&E#2~_#?N!nLIZVosiq#OuhhrGx=rw4drlfe{(E+S}N`rV*WOll|z}~Z=-Cf zzgr6QHFvkX7ZNI6LR~T$rs>nCcliop&SnGZ;mZM^YP7NFfF6^e$hje zl>=?~+bCP=@BIb(o5>g8Zzj)d!ymc*&E#n_Oh;~iGx-Ai&E%KyHtQ^V=e;Z{>{e3G0t%Bk=l`p{GOuxx@l*sLGCSQQRnS25MX7bDU8_MC}{^r>5 zxAy)?=5KQu#Bas$w^6p#->}y!$lpx90Dm)i+62>)+uuyS0Dm+20{qS7m+?20!@>Q{ zvEgsNN9OUwTn6zQ`P(R4>hG2U{mtYH@Hdk;`I-{B{mtYH@Hdk$z~4-M8Gl1L9Nga= z8~*0kTHN2}GKk;E-$vO|fA25Q-%P#$e=~X71k;h*-%P#$e>3?4{LSQ-@i&yi!Trs# z;ctEo#rcyA0h8~e^&X-_%kQuYwpM@pQ&FJ@}9LIztnyj59zf^Lov)lIB4wk zYM45dUBd$ngNeuNjIw5+omyFAMp--1^j#@br!S+d6lhu_i}e|0vdDcTmmrfH+my`l8A2;iqSOX7(?! zYWnkEU%3AK*B4Db@AZYtlV>t4=Va!5ObGk)UthTX{MQ#Qpa1%z*$;k&QAO9^YpgF^ zKL7Pavwu%k{h9H3$fosg{_6|Zpa1&8i;b3i>9B($7Rb$tZ*MMM3L}={#6p6tupW%3ys_(E4I3gY`v0>x-!j))xh> zFQzhBUliI(ZGAD7!TO@0^~F>M>x-gl=fV17D)W-fP(l)Poh258fe&>tz6bGrzz4rE zz76qffDalN-;Ve;;FoHAFXG#Qzd_?SB7Q0G*K7O+#CHI{Oyf5remU?R8sCTb)xd|| zWcHLIzAbed-4igr^WtrK+Z%K6eZbfKfaLAKhl@<6ryTLSa`5|e@SVWd{fYFH17B|! z;#UH{LaX-y#8-iTlg95td|Rp>wYMI%x1R2CnEmQSgWmx1Mtcpu9r)#%d_R(R0^g|D zkXM0!vnJn*c{wAYY72>gwjd^?hFPFazkp+|)b@YiU#`l7*i0N?PN!7m5CVUNML z1HXelE{=|Wu7~5_Sji5{)-tyLOtm2&w&^xBC=dSLD=#vG~F+uI0y!w&}E1AN1NgWsHk4>2LDd^Pa(ez|Dqfmore)BIV3 z_?5ud`yKHih9JKgddh)s_{ZRTQ&wb;Rc~(t@C`p0{A%DEb{c$$2?~k{R8Nw{hu>Hg z6cdmS+w{7+Qf*oJ5ED?_4S65%^|^M@;5&hDj2VLuF#+|p!H1ZD#_9px9uM&KIe5|F zL#)WkhggB?7x`^mv|s5%qiA z9x6i*`t8wpUie<=p^kp{U;pg=_w;@9<*&cxUh_9S{bvbT0Hw5^##PYYy!ZI{m>LgF z91BMyce`u1d);a%5{wRqBcpe_rzS`4Y;^B^-`eKbMD%DVIQhP{s@fbI3rvngC&noO z&w|ii)rMttejs+s4Q-M+71>Nf8i5P(4 z*pypnVTwb?Cqt3p(D0qZfysah#e-bgV0id$xA*vNZ>?J$nTiA_!Suiwu-xjgsl!}Z zt@|#MuE4~oW-x>H37b|n*avoXF~8uU_!kk zrvZ_i7CE~p9|vA@NjMq z9F9UoIctYXvUWgi+iKMg4$fKojvTeutyTZY8P`At5uq(7P;MEQ&Js2Jj9heM^$Dp`&SL4o|4fPGXcR)dBh>fp-=r|UkgY`YeDi@XJ`i4{bwe8;ht^4i= zEx>soIMy1DXd3Ev1nU|P*N%9HgP~wUL*q!pVQ(nZ;H|5zZ`e`4lUm&#Iy^NBXV9}@ z3LS%uBy8CRjj7ZVjtoQLPLSOP8%2QQq49&!Sad8pdSY-q5QYN2?Sdlj@wyOg3f*=w zaz`UjvA~J3XaKapJPwTyPHHDJdN3HBicEqmouuP~w481!-FrR&!h>|X0%d(2eS_@~ zJ($SUu@E(gMS?-P6XX~?onuOp>+h!RnUlb zjVk{1kw=zuYdvkY=GRzYVlvFU4_=J`AGx)@o;p%@YjF2Sjs;Fcr=V}Cmqj=8ZiB+5z1-bD*neQKr(>0PaVw(ObJfa}H+=o4nc( z1W7dPgV9KY&a8NN@`TwRbY4;K@bW0kLm2pQMKlQ0E_57>)E&mXsq@)T*Jg{(tYu>w zpI*=O>z$!XW<8y*qUPEgR(3j#Fyn)7yLRrJw|zS8u0m?RM(@|7BfE5Y+PECr1ID!Ar*A4ITv67(CRo`e|Xuoh|j-2x_!qZ LS+1};_O<^%?IlOB literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..4ca1d83afdc6353217877b9951de185aeb378598 GIT binary patch literal 1304 zcmbW0O>V+46oki)DJ&|{MHeiPuqqDF8^D5P?@$)pgH+0*N9d9T2jK{)7lLQ!jqF%y zWsyaa=b!oB#1ok2$r|7dz+wW(Ykyr0-ou;kOTF78@Vx=-ZSxX_?3di)I$gkrll|ec z9MEUO`d3MF8CU^Jj?2?=4yIj5tt;W#(@(Zo5T6#END%dBPiyUIusbVWm1~5UbGPJv zWQ(OO`3~J}4!gqt-(sg+`WUE4u~e=txO;Mg-;3k6YQKllZ_RY OiGOYA%9xn9tTuN^d`Dpb literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1216.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1216.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e65df9b33d0523e9f0b6747d65523fc4a469f3e6 GIT binary patch literal 65416 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..4e350c1cbadb5dd12a94a9ebc867d6d9b013a0ca GIT binary patch literal 1304 zcmbW0&27R!5QX2YO~fG*Ipn|r2`i!iI=}}C$$>uNNE}i|4k?5ZP#S{S@jQFIa-tP0 zvHvsQJoXtY0IU~)PWyHh?BlHIm)?gD;OhW{+ujQdV*Oy3Pr#d=S<-Z6(IquwgxcH};&_gtvA&bZ&?HmO_` zd+x`%Gy>()b4&Va#&gepw#Yn(s|53Re1leheJg&0TH_gHV>?+v-@wnOo@>a}H%LN? zJ-2f%J(uLL0@QQHo$>mp_hMILSFHD#>m74gGU}c2de41O@2OBPz20dx_SMF!MC|iQ G)^Z1zPecy@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..226a1e464f746784be8190d798c372296feae7c4 GIT binary patch literal 41736 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 PxVq#1EKgV+d)xm9e9RbF literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1280.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1280.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b92cbd029c2b85e6d9f7d5af384a9ae58e03b804 GIT binary patch literal 1304 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 Y@W7r$$0F{37u~$$jx;N*_U&!|2XtGtuK)l5 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1344.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1344.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..4fdae56fef3d10fdc0e8094b37a98f67b2f0187f GIT binary patch literal 1304 zcmbVLv2DXJ5WJ`4I7I-bNa4bOg}?)31FP@|86buChytj{7Iu*$;~1VGn>bJM&!Pw= zAk2c~Kc9Dh;t5jSIRTylEN6gj<2VUk{H}?i&F&re+yd^hee@~!p;M@{0xq@Q_roz^ zYsL6%Obbn{ffe(*);xoBOO34(4SV`dik0Hv&?^L~{_JUEJ&kTB!ISZdGN!yOd0&%a zZA-sHe_6n-@&C8j883B=P&8N>ugiGf$m{jC`Z#eE>)q#i2aJG3y;a8Bk@rTueWBhu z<2{nM0lKKw&&8hmGF}>i81&pdeKp~^2RoZ(p2JC8@V9@1BazEJSL=N*;yMP5kkU7> z^Red|^6DG3*UROe+ZZoBmtX`m^<3bc@cN+lXHMo~&+T%(14h82-U+Wq-W&Dq3-!|L QopuxcTHlpO@LLkgFT#>Z!vFvP literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9b32c886746ec0803fd825fb30785cb3809bddba GIT binary patch literal 57736 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 Re}8uSjz_axVYTmQ`#*bIISv2- literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e44e05f1a1720845c91cca93fcdf4caca9cc12d1 GIT binary patch literal 1304 zcmbVLK~BRk5F9%x>H(=7IP_4d5$Xf@L38LMICAJe2vQC_g98uX2k?Z750$aA(>PW@ zR(-I&>-Ee|Jb|ljyaOHptQP>c!#FuShFvp+Hv1RgZ4dbK{w}2aE2mgz1zKv}55p^A zYo++dm{v?|fsOK9Yn{P$YsOZIMm>Ed#iaQ1=m{aJKYQ9)Pm|k8aBsYhj45v`-lwFP zZSgzw=N0@G|9^{v@k+-8g~7&nea8DN-k`VR;|!x%?=jaqVnihAtuo$DyjSY&3-#6+ z@4I*#${nr2{tj>OE#z{~)w~}>T*inIQ+xwE zpL(tlFW;cOTrT(A&Uody1S6u+bCGw(>!aRwDdu9&9df-RM#Pfd8Ltn#SL!_$>Xp|! Qb`$^F(3Nx1Z%OQa0hpgj^#A|> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..727c9bd050d7e0f27b42a424e00af8c8f6d473ae GIT binary patch literal 51976 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 EAGnwDxc~qF literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1472.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1472.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2ff8741e201f7e603b6cbd38f47d224eb61b7a5e GIT binary patch literal 1304 zcmbVLF>V4e5FGCv5k(|Yq@Y0J6!C!k01BRwA_f28kgmuxDDsGuc>>A@lAn;Zy~Fve z16jDRz3cVN&Up^5dJqS^0GLkz-Ntcpc=fv`hBnI{_*esSUO)Mi9CQkGR=}m!`+f)$ zwpNUPjA^EcC9q&#*P3T=?ObE4M8lrGl47O!6?6(gs;fP%tf#^4BzQJnr;I7@hP-b{ zv9_h(p*znYOWghzTjQmU0g46-$S-X0?$QE!#;w&cB2Z&#?d z&UlaHZGbjv^>eZ3K8=?~AO<}*rLRUj_h@I6%yT$73I6tP@JHlw&((V0i@1y)Bc${V z?0o3ChP?U)o6F^L&#jD?o=Y$SntCqqj(EM-dz_NF*mK)lZ;uhMsCUHck@rr$yF$J6 RdaK=pzt(r?3d-PSJNl z1kXA8u3awa`J=90@{yiZ%dYPDi-K=l*RtY2{xsckks&CA&yn!Ru4pVe9NlwA??`Zn zl}u|~;TA(rhtF7WbZlsBC>o(!5nfPh=bx|tihmlXaR$Bne$AQo0{-blWtcoL!#Po} z@DuA$ddkr2GzwOxD;T_fo)dp#@GG+Deb>+v^@?_AHgSSUIH;ukrk-7*gnpWONmI)7 zdUiH;nG%EeF8wqBIQVfc+~VV(qFxH?X)cd%7D0~8fvX-rM(d;X z?ES(f4TNn` znp`nlv}swQ?MWL+#whjGq>Us_U-Ue6q1basbAsgM z7ocp4mK8n=)RGiXgFgj7%P4i~DUem9Zg00I&i%=@SKj!`b)<*+^TtI_+wY3Gx1Qyn zETz(akQ;CmwMHO6%N7JJAWbj<*Wl1Mu?rf6HtIu7Y@x zO>aL7bNH&|YoYrM`@__JVWFru#Ok$?z=@N=X^!)}r0@}z98qbt5$;#o~xox(vWm^f)&o&@icqZfHh zfyDc8#`w&JjK=H)ys07)*>v=1B=E$AqJaN`j5HSAEY@h0_+Kjyl=_VL{&zaM*^28) zzE%t~$)OiuPC0yWH#v4g5gqSU?0rKKIS7ik5yGOJ#(5yVv<%84EYgj-Jj+F-pSeJB zkbe;Qg=cPlt!Ot{@iA)g*p?!K#@HupmmmG;?JgGoZXW-uyf$M#VKHH`hVeBbU(9hh z@{Ndu^I7CSmND}0E9g%Cz(o>2xX5EaFtNoGD6L&{(u{uEin${{5P40a4f7gAyzRR0 z+34qwUR_uYpNrfLYzBCG)om+vHotvf;vf2^x%_D~KXd;tWBtQteAYuI+7z!0JtSrz z)I;+b`+-+zAILF9eLjz|Z!hx40DBhywrj}z`ky`SH4*m-8m}Vi-)XeNdB!SEF&8U1 z9iPVtiztY78tD*ct|G!>!-)5jIw5s%4Ff9;L^>bqI2zyU_@0ITdlun<9K?5ed-IKP zigM=o=JVGFH@><5v-;-)5#Q_Izxa+h-uL+ac3$!Q`Bm?H{a#UKkfS&UuYHh{cm-Y& znwNOHnC1}{KwjeF&l2|APumj-k~sBxvE~H%6$>U0-TcN)Yss0mH&`nJ+5&QXRcS{b zyt_MyR=>U2|JaP%zbJLG{ORSx&#ZpYoeE5R)g6fYJn&ixuQGV8I$BV68LXe~=zo=w zlN&x;4cV0&i5(=T{w3+ASI+L}<8IPg`m*!t!a)4TYg*&JrMHsb>GgV3rE@{YhC*_% zyzu_;kNgEIoVRW)44;IS!Qp#OKl-^s`_V5KI=bRjvF9g`K3G7y;`d#cg7;G|oPhTm zZhw|^O*HJ-Nq%!MHvWvQE550F2fRD~_UokU=EeJ`$VpdX3*?)+PXINu1#UxTo+T&C zJIbQJbWiQ1-d;w^H(Yqec5*{~8F8+Efu8-q&%a5!O1F(Y2j%sr$hnGL-vp}TA=~M7 zHBevt^s=2$>$Yz_Ydcw9ziRkZ_mQ2p@052uwBgCs?dx`Z3v?G<1{nM+_0#!9sJXnp z<)6>4_JKFFKIfuk-BjlJr&B9@P;+_5>WZJQcI~jWPONt>vbRobTd;_<#{K_TVecxf zt*smg#18@1ZSK~1-6I=F>%^v^3R_@e(;BGfOImrw!RIEs;x*fR>$>7k)KxnIasNs< z`~LL>f%pxpy5bA3t2!Hq|Fo>Wy#D&f{%>jdH5%0DhFe280;QE}0uxoM1EtlgLSG4% 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 Ee+zACb^rhX literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1536.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1536.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..97676fc97d1441ccd25328b5d05572f77dc44784 GIT binary patch literal 1304 zcmbVLv2DXJ5Ij<{kpKalB83YB76K2D4eY{$sPG6yIgCJWt?KO1+NA178cq z-_Ep>gDtS(xvVAc5Sq2bo{5S*bxE@J6443-sebKg=RJ+8lijZ?PXHdAjo z;r%3U1vF$8z2{8NeK{|UKn!~BfxepY+>_reCZ5A3MDus24G}5-4N9rk%G($)>`30g z@5i32$Xf%4TXFUq?3|aLOE3&gJZHQ!UQhHsk~!OR$2+|PhG9|fjMsbK`hR*)nR@B< QM!K=TR=Wzp{FcPw2hyrYTL1t6 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c8d202895513cd5f895bfccd8fbd322211bb8ae5 GIT binary patch literal 64392 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 Ti@5(?aO;jcGCW~*?dbeJN;tM` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1728.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1728.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..edf03be9fdb48db3b0257cf5b7d6537a1d9617b2 GIT binary patch literal 1304 zcmbW0y=}uV5QX1SvJnIUoFat_1116wkPYm@d&Gsy>|g~@;W1KVkc?oY$~MlCx(8B( z5)f7)>G<=$d*TzMnL7cV0W4>Lz7E$#@DkqqP}<#{fb$k`*X?5%a_@SJ>udoZt?mz( z38U_3%E7@{}y}W(#J?ei0{C>^3t=jLg^qVxI7X3B_ww%7L^;}Ptnfo*@gFp>t?vA;d$lQa?&5F$7A};1ToWX%g^_gpRf3h;th{JjY zHb2gsCs)s4mjtRaw=pg=muW;b&0OS8WIg%y_as+mZeRLM8c~aWC$c_pZ}fYt^vkSw P+D-gxLsud(Z&@wBH;hQ} literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1728.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K1728.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..77c4d6fe78d9b7fdb69568bfa95471f59ec4c6d1 GIT binary patch literal 57736 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 JQ@>5t?iX!bL_q)m literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K192.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K192.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b9cbf3dc1909c51f2b6971e749056b91e0c093a4 GIT binary patch literal 39304 zcmeHQ3v650c|LqdqHQ^%5=A3z*}kDQgGm*KdRW#gG4-ruNwzH6LD+7PD2kG4OC&2x zjNKqL(=}OMEwpx3qo7IDVkq3K?Oe3O+8P^}An@F#4<&Akro#d)$bzis3c3TlJREcX zIp>~x{(D6#SY zLIlkz`fR;f;_HX1j`!_4@h1;Ga&U2jFY$EW6{F=6l~D}mnefcvSUffzn>sZ*6O1s) zs+B9;qv|Pejt6JwB6E>glxjt}pvlJ1Z#}@z>Sdfj&%Osa(ObmN4kW|y?JIJ9*^C z=bnXGZU+e=)l7qs1~}8>3&|fFhcP zEf8`J{CIEaY^EGKWVOJIP)4+NDeZjqkd=-BdjRb+(8NGH5KV2;N0B8%j!^^b7`EPQ zA!qF52w5#HfjIKNy$`F49CTW_qTfc`uf1F5e&b4+`*&B%+|%$F1Nt}bl`SPQWlPV$ zQ`TCZ?0LaLl8M}efZm?P+! zpUzDSS=zhT>AvfXGf>&$ItP7QaMePugnqHA@4hi4Y%VE;St zO#hBteI}hb?JjYYFSS|9m&pF|rAjzgc9bvOOsK6P(O;_lN+MGd_}$f#!1UFUSDt^T zB=DQ}N&-jW@y3;szyv&Ad$%Mo_HK#W#pfsUB9+1WlH~cf%B&9H-?Cx(p}XHcxRbon zLwf=Jux=nvZL91bgJ)Miv9|V=`M;5N`8UD(fAPlYm$v^3dc62GS0LeY!(%Hvs^GD0 zsi^9vPH(F#_HR|>-0sKfiDT0NVgt_kze~Ab<$>fm7wN8i!|{>gK;p+cx)Z(|j+6gZ zT9uAk$Au5G`-`?Xj_)ZBpQF=)5Z^^*>9fVQrDuxmgNeHM&zF~;C?bQ2 zPhVbv=kvcj3(x!SeVGg{wjCNK|9Lt-|B_`e(KvJno*iHMHW|FT^u!7|=TvAq96AeV zp%s#7`eky?+g}xX&9yR2y}gNecVB+Va&C8P6>;qPCB6FbUwnrQR_>d-2=dnR#l71`ffnQ+qxI`(zqm2TOq%DUwrBt=XSF`KJ};Sd;*Hj za{kx1ym_mI^i}-?BGCuF1S;=zhrnN}_vcDrxoAV^p$Fa8GZ&S>mjOe+tw�-pyA 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2c07be337bd6819aa04e2ab7d4e2d92d6d829977 GIT binary patch literal 1304 zcmbV~J#ND=422(Mr|3{19XezP5TVEcdV^%hK|16fbpa1OMu#3K=!H^>=93l2DTH{C zs2}p}s4rvh~mzBpHuSaSE|n&g}!`XBo95@Cb? z|HZ+%)R8NAuy$^kaNo&|>0-`KZ&0Q8c%?VjFf#Qv6K+TDoqGF9z3qhiO|I(gtV0{B zJ@?~W8i6(FxkvhH#&b`8wwQPhCkf{7sJ*bDdad>iTFuwY@$1GgMfwJQe(AYLuD-#3 zOsV$V*13G~qJ~vd&lz{d>xEus*Xuo8>CH8aOT9B*AGmkwJyzxkzIa!sk?I>Tom`os3SL9G(h< znPf%b3ioJwDtyKQ(=*|ja5O@-B3#gD<)3eTnty7iaRR-2Kg)^k0{&@7G7L}5aZ0o+ z{KPsGFKc>znqX_Df<~)f;NUMcdP@$y?`V3WUC|H4B2LhOjdHs08agZ_^i$VM>RhHb zG}zj&b2RWB`l$ur)JHjUpO=4%c4=5IaMpEsr`|sbW0bru)~FE+p}zhbygKUKrDyIN zKl1%^&nysP0|_COOoNbm_@u{QB)(V15r6OL7#L6;D$%-)MeKY7W1Yl_Tc3N3wx^F2 z;6OMu9G(hHgrtoM2_>S7_;Js^ZN8m^h?kTSJ5N88}KQHIVpHK=pf}SnX zxoIH_4Gj+0oo5~X@+Rjw=-ZsL26`p*3pIV$jX`1KlN+Ut5rv;0dG6+R&!%nv{Et=w zpU%`4mH6kqF7St1+#u$)ix3C3>`w^0yd77O;&7!cj)g6k%Us)u!<8t!L6g+BigpvC z-CXBv6zANyOFu`nWBO00>i@U+p8}shMo6uNZp^FZWUhH|O>?LAEBf3KYX#;jtS1Y> zvvk{ba%P0IcUwosN-K$LZ=2&w7T-O@PJMC}{dL(BEf0O)lYUpdTnMZ7^Uk#Y!rNfM zf8ZT>r+-JTJe5kHauwN27g{W(3**vemEQ6@e^u`Tdgnx~+)~mc%En{3v0)?}9avAc^yDl_+-L@7%C>`tG;y z+C^UJqP>8AC>zKV+sb=K;N96vl;)li-?J&FZxiIN7jK+=Y5UKh$Mauv`r}>~ytcxt z0$$q|3My`D_cS}BzpNnVsy|yt?3)e}D{#*LUD64e10>HmNoV;R_74^M|e*ULR@P6RFmr4J8%b`K?pQmE8FIoEIdj}4|yZx`eN&4?DKE6!OITAFT z4=e#nHNz&5dYPQ_^j1V)b1n~3Z*L-=>dP-#&Q&*85c}?*(z74=$+t*<`Tm)UAa6cT z-mE(OEkM0bS}s)9LwoTHrGwDw{%^l*fxNzL^0&^pLCZgQdY`O*VS9Jw;ctWPrkfxJ ze^33ie+gRlG%>)XBH4Q#rE`9_eUr6we*cC| zq%-dOdX=@mys@!n%pX4uvF>tq#+%Molg|0Q;VO%Ne(w%w=W)eTb?V|`f4qLbx3WL} zd{dpxANOsAvp=)Dz#l)btv|l;&f3@g@gG(+dzwG|?0?BG;V-Y*;h(SF z?k}&~7W`_UqN}{c7JTwQwsw{8vj%Nnadyquk=`xgt-}OMAp5~eYq0PKVD+@E_mPKOUF8k8R9iaZpL($pR%g=HIlu2|=qq>+ zy}so(Kz&<#@7cVyYrg4eN_B7REN^`$H-pLq6MHS6OOf1=GN zpy({;e?5zvw^~R~#Sb77J>ZMK{0>(T{8cWfcWy1%Igp|{GL%On2N1)FH(l%s$@2^gZLy!rBoe;zROUU~DS5v#gs zhjQVYBSG6)pf4u;PZku@s4GV=CW6IZaVp*4O8CD}SnQtzKEzl#yPUA9y-z7;mJ&gT zwQ}^wi~g?`Y;Fz^$G3^|>`ROOM+!FkA1vJLPr&DA3OC?lj7IZ=3AN{t@7F$ z9q#`5Kp$~jbbQLOX`iFes(#k102kKEqg0uYbGz^DAXKK%b3R4S+1>29x2#&VIf^Wr z{%&gjMXy4V5Aq5HXsB0`%mRHA`{gSSI_xe7xe=-+2XIwuSGh z>a;sZ?0ni~m-!d6cH4U>vaeiu&lsPT^nP5o()K7V>Q+IEx>eAkZWT09+cWCm){HvX zNRwBMv>nl<7Ct)E_Ud}L&8&y@y49>F=^PR3!>s3x)gixzx&GH9WtVAV zHtS)t9{xkDhk1QU>kD2F8);F$3c09X1x?htjC!~xqaHTWRYE)p9)&kuYwl!tDuRxE2AFX znNbfLY4WO(wj+A&df08&!)85f*288!Y(6hxJ}+TDFJV3}VLmTmJ}>bBJTJlPQ&HbK zwfa=hqJ9;$s9yyQ&ke(KE&R})zaaFf2lnF6Ul?e3{=z`R^A|e3c0D{u%;$&A=WosD zpZPsX|L@`XZS(%Hd4JfvKWyF~Ht!Fc_lN&*?+^2ORMfZd{4lFe1ug1VL5uoT(D3|l zMm^lB*SFg97X})hzcA47{Dn@hT@SaJ^{{z=*t|b%-XAva51aRg&HKaV{bBR|uz7#@ z1GqoT>rqkPI<@*#(4u}7w5VSN4bKl})WbD;eaq`%BMr}A807H$g-)+s57(OYuvrhA z^{`nFoAt0+51aL{Sr41_uvrg(0QE4hM@4-L&kwWuRM4V+6||^d1r5&+XVk+x_4=0A z!$umOzc9$*`3s$1yB>C%^{`nFoAt0+51aL{Sr41_uvrhA^{`nFe*pC`uSZ3F3(pT{ z)Wb$v)UQ+@fA=tcW|)2#vH0dREBy|&)FDPv>_AvW*o&|a;Q@q45RM_7KzI(}MTD0S zP9nUF@Cw2y4bz&Qey5zVf1IW<;Qebw{gYTtN$f?~hwuQxBM8S3P9Qvo@FK!X2qzI< zMtB9`l!kf#>N5JrY1zLT)IW*Ul*C?yeFzUAJc4ix;RM2S2rnYMgm4n!WrSA{PHC9; zZ&ybDI4%3P6ZKDGH6^hZVIRT+2#+8fLpXu(9KwqTFCm;ncp2dpgi{*k{TtG+DKRbk zcZfnZR~;#dRfN3=`w$*Lcm&}X!U=@u5MD%h3E?Ed%LuO^oYFAwPkToHI4$}_Qmv?e z603;sMc9Y%0Ky{(#}G~+JcsZi!b=Dz5ne`k1>uy2dH?D%`p0S6Kl&ZyV*DglQxba- z_8~lg@Cd>&gcAtQA-st262eJ@ml0k;IHh6Uzg-#qmC5ne(#iSRPQD+s3$9`RXp|6>UIU=N{*h3*jpXm9aBZjyYNLqVU#Nz>PD zfT*h9n`K|S6~P6<#>S|oey?& z|5YCt(`#7**%|KO+22S0T?;HS<9KXpF%sq?{4oezF8ekq^&3>R3~*E+)w)PPU6W%`xQ zhGS*F?S^dnKCaK^7e3*&Q?~8d^b=ekt1|rWPuZ%o=`V799zb*!=I{_?i~HqJhtq2hdI(t=&@_njJO`4M zTBrv7{Spyx80);^&Ghq#H`8Zr;v{*c^ z!{Tj}m4QsgTgq0)yEV^vGyOc`&Gb>^ILsYyrfc z&u^ZCsf<2*MGqk>16syg%2vnwP@eH-`gz2g=`-K(Tkd!>ecBDfkvrZ@KaY4b{WanZ zayWRrITkT37XM$F#oH(=1DTAsl&y~UPDomLC-M4j@E{t| zroTqKK@JCxH^(yGyhi5v#3+OOjp8k3tK;38XS|ty9`R=ShFDV~cf6T?9`R=SdBmIP zuMuyM!@=Xtv5Ysr*5dIt${>HEcuU#pcpu6$-b_D_cr$(41;dd$-b_D_cr*Px;?4Be zh&RaL;PK{I#+zS5@pv0$kiSv9rA)?qqt<`;rAL~0RQijLcCrIrP(c#<|KsV=lkR@7 z6dEkBaD5*U`b}IR`H)YlD zOm`UcM}&Uyfvox;PInpf6GGqdk*xZe{x1ssvSV5GGyP8redous>Sy}DBJ?XZX4TL1 ze?^Q}#jn;iUL#^YIGbQVWVN5UURK0< ztUm_!uf85tVZZ8Ouz&USJ|gT_9?0tdfpo8N{s?`~N3!Z?=AT8OUv+C%{Y?9+(D!Tv z{nh@{d`PcV>I-2V!a;MdSHm=*>>3_um`prpXUJNBc51T53|R-z^ydtzO<#tr7--re z%k>$uGN9?zJ(W2!WEDWuyDwDc%#c+AO?ydYYKE)|=K`qk* z@>G8Ni>BYiPtSPI9A9G9?5}@+;r7?Rzi9gF-e0&rc`U#p{mlG4V$;TV{rd~IzyAG&>#u)*;ri>}U%3AI z_ZLln-TRB?&of!)TV}nnDCXPx_ZMz|{rd~oU;qB1=^q3C*R{WJ{q^rJTz~!h3)f%& z{-XJFYu5N@*Vvxc9 zqM-f7AcOryLHmnA2K$SG_7{T;_7{crQrlk)GT2`fw7(c+u)ip(b{_062AP*^1quB2 zHSEE}f-vx*EynjCz7O~iH^#RieiiV+0^{2e-v<0*jqgQ#JMeGN_>G8P4E)U+zaH@& zz%SAGEr?$Re0Xq)wd+ItO5nq2GJY}Q+fut|O~ClhOS|;GH|F5`fUm~^>Dz%17n#gX z8RB>6;1A^BJAtpq6WJ*PzTPjyuK<3z*6uxsuLA!@jo*#T~ezz?XAF z>i6Z~tH75rk@^+D*XR5t$+xA3ko_UuA3N~n7)gE^@TGmphqX_00h`0H_9X^B{HQ(S zS0FyDefs_Oj1OyH*N3%F^C#oO+SmE8_GzADd=>Fw?JH>Q>-w->%!e8>qj-!gp<(ucLL=s6AX>wz!FUE22o zUymEohqW*LM|@cOid+lQ4y=7et~JSrwJ+m??7-TGUk~U0S6-^q``ZY783)Pt0AKnq z`7Js4kQ1`%R{~!j7t}7~3T2b#PZi=<0AC+>#D^S$;wJqm1HO!paAe{R_w3C0ZH?~z zcW!KnO-GM~f-`q+RMnQ)WMF1IIz2@RAjd-Sa4^IPAcN6qodELQ&~zj;sYU`*p*!6D zeLaK2tv#J?buti{m<>z-FX&chPR0O?#b({Y3Nsu!F%yc6g~o0h3(N#m5D#->!{M2b&4*|VdKYr5fw8ga(DCDkW&@Mq z@o;FGozE40GrYM_Djg&-ackL8ZQXcQXC**Y|mbpUGGuUG33;GC`R$(A&J?fVxaS=sDt`{@{ad zvBKADwRgSjQ2%H_LJzjVGbF6jih_{tyM_)kw)Up$C3P;-8yalw*Es<0Y42<6IXK+k zGdOtH;BZIl;nv}y!>xmd?{^;$9t}+ehPAEF-E_ZuDsU`1?QVkXTjib#M;P`3js<3d zM}hBkKTzd98VZbsKYe_$dU1onyG~6PXE3j|YOG zBS%={qS0KRaLRyI?%myX@NTdIoO^Y9F0XMqZ22G zrvhOR@Uja;-V?PU+7()MF>+5MP_e+t$!Gwqz&Z|14bNyNGkQ1}osG>uuc?7>uKkB6v3EE5dVN}#umHC037#586C6TqQqiIJm$7H9Sx)&*2aeM z#x;ivnKc?}9IZ1BQ2pA5XtSDsMnn6&4F;DoM>-rEo(!Cf&cfKzD2rj{!v@0Dquetv zJTNre+c|i!vk%&u8rH5DV9ekWk8$KB1!C$~9&B*wr3XDZW7H$jnPE0_sEl6mfO2L5 z;C|pLqtyVGa|C0|5Y>9Rw9vEa z2aHEk=d-DUDVim{k5IG=h{x^!TDc1Plqd?zF%eZ zYjY2OO|4=0_tCJS;h&g}&c^gXUOfqFc=9u60bRkX=HTym7G$gdbN&6FS%0Vof%S!U Z$9*-UYwksS{r%C^9S>x=!sc%_Z3Ba-eWIDF9!*iImFwv%XC(<>u-$sZdGl7gr|YuZ>%32HKZG_Dh3%I(Pg zoE&%Z9fr#SevSXX#m=~ss*_YJpy+$;4Cg?j6Z zdm^_5da9LoJrsKG!?-j8bI^0Q^wo^#?rpEhJcqOM>hJIdC;36fR{RFF+~*}7V-8)) z8`%ETb1k{@23<^0?759`>A56_W)sgTcgE{c@3;CooG;e9%k{<_%B9{JuaDd-_3jJx Q((Aoc^Q+D|^;@!bKhoVwcK`qY literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6d34e13a3fa05229c5a6754a24fef51e781d250a GIT binary patch literal 57736 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 NuMJ%}r+$lKcLU~fMxy`# literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a3260adde26df8fb2deebfd1bb9ec972f2707245 GIT binary patch literal 42376 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K384.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b747772de6b6c635cd7e3d603cee0aac81d7b5bc GIT binary patch literal 1304 zcmbW0Jx;?w5QX2Y9Ylc?3W^kwVxb&>8^lEpLXmr5Bo`cmf_so7L|iD$j^}ypl|id) zG5bH?Jnu84x(fn41K6wp9S-dxc!{HCn0gFvz{ddy*TZ963hx^1oF8CU>;2dQ7rd`H z|8de<7k0pw>)O}cgLE66`$;scX$}nEK(8r?`m?6J*EB)RhEL8FB~H05xp6Ty(eKb- z*9bfO|1FNrrH+(h7;T*!GVUw6QExZiF4lX>^`;yKrrs*!cI4iuw=dLNXWUP688l0LJ^0=#^BgV`%x*E9t)3W)-=Nm}N+sV^t#N Ix5-?70la@k)c^nh literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6066790afe7cd2a22cc5c3dd7ad5c271f28cdfd9 GIT binary patch literal 43912 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4032.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4032.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..3f01c4bef21d7b59a5a58887ae7eada0cc156af5 GIT binary patch literal 1304 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5bbc2c80374a573fb900cb8060c116a14bb0314e GIT binary patch literal 1304 zcmbW0L2kk@5JkV8P<2rW7A#mG5mg+ZOLnl}AS}2?Qz?rcg9Qia5l}AxH-YhFe&SeZ zWs!yBu|4zV$3Jkzi+8{~fW-umY5QCpKEkYOLmT}k@Vy26eLD+F{!0cuX9xHyB|ki# z3-&G;{~Bp33oBsBb$OTEgR2)3+euXHX%ih5#1&|y1W|wXw6>lG*-GfK= O(Z4oy<(&F0iroW3`bh-< literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K448.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K448.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d9a9e83af4ed6f1698457f055528ce9851e9a404 GIT binary patch literal 45448 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4608.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4608.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..72fc6873ff0e34cbca97469e003265214e432937 GIT binary patch literal 1304 zcmbVLL2kl83>G!q?-_`6**+r z-t~+podWr=1unVPw@+Zg*NpLx zGc7f-1vbp&dJ>KZ;F${}(C%oSAKB)JUsFz-^v>W?t+pa{+ HZ&5727pO(Y literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4608.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K4608.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..82061ce92f5f415914a452e6ae81c6c11578b742 GIT binary patch literal 64392 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 Qf?Idok>&}jeS6#g0hp4#r~m)} literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..dd5cf038e54e11615d0d2159484e08204ae52850 GIT binary patch literal 1304 zcmbW0L2kk@5JkV8P<2s>F1lcWgjI2X-T*H+NEh6LAZ5WZSoA=s7os!H{M0dNW#NUB zu|4zVJ3nyElXt*7fYkz!*I`^8KJ+aNq0RmXoOgh~?Ot`spJYns>;NCFQUuxG>g z+ek}U*Z^y;%d_PkT(^?gP9m_Um>t$$fL=-v^=D68>uHjm1#iZ6Ld?05+>jlXw&WiA z+Y)|*|LYFkj&Z8i+gIvs3+^T3 zcBG2%W2NW5j7ycQLC-zYS2Lb_vAsp%Ib5Aj{*Kzv_ywyy*Gj%-{*JLmT9R*I`%}*a zasv>vdjZ0cqBUKa6CGL#ZGrhdIde80e^o}(WmwIQsK5)ZhdJmO)>Ge*!Nq?<& Jk{hrpVgQ4NQk!UqZs%uFLlsZ1WpTKqa&-9%T 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 S``-n(?zlb86IT27w*LdT__EIc literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5184.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5184.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..bff8949ff0d505d29a43d3ba6981cb2830b9af9d GIT binary patch literal 1304 zcmbVLF>b>!3_QtBQ3M6jAw!0s7K%KeKZplEBt!lY7x0j0bm)VEeki4A9%Kt{A;g0v zQsN!YJi}E_-U06bb}K-(<8yQPh`TU`_VyRxdIbFa_!?9GQ(k({E^w)(K0claTPwyt z#KzL8)*0^?c>~Z> zt<3dO=(%s>r4fih&pp#u3!ZzivsLCf+?-c`#~Fk*yDFYRE%hwYHDPEdGqCfy=K^_U z25kZ;_T0gE>A4ApqKW5}cfspP@9B-q#d^D3Z^BS4>Rs^q$ort)bD>^(y_atEuZ>+f Jr+%Bn?iUUcMT-Cc literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b991d4c5fabfd3087cb04d8e144ac5dc87b282e4 GIT binary patch literal 57736 zcmeHQeQ;aVmA`tDZ6z_W0>&dHcJdHz#!wUFk0efP8u=3&+re=X2DRO_6La|B!zhr*Q&(`hLQR-V*-pL}eHrdzn+B zUSTJep?Kbq8!!qsWD6Lyeujg;GwAhs;(CQ9{2>xs=Ie za(jo{2ThIvzC*ta2OR$xXYTOvZ&5FG>uJtfkxy#(xCP?F04)v^$F?S+o<;R44r_v1Q29Y@|}_ zhqbG1q;3`2PZr9{z>oaj_J@s04iZ-pGD<1W!M7_~*Cn5P-bRui&&=-rW5w*bcPeJ@ zy;w2Z@m7Ur0sapBxx(|t+ZCQ87pUaMXF>9b3`PHGBdM=Z^yC>Eng8C!K%&h}snbAZ zE&}TLIUrAF>)4+vpr)kV=}DG4>6t$Ui-*Xaz4lS3KiPBsr?td$`do#l=UfG~G(a+C z9_{`rZgn83l?I;sV_Cre$1=)+mZhAmMYG$tyF44~T!E^c?v!kr^TI_sb^_z)%TD#$ z=T@Jzovz6oPkk1+;$XFSp_VJJHESs?<@I^43<=)-s|_C1nJgu&zP0yNcGj(_`N4PX z1iszr4fP~2ck)+lLg7xgAZ zz4^{rEzY@Y_Vbzp?*r=xXMBAQ;%T&*-dmo>1BpMtIP;)>s@X_-Q>$jHJFfOrb-KP_ z^FK_S)IT*9M?N!3X6w7I{(*k3bOEwN{v3`7);~mDEa|kBV zX}b2S@m<{fH;JFZW_vArqW0cvA&>K4jKbxuqLkWr=O3vmeI8Y;(BLY>tp}=T^s!-lWS^e zTsPx;+`Z-f72l)Q^-0)&%3PgRX5>&UI7ae#wv2TN*?kJuRj~WvF>JJrxDj(h7SmOP=8UKMd{!o^04$xYmm1V~GcYmMnZ)!fF#{YY>FT2F}f3Mmrd1)}ixy9;G!JKib_9Jx>yc;oG| zz(M$X{m*5A1Ms)-R+-1m_uDKk&1H6VCpvoU<&R1wo;9s+9?xEY>y7gLew&yL@x`4KdJW*5C zKMJ4jexkMZRrsGtyZvi2r|Mq3a{Q%@zi?*)GymWYBzzwD+W>#n@K-ZiQhgQ7FL&(M z)#TKcPd5?gn%%?>oEQE%<)$l-JNB%bbXWb>`Qg$);>Vl16TY=~kU#0IdPjqERsWV! za=fneQ{jL2m#lZ*v9&aOimrcz_|E9FpDDG^eyP+km}rc@GB^8J2^mb>e{LQ=U-K?ZLtKROSq>fA2SHFOe?s|9wG>6dBb zt&Y9so*$;xUPbD*oO{W3YD;T1ac=%OJ^Rt0eUl7U?V36R<*hG}H|qC&6Hxz?w$ruE zP+#Kox?!kw*SB7_ovLfC8UMZe#IWt#b^T9nd46MW?Y?h;?3$~<2meCtbbbM9u50c3 z`s*8gU=6L$xn|uE<$1pL!g?RnT-U#`{%0Fqdu-h^o1JUy-7~vZts&hB|3B5+2di3I z8pZ;Nhrri8?(W3Sr?!ypnQf7JTVQ6}CaC9&T3!9|GjoH9=3Tzp!NhYrn;e0Je*>KT zsm&#U#4R<0iPaxzd_9o(kLuRC)|;RC-?eo&Xi%dY_SSF&sv0&0W*RpJs+wv-UkO(C zRJA!mPyW}2o~j-8kmJklo|z`nzdo|zxowZ`^woy6Zg)@Oxsp&)hmx(fLr&e(QPp}~ z{f>sN{>rD;cO<%68ei{U`@E+k@!6K9=lfR=czO~8t2UQ}PSmaMNjzffpLw2se`d3z z|8oO?oV#o7q0*m#)`uMZk3Q(>soH+s7F&1Xffs8@Ad&KP&+Parv=yv}R$q4mpn(nj zw_mZLXJ+SDDb-ukUA6P8TL6{TbkA(3eo3S@Ks>2?@rh?nZDDPE;zP!G0!pk&HqtkD z#RmAS{t0-Z4{Qlk-Q)>@y;|KXdSI?(Rp_AyJ=#-e^uQMZL%X%ZFYAHN0frW6hhNg| z`ioE6dcUEEptaf?^P_=>O4d-%X@>#d4;Z|rz47vBUUVG!EQM%J^#|XFDz+&z`+_!5W_zGP`iz zi`GYJk@pg`$a@J|ujtqsOlW~v<{U|Q~5L!SVlgO zN0{YavrsK!PbD*m%ed;wk3G?h;)KHvR*8{d4rlll6Uv43$+VNvc_<T6J%BRuztMX|opLTikX*|Cr@?&lz zza?mq{}Qywe+ioC*JkC@uF1-$S!wdBm3AU}>3o`3<9$BFoax3)u$bSi1Wi22t_i5_)Y3liD>iKC)M@|}VSM+~UP#!SX?=w|CO+7zNJwHu7KTSP9 zO+7#D1N8hfmd_ITF?fEOg%d5>l}}Uo zG?hT6J%BQLOJ@dSOmtGGo z{~duVepRLNY3lu+>V8l4eoy1ww(9+!MZbR?<)zf~)710R)cZZv`#shBJ=Oa?)%!jF zKfd3S=d(n944$8sl~1$MBL5}i;rVG<`Lt`y{20%tS!uX`)KU)jkDBz-`82P}r>T6J z%BQJ(n#!lCd>WqxjqN$!(pbQ6G1dD$)%!hjjGPtEB%?e?uKV58^V8Jx)A;{^sP}u) z>k00QmnK@}p%l7S|P|QCQ z>uJgNA?!zZ2;otL;|M1aK7sHY!Y2_Wtn^Y(ORwU5)HO(flJw#kLCj<645 zKf*%@k0KmLIEnBHgy#@GiEs+xd4v}bP8*oFuPLj2oR;ltK<$%QPfP4W*pKiK!lMYs z5l$j}0^vD?Pa>Q`cpl*egwqD*?YlOseVmrF1bM`leeOqf z4I%7@*e>LthzF64(K>c-oXj^xv3?a{LSQ%=QzyoZzgZcJ|VxqnS2rcX7Wq;8_MC}{^r;QG#}qQ2GcTn z?-xBpStZcY-?D76zxNdBZzf-aznMI<4S(eKHKH6%cQ?o8|_~Y>m@)PzKN4;fi6jm!Iq zkl$%YSigEReHM9QH{@#{2Q7>B_h)Xg$ftyU-zPz_gH(VmHe}CWX22rv7y5nQThvF? zvVqK?MV{CUd*D8~T!%l?Zjnz4{f=Me)ZdZmw8;B~e&_dcsV7~TZi{?M=r8|sPW?TZ zn=SIhA?#ldq&}Vm>w>0sWVrkGjxb{|M;6 z^n4!``fG2=Y5y&me(U%V@^v50DW4sG=7fCx^*QCU_3J{uZZ*g+wx7mBdacr23iA*S z8hd>PrVeG-@Ib?0;xRj`tPNqc2GDzoN0sAhUVoGNa8G30mh)3ZLa z`d|`oiVO<5`w-GJ8HIh5d!EFI<1&>kF4Je0?$O2fxCoqU-M^ z))y{c`1)elzcZ))?D#zDF#5Of^@Zy%e0|~ag|9DMzVP*h%NM@B81ekF4Je0|~ag|9D$J=f>-e~$IV&`;yz zlIsgyLRf5u^@U-yzOet}p>dmJmBIR=q4mXb9;`1KT3;+>u)b($eX*3m`l6xr#Zm_A zi-y)0OBt*$8f~SqzF5j&ebLbRVkv|5MbnM*V12Qa`N#$+AxXN<5*xz6hq@TQ4)OiK z2fs1C1M%yD4;mQXiTDoSmm7Q^;yZ!A*5J1wemU^3F!;@g?*e{>!EZzSO5nQ;z8~>x zfe*dO>?uclNBUa2Ct!T{o7b9cZ^^^=1K;!ml6L|hE;5;(O2qHY!yn4ScLU$_C(=_1 ze6wAMUk&^!qu$#QUkCn`2EP~a9qA_2-X_%ECc4LA_Ums-ely6+_Da4J_?3qI5R!KT zU)C$-b>LrR$PXa-0pQE_O8I@jUuVd7A^Enn9r+o0RLB5-m4R#DlzbQPrQamK68O>{ z$#(+3n?5d%j(@I)Z~6_%!`zqlBRKr0bklL`E7al5EF9B*8<<{mp7#zh!xrz!=Lqt zUk!Y--w_{T2=bfMQweD*P^J@p z>kE*^DuZS|Kr|ZuFg5{cXFBO^oY_@Z`}* zEP9i-VT;eJhohm`SR{JrChzpr!5dnY0L%<7p^{Kn!0LJ3e zUZI644j-EeN5{frH;e_Rf;tqBaAhNrv75ZUV>^5eUj5*7G&BXK2giZs)sIde;K~}j zH(GQBCl47m#NyDpuvZU`jZKD+9^Eq?9FH7~geTegOf#s7d=d=u9c%IGv4aPXhNmdu z1O10%N2hL;9M0G)rFrGkk?7R6=8>tqHbkOFrzUfm04<^>z*lY)z@WlR2ptYi>euHr zAez?#Xe70uQCiT9ozQS8CxEncLQ~@sPB;()U5k6ca6ywaz|sp1P(fiXNW>yz`8{wT z1{LM49V*G$0S%oiRXaF1Z|z(2)ZVyaZ3pk>t$ka*+E=XY(2TsbZ_iVE)3Vx5hkGy@ z3Zpng!w`xQZ8!4ZBBDmyjWUq6-6&&R+l?~(0Ty9V#D7?;AvW7qWsE~ayqy$4mBp?H zun%Lgo}NeRfPJfZ&@`_&U|(h)^c-RYM?pyM zt$X(|w(()grA#i9+dJGoXmSAD-Z{|Gw|iu;Z+Q6D;gPQPeeENA_q7l2yW4v-bT~W_ z95I$Y@6Nlu6Tu^~N$*aGzV+UTNR(k8;COH+V2!{Ojq7^Lp@4h9cJLcl&2 z8b1(;HiF>Z$f0O(YI-s}5RM+2qNf}*4k+vo-_OI_Mi4YY4T_dC?U@8u91mg1Pb`J3yOTl8pE_Hblb(q zt<*E|;9cXfAZUSk9G)1NGEQdnNGLWPodQ{E%)|&Sr&~(z&X0lc2;Htg*D>XzxgW_werS0jO(Y#JFOB zK7&g<#*vp4h-qGVu+F8I9`xj_UXRA6M%c)qW%P;%gtIpQ-g_?5TiZc%9%qbMyxJTB zNi^(3v1pXetVCq$E~`K2yrSOW@9r!!|{(5+hQ~pC5-DexvwQ@dwo)gwL zjDL)@mWds(<-GJQ*WiYY#I_TGHN9n<1+jA&B?VD`*3?-|v(s7dVq7Q0oZFMzWt*ie zxrgz(7C!#Ji=%O=W0pmNt#N(9J&_yr_LNtz_gv~tIkW`oZ3^x{?wxwaO1*8t{USF2 zgI1_bwdcN#%bQ{jdhU_FTJYSHt*r{r;o`jdJHA2qeZgwawQ@d5ndQ)Fc>`OYdoGYG zZ_uX%)t>8&%ZjrcnoT^X+y$>Ey(ivWz2}al-jqYR)VtvIiF>EsbERH-eUNJOuZ>kX Jr+&*~cLV<9LvH{8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..290227cebbe7df7835965f0cf05265bab6bc5da0 GIT binary patch literal 57736 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..09f77c53808cee93b6d758b0bd5fdc3d527c10ad GIT binary patch literal 57736 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®&PrJ&`PqXCD;Q475TI9b({!HY* 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 OcRY~e3afih*Z%{Lo=cAa literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2332d84cfeb228f465cbbfacb14e82128eb89841 GIT binary patch literal 1304 zcmbVLJ5Iwu5Ph?D5QU{sP`HQ`3x%E=Bt`B)irfPuxuD<>6dZ&jL|iD$j_0w?%Ai%Y z*#Eqb_Zd>%1OXlZv=0+;;b8&-iH_9Z3~3+_AYLPSMBVcU*J${eQbdnK2}_R zJJV7(*1(GUI@Uac^sTP_COT?re^Fvpcy2H#1gZYiv~f+bXs+EmuPEb`cSqiLDzR$O z?=YN~2y6WRE%wfPQ9Ti`a^8^f9>^R0enmyriv1pQzX`*D=(oyvd-7iCcPR8*XS^Te z?SS4CT34L8Pv>P2h{3enGFLO1Yy51HWez6^mhbomhlZ+(-=Nld7TK6EY^iVH=a-r5 z$g6L#O8~{0+c+;XH^DG8&7AShWIg%q9?4wncc1%B7=}f^Gg%*buk?E?^vkUGs>c4> Ls7l20Hd)ILjK)V1 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d2e2d527e36b37d04196ba3f71a3475720a4c0cd GIT binary patch literal 57736 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 M=06xm5Vd3a1I#2mV*mgE literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..954934e57261b155184d2f96ce2903e17a71a8a9 GIT binary patch literal 42888 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..959d1568ea33d893431eca0fdd2116d506c0d54a GIT binary patch literal 1304 zcmbW0O-{ow5QX13DPny;odBm{- zvYLhM@y~qo>=#IN69jk!uvq~*9KW;RIgXk!^ftT!A1x3r?R}gI@7mZt-@vZc^YIIu z@V;XF?WDC%?0_xjwXeAb={FktPBg6PCE2WqRxoG^qW-LD?={U%C&7brMTsf5BljuU ztYzsv43{;+4*%c9!MW5i%c8;7xgq1ek{k8*lvl3znCqQ#SP9fyW!#?JEAZe1q=y1&cjb>-kB_EQd|&8~FO% za}Bxr2HljP*mHa5vf?C%WmC@?cfsqE-Y?!k NUmL3uF~23T`~ZbtMV|lw literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K640.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6d5556d88eb333c0c9d936e5e8812f33a1e03557 GIT binary patch literal 51976 zcmeG_3ve69b&CT?f)XV{Hq8JMDV-r&L)$bBek4&MZGm5tCMi>t^coyr_D$Cz^O;oL~%k}P9{pH9@gV_)J!@9rHLZj ziqN;ax3}*=fCMZh(;3}yaQEKZcW>XmefxIr@jgcaBSWEZElHZ&k`}Q1-9v{6Z1&T1 zPl&)dM)%4M625xSkJf$Zjj3l}`|DWc>Kh#!<8!H!3p7GL97ltrdm>|zk;s9g1Ec;B zD_KxD!#<5qh2xlid?GXvii9awm=`oy`SHlB{HUGA5wxHCXO48{@uMA;VesM!j){7O zo|uQiec$Dj9<5-Vc1%6YYJ7jG6|7BV(C~)uaX{27+M!s)2|8e-l+Js0?-3>RsPn~j zD&yPT-`uNHG~iqGs2SkcCpdANhaW|~)U2mC>8k9h_D<-d_*Iccg;)sH_21#wR_9*x z#QppC{`ka8GlbZngpdlxK}bCu>Gq}Ak4iYi_g!s$eX2txTC;HxJKsRa5;=0qYtPX7 zX#K;)&Cc?Nf&-yZ|AC;CQ6@nN(Lvl$`LS}fiV*RWr9_W&w9{eC=-rKZt`zQgAo&OC zG_7s-Kn;Yf16`i`{9JMkG)S?4N2t5?dMWOBXO}|zfc*e>rr;z6w+<4$zC2HxK`|m=IUYYInu*?e{xk>wgR~6c`lucUoiTKK6r?7k^qo;zG5~i!4;! z0WN;=GS}O6-DgTUsE(rJ#o0a7m9tQ9w*4_w9c-W z1JiVtB?&ne|Ndp!uk>7BWwOB4vQd|upRd){5)iaUR^we){E` zZ?)TKe}K146^e1qW%y!O(h}c=-$Ad<^gLGLO0_`#V~#IdyiX7Zt*3nDpp+HzKN`VHEhpiEV6q{_o8K6!X-#Aa;;yix%8i7V6#sV!bZW>83)vR ze6~U|Q}t*j|2b|+@t^O3|MWq~qJOU3ea8(wY=}Kvk_F=GGo*m<*h719FInp-fLI{o zPdUV$JaWRpq9AzCR?CMUh!Cggb6pzWxz6A_2QL(WHIE_Kjoj&;?JMlf0k_xZ#D8CuDKy{GXE*O^@%oeLic}u-jzol?mISv@3eMW z2NU3_t}Tz!_;X5O{^MGC2*zaNUHe_PkSp^b=%0`1KRo^}6@RGgn4%-qyMy>%b4^RZzen_~*hk!K&eTyXZn9}0Y7`2G4)!P%Dg3w(zz z75L75Sm4_azxO^U@D0Il;r#-alh3tOf@?OpqdnTvVI{EYB27uQDtwQx48_{d_3KN; zt}v_%VQom)ZH1QDLzjOVv)+Ho8jF$G$&1B`9q2a}&OUzc`}b@lXFJ|!ZSyIG8kf8k8}rvKLIi+Wt}TL-@~_?6G(m0b_L>x}$I z897n?WF4`u+)1oJIr;UtllHqa@|u&hm;RUi)_h;|#~a$Cp4In}->Z#kOO3s-yE>m7 ztIYpw@L#=oYwh=K&JSvrqntZ_my=okx13k6f6C{mGxt!T#?1 z-y*%!O}qNZ{~Q~eeACh!-O{%U_V&Meh4kKAba)=3dc&PysJ=OXj^7EZ_QYG%^U5Oc zI_LYTw%3!&>I-jLPE5C{`YqqA?0&xb_4S<d7AwdW9sqLPMfYR>li2g7y5L2OKv*mzYb+wc>-dweGAWMY~5e%0m#0y z!Wzhb1EfA~>wfAnS4ZjAo2xDD(ML~L5MMOzYMhgRQw8$dnly7#SG*D<~Q zMT&Knx0h~zu^OQK^7iSi)GpEZI*7-Wr=NTIL^W&Ub2n-J1eh3u7Sc7lY8~v$-T+H< zfiAw%J6r+KSE+nk_08rL1|EORr5rz_`kncmC&R^w=!SS>Cs~)hdCEh3UZp(N0S}tnwinkeJkT*|{K|ZIAlsm{Tf11QG zD69ArPwoKwI;M6o$ zJ!ey6<$Wd9s?AYg(fBt}`KLV!i9gJ*hyaHbN}NfcI~U>c^z6e9yURhYgSpB9RMpxr zbNLcnNna}VU1-{HqSNZMJIL6{q{}YjuZ5g#xr8ix_VOiTd|pWIzZ%>09ye_)Z(2RRfTE#%7I%s*t6 zzcTX=hD=JT7n%777*UY>H1iMCGnT&=UgSS!{$UCK;p-bS{~+csGyh=bAI$uNnSU_z z4`%*>Uh~5Icn#(scs_u(pXVQpxX2fXa*;0(I8p0T@((pB`3ECT-ZA2KgfE?cs5SEs zX8ys zoTwX9@((wr09ye=ze8*%MAI$uNnSU_z4`%-1TF*c5e1OO& zIJJC$z(u}5;38ijaCq+nToLh2d!B<(i?Sbop2L8{^Be{op6Af|O8Z-Z3<{#i4D<9$gMOk@{`TT|X{Dt}a zh57u2`TT|X`~|&&zBZq~;Mf1O{o4B?AWxO^8%)jnAGqJ7 z%kk-%Pc#2O%=b^4@1Hc^KWV;y(tQ6Uy;i21`Tj}yeoB}A{z-oQPwj*A1p*iO0)dNs zfxzMY4=MSF8a>$fW1MJ0J}2oD?|avC?m9CU&ux zY*5&NU=_h01bY$Ohu}d3k0CgQ;3)*pB6tqLaRkpJcmcr)4d(4@O=%y;W&4^@`y{L; zB{&*;sTWB&;IXgJ3U$`w%>c;4uWp z5Ilw8Sp?4^IF8_X1TP>sp~1X8ttsu}xM&keG^6%OSVeRXg1rdtL+~Ji#}FJt@Dze) z5j=RZvVAqEeG*m^680e2i{L&44TO2)@HGS1Q}z+a(fL7+&aZkwm?qPMU=_8?gM3Ft zcJQE>0Q|b1z^}^$enj6T>BuHfuha+njxtgGJ*Xd5)Lsu7t17Y^@Jso~&cLtJ38Fg; zbg8EU`2#^VaUhtWdL5`TM`ogd`u zbdaypLB38Ws9p!ES4DIWqI(g&577q^eGJjTZhBo{HysAM>H2`(5M7QVu$!bK{XtKi z4tnZxKu?_xdg^r0Q>TNTIvw<6^flb|8JuUavm==Yoow?qj>!GO4%_N<{9ew_{7Z5Z z^6oL)`gHs;&W~9c{GTt_s?+h$a(-?=bQbV$O2cqRu_GbKCNpwPHdo%tV?9KR>us4*$#_i2vVbdaUKRUCwv8)8jq`hU?VtY5| zXm7@!gS{C)vK$99+ne!QQcuWiZ^oa4y&3-!_J(rUxV<@S0i63ckHNHzK3hOHQC0%D zw6`oDP5E=MHwz z6t}mr4B|Jkw=9$PUZJ&rEzFkys&FKBvH^auf+WYZ(ynCZ!)u_zJPYUd62ZS+<1ijN zlU)XWV%7L7o&hO~<##9VHt@%Ve9xyru#FUhE*7LuZ?eb0?-lYr-&xd0RI{FBuYsRf zG=0c3M#VMEn`}1l$Ao;_FVo6zNwymJy+XeIJ89*&CEE@BaUs9xgS7HHl6M*SiB0Ig z7W~4_>;tPMy}z21UIV`>_-(hO482G({-@ZL9e|xgcz&|MXi|$U#e^;`@z#kL* zj*qA1Pt|``@RuA)%b%)$T<|+Tot8gU{{_KcwjwQms{RY2zsi19tCIK8!=yXzcZ9Ff}N< zh6fy+iO1}evL?WtT3JI%SsUQ_TA4SctO#&gBa8JZWhH>qYzi%Nq?DBbPO~qx%$ZVF z0XS_XEmKp~BsxA{fm-_B1@*{Aj|v1;?=tfX=g)qA(e&S* zR(@)H9<*uwoBjO4^m9law-;UlcUI7|w(FMM3k6p$z611+Y9?=~@FV^Tyh+YD8her1zdIiv-H<>;~h;B=4 zq-z33cb?yoj^NqT3R6sJ(Tly>)br!}M3rOL{%<%l1mT9q1(*e;?v^0$tWC`Bk7_ukrUF z{vM#q_DcReKwqQrw;}$fgcaEtdQ|WLy--;n%08R#m|rA;J%8PIi~KQHOF#BL;ix2}&J z=(3L_y#(k|zNEw0r?G(f0E~SJ1HC|_mmxZgefm9U#t&m(=ZCRR<0qrT*w^VW_Gz4B zbQRHI>?>&O>-;eG6*TsBI*ffqw*!&`V_(tx8qs0wD^{&u82h>$82dC{Gksv}>-4q^ zbchKw-ZK75#1CU%(PJ8-*8^SlyOi$%x^6eb4`W~IkLWP=6*(5992onG9BYyeV_(__ z$$_!2$T3oZ4(hibd33REyq&H=tLrh4^UjcNzU(QQ85G$0Gnmwx!y$tAjzau)t z5M(zgrv&KIK9cT9Sdl(fy}k87mv)f!3ZP3pB^_ddf?@)d6KC<^H&zA31Z2Zjy{^tg zYg#(Q1k`rP?*+O(*3L`16X?=sBpqS`>T5}dn1FnBx2{hm(DgBRUeX~}q@_cwK=pEd zwk}G5HsJIGu03@;4!D=&HYoQ13if2>6psV!)o_x40Bby75ezgR%4EX5z5vo#rQys5 z2xtC)aQ=OI$92om#RI!{ygf7j3L*0#l-BdDt02E=$C1$yH5wd09EybRaMx6O z+-fi!hzy6q2kvlBPVB#}!M)?o6-{H~kwd}2#GNZtwP|d`Ke0bDK1vZlhl9~jAjlCw z1CenZ0rbA$csMwshW(?#JKViJUHt>iUF~jl#2-E|=|2FpfLon7ItIY-*rZ!XVSluig-Z&!N}o> zdnAPuc1vzv`D7?Ov88@sBBKtW@ZpK^bSglLs0wgMuL3BPoeF`2{&Dq|j0%J^Y5ah`OmNNoyOC!|PE@6bB2*_I83z`Y)qymOssDTQyGeI;G8qREip$Jrzv395= zZ3on}Uai`}z!_`boT2vGtJZd~ZpPZTWUBqDwH=y~vG%PQYOlMZwo`ZahXX+rhiDi= zF{0^q9$ZA!Xu4envZmW*jBC1GhChHsSQPOe=4yz|mcpdAiHNtI0#IeH^8u{GSgfb# z(K=w=s&6#SD>hh{=^H&qY*Zh-(J5BwdZqHNmK>@dU69a?P4Em7(&>tVkj{H{?_p$Z zr}M>iD&yPT-`uNH0NB^s)6%tbptq~P|DOJVw&p#}1H1P$_wRYYeK>G1IO-qJrat%f z2i&9nLy>X!c8I=J?$J<~!5)Ce{1btLK=-&Gta2X=`iFzS^?Aidj2Pb@T5(L#& z(?iW>SkG0td+CCQ`fruHD?AY#-|r6u_wMDDi&`@r;gmjYxp!~N&U--$Q1%5zT0&t> zLcm`$w5={Myv?&M5UBCjHF#@E-BsHKLN}Gbh!d$z3sgNZ4f;e%jDr8Rft7` z0lE_CZedl`P%|-(3I740(6GeNA^+jvfHtWy&U$W8Xm74{1dLVCh_*}>fA-*mOPRHf zHe0jnn16gC#HIUQ1)alICwb7yzYnV^t)9aXgy)$&q zw5QWq)L47{m7PxG;^@FfuALj_BcD#YE0@}r>HXRzy5Dc;{%zE3sQV9$M<&PgPG0N; zH9Yv4UO-3iA|Lz{dqK(wFvs8joAHO%ATYkr>^L-RoE}r>B0m1Expl{bX|Ax^ceec> DFT3dm literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6912.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6912.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..02a4b956267e6a0bbd73ae178d4294dbf395b0a4 GIT binary patch literal 1304 zcmbW0Jx;?w5QX2Y9YjGC3W`WXiiJ{8a)YGEK~m%%F_McMgMtI(C=nM5v*UU8+8DHA z3$OQQ=9}kvh7@-}fENJE8KAH2xC-9lTh%W88BV}?3xwPDF>Zx-eb_y}z^T;uI083( zF1Y@3(n2@Zz>51impp^iOI`a-RIKUHWrT+{o^h-|$_=Q0rJa@ZF279(y=?qyJMw%*3M zgXq2pP;WWnevn%Mb$>tGbDz$o5txH+xu>rtJon&dvyta;m0ETt%+-VAm(e?!m^n>_L*lvS|;DJK^<2?<>jKdiOu{b~!8;^-g%b<^EIe VF;g$SUTZb>*T$+u%x}qBz5#83NYelS literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..51585b6657d519a965aaf012c0ddf0cfca0b7a25 GIT binary patch literal 64392 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 X-nZmf#QpE0n|IuvWrfwXv-AG|>r%ps literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d623b6a4fffff84695a04c9cf0ef1608bb5110eb GIT binary patch literal 1304 zcmbW0Jx&8L5QU$;4oZO(3W^kwvO*~-xIt3n5Ok!-Jy@hIatsO%!V#ieD2!+4VXw6y zD_hte|I9bfehb&!c?UcJSk3?$4&T|~C63x5wAQ}^r!C;G+lM&iKcvxpwt-!c^YQbX zu)bk@G15XN*1(GM(g&`=bxVnDCtB9@nr#-un?o-ti2AdpjnyTf!wI~oAT=Q9!tF`hn7ISO~LKRy-{ypsW%kd zPjXwJ(+ahz_S~0oc~i_m&&}zp3D4cz+N|&#&d#g9;~N})U$EM9LCz;BqZ~RdZ(!?V z&$Z;r8|+eoYR_$q%ZjrcnoT^X+zGEIy=@@5TJOHpn{sF_>YecVz`arLu~IL+-bpq3 N*T$-xQ@>@g`vF^QMbQ8N literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c77c0202d840605ff2a4810202ecefc02791db04 GIT binary patch literal 65416 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K768.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6068f4df2a2735e95fde11375d9d6f393a5f9fa2 GIT binary patch literal 1304 zcmbW0O>V+45QX13rs|>+EV^KUL{xEr-T)RHBn$3=D`nARbkPGLE<`7jd8rf9$|4K@ zj^~?azd)*|Aix`d^#agg|6K&{-Kg%T-i9;qxd*~+zv`C4hc*`H0qmll@4mnV?<>x) zPFm{17T9oI`^Y^=TI<{+QM0Bd3s%Hg&}s^z{;X-|HH}VZlUL`85_9f>+_6y6duVS< zgf0HRi=%U?BSYG7UeHsm&4*l=^jdQW$HhaASG-fF^4QehDK{i!wVL_LDci6g3WIZThTZ0{juk2aut5y zS^X7CJ-2f%E6#FQHuaowXS|;2jU*TAJ>KaZa#$|vo$-3leNgYIP%pinw3-#wiJ0HA Gx%>c57DfXA literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K768.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1226e12009f3ef05a17d266527c3fde570813776 GIT binary patch literal 64392 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 X5A-iN7IFW(;N~57q*-CL?P&c!69cnl literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e8ddb40e64191b9d013e0e79e56de10e73ebffac GIT binary patch literal 1304 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 Qr`6c6HdZBKeoJEc1*(roWdHyG literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_2col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..96cf55e65da7dddd589ef0fcfdc81731dd788cd4 GIT binary patch literal 51976 zcmeG_3ve69b&CT?LK0;{Hq8POC7mH!p(UCIKN2aCHo>n+lawh+@(4*fBnW~MWD;N~ z5|-oIf*spq$4-V#8`e}~naNCB*>zgFPMeSNp;M2liJX|W98Z)^J*?|?luSB>(nS6# zLf`J*-o66?60np^XMD%O-Ft7}y?y)k?c2S_`y2@j4}`*%Bw=n#TA=W69yml`v!9`R zLIln+x>v53@YREU@rk$IeQC?%6aVAd+7PTV&F0Ejlc1%9ZXncRJ6|7BW(D2&taX{27+M!s)2|8e-l=eIK>=h;SsPoO~ zRK~Zbx3OENXu!AVQ8U2NPjTW74?l`}saa2R(pA}0?VZp^b5}(g6=ES&*MEawOO<=g zWA_a0d*$SF(}dWdgpd-(K}aGo%_9~E+l?>kz0dQ^u>v}WTXcD{j-A#!BPOUGz^ zwEn{+$j+PE9-;2h>!rBkt=$Uk1NH;lnS_%h+>UT6lm2on335>z z!-VuI*IUS39@$40^7Fus{IBLQoq@pc?YBBy10NK)hCVE)TN69}vW3JxotXZ~#e(UJ zzblx2;Bvuq)B6Rk1^Au+u)uZb66MhF3s_0)yh7c5CeXAN}Ced#{#|IiXtndn{Dk z3NHTMWv;jD+Rqhn$QM&`eNFG?`Q|R>aSF6^KW*W3O^w5~fjC^=iv_+Sj}zpzTW40z zf@#`|6NDU{`~GFwuk>7BX(G?nv`Lqoo2%8<6cDtBR_6Npf1Brf`!{*MVN|0thcuUV zzVrQWTZn7JgN4ndPptpmx2-^1|;>8?i#UC9>6eZ=u)i}x|&p!KX@b*S4*ri+`d z|Il$Um&8_n@k!wcm0#8Eqby?|h1thPpqG`0&{-M#547Lj1O9WG&aEl@rvxOsQ}~ZN zrT-jU>_gmVE!U^=pKl`TUk%%H8H?;5)4gcfmT(Eui(DHPYcBogDA?>Xgs@R?b;bep z9-nPBnJ#-co&TJ$B>B(xz<+umWYIrY_P*nW9yY`tF3AFM^%%(`JoeCD+(*_r@*oz- z__H43P7XQgU{Me}sK)Z)2O`92`dpjBcdj+~&cTa$Ai0yq@ndy#zqXXs%Hq!xU-(X8LaMhI)l*>5C_ev z|D5n!PPhI(=da2(qTafn*!kG7kZmyq=E!poT+Tap@ppN?F#LXXDeqj<`+2@Y zm-2k)Kg{zD!S9_9@_YmETX;Xu<>YfMmEf95G_*#W+N=atU8Fw2R)z2Im7!Ssxqfx2 zz!ipdA*>DQx^0Ce_Q2&=W7d04TVpX2JM~_HVh8#SD`p-{@7k#lYDv$pw^73Asl zMVl{i^?=Gx)cHvG()@J;=-(--x);I|Hb#qe7{ol|@r^sY1V z@5SU~`4d&dzG@e-0_D`-&pBzoJ0mYSNo&!6*|+BUqOWXhje4%Ro4l*msZAC36`kd| zi+oQ3@z z_qW z?^xd*U3pvOJHF^oitAwfJ^#Pgl-{gBjZRoA!R9Nf*yx+8+~6y!S|9kDzqqZa-WE9i zi*;>9JFEfQSDkHBRitxmXx$IDKe^LW5>Q&5ZP6d*1Y#ggTxw6aE7VTQGIVUh#y0$I)c}wTi%k=n#&9=@jbpd4G zRbma~{urb_YU_OR5m#GL%}wQ&*671$N{BBy=W3nW@hr3zw1-yTbTdF*>pJ(ZUe`9Y z^I3|uuWv2d`D{5rx$9e}YN%bJbL$`;m!5h0`IF_WjZfdG`4eDb3|dIX%<6TpFa9xD zq62jC72WCzfWAuU8>(+6XGP%AM_kH@v#Rea07JW#gRiT;F98fKP!7JPTGcbhE$uI; z0cfpqe!k!LXwE8XIprY04*?8TQ_jEM@0$V`TCbdct>3Dy+Nhj*w-=Hz>LdwFtQrx^)LZ{_jC{&l)rcMTa03-RKR~`RVhSD>9scPpRFx1 zfFL82|F&9pQ{7W#9$T%$-96>+B960;haIbSIC8D(6CMSqFjk(T%!HiWe0K|>WePp# zVS3Kyy3)G~%T=2r&!X{frt;5t6f*Z9zaj!0Rw#2!0^PX?kEiDzbl6=EaxKhN4xp;m z+Ud)e;7a;Zf$w7d#*^(jgK8RPRpq5;lp zJb}PPo4A( zQU1!zKNvD8$zEjUA7Dg5?$gXaP|sNYT6mHFnE8h#{D-e^%>09xzs&rDnSU_z4`%+s z%s-g<2YSs5^W(=b|G@JBwEaB)V8lhfK$MGofxwAcm6U&|NXkDLaq^ZCw>d1K!H0N2jRcjLsgduPo1A2PoSE2IBnTj)I_+Fe-M zog3!;4=L}TG4l^RVww2|;xO-jFz7YJPB3j_}DeSj+>zG=^M5Nc8OfWz|~I=*!Np_l%j$$bBV z`ThqY{(pr3^JqSQVLpE$-aKO7|6tz#AbjD9-a=#MAI$s%ykq4fyuTiGoic@6^( z&vO`Xc%DPYm(D*lnfV9v{s;5^2lM_1^Zp0({gW&Xz>`Q<^zK;m{s+iYW&H+I^Zp0! zH>q-bdgjy2KM?c%lji#;&G%25@1Hc^KS{5Z>1MuvQof(krN4iYU;k74;Cz9=MZQ4b zB3~eIc>hCE{-Hw8CvbU29G>Sel*98JI=*!Nq0-DhnE3}Y|6t}H%>09ye=ze8M1DKP z{Qiac{R@#3NtG2@>K-8N`%UKeFU;>>nBTuJzkfk5>tK`7#Qgq+`TdLE@AohG^*{AG zoG%c#$QKA)82?|%Sq_D)JU=M=52<|~}KY~XQ97FIVf@cssi{Lo~&m(vN!Ep`d?Q2eIAID|;8d3Ws zti~nmL9iFWJqYec@F;>~2%bdn41#A7JcrsuED&0RY~pRxNKhqYM+GFxP(0j z_9D0k!TksxMQ{wklL($c@GOGo5Im3I1q8=6n740JQu{bA+jj$MpM=%8ggprMBDe>^ z{RkdKa16nd2%bUkEQ03{JdfZ71jjX48-IEZ596|ZyD7-Vq9ZP06~P_^dlB4&;C=*; zA~=TNNd(UzcoxBP2%bmq0)pcj%-hqP)IN@jHj#KEYM+EvME4-ri{Ksv_ak@|!7&6+ zB6tSDvk0C;@H~PS5FFQF-oC1&_HkUcuL8AC!fIT?9t3+4+=JkL1dk#(hTusA&medf z!E*?nNALoI;~LD{w<)Q89GC680ku!UYFxq|1bY$OgW!Gyk0LmR;7J6}Ab1wRa|oVC z@B)J42=4bgqwT7h=1V z->AnnFT@NU7Xkr-Pn49rR@MHQeFJQ}NGmer`Z?7VvLQ#oy2QVc~DwK%b&i{3_?qF>({K z&|u4@W6%cwgQOdqD>RrYL(B5T|0m%(gI;^kO_UV^PK`*Eufny zD+FBHTb3=h_wFq1&G@shH{)lz;az%rGk)3(!RtRO%-m+}5y>Eb^l~w$v{8`wW$v4=JBI)hT__MG#}@QA_^n8L%d*AxhP7T+_GbK9*qiawCK$H#_GbK9*qiZZVQ<#6xaeH%E z+M8c%aeEufAbulz%d*Ax-kqhr8Gjb`X8g1XhAq9l8Gjb`X8c*$oAEDUZzzY2+ndAE z-uxPh+uK+M@f+D&mPvcB)Y`um=1TxoI1)SA2tQaslA~H_N22|~HBe!Wh4Xuf;NPin z7!U1<4g){2YWyX~K+0nIoryaP{BuIS=d&Q#MhZX|3(}`M(PiNG3i+PzEb1ewSy!Ul zz)viiKIE8DaSih(8V&q0A>a1%l=7Pr%?5t2kZ=D^O8G5`Rs;W>ke~lSO8ISx+YS80 zCiGtmeqm?!fz^`UUyTW`fnOE;wk;|7n-fh2ey`xS?@YO8LqD+%M!;KbKN|@_1Pg$X|XuszQF*=RyAR!AyDfyG-tAf9DCGaoSpTcHdLdzUUWyOHg>Ln*7Y? z7cM{Z`9A)>dZq4%VrJAtm-6UiwAy525CF9v#% zR_}g9SAl-5MsG)STf7Rjw+gklimq{({^|uuuLgeEUP-qDy-?%tLHtgj%X%fh3iRtV z{w~Dd1$5b7$-fuqYc&2A#9tq`B0EEm3Lc=Z(BP5_lI{Syw402{#E(%bW> z|8qGU{(6*IvSG8XLvLx(ak@6Uko;blvAKNV+Y)2g%=~ z>thGH>?27p1iF+j=`i+bEMPtWV_(8R&(r9|hz?_)eh-@Q!`RpPVeHfR$>=clbvlfF z8s`{YMRXYZ3L5)5Ka70^jeVUCV_(tjfaJi~SMO zy(JADVgik~jK37|!`N5!n1<-pK$rb4<$Hjx+YRx<*q8bvI*ffqjs+CX*-gqR1iG}3qoi^Z#B@R9VER3=u%HfhnS$Cm_X&svH0+7tAb(zvSG7c zS9`oUB^_b{YP;n30$m?#7bM*Ybm=pa4lx1swWLE#K)$+1*QXTd`WU<*=@2VY(jiu$ zdO1H^7sWvvaC!pQo;p4UxR>KLDE9yg_GIN0p99#d;Uo?L)_A@m7-&9}$%K1-0i>}? z!u$JhW&P+_shsVcKsQ@jaD!?JN3ZPJCDg+Mt$J8xp6$q!* z02)a(sFWI1V!UzKqkhQoMG!s-w1q{7V0TpCsf@mZ(nBD>d5vV9_ z?NCX|4yb6pTD60L)7HK%P3@Iet?gjlw6$+fSNm0KJ2WG0?KNp?uezePQ+M}=13?sr zXc$5@VSO66TGIaEKoAfX$Z;29*O(-j3F?RW0k z%gEYJ=bO{1jBihGW4BHLV1IL0Q^&5p?vCExJA3QQI?gWi&}Sxs9WCGu z71jQln&5W7N86xuZ)haAXWTzBN{ef1w{NfAR_UpRg0>*@uinTAW}!}c7hl4`37?(- zL6zn7P_Yfxb7k&sy5OPyTjuTvj|azw{DI)UeXMd(X}Tkv(xWZ+?rPd~7f1oh{=jfk zD6B~c?x?I83=Y)g?=Dy<0yq*J*&7*+3`Y*!+c)A5K>=TOL6PT3Wso+7F1r}ItroCR z|GmQzKS+Ub931Hz*G^`5Um!9O9tU1JNJsi;IbBk^cYX?(`{;57%DP*-`&uA+FqVnK zL8=go1buWR(AmVQs-Sja9OM22K%rrYp#%QI!9HzLW1Q98qR`%K>j)UDpb>4ED*pKX z`YX=*HQo2c!*gatQrP7GHX>8HKcCVfvTF?CA$lWH3}NoK49#i>ZJwIYBl|m z1Pu%sR7&pY&}iSV|K7+1^ewfr=w{w+P`J34J9_$h_VjhO_U>x!g1Scfv?~VaGq}WK z6nRO3i29WW>s)&2K~GNV^>Adok9iI)qgOn@oV);V-@i<6)qv#G#t3XPShYF;oXG71 zk#LxftY~QbUZXwexT4nKZcm$Nx4aTjh)0wMlqeUlHFrUV!S26i| zXXuD#XCbZ(rFTs!TqY?NQ7_bZp^e!rpncTlsT?msXVnHbeO zd9f2z@Ze{90Ug1MeDDwK1xX{o9Do0B#vfXP!1zM5zzTj5D6zs1gZsbhqq!P0p{#`{9vsQ2^oa>aW0x!wW8N}%2<<88@%rQWVk zZ=LZT$lCy|RcKSO=Z?-xBM^fxcS~PQc<#>6W|`-3l3@OhJ@~nFu($`c-XEllFl<|U z;OAq{HRRPEYzKg1&#j%86(<;mrk*q239k=&5Bi7Dk7B*MT&dHPVx|LMo<&vk0efP8u=4Dwu9p&3~IY$E3)D!*plkl zB9ws$re#w~JK65miP37aO@7#0Gz4zSvPW0Y89v(Xsjn$KkI+pZ6^;aG^O5iy8 zEBZ-@pgBc9wd*BbIpjKj-`HSjK*VBD#i<%?EL%U_xZPR8Yj@F|3{qYF5%x!REFX4S2!i= z6?S47isuZuKBHhmwtzwF=Q#K~gI=FU?%Rf(s8_T@vxyT-;GmrDJN6$CCG^{rOPgFK zw|}s;-{ctJ+w|LTz=@A==1xEV7WGoMp5?3+`J~oA27Q!X5p7h7jZj;E34a|8-gPJM zIehSkXP%xR!~rFQ)G!G`8sVEBf1CP2B}e?Tr(79EwJUqT`{_h}2Onp+s~N5BTP)({je+lX%!IY{Qq%fOHP-;R^UBnOG>2pOi7=kT8@n%AYCe8EOiAI;3{{X@mfg|{na z9=KdF)AnYCXCD3zy;b3P{ZAF1qnD`UrsqKNi3~;mX(Q>cQS{_F8=3p=B+UXCT#e@y9j9bM``or|UumwKPaF zWghLJDsFW!rIiMs|3g_Y@P{(WftID6tVJ_BcDOv7e6C>CE_Yfs&3WlE9Xr9Xi)ClJ z?X#;-+sujt_=&`L#quQ)R`(JtiH7mR<`@rY<%`R zb^_n-g$=bNIPLd9{ovhGtHeC;5aMFBq=a5Wdzt3)WNfaP^%p8Vn}`cMveqc6Zx!{X zM7{aWSuM`FYWDM*gYN?-_LH~K`zhqjX8RN$&K{|QgYpfsN;dqDf<{W^D zbe69DYJ3+rKY5S5cgA;id|4U$3mEGcZC81$^OlIXevmv)%2=d5NY=Z`h=}hSVXIa` z&bU&WV0D2Je;*CyFjHxyhge@wEC-FjGFTJW_tMYDo6G200&%_F*ZkPOe#b_?$;6r( z8rRMEo^Wq{Z^ieRb$t@{pD|abl^Hoy3yzUIo-JctLUx~lbrtMBIYQ3(dLKI(vN;{( zTc-WI$Dz-cxi&2x`?L)+W9`>_N?DXo*xAVUR2;n?M#komn{Fm69p}Z^=cAtQZ0IgS zjD6T2q<>!#tn$K%qpcQ4VJdny9YEVu(}GG}}*T|4&jrk}er!Rdc+2a|pe{B3~0YWUkYQ&N2$%rAHR zSJmXq)=xJO=bF954xAVNIqjw^k30UHn{-zFxATLg!Q>A&cP9O7?xf!bj!X$^4k-Msh4g2$?XIC;M4i{Unl){mLHpgRdseZ=o&Z;$khb9$%R*F zapMHb%SM8oW2j$H#lGkewd;?JLleV)p zjZk0m?7Bgyb@w-4v7PZXZyfub`_!QATfW{Wx4y8cyXL?*L3Yh`;Ddjmb~--~HT#-7 z{^_+%ez1nt=UlUHfbu+FdvU!VYWDSRs{QFE*FIb4^cLqDd*}4-RclCRGVqVJ_Wr7- zrn-?}@?r3Gm%B5$>#41zb9#HU))t)Jz8UKIg669|ac;Ih*|^(Z)1Q2PSA!#%3~Ye2 zKeeSKnB23mKe_rt^{)k!|54rSYrg%N|6A+3MS~jMu(yUISXH+^=&IUj4?Di(?wW2Oz3ZbJp5OlHE`Lo}>vVS|pDzigbST+o8+GcQwyNfv zYIoLk^j1E#zAf3&RR3D<+7~=+$R!FFo?RX|KOB9GnIWt=C?EdDyP6*{q%Y`f%9s z6wv2V!6!?~sn@k5=ThPFFS)huZ=`~MQ(7K81$^+a_S9U;uJ?XXJ9#=4248DOeli>U za>+H#A>#U;&HdENv%yD8t_eO^dQC6|-=8YI=04kc5;$3MOQ|c^cF~Afyv-1Uo+@SW zj?zK5gKTt>U;H?OV^BfyC!N_1{&ih!G7~a%X6>ZcX#~c*zlS)W{Njmk(~J+#AOih! zyG}{sqi50n`Cvy15R{kyT5rCo`LSBRqsis%pAPjA*E!cGTx)i^O6~fm{Tgs#t~^GC zA=|X&?hZoBGVL_vk@SN+V*xbmFVai{{Sf(!^AEb5 z9v8V5_9iai>h`9Y%aT4z2`(ca z$Ro^huUV)Tv8R$5#ARG{<;Z5Le45Iq6`${ZuZ?fM-pPFZ%Gkd+r?4n@tnz6ppJx95 zz*YQzo-5=NR6b4R(|F9g!vA-oaYX;W^Zk-fez)Sk%BQJ(n#!lCd>W0lDxaqEX;(L& z#`9YuKjt>_TY?t(FF}j^m!OH>kd;rX%gU!&Y4WO-b|QM|d|JKAr>T6J%BQjaYgwGn zTlyD)1>_ji@6*ixzj!ZXTyy3)u$bSi1^c%DCX*Xo$)2uXk)k-@Ny>vd!tMX|opQiF@DxY@M?gtjX2Uhts zl~1F4FM3x#zXmq0gbTj6S)9f1c2oCz(q{lHBP07h%_peer>Wnk8Ifh_=W)DG$N#(a z|0yb;rt)bjpQiF@G}fwon#!kL-FzC)Z;AYv+sJPTTI9b3E%IN2hUcciDCLK7|0rS4 zOaqp2|EPtA`$sJ_+&^m4OXt%D>62m9^V8Jx)86s(-}v73y^t+Y_j{`QJ=Oi5#-U)|pQfIlrk0eHr@?H?wd-Aar(8geLEZ1E?)PM4EBE+X#;=RkTAwCQ-*&?D#qZYjl**^6 ze45IqseGEsr!BopSnU{+2eFW-#1duR-{r+FT`v`bGOXSDk`Dt1C zG%GFgUqT+9pO%$Rt26UsJfCKz;r>xeIov;L(o5&l>Qz2X<(!&!XSIj`C9K`DyC;Y3lu+>iwST{hsRmp6dOc ze~$0>;TTJzSPxXG!93yANGs!3qlIwmq_53vT{51Z5AnN^| z^m>B(V!6-bSRDV=^V8Jx)710R)brD5d{NI&Q_oMk%Fj=;&wX%<@KzeN5_j?W14j?>$@G!y&gi{EgLU;Q zr)B$YK<$%QUy#_3Z~)-}gohDMAe=(@6vDFzpGG*1@EpSP2rn4en15zY8q>0U`zRFi z&&2wIPT5DG$CL*>ro0{i zWrj{a!a8b~AB`Oy`N5B30?3UE)d3G#yr`5}e+@f7OES;Rk$_+Y2$2e8xh z4?+G1J54_5H|0UU$p`%=AM~4ig6egldUeG2BYpt!2M~W4@e_y-elzO=znK{PX4(UO zLwq@pz;BX|><2qdKG2)ipyhBhX3n}j;*=mXSqCgAUX@=x8#x^=JK%dw;o_m zRW5m*%a>TC37OyRD5Z1I0oNS#U~7eesWG&yT>O7KTxZa04|<5QN}#C|>3J?xw$4T+ z2$BAVzAnn&Ouh(zGkI1g{>bldCeMvTC*=1xlP|*GOnwP}LpdDW-y92{mW%s^n7^%M zl~5-AEz1`ByR}GvGx;L?&E%2iILz;FCU46=A-}(wd=dU;@=N#|%HiPt=GX=_AKyF% z(=vMR7d=E-CD78}vTU)x_Z8`HCSQcVnLM)%f8_T!lc&wF9QpmtGnm%-`0sN+^^5mSv0meFFroqT)A|FT&qUzr}Zy$nS3^UxdGzd=dU;@=N#| z%HiPt=2-gMc>g5xx3vu7wg9ZzfNhU^(*po5>g9Zzf-aznT0J z{)TcmxW74;{^omR9#5=g5WkVXW!YkXw-)JdCSQcVnY_i-1SERq0d=dU;^0Wz-Bfr0yd=dU;@*SvZp`OXORyG{r>MR z>LY4dU#8z8Pi%%gaGzYRBamse$ftyU$1if~Z_Bh>KO>9EKT3;FUr zIpuH9bXnw6Lf-Y^obuWB&kFg{}$9= z!(u$RpDt)T%nJRLKgg*+d%WpFzw42l`m@LLu+ZQ5bWZ)*^JQMl$Ht?e|H|`G7y4@- z0sU8=@54fW&7Pe0@5%I9$B&TreK@ClcKn$Y^0hbTl+V_$3whsakY8*+jfeDFrLh#| zAsjUJ`VCAS%C6yohQY*Rc2-#n&~BrwDXXjlX!@=csxy#PRt_|+k;VF~vPz(7HieeC zvdXG~rr8%-=FTds0h+dwmg!k#wLot&%6wU6eL(9*SvM-P<~yindO(~iZhbN2ck$D+ zKC}Cm*bV)KuPYbU-0_E<;mk&mUA+DKBk2Ig|9DMf8py3moI#MG3*Dw!lo0tL;qryAFI>Lx^@Yn9zP=dp1+OoLJx}Kx zZ`u2eSux%UUthTX!q*orU-61XlQ-0l)?ID6u6aZ9UBH)qll)5H zOM4{W3H(m_xHvlgxgL&xXD8cin=9DF!^bgVlb6=Blq`_=&6Y!-UB;N;oX}{#RI%B^xL(2_H23fnc?q0a;f2$17``D1EsW{rWMfNvitb>n4XMG z9E-+dw|VQf`n`H27LJcZW23iurzQ{I(&XL!q17#kiTKe-c=AK5b-g7q7MeU9pBSeE zkRy>~G#udskm2}*NdS3wWFi(B(_^9W$Zg*KzMjFM)}BtUJ{F3NPK8E+7xwCt_a*?0 zB&NJV3sW39J{gIPL`H5I2~CD{C?4Xxgm z)p>8V=n74Y8aBie(7K3M4~>jWM2;QXHx(L-9*#yP*!fH|sEK|Y4Dugu^6K%!hmS=j zDd7kGN8-mO?~okM*e|7d3w2OIVJ=9D;OI7Gt`iV-ch^57z(M$4@-khR<@V_eIvGW-D+VNt|?SgRp6+g4?aLqxn?6hM{5 zt_QFWW3ir|N9%xnt9j5guQ*^|W*+n$aZr2kL6=xz>vHw2lpbmy-H_0OE$|Ep?Q};$ zNcSE44=}dzValaVE|c3o*xGM$0NmBy*VeOlsJ~}$@Q%Tuj@ARML;DZ34j#DAdn|k; zG9DT-mOk&U`@G|!qwxvvE{MLh-tlORVL#wRXfk{R_ z($fK>p)MTSu_LlQdjX>dcklhO#MS$ax@dNQhd@MeC@6dQC3I%-I1x5bj^%2?>y6s}* zwkDtwp?k;TATXEHVLxSh2ulCoNg(-yFLQKLv*_WW&NG~Lmd!3 zn8?(z2sMaBf+4yS=xt+F)lok&iOJ9?aA;U!=0 zD*o#J`S;^?+y;gtFc}2a$%i}N)Vc^3R(GX0#$Z;^zbQt%h$!9~|m@Ou=j*V%2 zdIQsMc7`dL^K`n3T5E4y-s#(xcRF{@J2swn*Z5H3r(dD>>+^SiL%pT@cT%^Z?jN0q zPbJJwUOWic`k_Vv8}Ez9;JZ8uvSxsqe}zw=EZ42{{6l*Xm|tjh9BDYTYmZ}_h%SPI z9mn38o!yBMH(S(BWGf=gg9sk|@93)6;i>V6zgg3!6D={MEhUF&?S1H>DEOp(1Y0f zHbi1Fdk#I&D6%CO`W~Lsx$MDrrgyGqFqrlJoav1iibcKiLN9uMlV0>*@&D6{{$}48 z`s;ZcgfsXG&!NA{OV1I5o)g|F6Q098r?KdLdC%2)r?$g(L^k)JKDzuvA2E~wSJEPtS z&w1Vk_Z*9Lo#(WUbOtdJ&-wmNdrtQzJhx!)lYeP*58%1H=;J>8;o%Q7Yy3IxxE{hYT&+^F}C%x1mtT%k8&C>A`Y`xBmvyh*NRz3`k#FFn^Go26!i S3OOgm+Kp=*%J$(dtp5PRE|(|( literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1024.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..fec15a4ca1a3a9ceceee56f79dea0c28938bfc57 GIT binary patch literal 121374 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 Tkr;p%-P6b2Ip$f-H#Yr$#@qdo literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9ec8e5e759e250aac34ec2c150cfc1c4787d3084 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..83e2f29119175bc3ac2b882f5087fa99484f4a5f GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..56bd566b7d6777960860a34878bd857d7a94a2e1 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6a4f107c4853d51b4115bdc17d2e18789ab036a9 GIT binary patch literal 2592 zcmbtUF>V4e5L_P@grZ2HNRa}GD|kSDkSlly1^?g@QREpEc?eHHydXaz<2}!w?VN}a z6h5!*o$>4r7B`vJPGl`2&7%mW{qN+eH$Q9oFpSkjrjXNW$F2^*J2fFLG+w=5%fAJ&3FgBon;m41+OLPWWdmndUM|PPQB|wy;Y`nL*7Ot zx@xiKwt<&MAO<}*qpwCh_Z0Rfndds*$@d=j3cunW?8BXy7-8rVdZ5>>vs$1B*8A3y zrPy=mfo9PG5r(eAbNbDDaESFD^oSpd^?v7i2Mh(H-iJ&tdViN*^j`7*(~JHl|1tEp z=WUSAWazyVzH{iW^3rp}pyz~d%82Li&S@@spTBdpzNy}Gtse11aS!T~t1Zh<+9VS6 zAnd2LXpl$VZb&Ki+$!+0j1h*S!E?$x^4=J)9F4eG?>g5zU?>>%=3a;AjJGq|^8eVj zQ16K6dfo=_9E)|E=d_OW95Eu#_5B_9obHWyZpz-v#)?tg19)y~S$?ufBJa7d|HpI2 zdmK`3@toqaj1h*S!E<3hO7`I{#J{aPlxP3| literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c480a89798aa6d6030f1b7cd67bf5b3f942b127f GIT binary patch literal 76062 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 dzjyotNnaTGtU%zwoaaWo6m7Q)`^kn8_!N( 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1344.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1344.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..344244434865d9f3569baa0b84fde2d9b4e2f4f0 GIT binary patch literal 2592 zcmbtUyHNu%5M7-x?SCwK|HtZA7Z$W@sM$$MuvP2E|7uuYe%cshWC;d2n|i zlaZ9SVK4f;27TBb=Tbe$>0T^+FNmJ=&b(d&r5SJ3+m4x5tQWk@anFdMG4YQBAu()uEm~PdtMrW81&pFeKp{@8^1ToJlC-%JNw7b&*B+ueN9$~{vw8k zn1PmCXT87-!t7g@Y1d-UVFsGTid&810?%oX&tRA8eV;I)Snp@9H)1Fj^^P;WnEk)> zt_$^IzPbFag5 zfj6nO_&>HT)H~og$J^kZW3$floc58E3|nCY-(e1f=2_z;ofU(56QW z&cN^g@m%2j(v!Lr&j6lNT(&X6P#}2D@Ar9I4`Bh3EQuBZgwZbGkp^xxky$ fTC5kIE7D8Pb*N^l6`@1MNEVwI<4|uO?n3+vE&!bR literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d4c844ce86b064d6d2e66ed9082756f964d01821 GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..09dcc26cff51f42fc4fc5b239e6acaf0da2471bb GIT binary patch literal 2592 zcmbtUL2kk@5L}0VXjQ2kdguWOA9z52&>VO~j~w_1X~m(>;Lv}RCm>$XpU}zLV>@m{ zjo{#9WADt)?qD&aNo_<{B4Y1F@ald?Q@wO=)`fnp&LW>%k?Opib)TwtEPBo#;G;%< z_pS>+;yL2`$?eM{J}gA${ElbMJu&Sw;-n_W^_Cn4#djqifFRYSntF+O@N^=Rk(Af6 z7kyrXKJ3m5sb1xBFP6R+M9+EWUax`Dj5q3S$4o2M3tr~9XT;E$dUM|9M!l;-y;Y`n zOEd!x*AEoY%`<4iARf0JI!Uh)6a zi~08cW0PEGpLWIR$wj> zL%(1Ke!t%fi#+nS%)P>MOV7(TCK!qa&nfS~eG_=4nUc9!?<&_DF%*k>bFag5fj6nO z_&>HO)H~og$7^xVv02x7PWwn_5F_!NoA0pabZ@|O6V6_&OGopHX8_NI%R-wTF*L*s z{Qe)$1>S?6)TMX^@SNhZjR}SV!E=7U&)Xm`=-uCuxmYhe*Vh{{6pMNXJQsMAT8s6< cb47aTxfa#Tv?6rK7|CK2V;t)3!(E7f0r2mgz5oCK literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..59122cbb0979679fc0e513c92679dcb3b7072011 GIT binary patch literal 96542 zcmeHw3vgW3nda$-TI~m@4Z_py7j4;b2{5K5*|M+=ZoQ0*ERY|t?wxE&ZMkjBSPyJj zKr%p+5Q+q5N;A9TK@=EeUJF^Wt5jw;4^NUN!+KpI4*{9fklAImDR#@7%~rLu8Dqd$ z`<-*{Ip@Ev?pAkfQd8w~RqFo!|NQqn{(H`M@BRDSb06+Ivaf%zp3T^;s0aSjzkTd5 z!?xlP5C39H7J~Tj-eB;RL*KpQzkdFq2mkZ*(3k%DxqTlF?aj@((oqEPJ&+pMGc-JO zWa!`{Jp;*pkuvR-25QGB#Np)8k^YhXp+RmnDASvK^84weY@f56RFcokewp4;A(cUr zMq%)d49DxMwu&;o5|$A0k$>N zEPDE(1NZ&#)K|tC^NYH#hMt$X-ZA~x=^s=(P<(A~>+X(*qReSFO){Q#Y3CLmzWKH1 zd3pLs0Vn%YJ^cg8gDJE7G6N0bgZPEo+n4|4zhLYy@Xx>LrUp4b=omBla8sMh#iuS@ z`j{X8*0y_50%Ipphb8+aXBMGBUJnLZbaz0tjmx2TcLsPr75|XKIWo(UgGA{8Wu%Li4FY5br4s48;!BDY%c8mwNN;piVx!dE#u`L>5m{qj;`bW4~^ zXCS?F3258TfL^(@VgGNc7>lHR!ALp~d?=J&@k8X{#h`eo!T!N~FDkM9ce?iOl&*sX;sU@)nM7+!%_iV4+C-d{ts`ER6g* zd=v90;hK(RGmJf+`R*liT=~9<+L_8o%PO670LO&?MOyll?sM}4iQa#zO#I?Em5C#y z#Bc>`t?hj8yWfKKiYKaDYoA&Eop1S|TM!-&uVaZ5vB>gz54xAkF_BhzJ0(p6}GB&_46kK6AD~<^WHj-rP^TzUP9gQQtQ{^?rdxu3emu}y#^$MUE%Ug%mL$&q6OP*WjxSV4ay=0ELg-ID@uyjcm$Q7q z;jTCvU)FNNN1^ipmY)Ad&#InK|7GnT?;QT|3jZV+jM*lg(&#ig- z&uZjclc)dGp$Nh-oFyQmwC+cds_FRIa?xgFuf?UVs_0<|9Kof zdyp|P3a-pJ;Jqi|zk!XfeX>yhdD)ZGf4+nM(+$evf06S0P7RK*i+f~F9`Ne(tddFY z;Yaa4wj@*uE-?JF9K2J(PK5*uq6cmCeDtBBIHx|><>@=ux%$qb^OeZClk@oVoB8LG zT2ZRtpJ!h99_ODy&OZyne=GTC`GXGs{LcH&oUM_qCjCd&+{K)t|IEAP={9ys_kX$H zOozL=PmrvCG?x^qW6eC^!zQV4+;KR=W+F)b4%C$uFqd{wu1KnURT+7BC^KIzdG+0 zoWVBV#m``T1Y}Wj-hW=+=Q-2Ie@fq%9-p$*q;;&}I@dY!dYTvl-$eSzvAv}{f@z>$R zXe@&NrTAZl|K;Nq%dW@K4G;Z~W$e_tXBt>=!9C0e&FTM;3G?F~9(paz+86(?;4Oi~ z=nrpfAB|o60DC{WIoeVeoY%Q7z#gv+d@=Q3;uTAR4{QjePN8MkVsA&s|1jVie<|Sa z8m%Ax>BRVR6|8IYbLXekQ0msddCPOEcJuNhzYdS>@_eJV^W?hM zS9Gl2^Ea?va6NqRA9+24e~OZ8H@E%!_g2JE8(v;;!J=-ii+uI;k{C*^?Od_;?^lF& zdfHE{2`=!ppV&HY0c#(P|GTxmuEkAFb^8;ePr=vQ!tJA*US7xAPc-(g^(0O--iUHu z@Yb$<{OyUZ(e+zntGhzH*-d|i(kr=&udDrOtJL}&|jQ)7pW{kgA|KGK> zxAH5;Fs_xbB^KA+m^e|tBC)t(dEcKWmu*|T#ou@Ge=ps(_;z2P|I6WRCmLAilK!RN zZ+v!BY;~WvJ-lu7`xSlZC{i|f4hEx-_r<*Z4dCWCu|2p4Gm-z>kpYQ~u6pzYy8B zc;ij$Jnf@TzOkAmMl+H26Su#DwxafE^-Z?|?O58m_nM{KPHcLGOC8JG7jJrH9Z+C- z`-zR*FQb{I;N#jiUVQb`I?=`#Kjri%NNNmv*!GEQmf~~SkKl>zs7qq;9g#lN*IWD3 zXkwybUf)w+h{M^!sfq>M zbKXP1p96;1yl3C)O`HHm>%C{+?Da(#+~_^?wcbAe%aGqrCr(x@@XKLu z$Jf(|KMpKRj6n|{dtaVP`=XsMd7qw4_rcfRLqDBJ{CUMSo0BZG&l7(6&56Xb71t!5 z2wam$C)v zx~M-?>2d7W@ciG1d0FNOc}D~pS11{g1OJFH$*1o;5eh~^>^hvQLeNHiP2-m?;!gTv zRpR`X8&7rk!od(5K0Ol&8vgaLcUmqI&%Sf%qMM(mXSUKf0WXisDo&te6(>-#iW4ZA zMO$;?4$V1n2e-`Lb<05_FY?Hv!}FdUe`vAs2OED7%$Pt7MY4st^0)DalHyl3{@{wF z7M~aL zdF@N{#Ms==@7VZ*jX$U;v5i02_=Al<*!Y8uKV0qc2N@4g@r1Aw4^Xm-7bsc93zUp? zAN=weDLH=v>pu9oN5#KMc@CG1=Q*@oJpQoDkKdW>`VV&f2c~{MqQ5-a=P&H@ z7i#4ZJO9DXe^7nlvR0w7@dq1!z#1#R#rj1h^&I>Bg?;|QK7V1Kzp&3=*yk_!{q)uO z{Dr*#SMda_{~+Q4N>=d#C98OWlCl0nPW+)+#}l0AIb1TH=Wxk*o3E()%f;gl^)~)s z;}16eVB-%q{$S$|HvYiOyHo7@FYNm-WMqSX&R+SY*c>3|{Z01$7xw)Z_Wc+3{TKYU z4x3>U`~D02{)JNp#vg3_K`^6z{=&Y0)0`n^UvJyzFY?`m*!3r6pGlM+zq0cm?DH4)`3q0nzJJrc zf78By)4qSxzJF7^1K7TQ^Gd#dQ{Mlpcmmdc5b*#dt9XHuRlGpSSpUJBv;KoOXZ;74 zjORIAGM?wqa`E`XF0Wnxfpz%o`VV&f2WI0BHvYgp5UKxio|OPaihcjZ3Koi_i~aU1 z`%sbim5o2x_=Al<*!aW5Q#Sr!;}16eVB-%q{=gzpU(=P0Kgj!k6;HtW40VJs*AO<0k@a&RzbT_g#rY=PU1H zOFAnV?pHVS&n2~$3{TdDD;VCP`@;9Wh2Pf)pQvuFT@e1;Z~35Gu>8UBI+i#Qi+tm0 z9~+w&BjwrmU);dP*V^?b?fR2){PEA(voeZ3gJjpA{J3iT{Kr)f+4U#w`jdA3NpWsf zXLHUbcKu1a{^TdS{-nJB=N*s63zV$l1xi-&0wrVp2lP_8@%=;Z?qoUZKe%K(&*75s zJcpKx#~*g_tJDm?Vx3-C>0Ix6*hXBFs;z>tUSBA(@58Fdfsd*-FG`<$-NVwKo*Dn~ zd2x;zf9z7#c*_S>k!k#&{irH(_#(Gj@fxgNoZ;vnQNmX_I{CJTP5tsxVsuNGOJ^Xx zbP0%Gc~8A^X~X{CR52Dw`+|7FIQUQ~z2b++!+VA?ejYpfd*3^K;U}y4d>XlRT&U#W z4otDRa7kUMf1W(KooIQ#GLbo7DbwUT%sh<$J`&+iF~`qWB^JlR$j`3-fFp0$pS0^g z$dST7XJ2pYUm@-M2Rr}4&VLArQL^Ch4Xw4C?>Z22cHvS;uPB#8v;}16eAnq#d`jY|E6Y|BPiv9L0_bd{>nsYXX%t6lH5Yb{eb7T2; z{!pjm z2{J#ojORIA>3E()%f;gl^)~)s;}16e01w#pC(ZdW-#w?D|B%lscKu0p*FS%bn1${? zHvVAWe_`K$Vc&mY-+!_08TdOaVB-%q{$S$|cKrvt{)6Cwe;%{w?fR24 zu4C7qwChh|M4o=%d5ZMZ*vwrQXKoD6n^7||B9*80^I+p!{w_2gvd>@G=P&H@7xwuJ z`}_sJpT0VuzmWI;DxMH_;sHul@d72QcmbCeVc`cJW55~^0lMaclDUn~gOu#ffWjey zqXfqYjuYHXa4*5b1g8leBY1+~NrE#3PZ2y#aMr=HeXTj|ld@_P%Qlnt85|}07{PIZ zy9w?kc$nZc!D9qZ5Ijk6hTtiJrwPtFShlYrr+rd3?W-g0GdP+xI7V=s;BJC@2_7am zP4F1O69i8ZoFRCM;Aw)h4wmg(mD4^coA#|F?K3!v!4m{e z5}YA;ir{I2vkrE~pFd~(3E8x7r(fYv*5D|?F@oa+cN5%8@G!w?g2xD+Ab67C48co+dc!U}ya0 zw67tjeRZUL21m07#|VxS+)Z#V!NUZn2_7SOg5XJlGXzf&JWX)c!Or;0Y2T`x_N^rC zGdP+xI7V=s;BJC@2_7amP4F1O69i8ZoFRCM;Aw)h4tB<$UPGD6YRs|hPCh)vxiCa< zl;9Y_ae})E?j?Ab;55Nw1Wyn=NpObXDT1d7&N^7Or!}X2QdVtZ*=Eu{gQG+rBREcQ zH^IFG4-=dwc#Pl)f+q>i5IjZjG{IR1%l0+ov`@;WeRZUL21m07#|VxS+)Z#V!NUZn z2_7SOg5XJlGXzf&JWX)c!Log;a@r?l)4r9YeFjIf2FD1F6WmR3FTukErwJY-c!J^JyHnD88Zc~WhD8Vs;;{FoOQ5l zUqep&q-@$(N7`p_G;45-;5fnE1osj=OmLduF@h%uo+LO!@D#z*1ZN#A+qWvGeNr~< zTS?kya5QUhjNmxI-30d%JWOz!;4y+H2%aQ3L+}*A(*$P;j>kRv{M}7(9QRP1Sol3) zH@UZhUY!3Oz1|mk!BdW2a}xBze~w=J3gv2yay5?Q-o}(`?#G}fd6MZky4--AwrG1WeX^eL1f2~LUT95p-9)8mp ze$yC!)AsNi(HowJ--zDu5Bx^-<~#_$89f;?M{6AmvughmY zA?>BZ$zHHulh3|a+N;%h^&Y6t;(Yc|X^-WF-P`n5e}MCeA2D;jiEBLv^UCnFg=&5s z;^aJb&Nr1-4VgQU?-wFzi#*(dG2?Iajk5eL?91@Cuoq?0kHY>I_Og;>hr<3A_GS26 z*cb6P(y>W@ORRjlP(4p6{OwMwMw;=rNt^BO<}&>)?91@CuqU3Au&}>{y(f2v!u}Ta zW%ygz7x6dJu}ObR?13!%x8y3G#-EMln@X#OZ2WD~X8U_*nf?~`W%ygzi@MQ|!u}Ta zycw>ou)l?U8U7abMf{C)Y|`HnE1xb@>!k~SyVI(XX8di^X8U_3NUJRV=JsXyTjcNZ z9Ty7wTiBQ3Z((1CzlD7feg?$x$o;Sg@ z752BVFT>x$z6^g0`y&2EIyUKViH*PIy^r*_I}Q9z{B6=^`y2O^W$}ryFT>x$-sNj9 z6!y2UFT>x$z6^g0`y&2EIyUKViH*PIy}0zZI}QBpC;Tn);QP(?H}2KT^0%-r!{5T5 zH^H?P_P4Mv!{5Tb41WvzBK}4?HtBDPjlX4#L;BmD2L2}gHfgi{-CU->g?$yG#Kzw;CMW&vP6K}vf19+~{zj~`EItwTW%ygzyL`=s z!u}TaW%ygzm*H<=U&P-?$0q$PvGKS34MY0dod*66@B_uu5I+%l@cm}{8?o-P{4MOu z@VBt%O>k|6{VnXv@VBrp!{5Tbh`*7JP5N76<8S#Jf%LaK4g5{~ZPI4@ySYq%3;Qzs zE$m&s=0ahA3;QzsE$qwix3DkbZ=_?B{+8JITmDul{q0Tze-nS3wAudNS*E{*eHs21 z_PhzMt+2m^eHs21_GS26*cb6P(y>W@OKkite2fv-yzI~?6 zW#6mp7yclx{arKLT=r>YANqM-``r3ZDEsPP=C#kQe@5AdKg?^NTmNZgzwAqS?Q`ot zt&Z2SUzT*drd59kA4dMOx7_|Pq4KZ(LEijx``d)dKXmu(%%REc&%G-D)nCb*f9`mR zYWpw2e(v$utLn4%=DhXE9q&Nu6Ly-tOZWd4=*rSq?}FP(p-ed+uw?Mvrh zr~c2wnI-YBQ~$5zwa?|RxX1B->HO=|{|9;V&*iVQ%D;5}mHC&>ztX;R{+0Hn^RHuH zGXFaDIXt`bLz9PprG4rAEA30?Uuj=D|2p<1^RKiooqrwsIr&#yGjo0d{|Zd_SInK@ zX)GrV{OcwB>)H?e>m~f_N(29zcyLah;9oD{U)O%%UoYWbR~q=&OZeB72LAOD{?%!D z_!sdabez)p*Rd~|f2Dot{Oj14%)ipUbpDn0rSq?}FP(p-ed+w`)W2l@b?RR-|2p;m zc3wWsy?*TVEOF{zGXF~Z()m}~m(IV^zI6VT_NDW$V_!1=I`t`;f2Dot{44EC=U-`G zI{!NMCG)SeFP(oK`#JfSvyQkv1pf+5_*cyNbNJVl2LAOE{&l5+fBl4iU1{K76VJ^l z5B%#V{Oj5e{Oc$D>q-Ov`U(HK(!jrd!oNB#5C08nSZ5y>HO>1&&j_!t_uDYnDDQ7w!q5tps#ZD zTZq0I`fDA16Vb1R9yJ&B2@<_OyNbtZgg$(3m2P8G0eukq8yx#R#6Awa_5;!HDWGqI zezB9!UShukdhIu&uZCXxf#{>qU+?6zgXot*U+w6-i9QVdb&kG+=>6FS;)e#}hy3~= z?9o?*-=gP?eH--i9Q|sd4?}O-W$dHS8$TGmKif*`(@N@-Umt}1^-j4v&KdhH(3|=g z{SN3&eT;rD^txY>eEiwnq&~ZKeS*+eI^`}qXY|$3oBWM_OV-Em!;SD;^*Nu;rww{j zPov)fy*chiAA;T-U!xB~-_Ed<4u~3%%*LMh~v@60YOrDz5VquH$!# zit7w!OZmN~&__K>wH{pO*KH(vaGjrUowf(p`SsW#_TW0d_Bqjm>->c4bUxrZKjAv9 z2iNiYdQnesoz{cv_&v7JgX^>&T$fi5PV*bz8heb{y!sC4b$v+wP0*V@Y4QP=`puX! zdT^cbC&>rg;wRjq>klsSo3Uo{0oNJ-lYGF9#{WbQ4m5rydT^khaFi|=+-{B+u?KgV zesZos+kcL&aKgPbhfPO9X<~SOAa9v(KIEwhw*n`uE|BW6TNc>>*)zIsHOWFml z^P90|?Ds%#j*HQQ14(;ZwSU?Q=)rZwZ^jNpcI*0s14;ihdR*6$`WSr_dd(Z>j2_(RH|Hjw&L7-J$~Ag$9XT#W56&d@ zF?w*IpKu`0KO?UFe(m!U4n!Bz9B43G8qn9So~2q34#XR>q&@E4v>qJD?++DcYCSkG zp!*WB2L}f9u_JnLU_f&V(Srj6`q&XYIFR34D-P7RhYN z2ON@D4-O&6(b#uDZ`x(_;0n?%qX#FDdK&#Q=yg9N^#NB9KkwG{Tn)YHKSmD@$*Tv4 zkop+=Sk@OHT%q#^hmdl8TE7~4b6kuboDd+K!0j^*Cj>Yrh!|BCBOINBfibk4fgG2z zAL%iO$X})7VQvV<-pewOH&my>tGS;iE%`Q+*?M&W}d73?E6392hz}zy*l=Q=|QTDJekg8#<~5h!3QW z4yKMo2a^M-J8HUiY~R(>yuH09dL%h`@ObhdbbU3^kw=CB_75MgQMrhWQxA`%2KT4- z-?~3Jl8hp`M`qU3zyFS!*u%HS>T03~jt};Ypz6sZP}M|_9p5K2tE;)ql~?lUL8lHw z!)RTqCYs#8|7hyiv7N`0NBR%+r;dvKMb5~k|1+pi?BS-G=+J=!$5JC)h#~(&L&rw$ zH5#edZLDSC$NL9I8rS!X6s$x4;IWaT`Ko{x@hadee-%)n(yGvRD0wt`bHNG>7OVjp z$!kz=YOtO

8fGz}h&Wp}vR{_6;Gg*+;=~L4&D)>nPNrfYMwrI@G_vum|=Hp`e1L zqmaA@psw{wl@13NEPX?P((A8S+u_}Ur8gET{ff06%_vy<#sZ}`Tvpq8cTW!Xr3epk z8X_FAwpJ#Ecw4S=pPg~20WY`={p2{tme_RHHT8k{V7;|wx%n2u)h!Lhx?A~>mRI# z;qLx}gUONOM^igeg9k_WE(e?qiJhrOT8<3$JwUW7)qY=H9zbunZ?ONtoztuHa2Z&Xlz8nwv^~!yM_j+3Gbx$%S$-y@af~o zsD2&)s@s6;xwSQ2{DOz~-?cT{2S-vz4LG`A4oPH*w6&~w$#4k2eAj=8$;+A zE+lcu)?v6gdPba`h1}CObbN3GwtSEd^zd|kNm;Y$_hH<_FISM()!x<92KEpp z$B(6Wg#;7y@GF7N7Ex3k_mi*~NgjlT(~=PPC6A?goRgZcTrWL}_Lf^lpSuXoXmb?t zuO5B0m|GiovmL(gd z;srZ3%*`nobJZ&MVD}IA97#ShbR375J6auSdE}5d`#^8+?&;p$)7if3p7tFmY@o-v zX~1E_U7paGy9%PzHy`5o^1BbdbIySu92)5norkCKn;sbFUIWxTI>!Oqh@1;~qtWHp z^?fiUUB7Q=aFCC#(f*M~+z#Pmi@Qgr4`D2#^W(0l2SYFQFlwniCf%v^qPsgIMl0(? zzoxr4i2U`@(3W|3=VwxP>FY0V_YIe~yL8TPU3q@I26{^0eU8IlU+nnra~=QNx!=g~ zKX`QL_^>|8vwK0EWI)>u_!yqm34h1kAZG~J0a*G7%5mM59)RRR1mlaGBI_FW;Y>zO XlDVfNIRLM^tB*(X+-J4l)As)X>UVa- literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1472.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1472.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9de67a3838036bb5fa57bfcf5b4b3d4007521e14 GIT binary patch literal 2592 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�AMsXYx;g zE%nt4kKJ|P)}NkuV$`yHyzVQZXJxLnP5(>gCzUqjU)x(cJENhfWjC89X-_+}=NIn2 z_NlM3^3;_A?(Ru<_4IWgOzYEUj0Kj&2JzQwHZFa2z_R`YANEZTImp>X$Cy!)1%M*zGC$0w<{t^r2OXHipZh&Dk87r(|eX%{Ssa8(P`K(dkXe{&(RA&Pn=`A zUjzM`p~p@E{q|g9cuV*@JKwIbtVpIT7|Hm9cZD*`Fhnz642rwj$}+Eg?C($h;V)KN zH=s`ca4vH4%?eT1$d#X4Bv2yb^(UI%3?wFgA7C1^EIF6AX!PH02t}4%8%iAC6#gF0 z=ST3L&Ls}~0hWp1{ULCot!!fMxTkIY^nDXwJ||6B&q8{1IuP-$P^I{BP1wJPHzjrV z&$V?ZGa9sbc{h5lZmwxxdczOOtmc||;cR%dl{g-YOq5yhZfK4i2NBB(@lrA}Upx1J zHx!xnghm&Cw=%NK3c)7}?3C(8S#Cy_Tj-p*@*Got+yCDq-WOg=T*RI~A$rcSB>GVM zBekCEtPiIDB!+(X%-7JQV7eUfwSg)fibNj$gDtlsNzhK88Ny-0ZZPG1)l|z7{GbQugxGXJTAsB#;WheAMjE!dU5AXzk!h}MznMM zuDZ0w?}FU%`=?p|i*)=F?~C!f>Z2dOZ9X%8KdR?x7ktEeGP(bf9>nGYgNx1hWgd$B zF|!$$-skf$_+4CuT=vI3VN<~B7=G?y+==b`Z@G0Jo*6%BS=Ao)Fv;(Pm;uguhJYvL zpMCipeX?G<%sQ5_9<9CqOH*F{)IH4a$u)jHrkQ7oJzFPEzRBmf9_z%&^i5}{uL)vK zY(KY00w>k1akTcwq0vxq;pifKuktM%{j(-^=fB+w3Z8}kGu{QK&%GZwJ^X$k@w>Bu zMDN+a>8IZgBwl|nkT`_TZ{7_g_T%%)JAp*hR+>mD$+0yTTiUe)*iS zhi-f4mKE0NZSU}wCA@R2N0%;YPvZY@yXD=yy(0c(HXNTfeWK>sD|??`_N(x8;`m>O z6T`6xK1=Ya!e{AddDT^TjtLL^bCq>s^%v`{;Jlqy88j#Vb|Q@D0i-+?wpthcCiv(6 z#PCnAX&sI&xYPPWbaS++E;y%swcon0#{c>B|B06`4&J%WpFY95fn~*BjE;WEUpD%6 zzprC>&EPM_Mjt6h-?{&-N&J8EAII_k&3C?e`FHRd-08k_jHZ}jc-H;%f7&RUe&-W;mO^swpUp-tKWLwb7J-8Dl53^AKBRt z|MJ^b$D*x6FCu;ON$a)Rz263Ef6Q}ghEu7VG~!|ECQ3QDfo-10ZCE{mZyti0g7g`G?n`Clg&$53)j`?A_! zE(`7Qv>sm-oLAO*eCwQfR_k#5f7X_DENW<|+n*SI2)^DHZXMqA_-d>5`1+n&PvZFc zYf#SDyfwA=y*Sn}ymo7BWykQ-o9cau;rJ4q{rOepiQ$` zH2md;`e)kb?ucv~-Z5uYd1|C)@wVYFc-oIY!@j??%GdsvJAi^aSC*yxKSQn$`Pv_T zFtTmYhL5lIv<^S;>`E&!JP~O+ucDFT)c{@O)eI?4wVfSk2q`=%3mB36dOv9&7v96-)4c)z9FG?Wjv)(G8Il z>g%ofMKm#1J}33igAwoJFGdqz14g^OhhB&#{t_51@E&?TS{8lwF;CmKqA9f2``TnO z@lg3Z<~i>n;QN8$HScRLBooJh(R%M|&nL^G^RDrp`c^XKdmQqMnZ#q|^O@JZhhEI2 z=6@sXZTog6@t^(k6C=>W$KJ;$GiA~CuX~S;XHxLB_s}oK5`R^G#pZ4+w9*@X{Q0rO z!{t{bKI^|Ck-_)p{a1Y2v)GCsE5FVkN;JJ~vz2Hw7^p3%7$_0;SxZCKOFy4J{T4W= zAD`cXhwi}VHSo^?d|n0r?89d&hkqufx3c;FBb!(hRU8;un>cl&zsI&)KBT{W-}iZR zKgcW~|Ees?ZEM(B?E3t9ONJ?e*8EqZn?Jt!k=mHAAynOQynBZgdNK4sXx_$~T?^RLG`-E@|C z_Vl^4PJW)6-b&-ftUM;mxUrOF+*ryoZY*Uh+ME-IZp?{8J7w!-ryL~mLJz+dEbBb+ z=q3}7Ht}dHaT&$aO*}f^44_c-%EY7DoW{hXF>fJnDK5bKF_$w+GM{%DPZv)-v!6lc zYq5H}=d$)D9?h->t|8tFn|L&Pr(9|eBK_aQvo74*`O?QP@xF;ioA*iQf4eR2LuUL6 zKYTP#4<;UM;?X7^ZQ{`;9&O^$2!CG2@n{hrW-(w9k9Nv3ek{{v{8-9Xv_2;uU6&J& zcFNYvPB}>A;_>J;CLV3#(Iy^!p4Ge`-O6;cKAO#E_`JgY`v$yUH0z_W67_tmy=Tma zUB+|e``U{mqD$uUF6%GaeR0&@#G~2OF!5;pH%=xVE&pDu(E8Aebo`olwE6o6^FGP( z_hI?hcVBGdH)7UDoAuFVeY9C0ZPrJd_0b5hB7Sfgu8$V+VHsZz+woy3%lNUBW&Bvm zR&+&9JbHOfJlZK+FFWNRk&DNpt4%!G#G_3-+Qg&HejR?ZUkAJYn0U09QJeMArS851 zkD2{C&T}U*@n{o|)^8_@z2`3U7fWQn9kXA@N4Ni7>F(}$$55zl}nSW*f!N=1tw)K_biHNPTl>5(`{W{Ek9e>2% zCy^dx;?X7^ZT62g`$wDoqs{)&?0LuRA8q!J{($$7=J8+|U&j8?4q3*JWx9+XOBwq| z=ftBMReagr|HC0;{||?Z{XdjkJRaR-;?ZV(v{@g0o>gtd)-j!T=02-mk~I5uF#nqU zI^=Jf&LSSK5(XuD7@0qdLS=|*}uJ9x8hfO@o>>n+E+gkh{saYRw z-Y1#&N%ph5b8UfOZnHkxtdBP9qs{tgvp(9ak49|uGF~4o;=wY$9Jb@bQkL;!Da-h= zl(BzwPCU9!#g|1q+9_lI4@Wxo|4?%Ac=Q?*k2djW6OT6WXtQ63*{_4$e$0LynBj|m zGb50tz6~(@M>9_%rfPoAuu}X6XsJEO#G?z1#Si0c02#mJZGc%HZPrJd_0gBg{_kf0 z=uxwOwAnw}>>q9Rk2d>9V}5&??jOzL!EAm{S89$ckGJY&&>>usT*+1HwvwyTh#{M4;8T)@Ixp+K!w-+-WvwyVN zKiZDSlKJnAX8&lpOTw%o4`#oPJh2?_0(KuxR8I$-zk!x$dNYui_F5_{c z^x5_OLgS^>+MD&!%#-3ij9>e;0{l*lu@nkek!9D062~`%vEJxdnH5Z8zH-Ws2@GU$ z;0-qe_O)=aKaKc3;pUoWeK-DqmukkZ?LFqhnPYKQPo*xdhkfmF75MYlB|3i1`e?I0 z+A`~-&H8AwKH990#`DPKxjtINgW2<#SkLT~W&BvC%lNUBv43<k4LXD z@n{o|Hu325JjKsyC5l-eoo8*2Ss(r3{KYDXXOW1g_+m z2g~?!*p3fNS;mj0EaS&g#{SVc@#y6$zAWO=P8s`uIMT8IhmwoOqpM9k+Qg$xJle#g z&H8AwKAPQr%=&1vKAL;L>>oXw-BLtUb@nUl$@?S{5jFeIemHOQ%zhoLAEOVN-y=1@ zN9vM)F1GhcCLV3#(Iy^k;?X7^{ep={V}5&i#-l|%n9c8L{8-8|ek^4fKbA7~kH&ML zIN152mv>n?`$s!u?Em4AvHypXi^rpPv!_k7f3(>@+K$MQ`LEeOda>NK*Q}3@tbZW% z6;J$_6=L&^rB^-Kk+DXr?!Wp+p||{>tfM_aXhgEm@&!)<=Kn@hswf zvp(9auQcl`FO~I`;)#ewwdC&OW_`37zh?YiD&yD0qfI>8#G_3-+Qg$xJeoyRFVA?i zhzGOwi+HqCmhoemF5|~i#{SVc@#sbsUl#c}W$gdqNXPykN-iFcZZh#`vp(9ak2dS0 z&H8AwKAPQr%=&2DdF}Tr0dFYc_zlETci$xID@{Dw>>q9Rk9P5Ul49(c{iDtP(dPF^ z<(-Iq&-`19S*?;Vzh}sP<91WP>KK0RVf?bN{d>aY)_r&e`lMx5d)SY2+D`(rXCtiO z_}Q1w(QCMLnRP5!a&bd|Bk@l(GMZBOUvHD7kn%dX0%kn|QQ|N1J%GiAS4wG{50ow7-W& zBD%%acVDFOEK+;3KH99WH0vubmGzZoeKb5^_UkbFb&$UhD7IhF#diNS>!VFP+Qg$x zJle#gO+1=Sa4*kzw1@|@_S5*Wlx6%_$})Z|W$YiF6OUf5;>#jGr;PnS9O>BqL&?SC z(bXm%ZQ{`;9&O^$CLV3#(d_nP)<@fGqVlasGwY-CuhbL2P704*`ME_h9^qA-YT{XP zwOS-oY7Y|8P`1vV?if)l9(2*ZPr5|oStcHB#;+N_?)gXZ|HZKTzT{0YhUI=cl0D7( zXnr@(co&>L_kQ5?@cV(p@6HAiy=McbpME=#c>TRV;t)Q+c{h;QkIyUb1QN-20+F!T zvyY!UHodiVxM^FNbpxIpw@gR&y;~7^6`up|RYYFH=Z>=#k>BFe|9-{jTklug)mE07 zyH+|M&*cbzKBWUS1|w=29s=$FqKd+4@zZdqZS-u4b(`JM32u^wHzs6C1Q!|j%L z^Y)7Pli6^5-t>u@XRqvie%Y_W(~0AM9Zn3#BKR!9rwX5?qvcgsHP>to5BzhLbz=1w z>#g9tohBY_;?X7^ZQ{{vetUVwqeVQJwV%e1r7YveQkL;!CNIRoXm$?vkoMC(qovGj z$~;KP?&5z@#Bhkkl+l#BLt5TJWlWg z!IK0}5uCNLJ^pgqSD(|qI?_Ikqgjn(1jh;PBsfX%Ai)`eM+hDxc%0w~f+q={A~c_ zHj?&f93}b~!Eu5+2~H9`NN|SW5rW4E9w&H$;7Nj~2+rDAw68v=eL~jlt0V2xIGWWs zMsS?qPJ)vJ4-%Xqc!c0Fg2xG-Ab67CDT1>$7VTS+(>@{V_AMvv(>R*dI7V=s;7)>* z1P>CNA$Ww~F@nblo*;OV;3kl+l# zBLt5TJWlWg!IK0}5uCNLXisxa`-CjpWMvywn?eLf362pQC%BW~B*B9OX9yl4c#Pn2 zf+q-`BzTJ8tc^wc>T}vBWZk|x(msu&S&d@^#|iEvI7#pz!5M-_2p%JNoZtz9CkdV+ zIBR3kz7;v`6S8jKa?(DHqgjn(1jh;PBsfX%Ai)`eM+hDxc%0w~f+q={A~;KMJnm8V z?@of_m_spQVe`IDGPi=B-~VmBIv0A*Q?_1l67<}EwqE%P(Wqs!HEFz89S zjilU0Qf?zDw~>_FsPa$7(I6bGK7$0uG3U_b>bVj0q+I>X20bZP-%Fq;QODm#cD-52>f_tH?*`k&p6Q zH11J#ixC_p*EdEu5PIbw=vBGUt9nAO>IuDSFZ8M`)JNrm`sjQ}UqyXLKKi=H2xmp{ z%pm;7&hsgLfT zsE@KoeRTavA47ded-ZjX5gv%*o~-?&`w8?af7t8%N&kdiT`$x}<%9aDaxKzlLIhhR zpAgB%BJB;?@c`C`Ey52W5)-jV{|S-)gZilcjQXhSg8HbopgsztKB~Q_57F!Eg8C4> z<|WjJ=yg9weYBqRpAhXoL?0viIMH_!eUj)0i5~4zK1aJ0M!VE?LA!`v_d~Rc==FF( zyNF(oYqU%2Nk2rpRC}XDk9H|N+NJ!Ab}2pDrSxc*(p%&@B7b!qk-xgW$Y1G^ztSUr zrAPiskNlM$ep48JQy6|z_V63gYo3SSh+gv#{6_TpJ_x^QJsB@(m+~jtrLGs+rSxc* z(xY8Uk9H|N+Qsz?#pUN^m3xBx+nPihe3RU-LLvU2+Ui@7&ps~fd4AOXmHT|l^4VvE zJvHU{|9;)KI-mWRuon&|XTg3|KKrDwN8s9dpgxQ8*++$axzpORrndV0j8A-6Q_T+k ztY>3Z8J0F*uD3>cCHR}$^D^mwh5gO# zMJ34zh5gO#OYk?hFXC^c;}HH9So(Cn+;4^Z+nH90H0^JlHq+mYCHkA&m*8)1Pdq1J zVSjUbPwokY{mt!5@He+F;%}tm5dId}16lNM!Bs4c?VZC8nN|r|`&*~Y^!Kh3{mt!5 z@He;Tb))|k_BXd@&2Sur{mt!5@He+F;%}tm5dIce`gFehy;bgSXIdrFw7+%QOn)y2 zX_ds^%)SJF^ZXsYV?tqnbNdqf&FxF@H@7e1Z=~Z8{uWsKTRiiK{_RWye|xpRb=pjS zvHCHR}$vnDu>!v5y=CHR}$m*8)1U&P-?$07VJu=cl@`v`wK)4<=v-#TrkzcHsQ ziBGtF3I68x4qr2&u)n!|3I68xCHR}$7x6dJaR`44to<$K;= z^Je-RvF?)m&FxF@H@9a^a2$pG&FxF@H@7dr-`u{4zmbkZ_*-D@Z}E;m_}iHV{wDs` zX*2!ZSfanVeF^^N_6}b&p|HQXeF^^N_9gh6+ZXXS(s2lX3#|Pu-c<^JJJZ15#NRq? zroVTU=x=Ucg1@;vYl7n_>~C&gg1@s>H1Id^w@%ak zo@=*%G2&H#HTbrI);0Kmf%xwyFoW&WZJ%9;0?R$ZK5j|-O)PoF(Kfx^VQ-b$_R+5* z7oSyuygelU_UW4)_HkwZ!x=tjh21>e?y%3u`dI&dMqQX9KHccFm-+i%%A0@FbhE>L zLgpX*RNnksrdyr%GXMGS=FNZG^i2+X%VYZozpKRj&-{bvqw;^_blhPdmG-_T^4d2~ zH#zL%(mwdZy!NfrEe`vnw4eWzy!JOuZ*$mZq z{tgNlf3!o@>fRY@1B1}{_go# z*t_RnVeg)QZF|@JYuD$FnVlb+Jp3!{-Se-ochA4V-aY@?_OAI?*t_Rn+y1=#%b%GU zKY@QaCj86SPOvm9Ck_1TCH(6+5B%#T{Od>q|LS;fPM+XjFX3OudEj3!;a^7@_}5GL z*O3PP^%DM7X?ge;@gj5__xx+yyXIeE@1B2cd)NFc?A`OPuy@bD!rndq3VZkbYuDd3 z|JwC;&A)d2f0&m~bDtlRp2c?kUGuN7chA4V-aY>cd-wb+?A`OPZSR_Y?fSUpUt#Z_ ze}%n!{uTD_`Pa60&A-ClJ^$MF=jC6nHr{NCW@!nLax&n3E^?SI1*>(!jrd!oQ9@!M}c{V0j|`;79}i`U(F!(!jrd z!oQBRn6-r6dNM55VtELL9$w@68lsOw58rUTkLZ2S&$sn4q7OoUg{@yp^z)$)+4?xq zhoG;p^;?L(68Z(UzJcghLXVpB`UHvImtDbPHC!J)vqH78p@2RJ{nfVpUSc1IUipFO z_ZHB%K)=Y&=XPSh1A65*qOXKr`GM%8&|hWevxDfXps%#`okSmo{z_ZlM)baHJ@G?5 z@k4%n5ccRR+;7n{+P($)IktW!(TAbe?b7y9=(QiT-j{7A^=T&c$*&K>{wllN9cQ%t z7U*?-w0;Nlx;|QeJM^kwk$imFJ)}N+RDFWb2kdgI&S-rl^g4g7-;yn}@ZyI1t@2En z%BKZ-T~Dpw0lmKNS|5U5Utg^cLf>j(D<3vaMg9W6QD&|4TvNgH7|U#K%j6U0XnpG3%XY zx2u-qkFl?>3(;fjd-a&oegKDfb)V7tmC&o}Lh`ABUXLkl-w8e85LN%%p2OxQ^fuWgmxL`%UZHpx0wc>%lq1KUyDyUi(Mu!9~OmT3-dd zZm-sZqewlQRXx`h(65AEjjuD>9^92z-vGVtpV~eQz3vZM5AGuE)%qy(YCMv1!D+;A zdsO|wX=J=;{q4{z9yp`*YqMn}pE8vXIF0y6>%m>b&stvzy>6G**FdlPt=5C)cz-WaG>@x(Srkhgriis z;C6kzh&{MV_meaA${w7PR}bzY{?YcG1@yJh>+7iP!F74{;3(oxZ4XW({?~eNAn}9N zS3qY z3%wdy?->aXp=fj)h&*`w+Y4kZ0k>+xJi>ZA2h=oN3A(Ry&BPv4u$RQ}*bQm)p6 z>&SJ{dT=JGkJf_&eS`y9{uBJ!?~O7a;XrgT#eo`IOZ@8D)w4wD!GYMJUf5&qru5)I zHb0b{sr2ALzv@fG9vtXb*N*7Hfqum;L=O)1t7}K};6OIFmK>Z=KHwaEeThA|g|tiO z4-V1&>P)lB2ON@D4-O&MQQNmcuiK^d;0n?%tp_KNdTMiNPV<@EL-L$T%qy@hmdm1lzt`j`nqU6IKfXif!R;koZx4iz++TdjBs=g z3yh)U3CM9F`;Z=ki2P+b{+Jtrw)a{SkmJhUOYL#K*G`t_`*P0r<(%)M=UZ8iKgZrL z?b+HwUT5sP3drW!w#=_Hk$Hb6G9R}@=A2DreorAXzt<9(Kg$rAKMxa`KYtUM&p(LF z=W9gfF#;mbljj>S($@ zHL$;@|KJVPM~4nv*HFFn#<^Pt4-edtP7U2SHyYhC*xNmHVBl~c6CmzS5BH?fLV%bW zIIIMSccu^br+cIQ-F@jBsylXU-`&-?y|p^p+ueWgX!k+rQq|F+djfOCiRY#8;-6t}utG?cm zSNGwAb{z%=(YkbXw0r;l!|5YOb{*~R?K#ksKFrVOIU}2%PoYAwyBn&b0|yQqNe?k0 zhWrl=92vSrYlLEtwibmS?dcy{zqV_rU>$n;j|?5oR|T|)RRLf5tAGl*t3v8f_u=TZ z1uM{Bum)%(tHBywgSFHNb?0*ethE#B*A#KWz5(Pl^D5XbsMi&6T!lIm;LZiZ13mi- zdtl!H3MyDS3dwr`>Y6W9>2Pqt($^Izea!`HJG@)4^!0^GzhG@gGYXczp+M>NvuZo* z?%n;VG~ppeLxdx?TrbE)vc{I{HIZ$(UUS@*>oxrWOInmnk7s<`13Yu4?L#u&CI(Ps zsrLi+Kq2#H-#q$kXTl~R^1!ozO~hTJ^dWVfCsyWQiq_ARo`1%eJI_%KMku-S9f$D>`6g= zcdB<^PyZSi?&&$$-#v8naC%3&|KJci<$!%4u|0iHQ}00PPNJ2m=KJ#U0D8l%{XL&N zn%>@m-jJ&A-moFPzB^_gNZs4hm)?x0+tR#$?H=f(Caja* zCLZB%!hbl5jMl7XUv=y7JXc%Y!5(;6|E;aw-anK+e4sm(zV%jKxGc2LH%{raANOu+ z+Ibstf#&v9Z&Oddox{EjYr5+i()HbI*KgdIUb}JMx^?^Z*VS$4-gscmzV&q}*tewj z9X*IM*x49DNAMttN473Kl-hgx_akvVY85wI`aw|8K0pm*TlJzag>JxCCbT}X=E zy(Z0?!XCT0xUK=xVD~+}1Kr34<2c>dHDsU6<*wAg(f%RWvO(I{#nRa$W%Z^{z_^P& zt{|Zr9!awbaVF?uPXg^tyr??nCvGv+eGnQ(OI+O7eI(sw-_*F}TH#T& zx70FH&LSA2ou`QZc<;T%+*;3?ZToew`|wZ?_ddMZ4?S^feLZuea%){`O+!P`>qYW) z=2VwjmvUaBwZ(H{1=}^u&1qlEQLEgG-80zL+kMZ#QCwc;XnCc@l|$mp3%$Lwt8-6R zd+Y9JtBPoV-cMnv!X5xz4YCvrSh0? zr_%H8ZjTtHtmFNfo?g%MS64$><~^O=Nu8yyo!#l{W_P-9&L3TQcD?$#+@F4)%fF`B z_21{X{u`O!$n`&Xc;M)uy2>+qL7iYg(+$`dp3w*=PB7Z|^p;m~vVfk+q1_HzK%ozoRLh>|O0bzZPea&z(qd-p%c!;vI{==U?EZ zLcYD%g%5Epd4F>Ia*qc~kp-XQT5(TI`-r$xljC~rybOw$Qa%7ds!KKX64T(}L?$C$ z-kQDW^BVMFe_l%QESGz+^1UE>%DeD-4U{IlQSV{Ov~0cLWsbW>42`KbwC%bS97R9OkRM^c*qhIpLWy;5nRgnv2<|=Uk;{s`cC^AZ5>>I+{v> zxkLc?Zs$z^fl2$DOTro$9q8vd)isQ?J8w zfwztCXaC2xnR*92=Xh(Jb8OZ)&uJg&IbsB-aK6Ky)7$~iO*wm+PuPv@8NhSl1Et9k zLqp8K@Bi^!;60FaoaYpmZR}tu8a(Is`@9Y64SJ8aWX{$L&-L|248@|}0nY{APOW1+ bm!+4UYf;TyD?*2ikt8-T#!J0@xC`+wQ4pJ$ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1728.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K1728.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..fde3b53c34bdd014b5bb6c33d42af861f7e989bd GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K192.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6cf5e1370c9d589bf7bae4b8c3241a2ef20daf36 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..20ea251410896fdf945940a1f81257cf2415dbf0 GIT binary patch literal 2592 zcmbtVJ95G>6nruclkbEgMG9tc!2!5ITyT&S+yf;;kupa}k%Mpqh6|C^lUA06hsXnk z{%=?N-dc#6Olu>u7Ln#&1VjHjm}=!ljh}|LI*EL3MXJ+w=9a1tGJ?EVVy#`7%-bC*m!;1BSmocG_7&@okoVUGF@48TLmFayaZzE#E zjnNf*ZWDNE1Y*#0xAfJ3=N`k}B=el*om}l(BA0t^7w#10bQrpX8YpO;YJZhp)L!xb(~J7{zA@C- z^EL=)@CeVLzRDY&5isaE;hQqxIlOZki`wV!T)lET&U3cbGiZuyP#;VT(%=q5r>H^L z@8_aH9C@vt)TY>T%fQPtCKw6?&nfS~dlPxZK9RXt@A^z{#852i&AkrKMc(AD#dWNAi@bZX z;!7Oy->SGwV}hY*@LbsM^R~Eer`IJ)e`7qC>5Ui)M7;x^i@bZ!>Dpqw@LZ8zdd>oT X<`~@LW{g;jlDX;T?nt^1cVYeq5KW$d literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5a9a5b9be5a5b093f19ff53bc02ede976a45434f GIT binary patch literal 121374 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..603eed12253983eecc3fdbb5764a45fed4098c22 GIT binary patch literal 2592 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 BK|cTh literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2880.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2880.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8c64fb14b490bc9ab644637e8221698de3d5a9d4 GIT binary patch literal 2592 zcmbtUK~BRk5L~BeRRMxZaNtm>IrIVifE@Y|4t)SWXh1#i3wq!I9C!dvsQLnaQpRgf zoS3LAA_qGgduKem6N?*7N++@sk?KqYui@Fd;?BQSA&g^j6nWW*6vxfXe=43Z=)Smt zQ;B^4t^+?}9`XGU*5wKx79w+g$6RtvTyu-KbEd%c(b)`&*RebUf>fu@)Jx2Rn**7g zba^Y*qR;D4hwX78#l4)a#WL1{=sE8^>UB_>@g}|XIn&H~!ONU5Ck&0LH|MSYsdr`6 zTV#44$Xkgt;lzG4du|b5r_iz;hRIZIpSg;hB8z_e8dPZX3_!h3JzoG(-;+ zw9IOO9<;r$L#7|iowYN&`HnLEeL1SMThS31-i|<$4o_Vo~on(~I8!OD}q_ z_`m5ze|!HJ`WtvFq%-*soK*W0;H_}au~>ieoYs+^BSyz_p})hP)3pK5P1t*RoU$6`9>8-G zCh43oG(->L`VY^wyq^ic+yi({aaqO=hN8i9alOx5Bd^u_eobbxUU;srH(@9i^$vKh i80lyoF@EHsE~7##V*Cz*jtCY5Pt(On4@L@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..050862bfde252191b5f00674a578e3490f2c6093 GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9171ffd94dbcfe6f2f917dc53f6a3e4ed87d36f3 GIT binary patch literal 2592 zcmbtUyKMqN6nuM}k!4vj0f7S~E}#H9@C6j$5**M6XN$n0J1~I@aS4bDT!K3|&%WE) zpHFBJ1bh2?Z{EBaR?K8t8UT4{RlQ=+d+q{1 zHRA1D2X5j!;ruk5%L6u+A`9;0Tk}jz_lR{=(||RPE(79I?`LRaws18-ei2C{Z)LSz2;}dt**jA zzR)-Mk3ru7x4~To<1Oh6-#O^3AoLt_&~w5!WyEuM=QI}D=kHvtZ>sg&L9f`M*mL#K z)IQ2i4#`TOfjduo(IAevT?i@m+{)pyjZqHG1`QN<4hvXhWQ zx1oVM|K~Z6`>i*1DAoX;)4XhBltUB2bM8FFZ4u}BuGz_QzVKYiH{?)U@*VM<$Bk+& e<_pgi@ulZFR5R0x&>>?aTbr=PrQ{qv!TJx@=9sbo literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..0dc7458261d1b1c01f194bbd76208eff1f0e9995 GIT binary patch literal 77342 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..182565c16882ba5c67521a76b3822c27acae3184 GIT binary patch literal 2592 zcmbtWF>V4e5L_P@6h(cd!sM8rMc-DI(3C2wvTDFx88FYh38Z>Ll{95vfj_iTzZ)VbFbk1E(7K z_FV^l#605r(XGoPKFmdC{EoTinwahxadIZd^_^@6#n)Kg0YR#BXX+*9!SqNbBPnmg zTJ(7h>aab{rFxa~wOIIC5IyIedA$ZoGv27Tdth3zUhp!<%@IRm>dkrEEA=i5^;VhQ z6?q$x&Yjqf#hzPxUK)WI^xQ3dHQ>2>zc$J|*YQlY_bVcmdv5E`WQFJxF*HOE^tg3a z3-loLzIB;)EcP6FpjmW4t5F=_ISuk2>{7iy>TA2N*mIw`-iV=m)O(ZZMencDi{2~# ze|pj1-fs;3b-WGInS6og&|l@H=ZF!U!aHTabGYX;7roE#xmxd3>$&|{_h2aQL47ba zlXQ+48lne&yHhRUWexb zZ*taRz3W1~1D>oU)29qBn@B%X8q9rm2A4R~(M-s>L$*M;I9z;nTWkZ`Sm_;i@czB_eADmz3^OLZ^Te6>K*W0;7!h2 etQVdu(o4^EIL$;)gbEoWS!`mAO}%xv3-K?X6sAr9 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K3456.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K3456.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..000ea1720e590bce56cdddbcdf299b62bdbb6630 GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K384.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5df33ed4829d4df9a99a8f61511410b115d38756 GIT binary patch literal 2592 zcmbtVJ5B>J6nx$+5kg2%P*6mQiyVL(utg4%BKOFGQg93k?m>S-Ff%uwz@YA`ksG*j~?-E zt^+smoN<1d&gB6cOOXZl@$7jfW_-pvscFJ;oAK9ui@YNRq5i8WMpb4{Cn6b1aV>k1 z;~Ml~e_l%WD*yLl<$J;GCG^7cHDFrcM!sW+ZsrTz94h9}eex}Fhb#H68~Jtx-wkoC z$QUbc_T1Lv(g@5!&)w2j70=!KvsvM}ku^DCHle6y4fejK5E*mm7BtXu`=S@nAZR~? zU}^RoG|(tIAjzTo@SHwN4L(!8Ka7@UzF#HZm_zZ%_omrG&_Ho3_f5c+A#}2t@4Dn0b0{wPmR^VF0&Y@k zGv93^--_oZT#I{-&AQBU+DCSZITFuJ`qn+CXBE%QslC`xRI>)~++3T@A?DB>XyDKP zcrM@`7>h6Qg8x>{%Zig6nhl=w=Q-|xdIR52cC!5&gXeO-F^A%kZ^d%~H>tImFFe=8 am!2C@&7)R?4jCiG+Qc@ww&0A0BZ)R2 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 MlV$R({s;R0FS*Dd;{X5v literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4032.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4032.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..83ce6fb05d8e6ce36241918161bcf0a07564a568 GIT binary patch literal 2592 zcmbtU!A%1(5L{o51OXC}Kmv(Kxkn111MZPRc%+XUC=Z^LkOu`&LQ06z0F*!hNMXG8 zoPFj5j*^Fcd%m67*_~L-U|1TFxrkI}B6xJattsy9Q{_Ux7JHGGrAV<~j_s@B35$N` zKj2m(-#+WYm)Hk<-nnzR#EYrOgzvGJJQLI0B93ZuT;I{hp!gWcGayLyS52M7G`QZ8 z$w|9Sl~Gg(iyB{z3*2{$oAY@syARL7WJMadNKQ> z^kVjk|DRsWxAPyvd>wCvbS59*Im}mi={aJwPT`%><2l@Onv2<|_gtxWs`cFGNWa07 zJ%e&l-p>>z${11BPNz zZ|Ze;uH}tt&DOif)Z61Z$6Mi^W3vwPoc58PBSz#oH{X8G=~<8GhMc`@&kvpfJU3*L z?g2wX%)p=j@?6Wi2>{tMfaesKZHzD!4W9GoUEUgbt=`u=G9Ti(uHJy5Sk&9&xt2Go fHCrz{m!+4UYf#NtD?*2ikt8-D#z&oVxC`+Qjmxbv literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4032.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4032.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5c26d00ccc4041131719593dc432482abc1c96eb GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9ba9c37ab3e17c0def4f7b8ebfff1c22a3ce8be8 GIT binary patch literal 2592 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 Ee>eED0ssI2 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4608.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K4608.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5f17c4a0e89599940d0d3f67e24ec3de3cb17f7e GIT binary patch literal 2592 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%0DTS3@AYbVR|eL3g*a?bbB^R2AMpJVTr z_H1n-uQT>t1!VJVTjtl9$h}cuS!@oTs1$I0ozO3=5*bd~vFHFVo4{hB9zGr)U z?!M{YJiYYRCyu>!_5S4iUH@-t!edR^<($3<`ETBGZ{MNlaQg6(-huv`VzsN|v1q!# zXJB7%|ACugM~C*`&=A{l^W4pYhX?LT_YB=UHyYhMcqlcrf8cN*6CmzO5BK(@g#fW< z;II-P-km<&pFR}rPxYm5igj$?wzI2oTWc(ODAj-9XzBoTJ+bJ}eS-k|29L&ME`M)$qDbx%nRWH!`x^yg>+PCj;`pA(TM^lG-_xGj`^YeMm$fozxs8IaghFEl9|NbNCAtuC; z|G|MHL$_;P$73!=sB1=9KF6^ z1^Nrt0F7idsM9rAL!D52At%6EJE6X=h!ge>Ag`HM!FEBtu7Kkz)S>`)E*Ku@-B;KH zdk0WZ!O~Gk-V0FMe6dQ0gA10vwm|817p?8^Zo$&m6)OFrwH?hUSo-<`rPt4@?X0_} z`g_uZhZqeJj@W#oAQ#CRn{U)aw)sZQahq?{^am_yQ8GQA@o^9E%$c?i$#@$XK#`^1 z57+~R%$t4l=(C*(n}Emz&ob&@=g5QAhaT*);$r1@vGQT{!<>U3Ea)W;1$Z;tZr`x*stOsp?;*TCV}MzC*9tgpA9<2dkOYN+QR^zqndYhnk}seNf!eJ0kCI?&q#^}RiZ z_V)JI!Ejgaf&SFc(ZlKO>HY&l?3DfXfyDOoeNBf3dhRA#nQFeTEDxYJ?CJ0Q)Y0^| z7Tz0D>GkP#sknV0b$4%Hde=~@ZxG3~>l@asYgk`b&${K-H1A(K2l}W9>!f#xM>w4D zZ;v9Qy4CEfb}gRgYGNJifrs_qn%K7fq4eSXsh;$nJ-l#PXrXVM(rG{L-O+U09moZm zJ9`c__4eC2q*AH+^&9r3_NVry_ODr&TD!Jk!if*kczL z*ET>JOx<^AAcb5oj?;ZzL-xsB?&=vh+CKzaHc0!rSUP*8jBWfRjJw$53eq}SJGxrH z9^B;Uku<9iXM!&FB+%Z(i>hUQ;ub@x1JE#9;^N-ak#v`RQ{$Fvgh$cdQp@OZ7Qq

fF`U-n#R)*6k>) zugjh^;Id(s$2EFZL6mCp!LKiyeXx^rE`0yMP#5n!ER9WiV4V955c})}F4%hHT*w>i z9DZHX15?uVdj|UZ+2|VX9lFoy5H_}$dqnyG#v(dDW<^~Xdg*&nOXV@)PNnDF-5xPY zS+qL9Jjw(+$`dp3wC*4tYCKUbFv)Bpeg literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c2c6a3f69c0fcb9fb7439e6865ca8a58d3debf6e GIT binary patch literal 2592 zcmbtWJ5B>J5FKw!gb)%G6ck9=A_w3Gq{u-ixJMS0f@4r{5RMS#LgDSK-}r+Syh@7o zXV&k{n|W~}Zn5-EWGf>5jR>aG=is{Man?`E@a#?^pF5H6w7Va-x_3PEz3>7DkMrYP zAKb*a;QTnnc-~-9isEU0>7!J+R(y?65R@4n5FQ zbU=ck`|zBOWe>hGy{u%r=f3~wH4NpW-m5|{dVi5#^j`7*(~JIQ-!b&pcoE{K*>mWx zo-vgHgPs%KDHYG*p3}4FeRL?2dtT~Tl8b$IR~z3^O<-iqfUFN-zZDNVnv@SO6} zb3?!|)$DKGb9%PoxutoIfHUqne{joKf6O8Vdl2Gz@8LP){fPi`Jg2xUV}hY*@LY)J zyzrdy%3zh7kd6L38NZdzNwIcujTf^x+=cZo DodKBu literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K512.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K512.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..69bc587a5afe340c37b72a2c20dcb64b790445aa GIT binary patch literal 121374 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3672e1bb6a899c75a82e5270a508d2770aae736f GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..edf667f4fea26507dc993d943af4168730be5e92 GIT binary patch literal 2592 zcmbtUyKTcT5IxF_5d;C^B1H-VX5j&{K~#7U7umx~;38#4aFGErLPjt=Nj6ZPPJH}9 zaA?>CCGvFd-Mf3HnAzMKk&TGBI}yB&zoTiMhc`EF{o3>*A3Kqz-z|ot<_(K}=Re@X zB7b<-g@<^~_Vt$dc!HTE@h5PuM3lja=*GV^FM&yaR$%=W5Cl%gy77Oh!^( z$6n;T27TD~D`{Tjd@t6%7ep_4mtL=d(tfKc8Z3?|x z@;Z?&R$lG7SI^5%5rdw)rLQJDckg4f!gC#K8fO0)imLY9-q#c|BZeMf23oEydVv{) z*|#BCsy&ApXciriVCXqKr_XW*hg9#8ovioVSE)B*C?ECS6nZiHtMp>_ivOQp%s2aw zVZI};Lpqajm-LnQ9OkRMp;I1%o)g|F6Q098r@5GYdCytBQwPtvP*k<&?9o^S<`OaV z1T*mQycZ66DK0BcFcb}*^YNUwO?YJ+I#;cCQ|gTv%1gba*WtOV^ulvh zdM7+L@;cmeY}RF-Q(k(G7@>2V@3iMMcfxaX&R)JlQPnem=jPgME)jz>@bP^1@Lb^i zVeVy~Q(RV@U?>_q=i@mqJQsN7H*~IAFFcp)jTp)c&uM(ZbAdOhwfa8>&sFKA=Q>og U(2CF@W2D%dxW`9X9PYyY4|y(?$N&HU literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1533f35c66670b192a623b8a98d8411f89deea1d GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5760.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5760.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..127df17c6880609ec1afb04702e6cec62559dd58 GIT binary patch literal 2592 zcmbtVOHKko6ns4l#E6M5jB!E2n2@;j2D0EFELeC8M#I8mu<#%pfp7wEg4M6Px_jCY zn=p&%>CdZr^3D-_=p%b1hOG*LQZQddEx8`2!qk z#M^IuaS`Ky-v_rZw^*2pOt_A*=AM}L5%VM`$MqIgY*h6+mJdLX>Qqkl{GZSLfw)Fe z-iEd4@*31(bDV--PS;}QYeDopfr-~^pfux+dfNwv73&2rW84@qbWXiF@BBi&i$c9s zrgur+Mx=Ea+jp_&R-TteAO<~mMPK!J?#Ay8GS9Wl$@YFbWLCvJ*!Y|nm|*A-sksRt#_*R+y*D+3 zbc`4}MGyRbw-ycJ$lFGMV$aPyFUy!lJcygm0#;FaAInTz!rqW@}g619)y^1HuzA zbO}B1`@cLFcy}SV{GNm76qjX8Fcb}*^ZQ-iIpTue literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6ab1d1b63844eaa5bd04027bfef2cd1b390cd227 GIT binary patch literal 108062 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

G`I+yYStq*DGoN<)6Eww2TRzRtET49L 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e1ab5b16b9018b3a352eb51436dd3912bb1cca48 GIT binary patch literal 2592 zcmbtWJ5B>J6nx$+5kiqbh=L-5Euf;w4M>p#a06209$8Qd3JQ)u!9h3z%1O9E7(aV# zuUUdu*}`6b-pm`nStnvf}d?1{w@r!WlfkbEvQK(sRV1=Y)4kkLPgDX)J2rrr*7MnOg5u>$&Ab z_n;}RL5+9@X&*6kh#L6y?pZVmZyN!MJ$K`Id5j5$qQP^@+jHMUz0EC|i}fyYy%9sP zs5kdIJQsMAT#NOt3ibAQ&ha+5=XhAdJg4VK&k-Z>oU3oY=X9;dbK~H-xAVa@fak*H zsKF6Khp2&H|K+*B`$<-Oi35IH6_>}DU?>_q=hwTubL1QJKHQOci08U`BZgv8Z;$5! iZ<1@VUU;rZFFn^H8~t};FD7Fo8=E-B#?Ct2h4Bv*sGjTq literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3a40d95b7ff5e65833ac9c913d436643766c6ff2 GIT binary patch literal 108062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..293e1005e88e56d81b553e2340b5a51af89a2f5c GIT binary patch literal 2592 zcmbtVL2lbH5M0WtVH5?LLk~FwC=Y!=eo!6!fIh*8KA=Ac1LTlrg^$1ED@T)4M>w@Z*h0K|F3` zEp~pl1k~Z-_X^x!r54QIWWnU7@Kyf=cjP-XQ3FDE{_$ABhXir7`53d(QG^R!t7e2F+E!=Q|Kry@wGPR>Hf; zcR%HOK$LsPw?lJ0?t!?U|z&|Jnv4_?Lu=V;FIvWzZ=WkV0D-}fGx8~Oel zfng=Qi+rKE!l%TxIV#^7&0WM7nyY*i`K7>fAYW=O!Et3yR44=^=jLJbV^iZt2{8W; DaBqY_ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..8b02fd6ed521d103fb073262192c530fe265f64c GIT binary patch literal 78366 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 z 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 U??g}`W2BgyILEt#vi~s-t literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K640.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..f2a834ab44cff8e4a188a882774bbf4faf9da803 GIT binary patch literal 96542 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..08746a939f878f817bafe04f683deac0016d9582 GIT binary patch literal 121374 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 bDcs4(O)~d(BnIGR_w;dZo_SX5j+XxqpbZ8i literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..eb96e88101d92a393c92b0360821cd41075b0a34 GIT binary patch literal 2592 zcmbtUJ5B>J5FKxp2q7d=P*6mQ3rY%ZK#JUh6dZsXWI-u71_cM;2suKO3oUQQe*S3{ zyh;l1+OzZCyqOn^nax`xvJnw`BZ61=JDTQsc(ZQn*QOWw+KDv%ZZRA+A6WD|{{bH@ z@`ra_c!=kW?fPGSv<9bRy2F0t9Pe73BTuoVGxw$`)$wfKc8Z3?|x z@>-EDR$lG7H_yvX5rdw)rmsdkck5%b!gC#K8fO0+imLY9-q#c|BZeMf23l@g^a3*o zvtNf~srDRZpjmW4f}!W|oIcALe5ZQf*|~bp{giqmhVoJGRiPKNzeq1;ulWDz#eB2> z80PDEEz+5cyQHtY=P+O8rRRtdI>$R@#B;dkG#9fk@3~g*)WLJxP*k<&+M{U|m`lXa z6U@NJ^Illwk+)+mx-#LOQ(RV@U?>_q=i@o=I^h)?O0U+tDfLDS<)z-z>+sw~df~Y$ zy(6A;ycYKyn>EdI%1h4?Bk`PT;<)EDHsZNCXDr#bp~43`K+Id_3oc=K`-BUAvGl#dEpdh@rgjoW@5y7kHCetN&y0T$NsWu0u5o Utq2`5MvA?Odwi6|;Q{Rb0QvTpPyhe` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..922e5363727d4893716cf5957a88aa349424290c GIT binary patch literal 123422 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 II6Q#&Kh$iP6aWAK literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K768.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..68664b04253be9422c8d70c127b25df505904218 GIT binary patch literal 121374 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 bBE9rni)`ka5h`SiWOEbdIF#(e1DO8;f^(YI literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..fc6f78f6bc284bf776e39ddaf68f5df283595014 GIT binary patch literal 120862 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f6cf51a6890cfe591e210f9984da8ca19fdcde70 GIT binary patch literal 2592 zcmbtUJ8r^25S=v!MNy*ZZH4l(`3cpHqm87`lZXXu4%q3-loL zz7D}+_8fYkQFK6pq5JTh&Up_GsoqVgcQBase&u>2hGJ3gG}DXT-=r74SN#9^tQ%#4*gYLdX5s)WdP%P@ry$;U>-XvGE z-mOvZi069V3hx|?b)Dz5j`SQc63_Mh9rv7`jd*Ux-phf=_WwORH)G>;ju^T`5B&Kb z&jsFN1Tgmio>N?wF~LwYc+Q^>d27T4y;Vs48qb9wC5jljq}~zF1>PiAvtD@4q?ev+ Wkj-2(LWP`@Z0+J2mj>tX0M@@FubY|x literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d9d6329a1c65b6e01708be8d8912c5407effee10 GIT binary patch literal 96542 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K960.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K960.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c17fa8fa901b0aeb842e68cfeae2fa5fa6d35c5f GIT binary patch literal 2592 zcmbtU%S{6@5FKwe5kg4hz=1=g>>&kE01`Q*5Dw`h3(A2bCFDQ>l#mjlGyo;g!SZ(2 z&-R*Cm?$~e>(9J5Z|23~Mw8NstVE=`7QtutJGkPZ{i?d9AB#rhZ6i`Nn`ygMykO9K z{sN~G@$I(`+{8TM_pv*dTWrilX57bI@=RQPk9Cq$$Mu+82E~_?S3r>JR8GCXd~tUq zlarLUVlDc-4t3Zzb19zWbS)OX7DUf^XI`&^(u_Ci-G|DV^@6ug6)|+5dUM|8g?d*; zy+x+?nY@)q9Wyt3ZtZz#1Y)pqSM=3@=WhJjDDzy+oZ8<1grv+p*!rA8WW>-d^gz=s zvs$1Bq4&!WEN0K42O32OBpA96&*_}^V3+FsEcFfsv)+$fZ^Te6>K$i#(ff<^qW6mb zpI-F0_a8%lJKhT642Isu_|Bof%1h4?gPs$S69b6Q7wju?sOy8aG(PR|BBH(~GPKxF&>9-f=9aXLo~ zU7`p6{Ez1X?>+*UdjQWVF3Xr;C>lKH&-=Vf#091V(5~32Rs*elU&Vu d;W?9Ddagz`Q_Tn!a!#_fi)&o!ox=lI{{o1cpjrR` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu1_4col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3645a1000814f50d760f9db488822fa2899c6c02 GIT binary patch literal 108062 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 t_z{#7y7?Y}9dU_3x#E0w?Em}& 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9bfdb266adb13501848dd6053a99cfbb63e2f3a3 GIT binary patch literal 23880 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..611b1d73e6f784c132ac303878bf8a58de562aac GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..3dd5cb105f45152a369d9fde093af4dc1a6a5548 GIT binary patch literal 660 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 W(ReRX_TTSZ-f>%*cUW6@2mTj|5E|qF literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..25b377b3aca48996d314e721f9615616cfba5574 GIT binary patch literal 660 zcmbV}Jr2S!427T52)Y#{28K%QzyY`c3><`kgQOBi;7AONhzqqZt&N(BKVhk{ojU%W z6NsPX0xSVs9Kdj}yI>omdPsG3JK$CUuB{ev%Qam3IxR5gc|ICjCYD+DP*TASHY{zQ z-rGM&STom3)L%4di?^CKs%eBu!j*D`#4&eo+&n24%D%R9xB{Q=;-FlcBk97VRIZzF vkH)Q86!;DHd;`lH2Cv@WG@Uo-33WDaHsJ>2{yFdY$9cVSqpbc0qb?D2BLg8| literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a8a7735ed879697eaa73b3782f79c7f56ef49537 GIT binary patch literal 27592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1280.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1280.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9c0d93e21030f4796be28e0c1dae62d80d8d575a GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1344.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1344.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6b76ab7e4d252cd51332c623ba6dc2211ac2bdf7 GIT binary patch literal 660 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 pfoTU+_TT@T{U_ugu)l=6qc= z1mvc30+s--49GRbgRl*^DwTTj4roe%+j0?Fe3m25>3}6C`ym9f7nxO0Wy+-?fQ9uX zJ9`89wbVL^$~4v1iA#Lrq)8#ZYTBqKo%={DkN^Mx literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a103edb14e8379f6a186d16f1031157f5698f224 GIT binary patch literal 22344 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1472.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1472.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c653c311c48c6b35faef7ab852e4e6b97a4d9dec GIT binary patch literal 660 zcmbV|I}XAy42FNZ;jtAY28K%QzyY`c3><@jfdljiLE;D;h=G9-aRH7}oYa<@A|Ap+ z96PqZ-vPPdn1CsO69aN>?M7IJTh)eo@(Q??05|0%r1&65tkVK>PWpq%$iy;>?n=rf zAp;A`i+A=0@^gu`5|wGHEfbsg!L248@mAA9HEG?8n<e1WM7&QILGI| z*eEwq-5FIVmwViuack*353J+oefP?>#?FkGvVF52*BkfGeUHlhwy#sJ7d7z*gDN6C E0m9%UcmMzZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..54156a2d2c75842ed7e9174ae1195ba0dc746b1b GIT binary patch literal 23816 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1536.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1536.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..180f2aa733c444eb8a3577ae5c9bdd1ce11fce16 GIT binary patch literal 660 zcma)&F%H5o3`M`)sIV0z28K%QzyY`c3>>5b2MH2K;7AONhzqq&YNMtVC?4Y2vH!CJ za^;$UEr16DavkkWIEGt0hI;Y|cr^g`%_gMyCP%E(0&`CKgNbBfg+(7FRgw_F+VbL^ zy@C8*Vy#4LGkMFzChmEhNhN;HbkLc!ZsB&yB_U3^XXAEB3(45eeg&@Z|1U1eO{Shm w)ym}=w=-_sx3rGzeXomszZy}?_AO>yZ`{t1(P!^_&)nB3*Nc4o!GIyc03k>tVgLXD literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9f8fade3679901a3e11da00e6f7c3a56199edc22 GIT binary patch literal 23560 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K192.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K192.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d6fa926a5ed1289c6a003960c4b6f58f62bbbbed GIT binary patch literal 22536 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 xk*G*fD3=G^gK@B(}yB2EAR literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..dfc1c189ad349c624924e22709921bb51e7e9887 GIT binary patch literal 23560 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 TBDViNb9u+nBA>9f?)LpJWGS%@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f394da966140e33b715668748253a4645e42aa53 GIT binary patch literal 660 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 A*Z=?k literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..892f903ba5bd2794f35c67a88c6f3ebece33b901 GIT binary patch literal 660 zcmbV|u?@m75Jmqv7SIKx6cmw?f&tio6b!%!6buq1MxbXI3d)Fu!gq29P9#u-3)^?T zyZ65#ezp)`1>oucUi;Muw&7Oxq3&)6JPN?I#WJManOj$<1$KD$hsBYDm00vtQpyAe z=9cH_?F~||8EYj<({zZ6iMXjI&3@IiQB8yHD9Ds6B*xszxLH(8S(JTm=Wr>0|HWRp z=3_90L9Sdk;vS6~{8sPo$$n2`zn>YM1oNAWxV3Tr^n01;*DJTCn(haKDiOQ@Un(LR literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..48f7f87df5b584a75268ac134de10c064b0ade8d GIT binary patch literal 23944 zcmeHP4QyN2b-queMA~8_Dxp2bk=!RrbzMh^DUq^dM{X#YQY8P#v}FfEl7b?oN13if zG8CoJ4xG?#*Je(zIa^aO*_# z8vZ4O>rBJHWh*rK+DWTET6^J_fBc{SzT=%w p^>d?Viwac0bxaxC6HmlP<0A)x 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 H`uzV3!$tWf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8a9c139382dc662310f775775941791b1a266b74 GIT binary patch literal 660 zcmbVII}XAy41IQ^!h#AC14E^D-~ikJ1`g7Jg9M2qa32;1M#RKzij&wti$E0~oY=A7 zCm@%P377#mG9cF!SHddX>QrjxHE^i_ZmVf%@m^A#(*Zl2?1vD@PGnZyl&O%00G8I5 z)7cxyFQnE<)TXI1H5x)RAy zltw3TLnq#r#m44#YsX}9t1RuBrN*GdaDLpnle08+vKCNR2iQ_9kh2aLf?$)ArgMXA z+&TBY%Xi-ssaUZwpb0NPzH`3w-E;3f_van{X2YYQc%p+8DrM0KymaZ%0RrXW-@|7@ zxXv_uuDVf|ubq@!`MLN0`x`HPn7;7Jizl9ZJ81T7(|{Vdjz!1zCR54L+RI{sHu!&-JE7N$pyq_Wm z4 zBAW05UbO%`a5n?jyV#Y-1zS7MplkAs{_?$q%v=+1x|4qe(dTy7Kl}%=eLwmB(~lBj zCD>LgJn-s)2bMq2z1F}a_PoXC_p7o>v|)=TTF(Gnp_0Aj++)}tw#!Q}9u36Df+JB5 z5YniNx`dnf@ipt4X6gtz3lF@Cg>Q14bl5Y+=@vOxE5~OG|AUKWlW!NaK*$T&ho`3t z^)R3+2{xKKSR5Pb@|(Mn#vY(6CY_jcyP%^_d{j#X(#ID&*+Z-n8L$!`nOmmsywwn~ zx3*eTGT%mChB`9IH~qXWzwgDm4fVM$K&F5An|#x;y8OnIb@>~gsmphsuFFrHt;>J? zTwVV3kLo7n+;jgd(=1giK%e{(Vvn$?f~L?Ph{{;!=L%h&F%9 zz=JE;yyRC{Yn1lmHl_X;9U6@EGCRET-|do>m5O{>jVWIl{sN<`ME$#Wm1iCW{t4Te zA##4%w4|>7)kS6{xrv89kMU4298i?Y&SEILtf;ACo>Z_YlN=Ki3MDiYIr+wS1Zd-`t z+m76DPwzV$AAFh5-c)h+taOzq_Z~r?_Z}_fnM5S@Ynv3Mk9r?6PNQMPi^&uz-3 zpW2k4y=qg|pR_5@{K%$!^_)$)_pD9X{i022KMnih8Jj}Z(A7`qxiDWK1op=evD;<) z-I9u@7Vf9-Sw3^g4qCPM%uvmFd&){?3um&!=f5CJaN?XvL6dL--7qtm9d6(6J$&Oi z+t*=_SD$}7b-3xrHbsX0zQ&Tvo%l!F2}}Og&J}sr^DEAzXKTpOhaa+#$?Wl(cV2KG zefU?7;AD2T=Ez^KtNrHtj>Bit$7@LKH!nG!xN!J%!O?u-@aL?zljpL-r=UH0mgR43 zlJcER(gmsI?AO!_hky3$H=J#^r_a9B(suiSv#+#FW@X#SCp(Yko_|pNb!vE;)ZVB5 z&JX{{nIExB`CmZYyPIs6r;<&IXVu2bYGjqC@YW-L`VT(!9XKO>-v5NT9J2H%Lza_G zS%c2?dX~#!hMV zZH}tDq~+?mn}2%x{hFN@TboaN;Z#*g>iaEQFCJ?Roq9C=y?+ZG22ZsPvh^@{dT-xY z&vNRk&S%{UzWVEq{YSS0dlP%_gfsx&LQfQCr7Vht+yU?*0K>AS=Cy znduAq_&{ex8?Qkp67Kixdc2M5b~s^4j_SE8YR|0!`wfJ~3;ExXta6pkXZ~xOsa@|O zoPb2W9{66&DY<{`w1CLxPyD#9DmDMCW!iQ*Kk}iit;*`P(DtBxFX!|7Gd7~EpV3Z3 zsyzxZSr88~uR<2;Jg?$9&#So3^D3?rbrVE}73QxO4>_tz@#ukrVe zD(|mV-e3D|e}9eTPk64ee9fry{EFLoe#Ld7wwUs@W>daq)XAGh-7e^h=WEVNzE;WC zVA)mjwMxEL`8>4pd1&SHQ1d6nmG{>$D}nNfet(VSPdH4LuNifoUvWFnuTU4iyC!}H zir;19pKMz2GtT+lNGB-Ef~*R%OOU;S>=)!=K~4#BPLPia@{}M?3-XL0&kFLKAkS+u z#soj}HI9$zd`x7%R~Vlzs{-y4WUnCm1$kJIQ-YimH7HEh4JaKI=Yd@ZK& zFDvoJngR_AruCCFYu_6zc`Ag2U5C&y?WA_Y1NY z)-bMH+;@IqZF^zvb-cG&*9$SzaeZ!y)L6u2kg=doFZ4m@>#H`HfgF0Hfh#T;Xq zyTf{2DZZESF=U4F)&tg6rT96g}FPdH8}59cuxTfJxeqhJA*a{f4>3l6L@dL!fg$pV-T^PEZFKLWZ?I+ zdAwn-Eh*lVzl3;GK5bKcDj#pkXPp!(l#e&%FCpHPzev2n4u!>=$vmbG{&^gYx6#%B zHa*_DZDG87ml$u#UqZYoUx*wN%g3AYC3A)H@uvJG#GCRLi8t7xuy`|B0-ddIc6Oo- zKU>AZZ4IF7@z!k%tL*~T8rb|UGN+E+`sn?4EuuOFYGq(XSjdz!2&J<1BER{KKF0^prrq;g>42tsnX(O zUs;mBy|BZ`w`zRH$_0A_`?IsK%fRurv&XZh`godLwWo~O8f-)klP zoA=8U_wRcRyxGY|?Z;v6zvpT2zwkUU@AqNuzx!$G-+aEA&l8pV_dHV4zxlix=I3GS z){^n*D{L~X&m8BkxvM1KSJ-UePjPj$TLb9$Gd#4(CR-!u zt2CQpvbBPaKexhqs>#*{x~kdMm~8ie?$m5UCYuX>vjQcD@gtHT0}e5v_!79dP(j3dI`*yr&GV0A7s0z*hk;#zDXv056VLz#9Rt*V^?7c+b2==s!(oY2SQ+ zFVpy~mvmePTyIy$?SOBFpHb6w#rRBq*Frj_&(_iXI`0-@;x5Lv8*n|gI_?2n?}Lup z0oP-w<2_|?1#mrvI==yMeJncO2)G_Y9kuW&A?SSk3)bW8bxB|G| zPo3WYxZWQfx6Tg=@fj@k#}2q2PaSUnT=&m#JX;9!nzMD1n1IUlcUG|UCpt1a9Aa^U%I zy}jelo_zJz+C3Ymp7nd-KPJE_w$ptL{P*0E9UE0Aqv>(@|BQ{!_S;-eHJS(~Bk{z@ zM(0E(c5AoujxR3nNu`qqqT$RJm#b<|YBZRMCDUW5fEtNT#=}vjfErGwiwdY;j;0gQ zQ8f`9i*9u8*uG^?pm)n=r#c!;j7-4aA8d4nooeP_3WP{%!pXf*$I)yinutUrw?=}Q zpbF*ya~6n4HacC|^{#fO8kQcTgrAIQMLy#NbEs}-UE*qg!YdL0v~RjrtwVszw%%E$ z^^R*cc8G4-*1O8Je$B=X!zkPOx-zZ1uWIbL+=Gd5R5*w57!uBip0(_7;ipE=TKypF zS*xFMJ!|#j4`hBU;(3e(f5WMXd3oMEO`68R{pM)AM79G=(Om6V8gxR-TveMuhGz^?R{Hz26k-OvuD?yfUkFN zZ(wk5@1DK)JIBNOqhrBE4}v zJMRQ9fDDC4`{D`BLszUl*wGnt$JVXyf}w=hbwoVjuF(4Rk)S&o?843Di-smfpa#~4 zEi?{^B>r2QzLmDc6A>`t2zNrF2%_n~-@w4qE-<;W9Z?(#rd?F+>;^3rJUE&Rf*07w z(Xl{A`{OvO2g1pTL#y> zZGE(n-c)%p^uoYb>O*7Fd~MidcwdImVG#xNZ`(zjAsrSb; z*oUz2;T2H;wp}y}oh$~7MYD+0rLOIkBG^vXv{>Cu{TC;r$SheM@1n-mJy%z~^XjUz z;C$@P<8+M$uDtq3%zj7t=?`@nrhh$#O_=_XbaEn9oaBXzpq(9ll~sT{c)=R{e_jQq s9Z=bSSH6Kvp}W@mPsl-Fe+hR-PbjqLy@>6HxaQo`PNUsub$!_Q0bATvIM%%AI+%by{GTXMZ$~99U-2OG!Bs99USM zx3@P)*f7>gRHmu!6%%n&O`83xX{(wB-MwI~Tp_W~Js3A8I}^&jH*>fgzyIQ>T-&1? wk-S2=Zp5vPTeB{Fx+m{@8t>c9Xu-B`HsS{3{<-gE;=W$Ffoj?xjH*QN22K$p0ssI2 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3219c40ebfb506c781e1ad5642847c729d8006ab GIT binary patch literal 24648 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 I9sS<_1zY=KX#fBK literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4032.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4032.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8afab021eb07f44d951afb8eb1d88aceea4350c7 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..facd35956f8c75d4a519c3dea67866e6c5ae2563 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4608.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K4608.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..a5070232aaeb348038fbbd7ab2946f3429764efa GIT binary patch literal 660 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 W(R?pr`|k^vcidg%8`jnV-~R%kuCT)Z literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..75eb7c84f1cd977a0acbd8dcbe0b8b75fc6d04f4 GIT binary patch literal 660 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 x-3ho-E>E~8_(89V2ygX(AwU2C literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bb6565b3162dd931d53a7b020a5004fc4c9789a7 GIT binary patch literal 22920 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..bf6a90ca5776d5fd812e90bfa5fba4471c1887c4 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D=mEF^9XJRB2PqNr?5~#vM5<8CH z|AF|~LVy*3s{?q9@epjosfwwtZU@{;z;)#^l-!9+-=__>dA<+9k%P!AdnzesfddPx zbN6-!X*bNZ6P0PYB+W#W5;bY{tEO5t4PGb7TDd}E%598WC(V>a*|%;Em*e+e?3HUi y22+?6%5@{|!MMS1^Zv=nevf0npBcRb^P7#ht#SYKd!FdmE4QVZ{s)695xfB0xgov) literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..40c99dfc979ec2590634a6aff2b00450a741f025 GIT binary patch literal 26760 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'TVtgjQXCv*>r)ubaUGNGq@fKp+3Ahnk z1NQ-L^ufTLfEzJ1@U9ZL0=N-FgI@=@F%|=_2i%CEf!i0h2y0_Yq5lEEjWuB4PQZK;{@D@r-9c2Zun<7o-G7_5{3sGY|w%}3%Z}_ zcCdRug;<$B--lZ0kJZtC17+y!e{2n%{SOD~VhQvgpsEBDjpaPM5Vf26=6t-a(=iWR zueQ8$>euI2jP3OQ{f#phUTPnm>G#7kCcr7S(|Ha2ciov88&xN@)HpmpW3#*Uc8^=t z;*rE~EIzW?J&}&y*6F_Ub1S=&sl*{IlK$LERqaZShSJeQY77-nhqcLAL}Lo5kwmJX zfcgb371u`9cxX)9?B2C=+rD7;wykb;G!!41fX5$fc1PT5`fw72;pBvyd!dfCOj?T% zYs0qa;xJLVdkvWz24+2lp4|dkVwMl zG`AWW9!_cF<9jDUqp@gAOVRq&Gq{P}4;}JkI^Aj_8XectsCdBt!NhoakAW~?z+kh+ zCt~q*hcB2e*@swsJe?}m1sD-_0WQV603EurE<_H7QtGWGI}k6~0~jRspv~xkPYgoq zhXn!HMi9JhO9UaD0AGt|K@Wk~=zwV!TA_g}3&CU}He5Oa;RG~PvUO;r=mfNGxmK-1 zfJ?UCUZVB3Yc_U>Zpqd=O0|B?#ty?M+4_bOt$VL(?6}-R@rWjzLwF1cXGGU}cDV3U zqiel!kaev$&bY4i#_TbEOaQ5a&Lmux5Ygci&NPHax#>T90c6s zez3)TPzw!fzM>|0Gwfu90TG&Y$P5^Po%V+T6`ppRib(U;|}d`&uAj@1p(#O z^7WGy0ay(O;<5WCv~2-c4ecGF=mxDLi6lO)&DcsiV)0=xb^v!bB#Izfp8W;}mUe;3lWEg%D42FpwH+gq3>_X# zgun~zV{I&$)*l>4^ZP(Ua!2moJjZ!AYHS7>Q z34)jj?C7CQwPKtoBOMw61Ru9X)o^HB3+gvD%Ji{_!g!b4M#S6%KB?_Pn)uxZA6zP| zUL3X_SM#&-02jjQ^1$I+hHM zh7KntU~VzWe45#`fpPIHZ|e{C4+M8?-M4$|PH1Z^sJ~-?IfJ)&6fxdX2w>rz2c2Ae z>w%RmvmQ^RgLLJf4d3wq*_r^jAN-Kn!VOa*7{jKh`Xay-mVG1b8*oUz2;T=&Bww;!NP8I^jqFKP{QrCA&0c@pfTCDD+{tJ^)U>2>8cTscezN@R= zes$GZa6WS9ak|EWS6=-?X1}fU^oQF_)4vhJCQScGDlw5PO!DGI(8>sI>9(KU31j4gi=v6pz>-wz0kI45L965^2tA~;1yx_pX z?|DZ525Hu;trL}N>d?sppk?K#ubMWdY4kEFR>l<)Q*Q0tJZYvZ%Dz(mBzJFI_c5Bn xqA;!wO1TH;s^6Mxh?eOj_xS0z9tLRUezOn1jdTC>d;ZaHqz3idaJ_%22wt6K9l`(r literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bf361d2e203977185c942a49f45b315b3937aa5c GIT binary patch literal 24520 zcmeHP4{%#Wdf#WsmWXv&29Z93oqLvjGzCK>Oa7DK9CD%<=f4ssj0b3CNtPVtY)Qzn ztH1yX2iHI{op6PYpyX=WaxGkL##|Z*;nF%i=E!h8#&mMi-rbZs(9SSSXX+ez?R%1(7;;R@X=mj3eZTM9Z+Cxhci;Eqr;sLu!DfgOXpxdo3!zu6*6{RVgS zZ7U+Ga1xIy0T12Hz%?#*OXBl)w{$jj;x`U9}D-ul$^3NdpJ#M4kod`oBV-*VpoVdY|%vP>43{rvNxT12HV4Sc?rd%!T5M+ zG|B-&nlw?9a1lSdYE5&Xk&tch!J}CCBFB>sYo>U*MW4?rzxtEHf8(Ut;NJl)z#M}< zr2cBA&s}1>|oo<-2=U)D~l>6w6#Y~{q)w2?DeLDhD*Ey(Pvw+e+fb>l& z{S>4P7xK+dH{_pi)MMSVQtk<}$wWZz`lXaR`mE(3Ksd`!^=@7 zB){BTC%^QRMQ+T|p}@#y>5?S*SGw%-vU{$*sEo=lXP=jR4mTYQujjx`5sG{;tj3bv zPg~>*k6Pp>9<$`T+Un$;M|sTmYgoKDXRpn_GG)JK_oE|ccAiQHW=MUGyk9s4@n>sY zz#J?2gkx%-HBWY86q*_Yqv=!@27wecWQOC^d z=ozcX*1z_>HM3$Lj^lhmmYv0R_;_TQvxN+?o&x7(`B}R^Fmvo5R}M?||Lgq71m=`g zH>aLBz|XxnpWbY`2IrG(1^-3akuR`0RKn0FK4Avcq+kXCKR7>O{*;}cm1e^iJA+CY zDvqoSKj)c|kh>)XXHvV%|7q#k(B_id_y}Eb#h83PeFAHx%zDH9i57(@*ZfMp_prK+ z$tOw4jAf2r#0vEP&+Qiq56Kp5V@Yd2tZB^Ke{9cx3ywFwZqI*hz5Nl%H^lP;*vA^p zSIgJG0sGGxi~RO!i@avqBER%1>_sOm^1UxvE zKj}Gi@IP&#sq9?cBY)Oi|DBI)2TrAr)RFq{T(CWN?!bwHt>xT-ubFQnFK363LwoFM za$U2O?`)RNNv)^9t(-gX_7DEp*?wF4^xw6%-?s1ck6Wj*cFVCp?>v-yiH{WvRN3Bx+mr(caX3NFtWV7sDx$dGeveH|4_whgck>B?pz=ePK0_;gcre1l- zbgVgR^EVG!+Hc4nK6riBGuM>$$k&HMgU;B*?wWAu(YDycvm_>Uw63@Gj(z&zq19o@ zti+C=Gl$O%wDi{>s|}xdxUIjwmxQHwYwUPaO;|E1{SC*UuBRpD*&~HRkF~`-&8D!F zZtZXQAsnqrY~p9;@N;b~{ifGz!_OUtHjdVW&yTeBn`|U}-Ujipo~NbX^13M;I@A_B zuGY8MYVMMjDcv{x^u$MX+t0VPobcU)jHO;{-F*IVTlo0X>F>Q4J^+#GZDjKSi1gu} z@!n-LR)gQX8DjM}9DcvYhP{b>cvKpIXkn?-*>A!T{6Sm42}abCX^GkVaI91ME$ycN zFU-^j$g4l!3)2?;u|}lby2^W-Qfmj*xHQ2-wgV z8UTg{fSmzgW&l`$SxWMC&Gq>ko9owxi2W_%ojVfAf48YVU$@ehzY#ulO>k_o$@PjO zKjwA7I+jgySPyCj(#!L9*Yb9vv`zdMUC)iMo^|W>BCJ>c?1wO0Pua<7IKW-PdAw6N zsf`bGR@Cw8bRyw;&#u9HGR+QG5Xje1&(%in0+SN9<=Y{{xaOUu?8UCnpt&s zMnrxZ_LdSp#5@O2 zMKym`lR3* zT<+Ud__n^9KUec-{eMcT`Lp(4qiX(K{rw;1wgy-wcI>sCQuJb!jp^XF>*T+N^9b2OE*!|M0X{7Iuq4B@^7 z|Krm?FQq=;0{{PGh3@y&=Qr}z=Qpa)Z&aV(_{>kXRP$$XKmD>kzrpfZ94X76^*YaY zxt-^`sEf}&6ItjJ#;3`OfV%|QC&&Ro9v0-3Am;@6h#*f3 z@{AzQ3i6yF&kOQ`Dzou<4C7fed0vngRGE#h)i6G$YvXGX#;3{3f+o8J*(b;WK^_+5lpyB>`G_D-3-XL0&kFLK zAkPc(f*|{RQnCL5LH5BM#(9hDE+EWpADnv)?<>~z0cRSnom(O`6>&SrSTLp!`k?u1 zTq!~yT!O3!{w|^aiqNi0IERYRPnR%v6=7U1VO&JO?K)f=uU&{kgm&#hyE*t73Ln=I z^(QGf-f01!5%5_7pA+zT0bdYsB5-0CWFqim7x*DU9J>%l5pb7)`vg27;KKr*QgQJ+ zi&{zjh0`3IOYj z1YR4laGL{kBoXV`1zV$p9{Bqn&Nr;JCGk!Dm%ummr)`RVD)UYKSto@GmHDRrOW>RO zFTyw2p)kIg%sI93|5sDK^)?6CG`=-kDc^ld zsmwR^UjpCMe-XaH4u$c}WX`FL{|=Dyt+zSArtz)WG`^Rq!UuLB z@{nrnEBFpHLW8vu^Y;<%zgG3oAAE&Aoj)3pyV z{A?-===_JdzjtG#1!Rw++m2tw+92|69JoK7ru=Rotzg?oX9)ryfI<|`SdDd0XG8< zoKoB+;8wtaGm7^JxD9aNgyKE{w*&qa7556b18{iR0QK(`@HW698KbyEz|9M-_`V2= z%NJUUT=@Vm@+05_fEVKkxF2x1lcRAI0k;AU|L~=FlYsYDz-7RT{0sgH;6)w;+yQuT zyaL_?c%#~`U%-18OhW%@I!pWJ2mC74zwLsC+X2_w)o?4|8{u^&bY3xkCjZJrI;F2R z(Dl0D5jgP_x$Oa5<5t7HfNOowa4X;%hZ^2n0ha;SIMnh4YvZW^;5$KD&R8UT0b>^2jE(NG~B!}DDX2_?2i?2jZY1C0ItPnIPNWE z0Z`o7V1X9(S!bP zWcUsioBQK&uZpGM_<757hu(W_&g8Q``xo#1?PD8WjveVIWDbI2JJ~A`zxVd+_?R*k zO;5o4m)1Gmx4N84G!aRT#1o_IoRgW@Ej`ZLzrL(Dl}_%9MlxStrYOCsu}~(KOpl`i z>PU1d9*Hsq)JQU2R6zYkG@Xc!DT&Z{be(hC)=j&DeVaBqm9bD_bP`^lv(6cDDw+K$ z5JpmyP9B8@j%G8_#7K1HmXS~zuCa8kgIt#3mCFe05Z43?Qd6F&SpT z+|JdySfTW&+J|HcMi+G|p^=evbYf!XWN0iNi$~M6K8*}v;`c#^T-hF{l8nVBq8U_N z5PxrSBC|t77%-@Lv&JXmiA~>w#A!!F?$bz*{51)3FE%;UvT=Jqs!Y9<2kqv*3mXE{}q#WPGGD1K}hz zRIznvr0fZBZ@5ye1Hlzr@2t>z#}ykpuv@Y9u1c+6v9ZH2Dz@HTp>@ya8aqz+P$Ci) z_95Jcggv5nHQQYHuF<<%+sJxXYkOSpYHj-inQx1H|F_V+S-Oh9*Ng9XYf*qEmwG+G z7asB0c!aB9vEbKayufw6Sg;N+*dMXr?)JL9YrHOZ#53Xzdp+*1k0Em^I0rFZ0o%5X+k$?0 zt0r}soQPtF=uQyCOkm4;+LRl4q8^#hC?NQ{PO64O6Vaf0QKOz-#wd(;scl5`P2ih8 zFVV#BKJdU|w0dyZDzEx?tpYC4>hU0vMOwW*pf46z2&)g|4R<3+#Ymmr#RFlpYX9_s zI$dF1myBmRo(hhI_9rLd+#<{TG_%tN#?rIADG&?{2Dfb7wSD7OXlp#E-Z8*AgIhd` zXtxvsSiJL~Cl_x$u(IK-Cz6>UojGX3J05U0CIHR{E^)THA#!;#+>m?=ta>A$3DZ83 zOeAn+O~o_&^?cyELUx!v3F{ChKHL!nVcA8q(8(fUjLjlWr@FdYilCd$X|cM8#xI_X zqG#Facoo&R?)`k#J3n7_M$TvMJf5!c;N@4p#M$pyEvXpc#=ye zftzi9)meZmxMU7~!Lz`y0;=op@)wYSx+}f@gd7CcmvD9LbjKFG7P0mB8<%%HQ05M6 I<97f50%&h?O#lD@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d37991e081c2726dbd84854d1447824ad54eaa94 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14AV`Ffek1GH?(E4iY4ezyW#~21dk%%1>)US_xF)A&H$I zzwbc&WG27@z|{dfcJUDG;;HOXU0ns-*MMu*^H_3cF0D=lwt2pf!Ir(qEPE;`XMqh1 zt8@2u2MH_Yszhm?>O@RLC7ma&e)Y6bPrcVkvQ(~+m~!{V-6mq%qU~EVh0F2#FAmDJ zIeJ}~6v}l2?$Nk4MdAIEqvt&h=l%3(E!e!-fE$ea=e(DZ^Lph5x@mtfx)Q+)%b+5r literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K640.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..4d8ac966ce337638d439e8f1afe2f819fa750f78 GIT binary patch literal 27464 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K6912.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K6912.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..25ad11d3259a6e1461d3c82b16b74e65850c6514 GIT binary patch literal 660 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 X+oSPb#P;9kF7LRj#5b%hyL|r#6T7fQ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6ede7cbf14458aafa3cb8113a1cd4fd6668953b2 GIT binary patch literal 660 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 R_4kQ8cN{K~VfF0r{x3-iY^wkO literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K768.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9e5a4b13e3b9d320584b383adaa705cfacf966c7 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D-~ikJ1`fi&JqQv<;6NQ17%MJRoW!n@B2a~gBzBy< z{|&OU1pzAncLVS-Mn~BBQxj8J%^rBxfa&X{FPSSZp-&ogv;5u%f0;$0*-J%3dN1Gx?7(uqbjwMjE0E)+FM^{b|>Xv$tE$y&I?#FTqbZf=xV_M@M}l=wZ1qj1$n wf(*w>xMsvXDYx})!{jFWJ%9Ke{s>(4Ta36)xqte-P4sJp>sU>gpjSnNHyH0CcmMzZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K768.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..20e2a20fe740d27cb44dacdee4bc41fe30de42dc GIT binary patch literal 28872 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..665e9a7a6973aab289ac1bf2ea200970c3b1fca4 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D-~bHlbl@Ni9HdAbft|}RFjl=#`DtxPD}gFJB(dZ8 z{U3;*Ed*ErxH*8wK5D@(oQgix)g6Fm4!Aa7hLXE*>H4(6HqZAVIC2n)WsQ1OGUd7v_hj7Qw|xKHWWVRJ-_MLrg85BG+{(Cr`n^u{>y=wkP4|OAl?Yx3)+1m5 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..41743c68d6ab5237a5ca05ed16a73db284ddf396 GIT binary patch literal 23880 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 NI9B8p*0w$V{{>l)C)@x4 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2e24981a29e73619f8d4b3a672e06e0387d7b25e GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D-~fzlFmMnC4iY4ezh*?=32`{%r;ALsST4Rq7~V00ydC-$x+ ANB{r; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9d5b2d6c7b084cbc97e3b0fa3bb2e5c73d9d52a5 GIT binary patch literal 22344 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 ead$`GrcTrC(Rwe^_TO(^-f?Gy=wlP4k06l?Yzt Cl_f9$ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a1e9eb3af10b42fa907ca00ac63639d9cb62f024 GIT binary patch literal 22920 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 IjoaP-3pPAY%m4rY literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..75eb7c84f1cd977a0acbd8dcbe0b8b75fc6d04f4 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K768.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_1col_swiglu/gemm_swiglu_bf16_K768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1db4121112700fc128240eb955fb78832a7233a5 GIT binary patch literal 32520 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 J*5>X0{{sYzdp7_8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1024.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1c8ebd22a061e255737471e46cbb77bfd62980a2 GIT binary patch literal 1304 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 IuKj)g3(3c-ivR!s literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..09582183ffeec0a721eff0f6b9213e185b942ac1 GIT binary patch literal 1304 zcmbW0J&wXK6okjdAc~dPf`S4G3vmE$K#ClMf_o68E%q2&>`^Ev5f_4I=Z)-G*_B0# zB+ozdy@@9$ZLPy4ff&9_od$L8Mqw)`#gMxA$yTqT&D~8aI!yKmIL~n zuzo0MAp;v=&2f1;&cSpmsdXhhd-~263u0q&6$zsL>}jVx4R&Y6Qn^NmIkzFV%@#{r z@*S?vh4AtJw`i419|ILB*2=X7_egH=+c<8k_IoP*CXJ{?zmtO7k^83KuS&nJ;Qo;7 zfsStFT+fx6`&BN3Kn-SY&RmUT?nCFMMdolfHs(8=fv0kP=A7(LRt6ezSk6G_hne%_ z${93CpgMCqpk~Pzo$yS%z7u?#J@Il KWlYRlR+|^BYe$9v literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..42d88c801881d5991b789fd78e4c2bc17ca6dfcc GIT binary patch literal 40024 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 LCGN0xAMF2M$^eq_ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e1df7f0b93c4eea213a470933cd5c813610c55f8 GIT binary patch literal 1304 zcmbW0y=}uV5QQIU+HeuTDN?vFU?K1T*+42>WQ-Kv!wQfAGD3;(P zlz^}bNyne}-4mbS!eZ%wX8`LtAg{x9c6f2QPNU<@lFSu{yM!$XFwranJ(r?mGE&81m+@9P!{eD#X z4F&g$+(zuut(@zzGIQU?We}*r%q^L#iOfCN+`Pyf&dzJT;~8{RuFqVM{mIHmLx<%I zY<`@%hFm#=E(ug;Zf9I(F4Iso$((X0vY!0@EJ&`-+`jaiG*pXzC$c_p@AP}9^vkUG P(vAMLu`A~^Z&~ebGUiFP literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1152.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1152.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a28852ab1aafa1ddb6dc27e7d7134b7e8efbb79d GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d037496e7d8655e99fb3079208ae05e7bb2c8f18 GIT binary patch literal 1304 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d61a8e023c1fdc2605515dd7dcfe4a0df36e3e6a GIT binary patch literal 1304 zcmbW0J#GRq5QX0u6K#P+iWC$`tRfD;4cLN%q~IReNI6J~93%xrN|Xzc@$9_)u{M!~ zCHz10&BJdY@u3pn8Ng-<=(KBB!6D7+Zs~n^1-_3!xE&wUR(R9S?)e1{QR7n!-0*S1 z^^cR*y0HVc+}APk4AO3N?Ke@gCPViDLF>6_3Znk3Y40`lk=f+QxuV1|w;{Kh1W4lE z)(AWN|6iP(OC6Iey4X55WZV~WQ~I`#D%N|>^$s~K8TBqQZcFZ+dfyB6#*F(xZatQZ zV$Xd#mqwsmdak0cW<0m@vt{NvTqT&l(;GDU>ss*}M2%;Vjm=~QeFHzAdafo{-(VC{ z?76*j>A6u3D?mMG+!?PAdcW*y>WcNAa=k+iOGdpjUhlYf>OB|grPo`n#=hEAm56;_ HqqY13R>nq_ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..8109762b97b856efc7b109f26656e71048cf5d29 GIT binary patch literal 47448 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

SzIr|x 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1344.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1344.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1310f06cf1c998fcace97e27ad37c802d480141c GIT binary patch literal 1304 zcmbVLF-`+95S(=!NP!dziWHG@LU{l`$Q5}451`0DI3)f-iWEE~1!cqw_(@pXJ2{_q zAS*6x?|MD6bDo3vo0$NQ02Wg~w`rUNPhr=j&}R1vd~E=C-rR?jd($b_SpgTX_rq{Z z*g9eSZA^1btbir+x_X{Lx`oD8iH1FWX2nYJ;c!$4QvKP}+Ikw?&VmQy6=lqMTk<|< z#oCsBhvRt;x5EG5Vr#tAF+kB^X}qrBeIakq+v?+_QLT4Z>g_Qi67^0B-j2Li>V2=& z>kHmJc^jZhTEkrJxr6c22*jZ0X7tsF=kDxmT6hj8anax54faH?_ng=JLBwVB7%`=9 zVCO^6HRRPdXfK!RJ-0SqdM?9=XzIDhJL2_T@6Ront39_Z_4XJMi+V@Ao_Md+yQ|bo RuXox_{A)v3BGGSIEWd&YOiBO% literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..4a38901a067c45a98cabc640bfe4d8a44362d178 GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae9ba043f5293e1f8e7e03b7aa60b3f0db4d10f4 GIT binary patch literal 1304 zcmbVLF-`+95S(=!bOlluGd53+|0qlriV+$orHP zYg_sqj^_p38vlQbo$*q~2t|XH@w$TdnY=-7uaA>PwcdTHcfg29)H^G9d-7hX_pMT| zFL>X{+p658HO$qX`!HS_ff)2$LtjmJ?$*xch39Y*7yTXH;ETxhp7VM?h`5XaBc}8X z?0oFGmc04~-Q{w<=QhSm&t(`9O+6QRC%iuB?HV#ydu~_i9WWvm^-g#_@m{HSU#XW~ R@3ouw*M_b{qTjMuegRk(Ond+U literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c29b7c4ab2e678dc32da43f70bda6d5e22dd722c GIT binary patch literal 36952 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 DinXqC literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1472.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1472.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5349aeb5895a0a65c68e960921803a87123afa4f GIT binary patch literal 1304 zcmbVLF-`+95S(=!bOlln5xF!Do7F*+`jsc1W3*&VK?=yLW-Vc48G^+LPO1(WsM55kF!P}AdO1*ED zdVRsWCvOXMNo$y^J@;pkc7eh_gPJw{CF z8`$~Kb1ixG4K|m{^`2W9FFluGL^SnW&x!QBvQg4qDv8Z>%>xuVDy}L@i S^m?b=#J@IlB@+FX#qtZ@f=;Xe literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..debfab175762cce2afc5814c65202fcb2c939ade GIT binary patch literal 39896 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 R*V0Y;YqcxqlHan}{Q#07O5y+j literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3c1bd980a52ec01dd0719eda776987dc0c1fb7c4 GIT binary patch literal 39384 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≪x^z%j9mwvvO{RgiF;;l128-A1j($5#O z|Jw`tcgE)-<-hdvMfxxOe3AC0pD)tB^z%j9mwvvO_9dS$W`CY4xZa%k#=Kf@rJpa- zf9dCov@iX9G3}3{|0SI-(!TWbMcS8szDWDh&lj^lw-n^R!1-eO=kam%`N;Ea^L*h) zh=|QNUj!!Si+GQR$8F}Q!};PR=Zoz=oG)H-zS!z;zIe&`VynaX;w9&ctq$jlmz*!Q zI-DX3-HPQR?jXWn1`q0HjYwR6G^ik+79*BJ<^mvjf{L~SBUlDzO5q&50_<>^Kr=R!< zL2vO)^ak`6KSW;-J$@)t_&H4Ubx0ni{%Cz2^m@Luz7qPKj4g_NB>hPIQy<&xxv56vvH5PoZMW5j_9FU9=rxDh zz5{yAxz>lE*PLj59rT(Lt@q~#2qyzpe=4EZdqnH&px6Gj9x;T+6fxI`AsRz(tr?<6 z4B_9iE$k6PEPKQd9*2b2r~cu6d> z^oSu|pV=S85KE63!sEW^Ct`@D$KEffM{MD7Ti9RTtttUQ&7JNdJ=Q2b`e7g z>LbuwJQM$jA(}U$M-1^+nf+`gdc+Vfi4|76h*6qnVviU?#@lAuN1@leX?+j$);hVU z^@t%}z5cZxF{hwD0==~!h#$ljGA`{0v4ZfU^>xte@oIg0-bZ-$S>x(~p2QGKzX^KX zA8n6V;U%$x+b@c^@l&6d#0tVmx8<`h-(66TSV8)r?K`2@9BMsc1sS{68_-*O=c3jl zR**Rzu=;~oLHuhyVg>Op^&-E@V?|;!Gdzd2|$fe7A2J(m}Oqo&OANL1|i zdzAryT~+urf3F^*Da+p-)w2BEC@stH{nxVm-c~Kk@7>a}{N4mD%l~`hvMN3OhXnLs zVeoQZURdUYd=FOH^6RXr%i?;uW!oQ2X8*IH`yrBFT!zRb~=$7NsPR8BsLv0P(3J}4JJo!4@YLVMOwnf=uB#O8eNZ# zLlrirX5!LWOZZlsuh`_6*@tunqf3O1*vQCaVrpvtOl&+knoLZJ`-Nw?N#2JJMP@s~ zMtXE~DlyH42>c&OPfg#YHBvF4t!3jg$<*|g_QC0*eMqLJrY8$^0VCpFz@=~((4o@0 zFnlC7Y1~q@1F51tz#w@KT6GWFDG4o?A_3N#gtpc-NQkH5YxOLc6tw9M*k+*x4U|T~ zv2=2zI0NxC8YilvqiE|}i?rT$ zS!3tRJ(e0ykT}G{5Q!0;x60t6qDJSfI*@hVs$*Q|tvdVxtFXx9F)uiq5t}_%t(Zkc zyzLyINnupR1M({o>-jCb4dky@;V&Djf;`eH{2oj0;!V6C_ zWU+u4X5U={2UQKfT6T+;R@e<3=-O*(01kKW*|BTi;ND#a4%~HMu&3)_*Wkdxt^)_( z8=e|Il9-4Mnnz!F`+LI^v7_n9@ODJs=I}%^C2#~d6Pq4B0(~TWe{=XqA~uqM)qBHx zV`Ir-sAq@AF z;%44PCU$&09fKF_v>8U-hMZX2YI@Jy1hI14)!2= z2$Pwq1n-cD1cN*ixO0bSs)h3;ET&^)(D1M%#CU8fF=!rY!m?d5it(1)#<0B!9?>q* z#Jlgme=SmEn>G9A za1 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1728.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1728.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..670051ecc82983e178a862efa0023e9c97ef9158 GIT binary patch literal 1304 zcmbW0J#GRq6okiKgHRL+iWC$`SP=)v4WQs2P*CO$Y@{57f`d>{q(rH58}jUZBYUk) zWU;=V02o)VdO$J^f^h1+i;z6$zsL>}jPv^>$~)i*k(+bMA)R z_iVAWCEwwCpTaKj|F_sGmp*zbQY@5f3+|rW;P*1-wranJ(r?m;TJ+l#+?L!2{eD*Z zbp`iCt_NDWm2*8-X6~$927wyP+=RIr$lSBejf%|SW^BxNIDNDqLf3nikh{JLQ zI^WNnCs)p3lLV?Ww^A-MmuW;b$z0?PWIg%yPb61oZd>|I8c~aW2eRIAAM|^u^vkTb Q(oOtpLs!Pcyk)id1@`nycmMzZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1728.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K1728.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9f4594aa6275e03796f8275ee81b233219f7b0d2 GIT binary patch literal 38104 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 K&N5*hxMB literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..837c597db9eab9db06e6639a4c2d025f57f6e7ea GIT binary patch literal 39384 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2ff3ce5798f0a7388be9974116a7ba1534bc1416 GIT binary patch literal 1304 zcmbV~J#GRq5QX0u6Hy?MA_WB!R>T3g0Tdi01^0*}+E?3iA!DEO@#YBowNi|cYE4cPZjDad@-&lvF7f{&5}!s=zlm}7I16) z|1S>4rH)d;f|YUIfcr*nNEb_XdV?mt#~Zz+MkZ75WWbH&KB)JzQLi6xzsOa+F?X1U zX3u>amquU>dTvHvjd*TuXVZb_a2A*S9kdq~RIjzZf!BP^?7!HDDbhEv^J~uqa`g@N zeM+~_6}8@;7Q=2Gv7*E{ZmdXJ5I>Gi1H6nl&0r>)lV E2OoV#`Tzg` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K256.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K256.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bdd4038c94d5bda9929488d77c129c57ad738343 GIT binary patch literal 38744 zcmeHQ4{%#YnP2^}<;JF#inhXqj?>WJ69s3LZ zn=vIziT`$At?}hUUx<54`ya3S-96WS`CIYtUUg-;XP>F4$9+06eI%33Ol2ldjZH^W zqGZJ_4UU<12JYGDOfHp6WzyU#EerZQ^8W0-@@`g>0{#6VDGb-idjl;ac=&!PsCHF9 ziHU#qovE@O*{Ds;9xk|a{mXCN1yxp zqn~EXEBf9EJ#VwuH2w4Z_gYOTZhHntMhw5f%wf|aQO~AWr!arx(+~6ZteFCirV?YR z>F8ua`)JcpBfg10vw8cb-nTH;gCBmUm)hif(y?c(>83WX6*qmp^k00@>>9isEiiTy z`tabxi=`F}$nC;LGe)g;x$J-8kejbl@dG(fCbKfRfymq^|EY78*d1!Iv%_w$i)FoR zkgZ&ycis(P?8UtvgB82jxvXdqsIcWH&4sz2HWxPiuDS5iOU;EJUT7{{{iEi>lfP`< z(UL#-jEgOP^cA45{VULozdz~Er{eUH-sXrs`OJq~Czg?GKb({=&5{Ulq8P`3o(r zW>gNGjaYS5JJsrRsyc-+RX2!Tz?Fon<%Z)u~rlwOM{mE92~fwKCM& z2RrZoHufFms0*Po#wJ_~AKyI^=-KK2uq$#*o=O4VC$8!`b;Vn+{Ov2o%k|iUH#~4L z@bTw({jV;YVPWvU|FKxQH{fe%DSU&q6xiOD!l!WGxU;2jHRHZU$HAk{_A9jkw~0r6_NbZ&n9*?0I|?68VZ?9EFj=f}H`M^0b;wC|Jb zjMkMNiHz*MIo)+ZsRnQq$>kGiT~q<7Y24eeU_wPnMe6pFjOp?>pJo=Et8vk45|_ zT)oLv*s{s>ysP7ze`Y*?`Uj7HD%kbTnQwlpqwAd~zWGlbC+GdX$NqZDgZZcKGhWV) zFS5qFj6eE^j|2;o4X(nEQTNVGzKaW)O@ZF)Z@p+tT;E%I@qs`6_TbVlz{TLouMmNb zdHMs#JdbUfZyMZm%-40@{6qI&Gap`Vn-2%BiA6_)$=M_BSoBXile3>;NmozDPGA4j z@9%l=mYBxVy4chAbq+Q5vzRN@k$j@f9dmh%q2|X>H{6~KA9cl| zAL~qpH+f>NnU106Z{XfwBxirrYp^Zn}vGWrhL!KrUJKqHVyk59{ z$oGsV7JaZY`Gi^D*W`YWYlE@vy6->vQvJd6o$XIX5XB9a{d&jV^AB~#p7`|4SN=VA z8lD=P*xu9d^qZs8{Tqa@=0WdX_!??{=s)_JcyE%wdBimgZ!y=F;E;!p;G>;G9*n3x z*Pd(|#J%1a@^yLszcAA{!v6k8$8iAj^^NnZ@oiUpx$Z?%X4kQUU})Q4zMb=x_xKe{ zG09S$;)wGNj=+XyXc!C)gPmb8GYnR+N?DO0UyL={I_)=SAq5k@& z!VUPTZ^ONyy%CRS5A8>keSk4D zLc!nmB{LfGCIg=aC#&KY&C|FQmsOsoWR<5WS>u6_L-%<1b}BIQbtBHUTI9bMikY|ErK0JNciPjPU&Jb({am ze2kA&=6`ls3n_Xx>@s`7E;kT)?fkFD$^TyCdG9>`v*(O&^yigM z{>P)3lm9u-|D5N4m7a_``5%uDxL()!pUlVjFlGK{msP%|%2mFmWM*`f<$vvE`JY{8 zFWBV&;Oj~fBgMad6mCk z`?}8mWIo0RF7rRTtnxKguJSb{<8yy_GAb`#AD{b^pZSAI`m@V;KiO7}_meGo?fmaB z|CF5b`9J6Le^^;g{wH^w^Zu{%`9J6Lf6nLs{&zkZ={*0FQTFxy{7>dze55pAQ?km} zl&tbKCFApdW%=KLmCs3kb{X#{+sg5NvL&yb|Lt`0Kj--$Uv{{h{7>@W&fkA@;crMT9G|ny)EYa z*UtZXoczzp|M;@Q<>Y^o2Pgk?@;@j4bMikY|8w%cOU?ge{>9G|ny)EYa*UtZfPX6cQe|*{Da`HdPgOmR``Ja>jIr*QH|2g^J zrRIM!|KjHf&DWHy@--!^e2vTeJ6d=h{@s84n_I*Wk-3eBf2T|FkoaO3j{O811cwNY z5IjQgIKf$h^8}wEc!A(Wf|m$hCU}M5qKW1Bc9o4!%6fbQWPBPMMU6uQM+hDvc%0xY z!Fhtu5WGO}BEd@pFB7~%aM8qaeBrY3Nm-Atn~YCmqo{F+;0VDZ1dkJ(B{)y;8G;uG zUL<&l;AMhW2rimfj<2I^d{WlqYbWE=*eGfoA~-_u2*Kk7X9>;|e1_l!f)@#1B6ykL z6@rTO&}FA=;<@Cw026U*_1%f=^V zJ-%)-K8=l{#vy_u1dk9rPH>jsJi%uOULbgp;3a~W30@(%Xkt0OjJjR>5XK0^c>WLzP#b_~Kph{OcgTm6K+ICumpq2Xn`b zc>hCW9t|?y5ZS8+;SKiMKj9hnmYxy4-=^37^po|#2q%7m8EMx~+GT_XKj9%y=J5=f z#|5HaBzpAI;sO1%_+f;9^wZMAzhw{qmLC2sJ^WjGM%wk0b`7Er5q*T{M~Hr$=(9u* z-mJF3n}xxf)gSOi^m-qGH?1fAM?Wn+`f2$=KP^4_Y3b2VOOJk9dh}E1TjbIgxXxvM zgZeW1< zeyOrn$ecu8&rix)T-<_xf4Jfsb6peP!oCK+g}rE#{;JNmu$P@A6{_}%j#*ssAi z%5h1)C03j^sn25wzU^hLDARoFvekSK)X2B6uYqr2PneUiI^V+HRbHVw-@?8IzJ>i7 ze4`wfm#cyt31K+~GjXN$>=Udp< zz_+lkfp1~I2Hz;hCHaB<3@@ww??Ua9DRsPt}|J@cymUyF6&7xU#K{0x*LHhV+advC00zpJ#+L!l#N!bVPs%T%{{}pB5wxObZdH+|` ze6{_2UGp`r)9idjkF& z*sJYFL;3G|0RCTnzmF^boqH?xe{X4@ef=o=&F`sbUmkxJlzrEY746IY8_It31~J}B z@sPh(>8-~;#KmK8$i$pb@fsd77L$zGWo7-4@wW-0tgozW5HkNt3+^*gR@MZWww)(M%9l9w4}WnGZ3H_JAcmFKNCd*&D7 zRBh*rX}?2OFZ*3SzszI$U;p_c{jdLgG40oVzDRraa9Pi#SiT?gs{iXhU!?!_pD)sW z{pX9>fAG4#^F`XP|9mm~zoVl6^7uUNHRpHz=Zo~e{_{oJum60J_Uk`ir2YEO7t?;- z=Zo2&M=P$k@_b`Kt+(}`FVg?|&lhRG{`1AOKY{+Q>wJ;+>px$l{rb-rX}|vS#q7_G z75T4lzL@@bd|Z7#@_gGoU-%IsVl&PcfywzI-s9nMo0XN}d~uWW#a0jJi<_J;wlbVA zZgRfZ%5c88$@yX{!};PS=Zmcj=Zl+<(mY>mWjJ5lidbl75X=s`d*^%gdVdg{4^20x7fjR0-+CF=&;7#S4AIz-r|ASH$aaUnZi#i z(GOSAk5tk3LyvzDEBuTQKLO}1o{8Ro-r|So+n~q4KNNnB5q&H4Ev9~u==Vc^m8l;l zdT%jI_z4q!!aOGu{*4P--w%7ukJdLpkAD&-?AwU_a20(3dOa@frww{NF0J1Wz2-;j z4d|_PLfY*wddPfXWhhRdzrw_w7qs3Fz3z|Jw?ePyOY0k;-_6*P*hkWj#J~2iEv~mT zi#)cti*UQk>O*f8eFOBGLv7y&z2;o&1JG+uw7wO3&571~i=%{-QL8@<(Ca;-^{vor z|5}e2!efedh?~R;t6jt>%`>q_ z3?btUTlNv?HE&u!2)(sVE@(Ysh+D6Jtw+qMs1HGJtq0-6*_q6VL_GJd4TjO5or>m?nVD%WK%7XNOvMvYfEdrrSOUcNC1%oz zDI*=7PTU$iuz%0tv4K6igT_=eJvoPeXMbxj9yD^NvH%m=xuEhQ94F>;iS$Hb;--mc zE^457OgbA&P23s`&2JBN2aV)hI-WzHQ&wkoZMU(?w6a*w9t2@;2R7$PyE{}vfsRMhCdMF+C} zTXc-;zeR^XU=+v>_zgic6Y^*Nik=DiQ zsEhZ9Ui_$4eSNL|E|(wPKc0Z_izgZKvVa)o@a>~VR0+RZc1xC4*o__@IACc2j_umN zbI-xC1A7i1zWwmn;J}fAvC$&~hmU+PI2%8nn2wH_M_+Kq2ZPhm6PcOd4n*Is;B+c2 za0oaX&Bc#H9}3>x6+E7ZP9$LU!Qg@DWGW8ze0(aFO83BUG&Pxy=H_M+`xEKO9Iuiz zFBI-eoZ2~+iNB9%RjG4-V=;i$a5SBI|6F3vAXYV=$Vrw*HUMM}1nof-7qSILv zcW>+4y0tgF1;M{7IFu0U>u_e8n(#$>hfLv6;k|Qk)N?bxb#FmF*A+a#6CS>PyMlYt zxx`E|8c!TODjHXfR=cChh?(x)vGd>^@B+=T_|(o++Vl|Z-5L({CX>DKSWjq6GPW(z z9gS{}_iPQvw|Do160jdk#O5YZgV)9unnfaslx<9JrG2UN1PZsp_8<~P!0E*FkxVu- zm6<#>HXTi&K&D+N3eEQ<_)vJ-CB!X#kh0NJQ<*5dU>_%@$8u(6A&3QD0b)WO>@syS5|Vtl7UZM}4SCx>P>XsqENP^i*aJbIVy)(=4YAg{x*-8xOspJU#$WNk zxI6&}-u)`GwGE!DkP)>l``$P#$+C}U(rLc4PNs6F?0oQj#o3YN8SFzWe7qtW!?sJz zqmve4l1)o5mb$rHEM>P?)3kb6__rp*vaDF0pQ85Gd0?9!yX5LyUR!lZ&Ly|br>mCE zzsl_QtTFvb+w^bew2|qboXN~(tw~Eb|M4m)+X2r0`-9nkBnQF% bBBx{D_P#aGBDw$GaCyhw6<%TOJ~;S416E8~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2880.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K2880.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..60293f635212746f9d67dc468427152367ee6fce GIT binary patch literal 1304 zcmbW0y=}uV5QQIUDKL-#PLaZe0Skr)$Ocy7K~lKL7FK}l5f>gIBe+Ouc!F%=98dQ` zickW=EckOI@4F{H!Buxt2dn_hYe1%bJ3BmwS<^4A_j}-L1NiIaF@*e^bb8JXaH!;d zXr2KZCtP2QG?Ty*STHVQ#XY!gE^9l9hBdu1qL=(fjgzDx>d%_iR#So+OrMPFgqU($ zaz6*hoqUJWbq2r0|KDP3+(Fezs)ccV#(g0-=xy(Lqgd}Q*Bf(aF6y0R+>YEE^}ZMC ztupR`+y>~VR^D}A=((eDX$0n==ce@4i02+`ug*M&v-9fj@CFC@LHbtw29@0BB^_f9 zUCJBS{?Ky`x$*{WOi=8(wQ=dWB!^}b&nb7r>rwBw`Z}C1*1OI1#vIC}-Vv|&+#B`o S3iZ-z*{ETebjEAHn?Mf?ojkLSb z!<7?4)=7XAryW6|vk91r0)++-D5MEs2$gAo@R|`N%upCIa!O|?leX*d7{frf-#O== zd;YuHm3N7!Q<8gTto#4p`R{+u`OZ22`SkUNyyjn0rkzPYyCL7e)GOaD1=X$^hufuYummqh25uWVqH6fnvRk%L zVK;QR`+$X*!sq$bB;elLCAcFbuZkDm+A|WmDu21ZpT3>3<*VXNJNYrhzP8||2mgHh z=(oT4=);V88E>lz|M;~X|9JW9^fzmzB>(Q|8yqzJ1~Z3EtHgaaphRWs(Fdy2olV+n%V&%so|;`M`ym%oAU&Iq6S7`2$z_``>^|e#ZqD3*FZU>B;Zo-o_U> z_Aihge=$@4i17I%ZeifQ?a#QhM!PwHP ze|eXyf~Ajs%y%Q>dg4-M?tvOP8-aoQHcKh9*;^54S?~omJtT&PkzSU;EAxr%{=f}& z{>#Qh;2k5cm*xgDKK)|gv4>%Q)_49Gd+?eimvQqiF3MV#p1c2boR0vf10`@dXth&| z1tPJi!nQY=7+N*lOtkpJCNZ%2XZcd z=7uM)4cx%|nN78?Hfuf^w(e2w6uYNM-SZ0V@A>(UyTThnm^oQ8FOlWIo%drk1<2eq zBLsDC7;`PYw|6Aa+T(w~6<(0hzWJt5MU-Wly|1~W`-NTiJ*{SM(V9K4SS5iwAK*Uk zJX64PgpIk3_w@z>J;L*d^c?Vg&7V2Blb?^!6!1dqr1ulKZ7x?Zse1RS3e1XTl>I=O0f-i9A zQ@+5VFZcp2Phej><_oYbV)Zi-7qU6Vus@Em%1VFb?Jk2yExw;V<$2YmN@yFx=Z{r9 zQ0=;JW@$l*EF8DrxJ-*?YpQTRMf87`GW4~|l zq|;}=RIsWKU#kAdv!|cPRX03)`j5SDVo%PGJdXB6EX!P1@5*eecRlNBeCmD1v!}oN z*}n-kziIlZuQWEl>BLiCYdksc_nrIbwlnF^-DmtNHL}F2?lS)9%kK(iCMsQ-AK~8H z>wT9Oll6i2n|56`#%^lQJ^!A+`sY651;og{@PA=0k9oQR$2{li=d1hbkNKK!oPX%S z>*w26>gL-5*GD5m!SR_R?r7wlP2)2kV&ksX#vWhSK^cw4Y8rsulW+LmB#qY z_r1}NG&S^lp574s$U|u3tUG#ftg+uy&7v2p;h*2v*3j>J+7peOX&Qgryx&*teyeMv z(Q)H?O!HZ1|PlORw4VL<1b{4ZvH}wJq51;Ujo=Q@;lzYM5;pukORO!sz!kd;U#>hEVgK6p>t*cMzQrt7>v@0YmvBK=dXZ9FHh^v%hT*Sd(N&`5`B{kb77XX`C5;YuQ~Y|R!8P# zn_oKlnv<_#fjjw{ldt_=nXHqqnaKmsw_djSn#`a0NM*ie*HwO{>Q#QFbY`^WQ#QFbbM|NPab9A_v3SG`~x5IpL~DS zrsMrpn~wKaEq(ob?J&dVtDMiTajFgH^J|=jm)qySFex-DLel0Iw>$dVQ>Cdj?{Z(5%-e0x!_4BnJ zCtq`(uVL9a&)1yiYtHjE=lPoRe9d{j#Dvd-6JzQl)3^DCvR{7UI6zfw9r zzm}J;wOIL=^k>)c{;I7W@2^_=`uSR`ldn1X8kU`tuQ~aeldn1Xnv<_N`5MncP+n2_ zn#`B@uxWm!bd_HzUFBCw$LH7b^0fvl|C0XfI^JKk)#LqDOJ6@<3p)9lldoafIr*BC zuQ~aeldn1Xnv<{bECl5hm9NQsi4U9RS4vm;mC{vy#dZ4KYxFZ~{JYrHH*X5;<$ia(r!hL{1SoP2>e4FA{l)$jd}tA@VAbv!*P^*O)gxsq67Iknw5R$Z9!6y3 zi9AB&6p_+v1pqFAf`tdJjWC>5P2lUh8hY|kKPYZ{C%O3tM z9R4jF{wtlsK9r=>kL74pCTt@n+E>=&iIB#_(%`vH!Hp|*Jbf7?91R= z*o!vlpW=KAd)Y~HLvg-^eHnZU`*rw6J&NR8%8Ju!^?3)ux4o_wb((Kox0dhjGWizv zW$-QR33E~`&bP34<=;@8Z(&~s-@<+!zEO`N`IfQ^x?JBf2J<@p*%e+?T`hFYx2{{u z_n|WR7WQTEE$l_#=%3 zu3O7@1AwGBOumJE8GH+S8`oSZ&bP2HgKuG92H(Pd9llYIBKelG=3Bnjl6>3i5WflEx^6As zhsxwz*q6b#u;)XtmEwF0`!e_z_GR!b?APHN^(c~WDQmvvYbeRLy$1}FUSV0{v62dx7ml4|Iqn0bHsbLKX<@p&s=7I*dz9in_4*6 zZL?1+|K1-K^xu=~wb_T2|H|_P{rBZ|+w7N>|LWfq^xvO*v(27)RsV0my6}tn@)3Tz zb77mkq3pf46twTn_1Nsg%D!@ELHpggKAZiBvajA-(EiQ2ew%$-+56vG&_2Kai^{(C zL_z!f{x2*0z+DCH^ZUQ5?CUlbw9oJVs+zC5pOrLUBWgVa9xZ7-EGqxC-z?}qf4v#X zzyCc2{pYXe5#_)A(SrW-_sgoPKN`w^^Lya`%KLpp`ES}=u>X5=`|RsS z*>8DkLHqppv#9KwZz*V>@83}NTQ-XE7K(@bwMu&h_8|(7y&+TPgo@Yj(6N|g%+9Op zf{x!B5Otk-b$!tJ54&)m;k>$P=)6S{>+|Yrq4QVwyw0CjR|lOxec^S1yt*dne3ZP- z$g69H&VSm9*KNtG+Yj9^>jp@j{douX%nRaFdFP91zf<0x_cwojnaA{B`uQULmwvvO z_9dS$(w;q%*K?`n@5i+2f9dCo^k4e(gli<_J;wmO_IZgRfZ>Ttfe$@yZd!};RoqcqPK zTOH09H#uKybvR$#hIt>(7h7Ejznz4V<{U8>k%6Nvfo~yr7&v$nxR>C~z~MpQl?3+! zuQu@z!7G8|C-H=RC&8UlUQN-K@4$|SY+XdA#RV^AH)y~M-1U{U-T0( z#KN)n3*v|^JZ=m7EyNx%M30N$h&cuEEx<|4vD!rpDTs%FTRap0h#{Icf+L2wtIU2j z6C5$bO=5-BE@G7Cnb;$Skny%z_F>?fH;wlJx7NuejU$G*_4?O1VopIk1l(E=#1CQ% z8JG5hSV8#Fcr9=}UX8bBJ%neEHLgD3B!*b{7T~%++8(jOO=1PNUlwuWMUR`r3c^XR z<#Qn0TM$RAAbrsGUBESm8b_=kW7oI=+}b;rG>%w7=5)yF4`K!JuW`f*;$Pw-zv4f8 zh|SFK8rIU6p@*gJMSTb=coX$pUxpkub(Te+*XuwJyJxN$c|e{cBzRzcQ|?(l>Zih%PJ)UM|QBOTAsb2dixPb>76%xW3f# zk0&pF`ioz`?K2PP<78}l2ERwYE7Bg?qbn--OboNg-8b()YGBP`!oSxze)Unvf_-ITjP)C!~ zmIC!{vFSu?(nv(6V!MI|_U}17+`VUa(3p%QCg$*S;=6*QL1Xq*3c^@wE~vZ+$Fcd@ zSYj+T_J*;@Y{WqIuyi&YAKMiS&F=`c1dZ{z#ON%#9+?CbG-l?a(pgJztIbzrdcy2O zGKJB_f<|O)Y&teGb7(Fy86S_wrp5ijGu*`QLWe^0ok1fxK0XthPinnXiITSp@WC!nSG zYPAl6i?+V4Nb9XvZR}vTXzSaHwSLvcj$ssSy`xC$Z7*r;e7Q#wqcIYPco-rvqHC)R zE-GqtZPkISYpafNU0ZedgRH`$ivKv95u07tg!AOceVWR{_zBa7oKFuVhLiH1GfzwQ8oN(*)3bBup2tu zeZWE>9P8cRv*+OOfjx&0-*$Moulq>%@X(R&!$T{?%;vQM0^zR{ODvfo@j;PP<$d0nVp-C z?T;lUX8A4SW>k&=0aGr$4 zY-9om4@*LgMrLBe=AkAm+a;qIZ@F!Z+MD1J?Fvo&***8HM{64&w#jQMGCdm??1R+= za6)Ta8z<7DwPUQkbKU78ZtadbL!I^sx`HF#tl7UjN83hiUCN*7cxreuaw<88x#cXY zX_nK5%C)n+XK;9MXn5c5!v}ZoM_W_F<|_uw8D8QEM8BjUp!Lc_OfG-v!Eer+^+a-Z zSgagg$6xWlI6nah-gAZ7>VW6MWNdG>vD!WgOS0@olZgc1StsMOr|f+2eZ|?4^-1hQ zEPT8o8pgJZ&7+eRVUkS?7fapTEf&}!)-=7nP58Ga!?G-RJ3mG3t+&6l+j(4^8veao zm*o83xAW;Lr}Zn$e(O5Z-(j2n9h^2Y{S(v4xs)}@YZpO_41Ufk;5&HD8vH+A1$jHb l*?<3U_8-YXu)oOZ*x3V4e5JkU@i6|nGf`S5xRYZ|8H((16Lcu+?Bwi*9kG@*5odd z!_t;~hx2s~zsCRHVrN|H7*vs9Wn7T6K*L%Ic%r4iv%k}m(luNxMUhlXM>OBL1BzAwL=}9U8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b1b05e7fb69d4fb174471b14fe50c44585120ba5 GIT binary patch literal 40152 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..94652c5494a07c57a72af1632a196ae74a0da9c3 GIT binary patch literal 1304 zcmbW0v2DXJ5Jf*}T5yrTDO|WPV8QSJ*}y71NDA)}1;`*NGJrO43KuC2SJ}ono$f~z zp(KP=h~$xX@4om27mAq!HUO4WK&IVuc6e-OWw*4qe+E8xfWPh@+K_*dm!7i&9D?Mx zk7vNf3D*}R%_Xn~R*cISxCd7+Wo;)>vZsa-P4dSACn-VHuRU$8rwBEeE{yAh7;`If zzXr#he23F@4!_3V-(qjvLDx~Km2rK-eImD!%=(@g*?JGgWnxrAL)1G-xHY*q>U}lt ze|kg0eIvINxj#)K+jH;6r4d+zo}1BEBc8jny=me(oSj#HH=^dFU{~395G0>TI`%bm zDR*G|L(i4u${kdFfo#uhjmtZTYG^g_oN`CJ-s`OvBxmd0r+WJuT8nx|yxwtd)O*O( TORv|`jsCT5SI(*5qP6=5R&h?i literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K3456.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K3456.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b55055b9b0f124cc6cca4e1a46df741eef26232a GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K384.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c87b1ef7b41222f73cb586b4e7318301bb3fd297 GIT binary patch literal 1304 zcmbW0J#NB45QX0?CZa$hMG6WetcU|}16**B6x<_@l!K(mJwic|66HcC79h}I9ok26u&{G_xoFMa30N|Z{Yi5&(-AW z8#L)kvFCQqrE3N`ESq}HxD#GadYiuVV!g*)Z^~g@>Yea<$GubUsZcMy-fA`W*T$+u J%x{Ca`~rLSNn8K` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2acb64a73dc288fc53fa20e2eaa831ae9ffc9de4 GIT binary patch literal 41560 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 S>Gf8s(Z4oU<(&F0i`_5E?NWdM literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4032.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4032.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2c4056204315c67a4a2bc85fbbcce742651e47fa GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e2976167f578e7e4a7042f777eced8779c93f398 GIT binary patch literal 1304 zcmbW0F>V4e5JkU@i6|nGA_WB!E5rd(rh|fmq~IQGq#T4I2ce*#M7cn?2^r7M-}PD> zWU+T6C*E_w3w)JAY+gxu~L%GyD;Pr<4px#}fUV6Qj PZuGB>T{)+IOJes20&z=> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K448.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K448.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..83732f5039964169db995b497913090247ac3dc5 GIT binary patch literal 42968 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4608.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K4608.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..26b0965ae3338346c679e14e7f52f9843466adce GIT binary patch literal 1304 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 LJj2?#ulN4|vTUzk literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..919b8004285e00e466a3f044d503a58dc7e519dc GIT binary patch literal 1304 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5184.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5184.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..dc6113afc84c4f914334adb7c8bf136ea0b5f11b GIT binary patch literal 1304 zcmbVLL2kk@5FDFOAykPTIB-CXg?IozAcs7J1OFhEdgwEH=uu^rIPyicqVL} zG5#^8l_Y9l%e<@=&)~X^#C8*bJ$;N&eZ9n0Aej8Kr@i%*P>r^0<8{KA@;2mc*@>1p z`3~3n3ckkw-=a0%QFX$+HC~_bp2!>ZHfvTC>pkas2Mooc-dV=mk@rEp?}d7+jQ5kg z0qCe!=6Wgg+?Vmv2*jZ07WCDG=br6so_P*8=hfeF24Tsrif2$sJ&SZ5Ff^1I*!kFV zfxI$6OgIdfQy@fT38_JK^=7_d&hqLcR2QC*9~@ M8@qB&{g%Y;7tMM|5&!@I literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5aec5f41a3a53d165c78715a563246469b488211 GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..787e7ea194280489802a2a8eb2e770b973cc62cc GIT binary patch literal 1304 zcmbW0Jx&8L5QU!|2cyNK^hz8r^3b*abPCKFS+ZCIo zEV+mCbuE1Se-{ViQpY5V1Y6_!ihCqC>Fp`6UGJ&Zn{#Lh)Vrv-1GzWqeQ(qoD((ll z5g4>WZJIszXhJUh@%IIrJs0GBmNLnq)A9zkKJ{EA zSKgq{37S3E8J86oIW(JiPPsE)&w7u%xpvPTYP~s!a;bO5>m&C@y{AUK^!gyx=wF+v Ka!&nL#O?>aTSfK& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6574b285e06e98daf06b8135c160d901fb957f04 GIT binary patch literal 45784 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5760.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K5760.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..3a68c9056a6afa99ef2edeb19e5c0f4648be58dc GIT binary patch literal 1304 zcmbVLF>b>!3_K}H5g-N9p(rv0h+E_V{eeB?AssUG7jc0;q(dLlAwxzZA4(~j2g`z6 z2=QQvlz7K8&v4;x;eZza>p39X{^=ZE0p1ujAAcM zB5x&fsaEECEcD#B@zMyypyw9!)r9Bn?QEWT4xRJr?>K{I$*ziL5Tu?(x(*l`$_(s$ z?751(GJ|FSDE8dWcP$-vxsVGora9f3p0~kVO8X!=Z5hct}Xftx4GZ`k+p2MFp6ng#b z?%TKDJKf1T>|sjscE)<&_uKD%yZhVSZ@+tYzMCBxk0z2^Sl%hCGVq~)e8(|{^8F9+ zzlZth4yQHSt zRsEzkTsGbSI2Bu#59x14H)i~TPb%P~%InsZ};2~ARua@1S zg$ldDgWdZq#1uZyuOK z@x$Nx;$x36=4HICCj8^qHvHq|FEih)m6H6syLVu~@Egn=Hmwr(*?=`Fv$vdol()y* zO|VIES0oV|N=!t?V%kTY7PZ7TaqFh9*L~n7#@>&A{7Q@3kxW~`3_1~?@9{xhj_6?a1APZmqWw!p| zn(U42_+ zq0WEF7z?~(`1R7DJHj5kX2E6L{Id(PmStw%`8v)=fYX5zxD>S7 zsl@`3SX5yhO(up`4L1`l{$TOi?5B?V?`m5&dj5brJ+Q!rUH-tQnYw4A@?(1Qx&48> z%b&gB$!h~QFn@MK?W@h2Plv60R6C{aX;SyRLi>Ae_LHvgx)5egmh2U>9Ju?PSWN*k zH_Zq^7uJuu=HIt-IIyM1|9~qzC!>AyO`(b?%Qkyob659^JMMp4&EC8a zect_05zi4e>N4KHGZ5$zo`id*?*Z6l{8%!-b zR6J9e_Ohk?x!K`oUhj9YgX~-yO(FulX7Tv!aLdu~sq4=BK8QWO?wOyYPt||j7w}`h zZ}Ma^r~k!w+LL`l`^IeOa~sc1E>*CH9(<>V9iN@6c=7YC4?Xy^>d5igrHTjsW^2_) ze_nm++~iyZtNQ50>W@8p>TJHc;n`Dv=zSx5a(4I$v?pR&_PTmkw!Pl<_Z!ci z`p#$nD%kwS$)~>3*!;$0PkpWN_^jV|=Hu-TWj=Sm@r(5E0;{^m_=7LMJD44-bY*{t zd+)6GU7AnT2ik7hamg6HsV)Efd;j8}dyN+nBYVUDg}FT9=?Wb2oT;C!?yW!KYrb*z z;RmmuZC$FHZ4F!>jSL3kQ-|Eq$h(^2Qy*b**OtZ}U)T7r-|^7qsLN}_pLo_AJ>TEZ zS9NAx^!)uzeN|m7>Pj@mpQv+3T^^&a<_zv_ZHTuXc10t9))a58_e5QjjeRv=!nM+f zPkqlD{a8~&pXcdy(T_chHcq>v7e*WVJk>0Ep&I`AeXR|BzNbCW$U{x>C(QeO)$X^t z)*D-I{Px+OSM0yg)NnS8sA{nE7aR9nc(^J0#3PfR`BC%~JXKY*J*VL5r-vuH)(c-X zz1}_W)mQWI3!T-xH}RjIcJ;$s)YTsB^Y9V8r>W0_5j9LV#H)L8tuXq0&7R*EW~v6* z7yj)imMdT1h$2<5yXNoKJ#XslMz$XeZT;{calSGhzhWsWSz4z!;(UW6u%Q|12Sfc} zrytDpgB7e&maV9-%HCXGwLQZ8A7O1vb0gWmt*gpb+*F;t8UHHkaILEjR2j9|@wQs* z;sN&(zYli~Om58jLmQi!(KPkT!1dTi8?b+E`}Gp`YwvsxtM#0}^GmoOE4{!o)6eVi zL6^lGuT5tzzTaoJ@ncliBf_$b&@*mPpV@@^*D%2sxBsNe>vwB=>A$K$)axE10y6)# zun+T`Qu#Nd1(?sC{(6l&o%^h3!FMS;_G@3W+Z*LG^EJD!@+(!Z@++k?qp=`gYbeOq>^ghSu2&L$^?WVp_h$ba(v zRhy3YS8Y1pU$ykr^R0sZyPJOk#`*l3^ZB(h zKiTKxYy4C|d0FRcGGF4ul=+%nSNWBySNWCF@%goae68Eczob9Aj`vq>^>}~P(pS&d zdYpXCdA^2a=R99?p07F2*PQ2T&hs_r`5MncPzwKlz{@&cllc-KHqEb;uJS9TtNcpo z`21QyzSd&pU(%ml$NQ_cdc41C>8s~!Tbz8&$=9&#oP5p6*PMLK$=95G&B@nz7J~AM z%GYGR#D`7uE2XRaO6e-UQaV1rR*xms;wUHuUh)*`C8D)*PMI}%g)Ky zoP5p6*PMLK$=95Gjb|Y!uc&-Y=1Y9oG`~{1%CD5J@++>>?_Q&yS>xZuroNfO!@r{= zcR;9I_7mA4a)`)bA`cLGn8;}&XNWvUYOGn8*V}9wu^{$QdHf5qX}-3q)Qd@)D7kiJUWKIljh%@kw2euYrtD%SKMiAtHx~ zJV4}OBBzO*A@UrN=ZU;P?gWFp<+l z&JcNy$n!*AAo3!Smx#Pf`j! zPviw6FA{l)$jd~|nX(*TW5M{OuE*Cv#;0W?r{xfl!$ck+@-UIpM9vU-j>z*wULf)! zk(Y?POynGqhr=$b|7jwJafa}~!q12Sa<+sKn>4OtDC`AKroH78_5{~+9wu!K5IKz4 zuKjmgu`P_4p>ZAC7FnHzFG1!F^FF{2X}6p7N9GK&pL&kq$FheX%iajXndvh`WP^+= zMAnW$cnFc00DG&Su(y1|p5O;GPB=lkx<8mZZp8Z^BJ*gF@rKA=H3)C8*Zv95u(xnV zaK8=L{q&Rdzz8RPA~VvipR~&e4}QW!hRov}na6p8FAyC4w0J;2Eq)l`AN{m&__yrg z-@@VF!r|Y-8EMx~+BFCsB6yhK0|Xx?c$(ng&1wt0Su%LD`UBnwuJ;jm(>Uor`f1_l zr{xFzv~cv(!qHC)M?Wnb{S^2Hx%7p+&Sids^%DBzUBVal*~{{6-d7j14@-NozUUp# z-{-xln0-dtQ&S=T=U;noEoMJ2?InTaF4*5(%zjwf%P$Bf_UO;XV)ll#H^1Fn->`g} zw}S6MFP_=*BF+j^=AGen)#`aJ@^JpzgBMj-3!Rh5@AH$o4K8lMzrR`Wjkzw1Z(&~s z-@;zBN&l4QTiDA^k{e3%E$qwSTiCC{H|kL&-%?hbR;$lD2)^xgwW!m4>$;VEcbCbx zurGseVNaNoVrjmGy{qts(tHd1GWZtutMH9_6v?-gUC`zFmNA&u@z1XCqUvg)Yrb{e zO1=-2$+xgCgKuFk`bPhh=3ChFVc1G(zJ+}md<*+k_(na7kz-) znr~gVl5gaCW$`WS%ivqs^C8$uX}*Ph8GH--GWZtutMH9_6v?-gHQzEvmVDdm5WflE zx^5-k-DUDE?91R=*xR_~N@>1@eHnZU`!e_z_N(xXdKAgGlr`V-wU*@DUWfQi_||nR z`94r4-@?8OzJ)y>f~}P1TiBPux3DjRZ(+X*->65Cd`nsLEnh=PzU_60--K^nr}+h)%^rhU_+ z@UqhX?fE@6`$gqHbdTsy4f=v?!0OMw{9c=VSosf~TQNtxXM6MeZ1&7$_J=)c@3^Uj z^W8T4jPmdOK~eub`JFcVu<~DduBiXs{4SgQqViw;tD^q<@^7};Gq39Z4Oka`F<(By zPj^0Svp1Bz_m-meJM%p@`>?XF++NgvSH9O~KdkJl_Y}2%bH2}JpHcSyw-&W8?Ek#7 zuRT`OzOes`%06&UQTxLFFDv`H^+oLq`@gK_tL`Ujny+EC9s-Z8X+6v<|Fz#N>c4Qk z8Op!^y+!>OuIFLpzwNQ2{tNfZvf7Vr$Kbz`U2Z=b%762F;s5gceOUQ#+EcXud-Av2 z*N?K_^wy&Gh4E)z**D)()V|Qaq3k!U7vn7!5BY1AwhHV+6drp+rpyTyui>F%G0B)+ zP}c<=zcnE0It%K0q4OVh;XcC!b=A;$iz3z+)YU@gukLxBzo4!TI)D1Y>jDLJP0;x$ zd7V*E*9@Kiv=y)0R8Y4Ux?$G!lREqJ4(^#3#HsSm7t?;byuILW;rud>>3{9#i}b(t z^To7Z^Z6p}*`ozLmulgD%&7ja{d|%B*M7c8`?a4hX8*zK+RhhgzxMOR?Em(n{tM&t zu-Ba5wVyB2|Ju(NX}|XKMcS|Ze3ABRKVMAyHJ>kLe;zBk-U{=Ld9~iwe!fWmYd>G4 z{o2nL)BYIxzozp=+OPe5k@jmpU!?uo&lj^lw-n{S$oXRW=kamn`N;Ea^L*h)h={*9 zUxZA~7x5kskIk&04(E%ToG-TfaK5<7`C_ZX`Qj$$i>(gli<_J;wmO_IZgRfZ>Ttfe z`6$iv#a4&&#ZAr^TOH09w_)Cg^Tk#d!fz*`WH?96MP%S;OW>Ob9tIBH1nwnxGjMni zcqPHTz^hF>MDR-B_(?or-%0Rl;P`1Xfrkn12acZ>6nGcGYk|MY#M=no1RS#|?5hdx z%{B6zK;VIkjn>#ZOWHA zB<$;meSZl&09=nt`>6x2$EESTz%@S_H-KB~gtXh0^N{(%%21pDzs8iCE^6ElT=z%g zwZQd!X}l8nF2)wcK9YW<{E~;YyIxx(^4Q!?!tGA04{aszO5mD9ZQlu8bFT3KaLtLv zYk_M{H15p}5>5uK{!{|jdqm^4z_ovkBZlypBIX(~M9aXfHA8U35dJ;F!X7civPTTz zaaiDpAr_7p;wCY~!VyE<)*KOg#1OYNUV;wG`eY8Np|^Gxg!L&$hrE&DKV&6~!1fm`e3qQ((J+9 zMSjJ9_7Izy;WezKFG3GX-HZAVRPZM1xxNTFZ0anBM8$r;TN&`@s=}xFd(BWyUH&eh z*5&WcXkC7V}>O-|wW=ywEL zZVd&ESaKvann;fA2+mB$-_RMn?M>^u(vzuUv61OFtv8IW^mt@Co|>HC3e?fq@x(|> zDo{sKla>PYZL!H@Y}`mjCSp5+`}XcWIMls+SI`)bB*$j(bK*OKBSB;OL>j_qdM2p6 z2*5jIc>5_d&B&Vh)i**4b;$6U{co)#2wRK_SXk^m3rDO+^C3}ED z@*Zr_J!qpOv|Nq^SZfkmx2!@!GzDKPXThYPRd>KP3oU41Z4?|&B}Pj#5KW<>lC7hW zq7%@v^J=vYf=jmEUZV9aS8eQIw`A)brCPsgW5+N`w!XDQ>#bKbcD~#r$&na|Lp%(T z7}2#^1{W1Ix;E=T*0ov3xUS7Q{6SV>QN@3p&4|seYw~7M5pO#e&}6yi0rD#m>-l}W z4dky@;g5|~K^|!pevc}=KeX_pR`vBt{ar0Tynj3a;e{s|vRHx`X8#?7hg1!}T6T*T zD(nUicJH$g2uF7A?b*G5Xy5LG2k$sI)Z2ZiduZ@b_rXK=2B$`j#wH>|=Fu12es6Fh zax66&+>Yqm9Gplbg&cyMj!cgn1s)2XYz`icMMh(=x;MBlGL{$tJUcQTO(eI#a4<2J zj7-l=#`eaNW7GVWxLHtnd+bEdcxvQr1XZ=p^_9f{R>R?B;_jK)?p~~hZCfMpt+9?s z$SkNml$eMOPDduvsBYQX+0oItwY9Sq6@4+Wz7D1)s0m-BZ;>e+Zn$d(j<(#&FD>oJ z=bD52c*4WiZ*y>Waym8{kBr0)9~O8*5oA~}l6 z4%qHTq6l#!HgPDGPK~F=P7F;%5~z@A7pg+DTVi}DJna%{dndGXP7SrCNonp-XReQhIl4$dyi(&Q+(2xV1a#40YNk=rWFYvu6Ja9JPPvRiS*ET64({Kz7i~=pnXecyXLyMx5dD&ZfYvJyF}eJu2fw*s z)|08}A+d6J9e>3G$8r>mT?UuO2VtTO#uZPUMv(?+I$Y%(>IwkCPyB50Ap&shb02d`LzzvER< numha^_y1=9ksJj3i=2*~TSKd!MRNbW;_{A@MP6a;+TZ(soku?% literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7e2edcb9b51c4f559b067aa4aafc9656b7ec1fe9 GIT binary patch literal 1304 zcmbVLJ8l9o6dW59QLIFY6k8x+MWoLSpx_>%;2zmXDRYPvIYJ^Vr?P| z7yiHbtY_iE-OK@x0NN=a)4rV?p3^M$OY8kBa9jiavc6AS{!Kc)XBRjGsZY&w!^R2M zXJeYn#u8X?U&g>QxUQA8-9)6O_7^2p`IiOgG#j8 z$#*zh=I~4W|1Gx0dsRIUurOX<@b1W){C+1z+N%BTOTQUIf#`Qq@OI?A(eHbu-%#*= zk~adKD%7qzb6>{GAP|FTnK4%*nQQE9T4W9<=QZEy4R#GxRlh-ydKT%JF?1^EOz!A51+-m;e9( literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..948bd307e2c037fedf25ff339f1e26b12eb63e3a GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..844bb43b46f336d20f2de280fc933f1cb8e9acf8 GIT binary patch literal 41304 zcmeHQ4Q!joc|QJFWGpqJ62)T^IsHVbnU^RDWl6T|Dh*}Hs_fW~Y}tj;WTQxllIcn$ zs~=BJk%sQyoWvWHwi%eL?v!mQnluH}rulQ5LGH3PNY_FgQVdk@KUI@nmW%D>!9c1U~qMj~r(xM<3(A z8B@IE_;2?$n!bG07qU*!Iyj(JP=kQ^r;jfn6vLzLE z!-snJTN0Cap1+y^+;^80?g-0Qg$r-(WhuHWzq!9-n4{&(;!QjGXOR6Jp@!3cIDX{s zzV_rJjCmPvs}(=|wG%(Qd^-C|qom~TJ^e#NM!;a^u&GMavk59>=5IXzC~uFqt4b`H zh$g3E6A2|?tVxra;+y!hTXt;zYBOVB!4H3>MQw6E>DV*YbW@u*OP_hP@IQRf^!49~ z78v^y`cRu&Dm1uwgV<=su+=W-1Fs!)^K~kIzz2(XR>b=W&wcWr4Xy(Fyjtw+klX8G zfeoymtzMyb-VH$P^}Qa0<=fatMs8wPGL~h6%WeKv{mzE$voE>W(k(yFo&8LG?zYAH z+%=Ea=enM#&mH+veeU6B>T}P$P@nt$i}fc0*=K*?%Kq%U&&yEj%4HV|e`*xewpUT# zo#)iwgZh}Dz5}Z7Vs7&z^|^-{YkA$5UD=1c9uEV(?T4=H+0XiJV!4MG>T`2v>N)no zNWm98{n1UFW-PbKTNC{9!@gicRtyCrTNYcA<(}IX2yVRl>Nkvu;Is3OyCRM4Vl=8= zBM*uw!P9ZmSFrsNU-055e8GqA_vN;=)&vipRX%^@mi}H@zB>2ZiNM{5KQVUx;JN9c zC03hdKPsGq|K$x~ASX+1lkzV4pwAr$7F>bcwLiZqcr6R$8X5sFFTv*{)<{~-9+{do zby}@Di&h=)CF*!p9Xn!W(fZfk?=D??oR8x|As7rE2((tX=f&Kq``^Cb2L7%^2O>19wH{=4}4CFqE*Bf36 z2H*KD#GmuN;P+ni1$Qj^f?s|CvFI6J@Iznr1rL777i@n5 zaqe+nkZlRbQ6VC;d;tg}^<;j3z%TH2yEr~y^t|Ju-$3k-oI6_cvOnWxD~MAgFW(e! zu|w=!1|D!CT)li^ex&_ao9uQ5Jb3!Q>S8D6S86`~7u#z;_p`cF=cX5GSncO7);;#> zsb>mx&99z%xA#5l+4+&D(Vjd_uG#F$b!~RN>S}rMQ^u>OzW0?s4Yj>z`o(Xww7uu} zi{ETHF(2?f^_N`_W}o}0@$<|GBJ4fJ@BH;AL%9jREB8axy=$}Yjm7llVCVI>yXmm^>04vYrAg#%;|T|cdRtccLd)Vj}3>$ zXAZmLu}`#)&wQ4RySBFM^7Tyq@*@x48h3e(@uy$)#?KEn57a)jA%6a&tpl|^EbdCS zj6dDvj=Ma@K>bsw+tEDUal{pm-QPOivDp)MO}7lxe;u!WV|?cO-uPp!%>$m7HpCx0 zgEr2(;}^zS20V2vexVNjdA*M20pClWc#>R1UiF2W)P@gm9kvT=Gxp1 zn`?K*Sm3*?b7f&P_xYyUT+Q`$xf}3P(}dTix?ru*n49cu#6AvsR(L(s9Gc#g3xqed zF{5?nzr}uTz<##v*Eg_V`}lo_qpx@@M|kyZ#fblRrE8vy(snI-V??{Mk(Ac>epg&7WmH%SS5nXFIR*U8Ps~ zuHu=|QItQo7v;}(p1o%0{e)jXf8Ofk&rbea>fKemTkqu0PX28FONo;|>%ST~`Lpx> zv-AG*TmR0ylRxt;5#?>2Kg)cU4^!sPc3$PXO0V)=#WSO&D1UA)%Af5#d(F=K3BP{+ z9CGq!Cx3SGXK|0FTz2TZ|Ez8rl|zWfE&PqoeqYMG--5sY$s*#tbAKb}+~08SZ#efi ze&w4jPX0{e>D%@GhRkRANM-(P=T*L|^eW#~JnlW?oq1V!ecXGNcb*}V{_H&NgV^-A z4`T7_=g)`usps5(HgE4b_n-NibM9|A_n-MXSaWk1_i}}N%?)ubb@FF^*GD3OTaC{B zXXpO2bN~6*a5LP=pUoKawtoLv=C6FDG~ZRc%6Ap7@?FK_{&P|O+-v2-(x08jeGr=- z_dzUv{rq{ClRrD}KRfR~JMTXu^w9i|MGE`Lz4oDLA$Aat0} z5ke0UdW6s!LT3rRK+v1rq*$wgyrvC8hY1}a^bny(2%RBxme31? zUL^Dqp_d80Lg-aO=S^CUr>|&yl2>D5`Cc+UO&dfWCUk_*Lxdh7bcWDbLN5?{kUejShM+iMc=n+C^2%RPL0-+ZPy+r6`Laz{d zmC$*Umg8$F8lU9#_?pT1G;QQH9VT>y&_jeCA#{e&Swb%mdXdmegkC1}3ZYjCohS52 z#AWqAL+A+35FS|g88Jl8mIz{#mg^V_dx4W_Z~25hk?T2+khX>h9YJi@{(G(17D3F= zavj^2S(7DS0nHoceSja*ZZGMN%o$`q^&G*EWe-1=y%B*k(`T5_1{qhFtQ~{k5GFAJ z_EtY(Z~25hkss7@f(hEy{lVOEBi{conMZ?+H%#`bL2!e;_D^tzy(MQv9d(2TSjAnh`OLxA9rCG)sI=5dk8mxvtwv~WN_EqoZkAN{oC@Ne0}za@u%OAh~* zoRM||q+Nr^!$ck-@*yH0A@U5712?NJ;AYXl&FT+uBXYfufSZ<+{-d9k9R0NXpr4i; z{j}uhrzJ-}Ejjur!Cc4hcJZQgjo>xjTDKPOgH_@! z?5n_A*o(f=U*+)@_Iwz&QXX$%Uj^R6ejU7_N0E3-T47qJ{@+^QZPztIr}5UhwRkrp zXjK)zxqTIQ3;#CkI8z>PVP6H_!oCW;h5b5sLyscymbAuO=A3eU+jWTFZjHCrt;HL; zUR8Jt`zr7j_IwDoQXX$%Uj^R6z6!jB{W^Fe7Le4wO#asL;UedFA!fr8Ond)fs+1<*Yk+- z-}z)o|Hb=dRqe;lL^CV!Wl|A%9lstie7+;juSt(i~9n3=bZQNyh9VT@QHN?Gw80B3(at z{!tvk-e3V>g6zST)UvKKR6zTSX zH%#3i(b?bc;GTIwoT~18G3|HC>P5ec=a+d*|COIF(tqXWi)ml+`6BJvqeVTJZ1H}~ zs{U7gzDWO-pD)tB^7F;)KX9$=e3AB*pD$+rcb4>D9G^$L=KNNEzDWO-pD)tB^7BR7 zSAM=o`^wK3)4t;K#q7_MCD&VVzOks*Tjl4A^k4b;BJC?bUrhVs=zm4$i?px&e3AB* zpD)tB^7F;)&y6MVFLAz@{&{>{dp`1f+dNux7xFq&9wu@>W#>ZPL*$K+zr&Pw5_v1+m`!0{N95jo3(pCJJb1Ci8hdvcc?5C` z2V(Ds91oeoPa}~JmXQyYk@rB}X!;os*r-SE2!oP7*%X?t2@zHWWSK3ay>5XrwMXB zE-l{&xyDD!4alu^LfY-gd&qoYWhhJ_zrv(jFKT%Ja@`*-Z-iXWmzMh>-_6*v*hkWj zq<`XJU9NZ4i##^pN3iX)`p{WM?uT4ssO`HU*O+U05OR%)mN!DKG0}2wewbh~Z1u+v zx!xmM-Uzw&ujPm#Jf?`bMhww3Nk+y#T@HD$Pq&B1?`K;`W&RK@73vh#@@gi+&=8SaR(Bl5)fr z9=C=47GjSWqQ^z#h&d(YTOcPf$7&Zbq@+9yxrH~aVGYNA!NKAmVE?rjhmMDLvF2;i&~Bt;@0b5%Mo)*%EORb>w)+|Y$4;)eh@1N zK3d)gxgM{Ucji3=XOA_me#l7-vE*AI*ZtA;bk4WANeHbio6MD`sgN~Ry%Og>-*LN!e{=Ta4i95m|d8{&d`90X0m*4BBdHFph znwOuutae}0@-rGMy%AYE7(yquRWEPq<|OWE?*H%uA3-!ys?FJs@h z>7U-+_r8Ds>i%#0@BZQFXAJmWfj{1k|1$XRxqW_W(m0Wro=K)tw}sko35SeCYBW8T zOikPtnwuTJxjS_GdpGuErqjn0qqFbbXc#@2$=K|8dU}d8V8;?ClA{U9fE`UwTMXC_ zCZXz!lgA!9O@nwX1CKsFjOW>027jAiCR%8PKEn4e9g#u8&U zkHuzV2GmjMESemI=_sle`BV3eR_kjP&^UOk$QZVfa6mo|(N@{YvGU6bk24-%=;I)xK&77LpN+QZ4I z#PDovDg$-<_U>)ly1TkMw?i?I5bNtudWxFxMf!f3!lA<5b8xiv7XH%Sg?z3pw4WzD zeEqhC_M~PL)8nzx#E~PSan)$KS5z4?)4liaI`DpYf#m4uPNSj3wR?-!a5}Ud8i4?PKhYSTWuSo_9l2lyF?SefA78P!P>!xZQ`1VP0uC;`am@WIf1pK zg9B;7+P!16d)?_GZtae`#{@{0r>@TR9r0$({@ESv*ovB@OT{yt%tR++C)0D7TaL1t zW;tz8uASvQL(!q(=pDNc9oW4Oo~NSb69eW9k9b0&A1R2?dh!sH%O5>><)T?nrDvmJ z8-0uZ|Q60^m(c^NQbwq@Tr3QMx=N7Jbk-&rS;vnTC%@O{P6k@__DAr?NK zh@#kbiFtI=0!*T5$;DDPcZ(%#7i*eU?-2g2$*?R-R_CXvz4gvFSH0`aRhQuW%AM!a zH5IMA`Xy$6>pIgvZkzrc95yoj6VvIrj5Wz?7eTuWe$Fc3J9y0+e2Z5>(GGC-U*#L9 l2)fI?|40sk{Y6g49Ua~4o<(y1{nq6j_m+6V+I^t^{{ZX7EI9xG literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..099cb6f937d928cd3144bc646db2b4257c668744 GIT binary patch literal 1304 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 MQzFCKwrA*n0d-mx-v9sr literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6912.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6912.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..fed5bed8461c7af35d8a9efd505c7b8096cebb20 GIT binary patch literal 1304 zcmbW0J#NB45QX0^OGFVwiWEpe!a@`&a|0+i2nF|GBjq3zIRJ;CNQt-*nH|rw*Nzjd zvW3_CGxN>!Ji~>Di33&u=3_u!>v45>OK(-Zw5LA;UmL*RH&1EHzsp1K*#%BP;?wZl zuzAGw%}6uZSON>~%N%$H7w59Jo2XdRzR8lJ{Beqlq#)|on$}iR3K|;E#&tr>xm$A2 ztVE-oe22?@2EWAL-(qLnPIOkl!nnT2-IJ?&Ul>uW_h4KG0!#^tdN-D2NI~(^rhpY4I@6>}hWmUyJ2oldA zo!cC`lpff5*K-xQ(t~ZAptuKX$P^sh}-Ij4Th*6tfD_e)v; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..39bf82cb194fa7a018e6ed39a42381850d1788cf GIT binary patch literal 39384 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 O9rqM?hPC@Z@Baeytgd?i literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c430f70cd93e0c62b3701df80dc04cf23550353d GIT binary patch literal 1304 zcmbW0Jx&8L5QU!|2chNtbP?Pe*9o!YZpnQt zHcMG@52woXmp8>6^xTZT8u8q%txYS>;q1KnJH5gF_XV3h7vy}FGRUFR@&>j( z^jsuY-e8*(G<$AsTvlA<&}`y4<&Jng>y3frX1%*wZ_c5)sCUHcJ@-nzheo~hdMDNB NUz@6OPW@KI?gtv literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2c3d9b4f2f179f0c163c095f9485920405f5a3ec GIT binary patch literal 48600 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 Z$B5s*;$Fnp-vxK>xGPVFwRLy*e**xg8*Bgo literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K768.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b8917db4721f5358e42d59a60596a4bb264a6615 GIT binary patch literal 1304 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 Ps?onTR^^=fEsNbRlle-z literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9f844f8845e871ff7c613cd176ed0015fbdc3f8c GIT binary patch literal 40024 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 QC)Mb$Hdf`F`YnsyFKPx#>;M1& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..51c228e7fa76034068f965136419a5d5c09dc088 GIT binary patch literal 36952 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 Sz1~VS`m2pqIj4ThV)qO1a!nin literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..29acfb28e2f0efdee766e42d52ba529fcb5bb499 GIT binary patch literal 38104 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e1df7f0b93c4eea213a470933cd5c813610c55f8 GIT binary patch literal 1304 zcmbW0y=}uV5QQIU+HeuTDN?vFU?K1T*+42>WQ-Kv!wQfAGD3;(P zlz^}bNyne}-4mbS!eZ%wX8`LtAg{x9c6f2QPNU<@lFSu{yM!$XFwranJ(r?mGE&81m+@9P!{eD#X z4F&g$+(zuut(@zzGIQU?We}*r%q^L#iOfCN+`Pyf&dzJT;~8{RuFqVM{mIHmLx<%I zY<`@%hFm#=E(ug;Zf9I(F4Iso$((X0vY!0@EJ&`-+`jaiG*pXzC$c_p@AP}9^vkUG P(vAMLu`A~^Z&~ebGUiFP literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K1152.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K1152.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bc962b6194dbd4a9c8b125de824312017412ca79 GIT binary patch literal 45528 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 Y40m|f+>7}7`-3}o++QHW+OaqA-!~!X%K!iX literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..919b8004285e00e466a3f044d503a58dc7e519dc GIT binary patch literal 1304 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 aq17=G^{l!U@%eYv?K|!%a>ClV&;Nf!@lcKc literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K768.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_2col_swiglu/gemm_swiglu_bf16_K768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b8917db4721f5358e42d59a60596a4bb264a6615 GIT binary patch literal 1304 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1024.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5cbfe311b36dfe8732fe902ba9d86f026e92bf6f GIT binary patch literal 2592 zcmbtVL2kk@5L|~qQB|oNdguX(9C$!~&>VP35B!5v>O*?yLr~R2kBAS^$=c)CCZdbr zV8^j{W@mR|#MQI86WNGJb1#BN|2w$qrGIMtGK|$ppu%r*DKbrjWE(@LsWxm=5Ns0GnW-eu71ptRsk^wtbB>jf`k!W=PlO}!;=d!ycsQEye~eIsup z(uIsMnLW1+yfgwa=(#z4HR8F4us10@*Ds*wLlMI z@7oZG$?Q4wK%>Z(VCZ{zPUo@*pPAmNp21+&`*o%_Vkj2%P7A&0{Y`q&d&U1xFZ!E( zW9YBvZ4l1jD?Eq(Dla`p40=v@r;Kz&&6+Y#B^gZkj|4}HK;KJ*~$ z=e1}MN8V0P>R|TVI`FcL35Ei}bILn%-$Y)K8JW#`H)nbyhGJ1~>2-K6@+P^O^=^%N zM?B|w8{Bg&)^(oKI?@@$NId8JJMKB%8}ZzXy-)t7%{_qU@}dv_^z1>{Kl5DV-Rnsm z%sqhT6qjX8Fcb)$3;Q{5i?~7W9huE~;kiO@#851FPWMMV7kQIh&3fTElU{nRLpBS| T2o-WpinSZoIF#+fU0DAC5>cEj literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1024.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a79d41ba9c3af1ac936e505565df3f88d3f8a53f GIT binary patch literal 71277 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3956ee5f117a67d5083c48f15bc5a80dbe74ccff GIT binary patch literal 72558 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 Iy`}sA0on5eiU0rr literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0614a3f8890edb913f209648fbc3107829208b22 GIT binary patch literal 2592 zcmbtUF>V4e5L_PzK~bboq)35;3m(7^LP41#KL`c?;3DM#c|wXj1Vt%QB3_aokh!(T z_BkhF1cmSR?48-!9W16Ejg81kMC`Q)UfpkRszv)|UFg^9DDu4(sgB!8`>A@tqUZbp zK5FE*@4E0Ko&&xg+`io6!%Sq#?|9bS6Vu!yPHJ*okI7+BJXi7w2vVJ@sgsxocLy>V zNqH@M(d9Mh!`E>p)q|Yw#oYIT=sEAy>oriC@kYJ7nrX#)!OI-?j2IeIZ_c~CQ17Zx zZb zcrNfJwHE8$6zc8qoa42)=h&?CJg0r6Gl-FR&ds;qbGp~#xe;eCZvm-z2Jqa7gVSfk z&=525`+qzacy|$?cn0vC;xJiv^wM(;s+nj-=#Vjz#U{o$)Y*r-5dQ-7m!5e5 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1216.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1216.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b2f7580cd42c5b9616b7a6cda66000c02ea0b6b2 GIT binary patch literal 72302 zcmeHQ4RBmnb$+{A?<%ptt3+`(u^pb)D!3rXt|U9QamdP696524m46r)($TJ@m7`!u z8(DJY(7-wkC6G+30A)6mP=yu7oElf?6M}nu=t0dr^ZxzlRDeu(m5Ts$wmnNI!{u&+DWdhZ{O z9{#5V(%0Gq5UI2Fv{*^>(^tw<;w!bWos%3UPv`1c2*Y@PCdXixZT$7eSaoAt^5tqH9- zcdEti9Ee6j&QlSm&so06?7UZlu^-&f-fsO!H^#7o=Ggh~&6 z1H&-&RR%U3*k37>Im+bdvrM$!6HCbR5|`e?&+WvP zIpy5CBa*&*`PO!4;bNU#qJJfJ8rdzjrNN{)NM2=@7dy(^I*@DPf$G`ZI{mJrp}5HB z)WFNlhmB+om5bq^Lvc_}s@a(<;hQn*XEpn5zNZEh|4*{3yC%igx)|3mAnet1sCFIB z=e!elu?+H0&_P$nb)mPz>d3_Zk{K_RBxS#cL$NQ`Fly^o#^AGHC6J4yYOisK< zCSuL4<;NnezjS{d#r}`}XeBZ5Vcy3)ezK$QfBwF*^3FsI>-n)#yzG1>Uj86n*MAAS z*kL`XH+3GJc<>vs#O2S$5@)|0OMLT8EV1LSV~Ni^9ZNj$`B>tPCt`_#&%_exzkxP< zGL~?*@ZIb<&xD}ID-P3_BTjR3yqWEHsPa2q_>&vOntv@}r6m{;q_m821vvbk^c&hupdwul>l2EvHUT%|)HH zA359d@bjmhSZQg0{?zYA-sn6zn|mDN@%381Y*VPbbyMj1(B`M#=RSYxo1gt)vh$5o zPk(81=NoT-`YW4H%*JDn{ngg{N}s#i{dqCB;HRQ?{$ee0&!OY@VP z5~p5qI?Q=OaUB`rG%eeQeFp znY%mouHEGfg~m3IKE5$L6l!w!u6qpUcDIjq9}W%W-_tSLy{Ty^G_`r}x-a6j*&RLp zt;o>B9qoIYo>?>W@ckI$q43ZPBb)a&wKzjBw4i@>UU&Q6*fUK-`TIIXAD8FHTEcG$ zUF=@H;pEeB;`3^vaghL|s;y)IO#KR_D^uM;9 zx0@M41)caMh|jQcO7$<*0`IrwhrYTlT&#SyX(9Gf`RK1=o#9BPiI0czGb&!y8*Gro zjzy`6+!k*aQFQOs6#qq0@qsBBd?D%)}Q`0CJJUmfbTo$q_?W@5LZ=2OS& zdUUs~M{PZ7>rq>el20_IlD74ztw(J=YU@#3kN&3DqoO`k^<_fVhssvL6n|<|YyRRPg+RpdAb~CZ-*P}^WkJ@_F)}yu_we_g2M{PZ7>rq>e zUXb6{i~3O2mkC)PDqGc$%2xHGvhmy~9u^aa{Qf_}zIEsS#P|Om8{hwXY<&N(?fUiT zfd~e&&yU*YNBPsS_W99J+&({QzprP?Yo8yr&yV6+RQvp>eSY*pcz%@EgG|@t^P?VH z)sL!O)sM=?^P|3cv{%=cqCc;V@BcmR`2Jtp_3P2ywjQq}9OdTo6F z?`g;P|Jtr!k0xzBYU@#3kJ@_F)}yu_we_g2M{PZNLDr+99#r)uo*(tqqh4Fpk18I| zkLurd%IZ)2{;06;`B9IJ@BckEzW>*D{d)937=^EWe$+lcYM&pKzyH-fKWd*JWjg!} z9^kjXf7Jf|QTzKx?e8DG0Dk`{uLo6qiQhl!u~q%3+Ex9iY&<{et4DiveJP(G_1JiR z)MMlOe{I*VM|azL)ZQPp_ebshQG0*X-XFF1NA3Mldw=wTygw@HK~-Pk`B7dUDqGc$ z%2xHGvhn<=uO3b7`cghW>ap?ssK>_l|Jtr!k9OI5)YhZ69<}wTtw(J=YU@#3kJ@_l zf~-eHJ*etSJU`0oLuIS_QQ4|~R5qR;_0^;8y1tapk9ur8KkBjZ{lB*B*P}^WkJ@_F z)}yu_we_g2M{PZ7>rq>eUXb;us0USjiRVXoeW+|zKPp?*kIKgLqxegz;*igeir+m7 zm#9YvJT|`n_t^OUU)%NT(F5$SV%z6O?enAd`BD4)C>Naadi(q+Bf>sEYJdNz{r#i% z@7Lq+&0h$=f0WmQOxI}rsBBd~DqGc$%Et4fzIwD**O#I{uZ{2jJ?;4ZU)%NT(cQKl zwf9Hu{ZV^=)ZQPp_ebshQG0*X-XFan?~jUlP}P@se$-Q+s`^p2tNKydcz)DZkEV5f zDe6(Ljqm?G?fCv*+x6?wE?bY*O#Im_1gIU-_wro|FvDe9!=VM)YhZ69<}wTtw(J=YU@#3kJ@_l zf~-eHJ*etSJU{BIN4>VHA6a}W9vo#gC!QgV(%(6%Y!=fLLQ7>Js&JfOm*5n^8G^F} z=LjwmTq1am;CX@<2wo(3iQr{|D-w(R_W1G>w#vz=^pgAxc8NblaE9P4!8wA91eXY& zBY2+R1%ej|ULtsz;EKc|ziwZC!Z!J(Nqz>q6@ya*X9&&`oFlkMaEahKg69cdAb64B zC4!d;u1GBM+w99v*e1VrlApnD#o!dd8G^F}=LjwmTq1am;CX@<2wo(3iQr{|D-z57 zr~jq|wM~8l5ryLwgI$7C1ZN1&5}YHrNN|bZIfCa2ULbgp;3a~W39d*i^4a6dPuMCa zr_xLEGuS2m6u}vSvjpb|E)rZKc#hzCf)@y0BzTG7Wr8abi~PEM`3c+PmnQic>{bj; z5u717OK^_hBEcns=LnuBc!A(Wf|m$hCb%N8$ZxYRKVh5v+DU!}yA^{|1ZN1&5}YHr zNN|bZIfCa2ULbgp;3a~W39d*i_nZDdxzslK4Y0RI{$3cb80-?9A~-{Emf#%0MS@EN z&k;ON@B+b$1TPW1OmIbFk?*sU0xA~-{Emf#%0MS@EN&k;ON@B+b$1TPW1OmIbFx!?3XO=_F` z1{hTPPh+=Y{3(Jn1ZN4(5nLp=MDQHJ^8_ytyh!j8!OH|!Bo_JX@#QCMm6KEH)j7op zb_q@qoFO<%aE{<2!6ky{2%aZ+f#5}gmk3@axFWI0uiKZOuuXnxlApnD#o!dd8G^F} z=LjwmTq1am;CX@<2wo(3iQr{|D-w(RHv94uw#l!Zmk6FC zc%I+|f)@#1B6ykL3c;C7NWXt)3C`d%6cZNq88AyeTfxuk0qNK0!q0U|`n4v(&-s&n z%@xMg7~^W3!DkyYuK7F$KN+`|jN41b?Iq*(l5u-=|G5kj!olWKBshc59A;ee*$93z zuBqAJC*zv;68OouW{o3XJudRqc;4Bl$6WwcbIaf}f|-x`ECWB8kEyZHkM^S(Y(2tke*wLV3%Cq6wyHVH9zp{apBkVgkR4Sew{D;dMwOG z_k;PEe#lzId`Lg$x~GU{xu_WwpYWT0$hv}`_Cw}l)?tZUuQ_tPz>nq%^U>HP>mfxn z27WRhvwq+w{FwCyKbenNpO}x1$9&BE$r{6aNWSK}r-%-?cuzL`m~{fb?jP}{f3iN| z*Vha4(fwdPdR&LBnK;1?=_gM5aY(*#c|U-yVTb5LoZJ&}$oh$s^@I87^^E!G>w@{{ zTreMvF&~{T=0p7Ex?n!UZ*&RsA%3&YF(2b6>nBdv5AmmnKSTUk;?EI(k@%69<{Wux zjJ))9L0-gf)*+6XA_4P&n+K>LVAN^}T`qzH+ul?XnWALUic+>IVjrfhugE!(g`UBpG-@FfkH{&P! z1$k*ck(a(+$V>Z?m-Zts?MGhPkG#0QRa|~P)|yZ=e|46SLu85bDjeeH^0kpyR*TPw zc-|k4|G_&WS5}KJiFg{y@xT9N>OZ8hJ$ z4f4(78{nJA6Xpc0%{Pw^`A?|LH;-?CZysNVZ?xkOdu{;172k7sFkj@o?l_y+jq@pbq{I}X9Oz>3or_4`&h-`=)1 zv>Col+iJesAzBUTH;Zq8Z{EL$J7(18o5wf6H;-?CZysNVZ?xkOd<$&&7B!Dp-`+Op zci8Z4+E(+8ny4YZd3*zW^LUnm=cvs$k8gl)9^U}pJiZR!XvZP=7TEADYDvMjw+;GD z_%>~;`R;9yZyw(O-#p&KH8X1S&Ep&3o5wf6H;=EwH`;Lsz6CaXiyB?~<{U&^yw$*&& zGi5`1!s8p@o5y>&W=3tkd3*zW^Y{k%=J9p-Mmr9{x4?#P@mXB(?QMg8M~Hs&KG=Dy z`Nn7UhWO_34e-t5Sqh$`Hs3tH0ls;B1AO!NI((xYhu~Xa!?(D{A^7&TLB9##rfoIf zy$$ls;~U_c$9uSDMs2=%d;@&*_y+jq@pbq{I}X9Oz=m&e??~|NZG(OjzD?U|z6ToQ zo5wf6H;-p2c#hh9^Y{k%=J5^i&ExCvjdmP@Z-EWp;+~w~+uH{HCVZQ=)qLY#XG40z z;~U_c$9uSDMs2=%d;@&*_y+jq@pbq{I}X9Oz=m(}9fsiB+XnrPvJ1u9aQ}q&!OmOF zH|}*e#5a#`fNvhpQt%wL`R4Hr@Xg~J;G4(S;T!EZ1m6N1zQuP0f^Tmd^qcT)+E(-3 z+aTXOz5%{@yoYOM)aIMVH^4WKZ-8$eUx#nB;}CocZ1@)6RSLenZP0JRw`p6=_dtVu z^Y{k%=J6~A&rzFi9^U}pJiYNz> z)BWGLa)T#6qvKDn;+&0i!^(}G_>!8B^A_(!q?K9e^~S6IBj2ss|L&DNp7=%8fAgJH z`|n%1&Ks}#Z~0}_{`an2?}>Lpk{{SH(vjts1{)Ww$3jqvD%S zSB<}JrOy+eQ}Hcds~Ug(%3e==NyW#%TQ%N4|9KVP_T#GY{`oJe_{1-(#{1{Ltl~Gm zw`#n9{>$omZTxYd>$R-bL*jPyzxwd6hk4b1+t;f0?_Y28s{i;6t2>9szn*id|Bgqi z_V3>>u8w~%;?KPwb80@FudO;C|9*FM{Kbf`t|#nXdr$NV-XGJhl*B9n{v8x-Cg@!A zd~Lg6CuG}pUt0@o)+^UTUt1e&U0?ayHo|7#e6sTrzP1k7On_ON>uc+TeWh&M;%n=J z&Awq|=VeG+75&BiCIkl8Um3p>C#^pG*TZSLLc|BxUl|`*e?@$7{T1=S^;g6P*IyAI zTz}>KKLj!Z>93ssqgCVm`jrVu{)6kUod4IV_V3rPlIlOW{)+yC>#v9puD>EaxcIeuZ$0@zal=k{)+hE`YYmt>#v9puD^2rf%R9;Kd}DF`Jb+; zr~dje7rH{uKd}Ca_~800;)Cn2h!3v6B0jkO%J{(gE9Vnfe?@$7{T1=S^;g6P*IyYQ zSbs%)aQ&6>=hR=OI=nuF{&Gz8mp}6-_1Dt|{f!X)^|V2MBSe2aZO~tHKi4-N^fyBE z*K;29H$wE+(+2&G5dHPEL4PAee|1|G{l)#BhV)m)2i9K^A6$QBd|>?*@xk?1#0S@3 z5g%NCMSO7mmGcj*zjFS8^;gb6u>Q*V2i9K^A6$P$d~p30@xk?1#0S@386Q}G<$MC` zuZRz>zal=k{)+hE`YYoD>#v9puD>$=ocgQpt3rP{Ci=_&Z-LZbPaE_%O7z#$2L0uq z^x1jMzCNM9=6ic-o-9QKG+|Ht27Z=&z?Oh4l9je+&F^>CX^<9De*EE#Chw;%|fh zmD0bR_&eao%z1n>@kc6~*}WR>Pn_MXbKG9T-wgj{GX4;W&%m#FApS!&{QKe8{E+xI z_;tR-@4|nn9CttQZ-oC6>F+201pJyG;*V6iNxt1A-|GHm#A8ixe%!MrJ_G-H=|4jJ zJ@B_lf0p)&0$gH}f~~8Tj!93eT(Utnu%M z-^|nakHByEH2z5CAeqlWJ)dUy&A7(j2EXaw_;*#B$b6b~KYj3DBzuPUbT+-vB%kGUd{>jxWVx2T!4!2fv;_85f#R)ep@Hn>BCdiM=P%~5NM;p&Ib0GmHS=dhc@ERy$V0HQO83YBSaguAKDnv+>&@`V?^&w;)gay zw6+jGv@t?7R`(BWWcLU7JfV%+4{c{K_;-PgB zqOp2hXiil>G&y24!OSxSzvh|rzXg7?mrXo0(C|azp{0gr;)j-+>q7j{Ho%zM^BJx^#|#AvVaL+i-6#t*F{@lCoPXdUU___x5Xb>OV=Ljxm3({w-3 zv@&C0H0_6`vCqFs)3hI&R@DzpGxI#VS;zOlug4{RXi=1C zmyU;~RrN!o3~!_#)Ll`tN6fg;9K#QZhjtmBi67c!cq4vjRMhM>(?7JxT;H?Zdj6=F zs`{ZtWLy)EdMs+zyzxWR2+zh3%^^G(|3>)rbtm(IwnUAVns{gtxn9PPdW__2{LmIM z&pkR{)Js+U&=ztXO?(IZdS9G1eted!>WAi#d`&#GgvCfA&nv{{pZkc-?Fn=al}oSMA7Fg*RHi(PkD@mPL(baHB(88Al*C&q>g!hktEIi(GlZ!1hq6ppzQ z`SHRv$(#1?J22S0@4BRWEI)B{CVv#Z;iNl#vIsCzoJp!)c*lj=>B7WFVdV8A`RTli z=0VZf;MmAD$<*wQR66O7&P)tXW9s>1a3$U2Gee@Ybn+@sU-_w{at@P4WLHSK`H_*S z!tvt+Gx=j(c^__W~9*nZIj2RZ!sR>IB259;4@Nj8HnGlL#VLi$`J zAli`7-BpK#p-J?$`YK2Yy3GVUS0Rl7f>Cf{a%`kF14EM-sOIPxr0NAo?>S$igW#H@ zZ>=$U*Llkw?A9E8TdmR0Tkc4s=IB?~7`^*t<<6FSeqy*lbco3i(TH7F32{-XvFj=$ zWV^018n^2zBY(h37M0TDa~HHZbkT}Dl;Z7V07EwVcEAb?)i-`mf;MmcL{PfIJVSi!b z=rlWJR32!&v2b$tvB}}L5wB{sufJUkU^N_`7`tPpu&)oRVR$IN`*dl$iDB*CztuyGT>kaHBy%qIbXYwXi z@UZpUncO!qU6>lp4;Ky}=7Xz2YrW!>tStB5y!+-iqZfFN3?JJ)Hlcdhkslr1k?zXp zyVKq2?W0{iNGLtBV|eTK)JXT$!-(%I49y(H8SHFqq2nkdQL+u1t#sqq#0VOvmYh{K;dJdGvyPTo@mmmM3$2 zaCmZNVj8h*la3Fvc2-g*cfJ+DgRERZ+fCQqG}s6A;2|@|3v5DM2?kjuaN}-1RGRU` zBc}65;bF4G&7u79!k~OpgrQRLg`7{lHnn4+Cyh(EaNu6nd~v$Q3z#r)Lt7-t`> zPQXuS?e1noYFg8&u959^uNUdp+fzEV4TU1cfL0uDMYZp$XjGOHN3;~Ch31W5*zThuKKvE%IB=>ZtnYE D+ZA-H literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5fa273b74e7d4587464ebc550cd7603c9320debb GIT binary patch literal 2592 zcmbtUF>V4e5L_P@grZ2HNRa}GD|kSDkSlly1^?h8%#Ip6#57 z5fnbJ?Va)L4i;BWXHH}-BF()Brv2~esuw?N`Y?>uS>$^sQk{2mzf`?p&~xDcKQ;3G zTn8@VJK_A)@5>_=mLdzT<6Co2T=$GPx>L_Jiw=Y0Rpb*8q`GvcBry-3PGoWt^ERwS z%Ii>vuk+ILU#`U})Pm?a?;_}RP@3@$dOOQ1)(c)s(#e3KA@%0G?TvcZg?g(@?}ogM zNOaX=&us%QjX(@~Zbn~?cN zOO|5Kp$D2p2SgaU4$tW~@4-ISyVoOrDAxOt>m4u@jC$`fz3BZ-deM8u|4%RaoBYSn z-=4QYI+LOIT=>qRzsgI`5rdu+z9}P~!#k(B=zadq)%vD-&$W8Q55+yGkFK^XKWURl z(1Wm_)}lckdAlK{*mJAE%Q8k7iU!Xq@5p;&ymBz&V!i8J?|`9T)SG)9o-^LgXv_a& z+d{n~p6huVymKtpb)M5Y(sRU!JlFSk+;h4&;<+h%FB>aHaS!0Rsb%@eCW*Y~!u}u6 z8Si08xyEyf%Q8k7iU!Yx{gk)GeNFF=5f|%)=Tf}`hJsP=i06#=V6<0xu1GIE*MVcM TJgAU!lErR_aVXh`yAb~Z{7{)~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..4c86d6747a94ec5a883ca6fc4de41961a8d15ad3 GIT binary patch literal 87406 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 TjZh(DBwL$)jYCNs?!x*P2v(mx literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1280.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1280.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c2f27f319ec79a58f7a0d4f8cee1e05c71236417 GIT binary patch literal 71277 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 R@OQ5GxUy_mfDqf4a7xs%I>E z&L7~TM!tR5g&*-8@qOp^A~Sx+v*wQGI+#5}m! zk;zEP+prgXUV}b-?dMY6$>Clsd@qQe^Ul0p1Em>n)Z31kR;(Ai%yG|%p)vL5yzPm4 zSA}}3Oz$Ik8h^s{&dFTN%#M1K)O zL(D+St+QTW24VKC%d~5;=P(1!V#TdSae?PF$Y-!g^}bG+P^|Yo*Bdbui+abIUd;X^ zz3W1~m~ZbthWR?)2Ia9?M|ckNRbBKPG3YtroigA#+;f_X+2{9Mt#_*R+$JCw&!FC# zT7kJl4E=%``2Bt_8sw3;W9|{2TX{Jg0r6Gl-FR&dqn&bGkR+xd~@4zX7Ru2Jl?CEVStn zgER2^|2!9XKlG$7#WR5C6qjvGFcb)$^ZR|?7I{JM@|?`Ydf~ag-iV=C@SN@scrNfJ gwHE7z=Zf^wa~-O=){4*}Vs{{R30 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d6426d6bca86082e056bd4971fc4c8982d689e6f GIT binary patch literal 68712 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 J?YXVze*q`U`XB%R literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..976a5d6637a0bb029d0321a81e57245cc87ecb21 GIT binary patch literal 2592 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 BepLVf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1536.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K1536.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b0d62fdc55f49116b9ffcdf757ff4290154c66e7 GIT binary patch literal 2592 zcmbtWJ5Iwu5S=w91cU?y1qBi=asX}sMGlf8_h6AY2n7d;5CvtF3x((LyvcfF!601h zdO!2tyq)JwB(<}75?P8!cOin;;n}9ONqXwF8Tb%`J z;I)6UP;_C>p#~boj0+5%hv&4fYw$MGd!~EPg!R53>2(anqTbU=FKYiUy{Nt7|E3r9 z9erb{@4(w3oWXza9O|pQ^c*qhIpLi$;W^xM8jIT3_gt%Y>Z)IMq;L(|ZE6+R8^_QY z)WFuqXVD>!yxC*po?93%kFmf|G@|^Q- zbf-4q8Z3;Lo+~gE2%b~k3C}sNWc=|Np0M8KkzU78BzR7FCp_o88zV&**1HbsrROrh W_1{T~MR? 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 K71qAnyZ;Z5(Dly% literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K192.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..736fe8c8464b2e3b5e6603a728ffd7bd49fb85aa GIT binary patch literal 2592 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 E0AY8jBme*a literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8f6965981511671de3ee4308bd19b8ad7c3cb10b GIT binary patch literal 2592 zcmbtVJ8l9o6ntJBM1D$&6e*C{f&*}aY{5ZNa1R_Q2gngp z1%>}_#`E5+5o4z_BeE8e`bGr9_P00H%8%-H8rte8^1BtOj@w7SRK20mbKw9xi+DfQ zhKuMY93R?!dBDO#WX^T;mV08{Gv>*iTCR`eFetWGz5zk1b9d?m=98xbnT({oHFMGD zHORxyaUs=y)=P@3^3daoH)tQWkD34O%SIrZke&4qf`g?g(@?<;w0 z5f^TZuGn*%z)K?#gPxnwR|B5A3wx8ybB=fNwQq=A?z#7Hrzoex&?VGBL2Z@`)F9Tr ziNR9rIn+R-=zs)6*Wo$s^BR2i^xof8Iq zP~VofMmU2f<3Q`8{rpLj0v z?#PNSam0VC;xdg1hN8i9VZYDY;J%$+pD6u}@m!`iVki*x4tOr|?pjXY7VCxQiuBTR Z4&aZT!9Q-sh{GtEn{Mupr2B9e=6_#dqlEwf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3996c5b8b74f010edaa124b72bc6d1e905ff1827 GIT binary patch literal 71277 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6e9155e8164ea1d3bd2ac650c7034db3c000718d GIT binary patch literal 68712 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 O9ru*@gthmU?*9eynfieM literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..a50f9880fdb54acf2c59800fce220105d6d78f33 GIT binary patch literal 2592 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 bD!%mGfNJJi5jtdyWNQ=FcqutYPq6+2==h#{ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b642dd7f3f983181689a697362101a4b0aa9b2c3 GIT binary patch literal 75630 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 jL=1t5j- z+H>}qQ*e|#?A!D0%+Bt_V#@x|h|EQ#Iu*gA`)y2dXP+t;`nA}Jd@MzZ-Ew4K6^~f- zJO2T<68ZL77rw;aRZ^d4;c@6sTzMDvKFZ+8j^}Qf^$~*RY4U{IlLGRi&N`KjU!OI-C2Mmp=H|3oj zsdt{Kw@CCpkhc=4UB!0I_T0kr(g?($=Z5rEhv&}ySugQi&6@1&zloIZxhG$f6{5d@ zp&@3V<(5e=FoS0HGnZ-CY|mi^nnef9Gztqmr$IV{Rjl{*k_p+Kdr9>M48@|}lSD6O zf0SO#Uh)6ai}|+xW0?YXJvWg8<5MT6&*x8uHPcx81>=4`$5RBymg zEb2|Y4$n2bQLWi}7nyoHJm+{T+;eQ!VV=`I(sRU!Jm==y?KwT`@LZp>m(AJ1Gl1v% zOwv7IXowm3^FN+zc-H|Sdj{~F;*#c6hGg hjcU!-3(sZgrRQo?Gt!FCA!8(oO^ESP>m2Sv{0rRQvNr$# literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K4032.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K4032.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3c7caf322f23637ace1d4fee3d7cc0ac01504c09 GIT binary patch literal 68712 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 b=Zf^wa~9xJ+p$4=Iko$-)#q?NQ%6!h5W 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 I|E8}01HXyfX#fBK literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d6995a53c06a71411af2179a4f33edc9d8a88161 GIT binary patch literal 2592 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

qH7vBraBjjMXF#)D*SDnHhEP>qGu zgEbx`nxNvb#)Iluka(0o;!@uKZZD75#1SleMhkvGyza(^dSv z@T>llcA*Is{m`7Cp7Xk&Sj)lXPXF6TJ#;{tO#1Cx@D{UcuXk(aYtg0W{$nFpDenK0SAKJ)r zb?%2YDnGQbq8}Ql`%mJbX%+pu;8*=5@zA<3(OA_kG^e5;njF@ep!=DGU-3-pUk|@t z%Q_w!sQDrB&{EAa@k2}XaUp(aa#(AEt{>-uu%3I`4{g-*d;FSN0uAKFNG(DCUi zerOaqUOIkT6+bkV@TTLTfrK~hhh~y-X+JcL@TUFHz%bD|HQqz;6Kzy}XdvNXyYlx| z@k0Z{__=I8Z&#nu@m=ui@GUjP^qV!$i|mJ%Pu8zm`SVYfx?T4lj zp0yvELwL~s)$pt1PWl6FiD)g=@z5f2ytE(JV`RMA4{ag++^)up>!pf*XbU-xI=&Tt zwJy$RKXS>6erOIEua1YdkmIZU&=%6}LDf%a3#niGp)I6-?T5CIafMVp(3XhSF71c5 z5dO6v8WJHI!s?M45@8y`?{$@-2w40U6h_%4*ePL$QJ#c}<15SYQaB79AGAuaQz|}4 z8GpYOkmco$&5s+g`Mf1IU(dwm8c%F~ zt|2x**Akmwvk;qK4-=bTmlK=kE5zn`AF=s81!D7i7{nI85va!}eshD_bn8vu%*_BM z3EQ3)AC`4xfY&AC*=K{}i{bO_ZsGsB;ae|7d(M92_0R3RW^QX^vNd4Mp;A_J{5;gZ z?fR*aqxSLK__5)!(d!cJ*CZ2mZggO5aCr2{b&1J|q4#V~T>ricx8=vjZqE%&yzfHW z-j+X_nHU-yA7KW}!QAoTft)a44vdW}1LlWv#8d=e#Gg+SRSLxCG5=L;CSxXvHg>oqr*ePxpBTfuNl=0 z--!+-r#2_-v7w=3xd~<@QU7gY$0lyl9^p8sqebJB!=n=$yZR=o_F;JR*u;3HE?`8g z3;3wq1$4+?7Y1(2jN4aL?Z9Z&9$=8H2OYWxU6h3ObCG~(O+sf!4HB|rsB7_2a46{1 z9dI3mb~NCRg5zVugVhAjyH*R?wrjPAFz}~sr1OZ zpv{2`7Mx8g-c|t@ec-@N2l{%u4|Vq) zJk)*Q(1#Pp25!rZWcr*_Ut;Tr6C;`1$Ho&|p}uX2k>OE}lfe1R#K3LvClhzIC2q@Q z26Kq|aAIHP$nXH%Qv*k{!=oJtJUD!0G&3me|KGc-Z`HOY9z<$c+zW268vwEE<=s zR{6v(Y3Fk913fo>0JXq#c;INy@TgP6md>Hg8#fPi4Q$$w?b@)Z9fz`OV9VytOnas? zn}lq)C3T8PWb4yQ>4xFaK@@I8?2Wik1RTkY92(1y9UVJzqHiQK zi~@1lg`(tCM~)4JU3PJE!)93d%!#988PtMxoEzzzaCYW)-@w@9=mcWfA|2^t+!4&NrP5kj)ch#b`lMUP9HJ=%u80PGQ)lv8ft(~2WNJVRV$A-bp zHIEmm*IiS4#}-^DlDal@)vk#(?DWuEQ;r{A)hqA89?th2&72sU#NlN`%Ofq0910g7 z=-uhQ^ufLxb{x2I$6hox(&r=%IBdxBxJPFd#Ho@GetcQ>!FKi>_|dV6K0bL^8B2N) z?7ap^+;xrv##VYYHnJ{Wy9N+SrvAX#=qOuV$A>3QxCvovi_s&>$FLSL`H>a%Vd>?j z&`ZUbpi}wzbaz&aa<=n%O?U6)^{bs5SJgd8n!Ur$nifiJ~o+GM|trqXcr1-rU6^Sizea!@ig!(0kZ)A-z-3K iA%gWqPLb^$Lt9)YN$=@MEWjmq^>J5)JZr~|z5fI8=g3+B literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5184.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5184.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..55a0999d5e2de748d2c9823b908b95d5c8cbb601 GIT binary patch literal 2592 zcmbtUOHRWu6nsw8s;ZFaq6?5J8i^jDHz11~fFpF#18{=|iG#4+Xh%_Qn%|!6&o`Wei_N#JJ|1M48_c7e99Pq=*r;MPlMg_U>Re9t{IAdANL(W^ zZ^c^lc@66Dd0I*FAm?kb_O&2-n!wWQHBg%H2EFxyVcB}Y%NREX44qSN%3EKkx5?C7 zBzm{xtwdUvv3+NIZs&Pv1Y*#0Q~GMab60+Elz6UXPPX^+F|*3P=tb`@(u>|J z{$G00-`+ol{yN?Y;SBzV=g?o}rRRu2&k6680ng!{(^&LAz2{23Q?2LhrR<*U9+U@D zGDydOp;Pq0@Aqp_A&$Il0Lb>-+VirE5r(3{bILn#-*mjPy(4qB-X_%>Fcgb=Q?J8w z9dDFtw%%Q)-T}`!-U{~|i}gRxX&vb~Vnm*E{T=q4?hSZu!rsfq2I`aD19)!2ARPmS zPSFFu|HE?~?|T5q?g2cfxGZCYp=j`&-|zF*i0kw|-IF<6FFe=R8!!}$dIvn$@kY63 e>xJjC^wM)JvYBf}sE{#|%uSf%P;VdZ!u%TsiJBz< literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3d1b747d744e2ef0a11d9f1c5332f2f88f079f68 GIT binary patch literal 68712 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..58832296bc62c050b422a0a655be572e14c0437b GIT binary patch literal 2592 zcmbtU%S{6@5FKw!6d@#X;J_hLd`JOwz#dXa4)l>lq5w+ZKmnA15C@J?Dxrhr?W~`F zS_MbR!MpbCyf<&=#bWGyVMMkf;;u#TI{pr(c^KZ@xbsO<7pWa)7@jA)HHH!l8-^LHu41sQk|+PODs2cM=}{n zc^!L^^BVNwyI)K5D5ra|@x35=$-DA;4U`tVQEy9m^?JdZQ$-9tr{0pcy-@GAQg2h} z-I3Rcbg}Yk&pmlwc8VDE+=9NE@Z61$%?i(TtZA72YbdJPb1%N8kQp)b2s6-fZP5$N zAk4lE$x`h(%s{i~fCNL&;W>SlGk8n&9@xox&%Kv=BZl%(?^U4}v%g3$X0Q1F>BW4r z{}|>w@;an58FxuvdCy_K${RZ6G3YtroigD$+;f_X*_Zd6)jM_YoC`%&d(Iw=RbVa= zLr*XRAJ2Q?kVoE*x#-Fn_nhLg;sis{;5i@9dE10ncA<0Cdbg$Ch@rgHTY4RyyGSoQ zSEYBtb0e?AJ;!F9=Q-u2=ZFzH$N5fsPID(bH|Ol-BNSCV19)z(&E^s@I0GNgXAjQ> z-cRP9=Q+h?#R-O@!E-*I^TKn1SAIk1s`bKix!#DOyzrdHCp;H;lUl3)WAI#+UV5%W WHA}4s9Wq9Wy@`8#l*QpL?Ee7BLYmD0 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1e06296cc536623628f9b6cc7c0d45ad4a68fa27 GIT binary patch literal 84078 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

E#=OZduF6BM|6nE z5YdR8HwbZ&sFY%1}%TUQWmAsqwaz>2QFK34ykxM7{HLVJ|D0f3)we& zpZ=XV1}Nokxy+EI!_MTW&bh<2?1ncYG{9 zoVk5;EWQKk+ZrDp9N{&>;T&i^HaMI+I*}R9qq%MCwk=z>ZQi<_Ez7+*zP^r(4$}~}NIxiU;c&u-C(%*+ zd)Y(VX57!U#t*U^9=3j4an{>E`wX<8w_>Nl<+{12H&~|Xo!JaOt2M?JX&#?({ zCFo&y0yppCL$xuUc*I2JBs@%(xS7q2=X#tcH6Ga^7)8Fdj?w2Hf+^a0hWN-`cU7Y` z$U6k#+If(T7m7^!r9f zM%eB;H8^qFO$ggtj2_WGioJ-%kE*B#TQ4_-St`Z^oyyObyR&1IvyHE7dU}%gudarQ zEPFb8CUuYA@zze?{MJqvSkN?xpbNSn=Tz@=EU@)~Cwlm(y^*=c_I+<5j zdHE`66AEaS0o%jN7UBQ#GVp8xvjP3@AP;pHdIORh5$rGW6xo){YiJ6nx%nqKF_tfe=NcEK(#|Za|70Bt;5tkwxMlDL6=kC@7_4@N>-n=()#MGm)5m|~zb0LCH_v}seXulda_3!E^^0^VIj+<+{RK4J(=llT< zHRA2JzPN~S!0&_Gmn$sHM5bKFSaVNIdxv?FljC|0D>kZnn#emKNOdYFd;Ztw=0IE{ zDR0ACba@Tx@Nt}hUryIz?rTBxJb|g#YoIjaje6T#h861tFJs&oF?3G7Iq%}1dY6TI zt4!~Typ2ffGPdtx&#gT#jX(@~ZcJbGc<$2g4KmNQ%*pnCJ7iYHJ$UswF)+cLk~2H4oEO`9iG!M@4+_J+k{_bvEH{_Z^TeO>K$f!(ffbtMeh~= zFTLn*=QoD_I^G813_ini=&$n9bHt$Mgm+4h=Wx$yEP9{cbG6>7)^m%Ap24fQ2ld|6 z4AL=T=oCHh``ubJh$C+s0g630_q;4)f}v>eobvYEH-T4n_hc^CyUg`Q48@|}-0SdM z;7xKZ*1Im$+v7RM+u)vKvCi|H){&kgM&dcw-+s^OUXSNS?7e*H|Cy~_aS!0Rkqrn> z#Ly-5!0-R?T;Sb>;PQJ8o>N?wF~LwYc+T&4c^8NadRGr*F4harb@fIJ#iHIG&jsEj e*K<5qq?ev+k&WvnDrAgga}(z{*x84>F#iViF`)?n literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..457f226aa786cef546bb256a4f7830697e326ce0 GIT binary patch literal 68712 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 F{{?sO1gQW3 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d52329b17e0aeb1394c0326423c85504a56a418f GIT binary patch literal 2592 zcmbtWJ5B>J6nx$+5kiqbh=L*l7onoz2BgRVxB(R0gGHjG;0P2PBtjIF5hvjWVf^f| zy=DQg*uq|a-pm`nStnxJ>8=r3iHO}3!K;5Zrnzu$)(=D5Y(?JhM4Ij0ftzaX(dfRg zfnAGu_pS{m(NFmP;n!s!6Q?3`&ZBR+CZ;>aILpa%J;oUq)m+cy6%eHQEho4C$LHvS zxJGhb%d_b78l1!1_Eefn`TZ;w;Vg(=CNK|r4U`tVN$=XN=u@p1yo~XE!q74Gmb}Y< z>RnapZ3?|NxZd;rMY7lF`jKNavIn+R-=zt7E=ixc+%NjiAdOuHe51MMdFQwjup;*+rQ|LwQ z|D_kTSNy;9qQ1Rv4E6QA7U2vY;W^Y-dFeS~&~w5&Wx#W|=QI|z@AB_nHm21()p_n_ zrhCv-*Pul_gS1Z=Iz$b^djBkJ#@i);YR@eKFOM<9P&9Z>c?a&Bq}QI2xmxe4)SECA zi+W41!*h{0%e7kXZKd7;&v{;pdya=S&U1Q>^c*oV&-wZedrsE|JU5M=dpaCl19&c8 zjvAaWbch;+^>3bwylb-JOC0grs<=GH3`5c2xv<{nT_WG8_v)O?V?5W_n=llMdIvlg jd9z%r^}=&idg-|i+33F$cQF|w#n_}VHul!xE{wkbW4xpB literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5bdb7008ba5d96a5263f8bf82b35d3f6ebed7a3e GIT binary patch literal 68712 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 EKa&*ptN;K2 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9cb6c916ec6108cc99f294067112223d5da04d7d GIT binary patch literal 2592 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 KoVDjr&;J3A_tlI5 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ebccc8870058c056f47169aa9ef8068f7ece97f GIT binary patch literal 2592 zcmbtWJ5Iwu6nyI}QG}47prDA9Ehs3t0WNZo6x<_5;vgwFNEA^}MmYgDG2`c*{mBX& zCB@qNc{6X`8?Pe9&KE{xEh6q#1h3=oXqwmI&5ct(HoeHtR;1~-55rRPfkDst1AJJ- z5AQl~5ziUlPvgGaV__w-~dt$mL%#)l(u9xI6DBg@5070sAIc0(6+qaD%O31fy^fWu_uN;hH)1Fs_1+YE(fh0PqW6mbpI-Dg`^M1U zk=G%d!MIEM%6ks|RbG0I7@=~!Qzkrzdro7~`|_T%dZ!MaYeQ1ip0h_|6_`WB&=vH+ z@8`8}h$C;uSXAYLdrongae|>}@SNYzdE10n_Mvjsde^1ih@rgHTY4RyyGk!SSEYBt zb0e?AJ;!2Q<~il1=ZFz1$No-xPGcuLH)rqVHzZZv19)z(#pVz(*aN?x_a2@LynDu8 z<~hY>#tDX^!E=5;=Y{72uWYm=!})5x@LaApVkj>>r~4D03%q+hsYCTQ2G3RLrRO@p V>%S90g^ZD6ZsHsVvwgS=^FM|gn~?wj literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K640.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9a5664dacc6708a6f860a2295207972e3bc43408 GIT binary patch literal 86894 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d8af62ce3b88eee81b52aab3f695c111e59f64c8 GIT binary patch literal 71277 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�S@386Q}G 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 HZ|?bDk3!wO literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5376402b8ec2b228f44938f60ff531801c297f19 GIT binary patch literal 2592 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 G?*1QGV7qPr literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f873753c0cf56f35da05213ed632918eb176d424 GIT binary patch literal 2592 zcmbtVJ5Iwu6nyJAQG}34K|z5O7dZe0JuY$(iX4CNwO6dZsfAVfhKKBF%*eUhQvhs=MK>u~Rozy~y`gr0TbeVX1n?py%8H zK5E1d?>cZ1&k5fTc3-ZruoSuFI-WK6#B?{9M>$!p`{*zzUX6SLf>g(HN&@rA^?^)A zV%~cfyx4Oa$4es+gO!`pS0kRgbbFJ`a~*RUdcXHc75Cu9<>Vs+hAyE8nr@xd z0zL4(Z+);7dk#I&C^{g*&~s)WZP+scIy$;WL z-YC~%y_-V4Bc8Lo4emJ>>om`4k?1*MM4q!n9QT~=jd*Ux-pdn_%fEYgZl=ZN5HNHF zJ#hPfJm+~o7>h6Qg#T8>Wf>z3MT6(ue#+Y-U$6IlO6F5Mm+B1|ibcI6p7Xp>uEl!c cxgx#vT!(BHnh`2wjAU~Y<~Wq>!vmQA0?~(`+W-In literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..921576992a3d7edfb73526835ce51b5d52c6e36f GIT binary patch literal 72558 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 a^tj$6y>CZi1OC6OJ|3^|IqSZM`u+z^G^Wr1 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..45d5ddd8905e7b2afa00f1a43350c340237b457f GIT binary patch literal 2592 zcmbtUJ5Iwu5S?|LC_+f2prAmCiyVNG4i`B{irgbc;vgxw2N9y6jB)~QVxGtQcGrs) zCQ6E3?`PhdH}kUM%GunBtVN`{5y5BwJG$bj`>Oh-AB$GxdnZz~yG6HEykgLM{sN~G z@!hu$+{8TL_o+XZJ8UdP9=VUXdkrUEA_68dW%f& zhP;(X6Ein^ZtHnz1Y)pqbNXt;bGQC%l6kISPF?SRLQ>`)y!o6$WW>-d^gz=svs$1B zq4#wN7PIHj1C62s5)9pk=XB0{uut`FO1*=@toJ?F8!;4%dZ(FQ^!_Tn=)L0qrx*Pl z{KwGWp0`3cgQ2%IzH{iW^3rp}pyz~d%82Li&S@-qpTBdZzNww(4k0OX56YtpjZ=b% zp-c3@pATzMA&$I_-qgYDxs~T-#tDW3!E?$x^4s{x1BZgv8Z|-$?F7PI~ zn)PmtdPh9h^HzB0SggxDr*)*~h>>`%@9((h^lZd)GxlEgM7IC$;kg+br*p*6C3@h` z|9CF&9wLCb2k@NYvWy9aqQP_ie8^iPF6ga7>X&#f1SwI(&?WVbcrNfJxtjIDb0)p? YT!U;Dnh`4GoMdYk*SIt|hX=6!1#-inp8x;= literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..297bd44a0d894f71c1216a061094fd50b7076815 GIT binary patch literal 66408 zcmeHQ4RBo5b$+{A?+UD-6$p1RHhEg9;1VUQ{`?mcR+jA8V8hz7GoC<4+Lczeh$Stu z+44!K0axv36_OKPoct(J#F3MhnN0ngIK- zl+6wPNAN;}&m6k!see51<((h8W9f;@zEu3;U+s1G9FdMNK1Z{o2gY;bN5>D}+&`Kg z;Vp|n5pYPx+4#(*CniTGN5;ok)R<`4Tq8ce{}b^kPZI|DGx{@O>{=y0Ye^f0hh7$z z8duGe#xOi538 zg{)p{@f@@BE(K#RUR`5b#a8Pnv`4KQumOMcTA}NS`mGK5jquGq^q+pvO^TE`DrM}GWgUwdFCayg&LhhMoRP;2E6J{Y;! zdO==<{M4r|WAkM*J^vTN87thrMxer)P&n51myuY*tV|Pm&oL=0e12mzw$_RkF1(}u zReKg3K{8(-E?mxwsc=4_Us2S;)f!I zjVz9lqJ_1OozLgr(0HC~c`&Kx)*|O7TUMOYqRy$951YT}q1^1Z-kh3iy>Bh% z|Gt5@SbyDVJ!oCZW-pG{H}}|0?~lZyZ?X!lz30=chXS+R*aPi%MDGYBX9P>FYrY)r zwhHUEU+`M=m*IRvOZeZHW$q8oYF0u#o7lYtT#?vKpJIO!W?CUBY4j0nh_!ELeGdrj zjzwx43J-@GZs`8$mAB8w_C3hYewbfXXyX6;U2*xgSmcgq;o*F=V0|-M_!vIdd>t#x zV!fy@8a|!aMgNQy@+?-!cO$VabCKBJd^-}m_ZyMeO{XHUeNRSWZBJn3JQ|5v8~D|? z_&zKm7p#v%R&8yxmaorXfbspsnl~-g+SuF4lZV1j*XBaj!t%-Kfv4XR4OsiFlQ|5D z9e=_6@#%rKBgqpNo{HRuJ+5B)+odyyyNaWU#?3ZpI!*x@fVv`fAW>O6DKET!q)0fF4cYdxf72r*EKzN z;`c*uw;r1wcm(6|wOhDweW1{_KJZ+i`N@yi&z*SoOCO83zJ21!uQ#{8{l+K1*?fFD z8hQ9LU3cfda=ZP@+`yc*`WE~5zV^rQ!r|IL;fFZ)`t^}lXUEsaIxo5MReR`?&gB>H z`taZPT0aSZZ~H%R6%W;Hiyf+Yc>Q!;@A^ZL){Cd_x$~mwj)is89kGit>Av{zu>-+O z`U5S)$39^V2ilvrN46dP)%)(gA`=MN!;d@{%ADHOv~%^tt1_o|_*gNYV#<-Xc{^$Yj3WFGnW#20^*If0&5*I8GeKu^CoIJ)gz-dBBZ=xX$}v;LkRZ?0pr z8UDosfnDe=6X=TXtYI1aNz2X}WYjd-G+ft<&#=8S(pvNXg_+eU>xq9kg5@gpZ}ny8 zd|}m#(uN*i3x+oR`5!R8@-ml2!s}NT zE?vKRYubw5Wpysh3>H4OZgnAiNnPPm{1;w_&vkXN)pldyXlEmKacyvcorg116Ke|5 z#F|#iZaMZ}v5T;e8nAaA`}I}q*WUckuv$+>i(kbDs=yamCHT0>54JdDz7E?8u>C&0 zg?&+(c6>isd2Z)}ygk1G?H5>l&$0N=213!Gi5LB^Zj#?8N>QMCR`h(tCs_rc`j=_} z?JhjcD_@$b;$g73JzlyX5L&+LG9>!0qc=i3n28nH%mukqZkAssHe9$_EMKN2| zG0IkTjIvc7qioCWan(iLuDZx+ThBY~T4FZ@a4qDqvOe1G*GGPRgw;{G-t+4twt@Wm z$ghw5`si#|j(&Y4zpPn(^MmzeF&cA=;-#v^YLOYF+^QQWVO{Q3yX&aaRB`pAF2=09Kizkl-R*GH@h z!10Ezk3_w~(iHWP(^mD2YFG7)vhm&#Ui1(LJ0I^Ih1gRv{-1bW=dkg-&SB$uowh62 zNBcu;ApiX%|NWy%?^F5D*Vtb4pRf7P*Zk*eXZy~YUmuC@{Wo@fBfwyI}T zyQ*iDjrWgS^-;I3cSL_q8_(+;?RZ|N?aKAhcE3LI?;l~=`S*|f`$zu$Bme%9fB(pT zKbsXT?EkGfo9}0f`b5<`Fmw{XzdrKoBfmcK>m$ED^6Mjf9h~+0NYp2)-igV2McJyJQMRgQl#Ta~T=h|t zu6IOzmyO0sCp+R z>lJ0IdPdo*o>4a5Khl5S603*s{!!5N{*lAR^E!u(=XKhyTp#TZ`tKk4fB%tRANha( zk^lD}`G5b>Z^PdV<-dQ#ssJ2s==ZZleZtZd_j{bSs%KQYs%Mmq_m5olQMaylM1M{j z&+8oRcwVRN%JtE9zdrKsA7R<~_mBMhNB;dI|NfDG|H!|8#EO=){{9iKPgK2w_m3R5 zs%KQYs%Mmq_m5olQJb!JM1AD6@x0E_j^}mSu3R6r`}L7uA7R<~^^sp6`Sp=sANlo> zUmxM?;H=k2qCQde4&Fa<)kjWS)iWv{?;pA9qb6PNi2BHB<9VH<9nb5uUAaDr`}L7u zANlo>|L=?V|GtR-?~D9a{L3r;^EFll;CMqnUla8SOOw_!%2xG^vQ<5!Y`lMjzgb)y z?0md`gp!Vxb*ew7jpucac08}scIEnLzvaJw+@&nO%3AGzwIHeK(C z`p9YH{Ub*^p4Vx+a(&e9*GGPRgk|T~M}B?e*GGPRjpk zE6P^&jIvcdqino?TW#`vNetqQEM}B?e z*GGPRgs+3MULT42MAbX^`;U0NqHI;qC|lJt%x=JoN2~_IJ4lXylUCU*rY3+lk&64m z3P%aH2~H54BsfLz0Kqwe^90WjJWKE#!Se(!5WGlmQDTu_k1Ic6tDLN2H_6XnoA?t1 zCkajwJV0=c;5@-I1kVyYNANts3j{9`T$EVk*Wt=f*e1U=lApnL(clEZNrF=Z4-lLq zI8X2l!LtO<5j;=u0>O&}7bO25B6xt{9Km^lX9%7pc#hzCf)@y0 zB)BNC$fw7ZpRiRDUmMBKV7q8=g5V^H}la=+>S$B5b{zkTd=T>f1cEgEbS zoFF(!aEjmof^!7t37#Q%mf$&p=LudQc#+_u#3G*_SAN1)Ia$SSlApmg@h1pQ5}YD< zfZ!a#d4gvMo+WsW;CX@<2wo((D6z<|!Gp5PgR zX9=Doc%I+|f)@!cN-XkgcI78*lV20b&tSV~aDw0@!6||V2+k3lCwPY7S%T*Xo+o&L z;6;Lq63hLj@3B$ai^iWII7x7d-~obj1m_8!A$XSHIfCa2ULbgp;G)DL zpB`6!!d5w1#crKblwh0S1i?vyQv?qXoFh0-@C?DT1kVvXPw)c4iv$-X7Ws9!@)Nen zuZ`qquw67bL2#1b6u|=o=LpUdJVWp-!E*%96TCq1BEdz8MSjh${Df`tYa;m>Y!?kq z5S%19MeqQ@IfC;9&k#II@EpPO1TPT0NN|zhWHO+?zf%M!@f(T>3;PY2BEPNR=kvQ4fIwk#Dli=t4Nx$X_<7$j?HBREUjTzVc9)q8Z+fBypCgXOKal6U5-MasQBoe~G z=942hiQgP%T=Uxqelo79+2AMRn(q?$$+%{XBVRo(^3{0OTBpaI16FfO;x~eskNGVF zKbeoIvCxn9qaVVL_kWP~AG1C&A03bRnE8`6hWU_u&2>)@9kB78 zZ1^$j1b*E=;!Xc#eZsG=7v`h;!F=?%7Fjb=W^U>D@^U=9rJ{n^_I$z9(_|0{}e2CxZ66QnvW}Ra`#!uEyl&&A*PY{2S z_*29`K>Ru4M_!t9`_aGlgEx)Ao5tWx$AdTGH#!gA zh~MZBcq4xEJqX^6pX?XprTIi&`g$QR?MGhPkG!-Wd1*iL;{FD4`T1C@0=4|pT0jn= z1DEZ+d`L=iqDI98p`p%eJb>}Qt`7QUJy>sLj0wr;s-=L zZd^ML%x6uhcw5A;azZcL&yD_3o^Kw{(r_H*`R4Ie@Xg~Z@QrpH zf^UHpr*-Q8*XMjY+Zxek_%>}T`EG(}Ri)o7z6!p1{|@e$QJ!xeUj^Shz6!p1dep#=r`fpw5{a3yGp)!d=-52cn8b;oG#WZd0!8J3=^UdR{;G4%+!8ebuz&F})2)+e2e2aTW zf^TOV^qcT)+E((tuS&jod=-52c$R|WD9<;KuYzwLUj^Shz5?H9$07I@*zhgx$qBxl zZP0JRw`p6+H|}*-r6)YT3ch)~gKK7#=bOh@!8ebuf^QyQfp4_q5PS=4_!iGF1mDg! z=y#Z1DAtDiC%g}K-b%i4ue&O~d3+Uo^LUnm<0#KJkFSDn9$y9DJiY?oXvZP=7TEAD zo)HMXoo&!>!nbK#$#-{^eDnA!_~!8ru9;DuZysL--#oqwzIl8FzR`|D@GY?6TRf{2 zd^_8q--K_|wvz9CRr1Z_tKgf*vlJXhdA@mk6@2sfD){E{75GLw4#Bs;hHvqVQ1I<+ zgMJgfO`GBST$%q`+^+)MfKRK|dNclm0$I1o*4@jyPBdV^RRIy7v{d|78R7icwY=LA zZ`H_n`+oFNYt^G~++EZCU$cC*BR;9)Pp;scjdb<$HIDeanveBv=R~BHT<&(ptNuej zDB1t^VIsXyDPxo@t5pS#b z&_gBTdzQC5;*%=A_GHQU9m~Cr_yHAP_e{z7cP{UA#OGCf^amy5-SeMS@r^H)jCap} zUd6{=D;e*e|DuXtcUQ@H_xu;t^;-9mr|Y$-)Xn_t<6h4Ls{fXUO7`#GFSd@q3-PDlj{|Bxt(TXak9)t{I{sY5m(~+@ue~$8miNcB zD}son&3ff}=xS?(t?MgS+dA0n$tOE6=4xw!%>u2RIBDhKz8+T1S`qJEe`UO9{T1=v z^;g7u*IyCuU4KQqcm0*~zaM0J(qB3Mhf2n~^(z^W{Cn45Isa!$_V3oOyz1Y({)+y+ z>#vCSuD>GQyZ*{}&-yFpbK}az4^IjG74hEnSHyeQUlH$Je`UO9{T1=v^;gE9R)2ZT z%=8KR%Q4Yk{_X^8vs`V^-yqRn$9d4-Akkk(8}!%Q4|eql{S6ZRb({zN4HErzv_XG^ zM1LJ^(BB}@U)@$he{sJE3&*?u%6QNEE8@NDuZ;Jszarkd{)%|-`YYnS>#vCSuD^2r zp7mGG-?RS8`JXJQr|$Z3Ah1@>-?RRTc<=fv;=Svyi1)6)BHp|H%6QNEE9c``e?`1^ z{T1=v^;g7u*Iya$S${>mcm0*|r`2DkI=nuF{&Gz8m%sBT_1Dn`{S6WQb+kc$LqvZa zZO~tHKi4%L^fyHG*Kr>7H$?Q;(FXku5&d#vCSuD>$=wEC;>t3rP{Ci=_&-vX(> zjyC9TnCP#g4f@M}>9g}{U424-&HY$c8}v6!^w-fR^f$~LtWVs3aI`^x!$f}_ZP4E^ z(O*Yf!n&A!_2k*T7Art7{9ujyHxPdkesIJ6A>t3gUnl(u;;)7OP14^<{B`h0r9Vmh zQTXene;e^P!hfFhZzld0_%U-npIYJ%6`R?;8t#uRHR~KVm+{xaf1!*&K;o0|YaWRI zKpFoY_%%Nyz7c+%FY(*(Um(ZbL;UODKVSNH5q}JR%@6U1iX9~14w7$ae=Xv%COAL# zl8H~kzef5G5q~HAjnbbY{uulwU(=5bzsbw^8{s!R8-J+SL+0N@=3m-hi+D4C6Q6`1 z4^VhsjZ4PA2Yxe8<39wy;nVm-#Xd5hK0TjW_|3S+-w40y-}tu`Ysh?RbU(fDpCjkl zvSj>w;5X~U_@nS&AmjIt_*(dPSk^q>zrru@&ugr%z?*wIK1>jHn_XD^edtCdmXG{89;U{}p$7Ao8^ry=Bd*RpfC*wjBO8TKWL9^z~Jh7L9tL6M# zNk7m8!$0vuLxN^+ntq@aL9;iFzXg8HKk4TX{6t$c56~{dKZ%F7n02z$q2r+yCH>Hr zpjq1{J^{bs!T5KT@o#|NTwfCpEh_1U77^Y|d<*=BH{)-G-|Q*lhjtO(jDHXOhBxDf zrUe`1b?hblK+_06J%qQ?erOt5hbDd({6y1qKQZ{t`Z4h~{CfW`89%hn>{H@j2fyBT z#19Q5^Y7E+LIcS>jUO6F#x?%VVhx#pjqV2;NY;t*L+c3t#@`6P$=CQ>;5X~v_@RwK zqK$0ad9IT`uL%-uWWPAMhCmw)wk~GBS-IaPerO~6=K{GO+Nk59jUl3q+7E3EX>Lh8 zv@xXjChK*Txd>7KQuXHG{MX>0l(&%^uGaqvzJXgG|=!v;-RI6XX1yJn(IRR z(BzQO1k*ph3qoe?89%hqtdpe%B(&(6lhoG#w93 z3+ug4;-P6_qIEhRnikeMl6YuZm}r`gho-UL+)C55ADYH~|0+$>erQ@rKQztEbE#R! zcfzm7C4Oj8m}r-dho+VEL!%6Dq#x8>VY5ffxX>KK4~d6%8J>wB+GThnerQzK>^0Lr zw8&iFr4BuR)JrA(&>}LfiAOyaHf!Gap=pF?%D9*ln-{QA0+`9NF3MoUdRw1`|U z<3~M4@-=>F3z=t+&KLDkNk6oOTt^e%0>9oDOU94ik|q7n9FnhzhqjRGYy8j_GH#!q zC$xq1Z~V{}(!cRTTS#6tx*upu*l3sWLt6;{#t#h%6AfYgC=CfS4dM5?ickb>ehUht z?RnTqVTaJ3fQjp?+VMYy!!YqdYaVt|#|LRV&JW6Fb$-Zoe#muxh@Nj117TNuSjDq< z6#1O-_qPJF-{sQg*NxbG-4dJcXJT`WCpQ1CAvXW6B{r{Fh|TL^V)MG3*!=ejvH9;l zVvBzRo6MiL8C(1tN5&R^r$4jl(VIHR%>Wh&J5GrY%le7nM#ZzwTIq}8^YtE+@$(-4 z$cuZ{f3D~8XRiOzGgl>EvaAJk%EpPEf&RB$H9dONKAxR8HZneTWxVZeiMX8|8yp`R z89RJsd}?y|t()Ulz2n?%xry-`vxAfGIM=qf<&LH&hsP&InE`VsdwgUtD-4)};}hC| z`JU{=SoWwrmLAPs8Q;5S_x}Fw-88S3H1~_n`bUPYj3=hIB--Nk@YLAgB&MD|3Rm1dHkA>bwZ*S+^p&1CEaxzu zLw4D?ogNyR$R0bkZz_FsWOyVy!O!PCqnnXiFrmcs=D0mRJbWxW$&3X0KQex7@;c)Y zjy@AD2A>)ko7~vhKUsDTBV)%VCrV8L8L=tgqx2LoA#YO{Jd&QUFE2ZRv9dEjl57U; zW(J*fM`QPM|%YlGUMoLcm%XvDTF zgt#cx*mi{xvTauwjoWsGkw0K1i%S3Ty9?SJIA>WNO7XTbfFY~>K467~>YIJ?yV9)xth?+`RVkxW4_} zd$kAPP|u$2yRYrvyL-P8eb|2{O?>o@F|G<0W#|DpNN7McCt1rIwz46iXjpGyX ztx(_A_~^(O#|hwEdUEgx{E7Ijt??t-^iUR2?~U(GA08QmdwTF_W@M}#fqf%~$I_Ei z6WKl4vBQ(>lworn0+xu^P5?rnhX$ZcHcS zfz|^fquIX6^k@#vZJRc4+_<@Gb7vh z931ZI%yf2c+&r|obGR+DrF~PTeK?WMq=!0(5Z{~4OdZA<>}+hIV<;q1vh|y-bj`@v z5E?fk_F5E*fTP*b1LL{zqvMBf?jKE$ph1*fXi7}CXIUz&?BZtEW>~rO%}2-6=mq;Y zJK8@fPv&<2;P}+oBx2bn9qniBtfY)@y&l2+tXx6c-W_}Ud!ZgYWa?O!O^7Q&KdS_; z+0KV*V?6PQ$@F1(m@IKKlRlR1mtSf;vQsdMe5)N}&^ZKCw9^dnhqvBZiPjF5w&XRJ zo|qir?1R-Y_zA5Y9gIj#Yc?~qx#Hy_-8wtU4x>yYJ#}?f?uZR5=jZHbxRYO7Jtg;* z9?A6|P2W5|g=@=LR+m{^HZ-oh%DYqjslNVecI>})#~zF|+An`G;F{ql9`~4^6vU~2 zdGL$NetNKzT~~cjW zGI_I;54NuuJEDCY`w$Bszli#=?XuIDq$W(Tsr`JZ%iW@#ZG27B(>r+o`eNwFlBct8 zQRnDP*hc$*?bEwn-|2#!Uwd?RxvH7`X|8^I`ODwMl}GP|EsQpD`43NwPv!JQUbzU` zg!uWZfbHNFYw$O`3S2wD-+#X~`;XKh*k9z^aky)XoqAso_27Ks8Vfdd6lLWDSQjM4yOusc-EZ%T+xDyKmVPW6kav2m~PTm1Qs$)6z0`tZ7 zflN+P-io#8^E%YwqghCCFUM=K^tB**&O7&d9h7FgQSUBP&a4-_eX59|`_!BBuFllE zHtH=hy$|HAMCzEi*>fAuOCu12m7CI61D?C|XQRw>HFIiv{}Ylj_u$Fr6e1&rZlMR7 zZkg2rJqW#Dg$&fcl(`4x z-i5{~LB!A{df?CdwWttB-db+oFQO>#Bs-5B)_c&_8E@XoPVr+H56NY4=?@m$y6VbAH=fafOcz3ho>|KG!N6E;rg zh@ngLz@Pu|T;SbB0CNxEImKle6AVRz=lpq}cZIm1_c^3~iswR*5=9JMQtyE00&kM5 eSuZ?i(o4_P$Y!P)p+e3{wsvuiOTBY=0PA1ZuccoA literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b4fe524006992f35afa1ea93b61b226a44d56e93 GIT binary patch literal 68712 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 DiY@+9 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..33045e378e7ec686362954960ff645bd7b7d62ac GIT binary patch literal 2592 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 Qi97pvtW2JD@aVw*1&ruTP5=M^ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_4col_swiglu/gemm_swiglu_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d6995a53c06a71411af2179a4f33edc9d8a88161 GIT binary patch literal 2592 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

IJAMgtcRX6_>*=)BGzHm_+t~K?> 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1024.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2d5bcdac4d521a2ec6eec6ccd09b1f29413d3be0 GIT binary patch literal 135502 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 literal 0 HcmV?d00001 diff --git a/cpp/main.cpp b/cpp/main.cpp index f9c95e09a6..62306a0528 100644 --- a/cpp/main.cpp +++ b/cpp/main.cpp @@ -253,6 +253,8 @@ string Version::getKataGoVersionFullInfo() { out << "Using OpenCL backend" << endl; #elif defined(USE_EIGEN_BACKEND) out << "Using Eigen(CPU) backend" << endl; +#elif defined(USE_RYZENAI_BACKEND) + out << "Using RyzenAI (AMD NPU) backend" << endl; #else out << "Using dummy backend" << endl; #endif @@ -289,6 +291,8 @@ string Version::getGitRevisionWithBackend() { s += "-opencl"; #elif defined(USE_EIGEN_BACKEND) s += "-eigen"; +#elif defined(USE_RYZENAI_BACKEND) + s += "-ryzenai"; #else s += "-dummy"; #endif diff --git a/cpp/program/setup.cpp b/cpp/program/setup.cpp index bf7950315e..dc1d9b48a6 100644 --- a/cpp/program/setup.cpp +++ b/cpp/program/setup.cpp @@ -21,6 +21,7 @@ std::vector Setup::getBackendPrefixes() { prefixes.push_back("metal"); prefixes.push_back("opencl"); prefixes.push_back("eigen"); + prefixes.push_back("ryzenai"); prefixes.push_back("dummybackend"); return prefixes; } @@ -89,6 +90,8 @@ vector Setup::initializeNNEvaluators( string backendPrefix = "opencl"; #elif defined(USE_EIGEN_BACKEND) string backendPrefix = "eigen"; + #elif defined(USE_RYZENAI_BACKEND) + string backendPrefix = "ryzenai"; #else string backendPrefix = "dummybackend"; #endif From 9ea5a74113e174410b866fe94df1473c6049fde4 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 18 Aug 2026 20:40:45 +0800 Subject: [PATCH 32/37] Add RyzenAI backend for AMD NPU, first push --- .../bf16/npu2_8col/gemm_bf16_K1088.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1088.xclbin | Bin 0 -> 138062 bytes .../bf16/npu2_8col/gemm_bf16_K1152.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1152.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K1216.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1216.xclbin | Bin 0 -> 137550 bytes .../bf16/npu2_8col/gemm_bf16_K128.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K128.xclbin | Bin 0 -> 167758 bytes .../bf16/npu2_8col/gemm_bf16_K1280.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1280.xclbin | Bin 0 -> 135502 bytes .../bf16/npu2_8col/gemm_bf16_K1344.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1344.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K1408.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1408.xclbin | Bin 0 -> 125774 bytes .../bf16/npu2_8col/gemm_bf16_K1472.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1472.xclbin | Bin 0 -> 137550 bytes .../bf16/npu2_8col/gemm_bf16_K1536.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1536.xclbin | Bin 0 -> 135502 bytes .../bf16/npu2_8col/gemm_bf16_K1728.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K1728.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K192.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K192.xclbin | Bin 0 -> 127310 bytes .../bf16/npu2_8col/gemm_bf16_K2304.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K2304.xclbin | Bin 0 -> 135502 bytes .../bf16/npu2_8col/gemm_bf16_K256.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K256.xclbin | Bin 0 -> 132942 bytes .../bf16/npu2_8col/gemm_bf16_K2880.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K2880.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K320.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K320.xclbin | Bin 0 -> 138574 bytes .../bf16/npu2_8col/gemm_bf16_K3456.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K3456.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K384.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K384.xclbin | Bin 0 -> 144206 bytes .../bf16/npu2_8col/gemm_bf16_K4032.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K4032.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K448.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K448.xclbin | Bin 0 -> 149838 bytes .../bf16/npu2_8col/gemm_bf16_K4608.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K4608.xclbin | Bin 0 -> 135502 bytes .../bf16/npu2_8col/gemm_bf16_K512.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K512.xclbin | Bin 0 -> 155470 bytes .../bf16/npu2_8col/gemm_bf16_K5184.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K5184.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K576.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K576.xclbin | Bin 0 -> 161102 bytes .../bf16/npu2_8col/gemm_bf16_K5760.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K5760.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K6336.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K6336.xclbin | Bin 0 -> 130382 bytes .../bf16/npu2_8col/gemm_bf16_K64.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K64.xclbin | Bin 0 -> 143182 bytes .../bf16/npu2_8col/gemm_bf16_K640.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K640.xclbin | Bin 0 -> 166734 bytes .../bf16/npu2_8col/gemm_bf16_K6912.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K6912.xclbin | Bin 0 -> 135502 bytes .../bf16/npu2_8col/gemm_bf16_K704.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K704.xclbin | Bin 0 -> 172366 bytes .../bf16/npu2_8col/gemm_bf16_K768.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K768.xclbin | Bin 0 -> 177998 bytes .../bf16/npu2_8col/gemm_bf16_K832.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K832.xclbin | Bin 0 -> 138062 bytes .../bf16/npu2_8col/gemm_bf16_K896.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K896.xclbin | Bin 0 -> 125774 bytes .../bf16/npu2_8col/gemm_bf16_K960.insts.bin | Bin 0 -> 4208 bytes .../bf16/npu2_8col/gemm_bf16_K960.xclbin | Bin 0 -> 130382 bytes .../bfp16/npu2_1col/gemm_bf16_K1024.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1024.xclbin | Bin 0 -> 23112 bytes .../bfp16/npu2_1col/gemm_bf16_K1088.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1088.xclbin | Bin 0 -> 23432 bytes .../bfp16/npu2_1col/gemm_bf16_K1152.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1152.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K1216.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1216.xclbin | Bin 0 -> 23368 bytes .../bfp16/npu2_1col/gemm_bf16_K128.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K128.xclbin | Bin 0 -> 27144 bytes .../bfp16/npu2_1col/gemm_bf16_K1280.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1280.xclbin | Bin 0 -> 23112 bytes .../bfp16/npu2_1col/gemm_bf16_K1344.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1344.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K1408.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1408.xclbin | Bin 0 -> 21896 bytes .../bfp16/npu2_1col/gemm_bf16_K1472.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1472.xclbin | Bin 0 -> 23368 bytes .../bfp16/npu2_1col/gemm_bf16_K1536.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1536.xclbin | Bin 0 -> 23112 bytes .../bfp16/npu2_1col/gemm_bf16_K1728.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K1728.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K192.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K192.xclbin | Bin 0 -> 22088 bytes .../bfp16/npu2_1col/gemm_bf16_K2304.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K2304.xclbin | Bin 0 -> 23112 bytes .../bfp16/npu2_1col/gemm_bf16_K256.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K256.xclbin | Bin 0 -> 22792 bytes .../bfp16/npu2_1col/gemm_bf16_K2880.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K2880.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K320.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K320.xclbin | Bin 0 -> 23496 bytes .../bfp16/npu2_1col/gemm_bf16_K3456.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K3456.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K384.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K384.xclbin | Bin 0 -> 24200 bytes .../bfp16/npu2_1col/gemm_bf16_K4032.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K4032.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K448.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K448.xclbin | Bin 0 -> 24904 bytes .../bfp16/npu2_1col/gemm_bf16_K4608.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K4608.xclbin | Bin 0 -> 23112 bytes .../bfp16/npu2_1col/gemm_bf16_K512.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K512.xclbin | Bin 0 -> 25608 bytes .../bfp16/npu2_1col/gemm_bf16_K5184.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K5184.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K576.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K576.xclbin | Bin 0 -> 26312 bytes .../bfp16/npu2_1col/gemm_bf16_K5760.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K5760.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K6336.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K6336.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_1col/gemm_bf16_K64.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K64.xclbin | Bin 0 -> 24072 bytes .../bfp16/npu2_1col/gemm_bf16_K640.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K640.xclbin | Bin 0 -> 27016 bytes .../bfp16/npu2_1col/gemm_bf16_K6912.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K6912.xclbin | Bin 0 -> 23112 bytes .../bfp16/npu2_1col/gemm_bf16_K704.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K704.xclbin | Bin 0 -> 27720 bytes .../bfp16/npu2_1col/gemm_bf16_K768.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K768.xclbin | Bin 0 -> 28424 bytes .../bfp16/npu2_1col/gemm_bf16_K832.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K832.xclbin | Bin 0 -> 23432 bytes .../bfp16/npu2_1col/gemm_bf16_K896.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K896.xclbin | Bin 0 -> 21896 bytes .../bfp16/npu2_1col/gemm_bf16_K960.insts.bin | Bin 0 -> 660 bytes .../bfp16/npu2_1col/gemm_bf16_K960.xclbin | Bin 0 -> 22472 bytes .../bfp16/npu2_2col/gemm_bf16_K1024.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1024.xclbin | Bin 0 -> 38488 bytes .../bfp16/npu2_2col/gemm_bf16_K1088.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1088.xclbin | Bin 0 -> 39128 bytes .../bfp16/npu2_2col/gemm_bf16_K1152.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1152.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K1216.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1216.xclbin | Bin 0 -> 39000 bytes .../bfp16/npu2_2col/gemm_bf16_K128.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K128.xclbin | Bin 0 -> 46552 bytes .../bfp16/npu2_2col/gemm_bf16_K1280.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1280.xclbin | Bin 0 -> 38488 bytes .../bfp16/npu2_2col/gemm_bf16_K1344.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1344.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K1408.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1408.xclbin | Bin 0 -> 36056 bytes .../bfp16/npu2_2col/gemm_bf16_K1472.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1472.xclbin | Bin 0 -> 39000 bytes .../bfp16/npu2_2col/gemm_bf16_K1536.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1536.xclbin | Bin 0 -> 38488 bytes .../bfp16/npu2_2col/gemm_bf16_K1728.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K1728.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K192.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K192.xclbin | Bin 0 -> 36440 bytes .../bfp16/npu2_2col/gemm_bf16_K2304.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K2304.xclbin | Bin 0 -> 38488 bytes .../bfp16/npu2_2col/gemm_bf16_K256.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K256.xclbin | Bin 0 -> 37848 bytes .../bfp16/npu2_2col/gemm_bf16_K2880.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K2880.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K320.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K320.xclbin | Bin 0 -> 39256 bytes .../bfp16/npu2_2col/gemm_bf16_K3456.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K3456.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K384.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K384.xclbin | Bin 0 -> 40664 bytes .../bfp16/npu2_2col/gemm_bf16_K4032.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K4032.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K448.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K448.xclbin | Bin 0 -> 42072 bytes .../bfp16/npu2_2col/gemm_bf16_K4608.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K4608.xclbin | Bin 0 -> 38488 bytes .../bfp16/npu2_2col/gemm_bf16_K512.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K512.xclbin | Bin 0 -> 43480 bytes .../bfp16/npu2_2col/gemm_bf16_K5184.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K5184.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K576.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K576.xclbin | Bin 0 -> 44888 bytes .../bfp16/npu2_2col/gemm_bf16_K5760.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K5760.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K6336.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K6336.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_2col/gemm_bf16_K64.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K64.xclbin | Bin 0 -> 40408 bytes .../bfp16/npu2_2col/gemm_bf16_K640.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K640.xclbin | Bin 0 -> 46296 bytes .../bfp16/npu2_2col/gemm_bf16_K6912.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K6912.xclbin | Bin 0 -> 38488 bytes .../bfp16/npu2_2col/gemm_bf16_K704.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K704.xclbin | Bin 0 -> 47704 bytes .../bfp16/npu2_2col/gemm_bf16_K768.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K768.xclbin | Bin 0 -> 49112 bytes .../bfp16/npu2_2col/gemm_bf16_K832.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K832.xclbin | Bin 0 -> 39128 bytes .../bfp16/npu2_2col/gemm_bf16_K896.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K896.xclbin | Bin 0 -> 36056 bytes .../bfp16/npu2_2col/gemm_bf16_K960.insts.bin | Bin 0 -> 1304 bytes .../bfp16/npu2_2col/gemm_bf16_K960.xclbin | Bin 0 -> 37208 bytes .../bfp16/npu2_4col/gemm_bf16_K1024.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1024.xclbin | Bin 0 -> 69484 bytes .../bfp16/npu2_4col/gemm_bf16_K1088.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1088.xclbin | Bin 0 -> 70765 bytes .../bfp16/npu2_4col/gemm_bf16_K1152.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1152.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K1216.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1216.xclbin | Bin 0 -> 70508 bytes .../bfp16/npu2_4col/gemm_bf16_K128.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K128.xclbin | Bin 0 -> 85614 bytes .../bfp16/npu2_4col/gemm_bf16_K1280.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1280.xclbin | Bin 0 -> 69484 bytes .../bfp16/npu2_4col/gemm_bf16_K1344.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1344.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K1408.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1408.xclbin | Bin 0 -> 64616 bytes .../bfp16/npu2_4col/gemm_bf16_K1472.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1472.xclbin | Bin 0 -> 70508 bytes .../bfp16/npu2_4col/gemm_bf16_K1536.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1536.xclbin | Bin 0 -> 69484 bytes .../bfp16/npu2_4col/gemm_bf16_K1728.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K1728.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K192.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K192.xclbin | Bin 0 -> 65384 bytes .../bfp16/npu2_4col/gemm_bf16_K2304.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K2304.xclbin | Bin 0 -> 69484 bytes .../bfp16/npu2_4col/gemm_bf16_K256.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K256.xclbin | Bin 0 -> 68200 bytes .../bfp16/npu2_4col/gemm_bf16_K2880.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K2880.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K320.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K320.xclbin | Bin 0 -> 71021 bytes .../bfp16/npu2_4col/gemm_bf16_K3456.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K3456.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K384.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K384.xclbin | Bin 0 -> 73838 bytes .../bfp16/npu2_4col/gemm_bf16_K4032.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K4032.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K448.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K448.xclbin | Bin 0 -> 76654 bytes .../bfp16/npu2_4col/gemm_bf16_K4608.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K4608.xclbin | Bin 0 -> 69484 bytes .../bfp16/npu2_4col/gemm_bf16_K512.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K512.xclbin | Bin 0 -> 79470 bytes .../bfp16/npu2_4col/gemm_bf16_K5184.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K5184.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K576.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K576.xclbin | Bin 0 -> 82286 bytes .../bfp16/npu2_4col/gemm_bf16_K5760.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K5760.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K6336.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K6336.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_4col/gemm_bf16_K64.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K64.xclbin | Bin 0 -> 73326 bytes .../bfp16/npu2_4col/gemm_bf16_K640.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K640.xclbin | Bin 0 -> 85102 bytes .../bfp16/npu2_4col/gemm_bf16_K6912.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K6912.xclbin | Bin 0 -> 69484 bytes .../bfp16/npu2_4col/gemm_bf16_K704.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K704.xclbin | Bin 0 -> 87918 bytes .../bfp16/npu2_4col/gemm_bf16_K768.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K768.xclbin | Bin 0 -> 90734 bytes .../bfp16/npu2_4col/gemm_bf16_K832.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K832.xclbin | Bin 0 -> 70765 bytes .../bfp16/npu2_4col/gemm_bf16_K896.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K896.xclbin | Bin 0 -> 64616 bytes .../bfp16/npu2_4col/gemm_bf16_K960.insts.bin | Bin 0 -> 2592 bytes .../bfp16/npu2_4col/gemm_bf16_K960.xclbin | Bin 0 -> 66920 bytes .../bfp16/npu2_8col/gemm_bf16_K1024.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1024.xclbin | Bin 0 -> 131918 bytes .../bfp16/npu2_8col/gemm_bf16_K1088.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1088.xclbin | Bin 0 -> 134478 bytes .../bfp16/npu2_8col/gemm_bf16_K1152.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1152.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K1216.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1216.xclbin | Bin 0 -> 133966 bytes .../bfp16/npu2_8col/gemm_bf16_K128.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K128.xclbin | Bin 0 -> 164174 bytes .../bfp16/npu2_8col/gemm_bf16_K1280.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1280.xclbin | Bin 0 -> 131918 bytes .../bfp16/npu2_8col/gemm_bf16_K1344.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1344.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K1408.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1408.xclbin | Bin 0 -> 122190 bytes .../bfp16/npu2_8col/gemm_bf16_K1472.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1472.xclbin | Bin 0 -> 133966 bytes .../bfp16/npu2_8col/gemm_bf16_K1536.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1536.xclbin | Bin 0 -> 131918 bytes .../bfp16/npu2_8col/gemm_bf16_K1728.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K1728.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K192.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K192.xclbin | Bin 0 -> 123726 bytes .../bfp16/npu2_8col/gemm_bf16_K2304.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K2304.xclbin | Bin 0 -> 131918 bytes .../bfp16/npu2_8col/gemm_bf16_K256.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K256.xclbin | Bin 0 -> 129358 bytes .../bfp16/npu2_8col/gemm_bf16_K2880.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K2880.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K320.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K320.xclbin | Bin 0 -> 134990 bytes .../bfp16/npu2_8col/gemm_bf16_K3456.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K3456.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K384.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K384.xclbin | Bin 0 -> 140622 bytes .../bfp16/npu2_8col/gemm_bf16_K4032.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K4032.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K448.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K448.xclbin | Bin 0 -> 146254 bytes .../bfp16/npu2_8col/gemm_bf16_K4608.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K4608.xclbin | Bin 0 -> 131918 bytes .../bfp16/npu2_8col/gemm_bf16_K512.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K512.xclbin | Bin 0 -> 151886 bytes .../bfp16/npu2_8col/gemm_bf16_K5184.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K5184.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K576.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K576.xclbin | Bin 0 -> 157518 bytes .../bfp16/npu2_8col/gemm_bf16_K5760.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K5760.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K6336.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K6336.xclbin | Bin 0 -> 126798 bytes .../bfp16/npu2_8col/gemm_bf16_K64.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K64.xclbin | Bin 0 -> 139598 bytes .../bfp16/npu2_8col/gemm_bf16_K640.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K640.xclbin | Bin 0 -> 163150 bytes .../bfp16/npu2_8col/gemm_bf16_K6912.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K6912.xclbin | Bin 0 -> 131918 bytes .../bfp16/npu2_8col/gemm_bf16_K704.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K704.xclbin | Bin 0 -> 168782 bytes .../bfp16/npu2_8col/gemm_bf16_K768.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K768.xclbin | Bin 0 -> 174414 bytes .../bfp16/npu2_8col/gemm_bf16_K832.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K832.xclbin | Bin 0 -> 134478 bytes .../bfp16/npu2_8col/gemm_bf16_K896.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K896.xclbin | Bin 0 -> 122190 bytes .../bfp16/npu2_8col/gemm_bf16_K960.insts.bin | Bin 0 -> 4208 bytes .../bfp16/npu2_8col/gemm_bf16_K960.xclbin | Bin 0 -> 126798 bytes cpp/external/ryzenai_artifacts/grid.json | 5991 +++++++++++++++++ cpp/external/ryzenai_artifacts/manifest.json | 894 +++ .../ops/attn_h12_s169.insts.bin | Bin 0 -> 4864 bytes .../ops/attn_h12_s169.xclbin | Bin 0 -> 87038 bytes .../ops/attn_h12_s361.insts.bin | Bin 0 -> 4864 bytes .../ops/attn_h12_s361.xclbin | Bin 0 -> 88574 bytes .../ops/attn_h12_s81.insts.bin | Bin 0 -> 4864 bytes .../ryzenai_artifacts/ops/attn_h12_s81.xclbin | Bin 0 -> 92702 bytes .../ops/attn_h6_s169.insts.bin | Bin 0 -> 2440 bytes .../ryzenai_artifacts/ops/attn_h6_s169.xclbin | Bin 0 -> 86654 bytes .../ops/attn_h6_s361.insts.bin | Bin 0 -> 2440 bytes .../ryzenai_artifacts/ops/attn_h6_s361.xclbin | Bin 0 -> 88190 bytes .../ops/attn_h6_s81.insts.bin | Bin 0 -> 2440 bytes .../ryzenai_artifacts/ops/attn_h6_s81.xclbin | Bin 0 -> 92414 bytes .../ops/attn_h8_s169.insts.bin | Bin 0 -> 3248 bytes .../ryzenai_artifacts/ops/attn_h8_s169.xclbin | Bin 0 -> 113838 bytes .../ops/attn_h8_s361.insts.bin | Bin 0 -> 3248 bytes .../ryzenai_artifacts/ops/attn_h8_s361.xclbin | Bin 0 -> 115886 bytes .../ops/attn_h8_s81.insts.bin | Bin 0 -> 3248 bytes .../ryzenai_artifacts/ops/attn_h8_s81.xclbin | Bin 0 -> 121518 bytes .../ops/bnmish_1536x1024.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_1536x1024.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_1536x192.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_1536x192.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_1536x256.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_1536x256.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_1536x384.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_1536x384.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_1536x512.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_1536x512.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_1536x768.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_1536x768.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_3072x1024.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_3072x1024.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_3072x192.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_3072x192.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_3072x256.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_3072x256.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_3072x384.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_3072x384.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_3072x512.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_3072x512.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_3072x768.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_3072x768.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x1024.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x1024.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x128.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x128.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x160.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x160.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x192.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x192.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x256.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x256.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x320.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x320.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x384.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x384.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x512.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x512.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x64.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x64.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x640.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x640.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x768.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x768.xclbin | Bin 0 -> 40232 bytes .../ops/bnmish_384x96.insts.bin | Bin 0 -> 3248 bytes .../ops/bnmish_384x96.xclbin | Bin 0 -> 40232 bytes .../ops/rmsnorm_384x384.insts.bin | Bin 0 -> 3248 bytes .../ops/rmsnorm_384x384.xclbin | Bin 0 -> 42408 bytes .../ops/softmax_1024x192.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_1024x192.xclbin | Bin 0 -> 31224 bytes .../ops/softmax_1024x96.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_1024x96.xclbin | Bin 0 -> 31224 bytes .../ops/softmax_1408x192.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_1408x192.xclbin | Bin 0 -> 28280 bytes .../ops/softmax_2048x192.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_2048x192.xclbin | Bin 0 -> 31224 bytes .../ops/softmax_2176x384.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_2176x384.xclbin | Bin 0 -> 28280 bytes .../ops/softmax_2944x384.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_2944x384.xclbin | Bin 0 -> 28280 bytes .../ops/softmax_4352x384.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_4352x384.xclbin | Bin 0 -> 31224 bytes .../ops/softmax_512x96.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_512x96.xclbin | Bin 0 -> 36728 bytes .../ops/softmax_704x96.insts.bin | Bin 0 -> 2288 bytes .../ops/softmax_704x96.xclbin | Bin 0 -> 41336 bytes cpp/neuralnet/ryzenaibackend.cpp | 694 ++ cpp/neuralnet/ryzenaidevice.cpp | 225 + cpp/neuralnet/ryzenaidevice.h | 82 + cpp/neuralnet/ryzenaikernel.cpp | 738 ++ cpp/neuralnet/ryzenaikernel.h | 193 + cpp/neuralnet/ryzenaimanifest.h | 56 + cpp/neuralnet/ryzenaimatmul.cpp | 1504 +++++ cpp/neuralnet/ryzenaimatmul.h | 153 + cpp/neuralnet/ryzenaireference.cpp | 1361 ++++ cpp/neuralnet/ryzenaireference.h | 191 + cpp/neuralnet/ryzenaisequence.cpp | 329 + cpp/neuralnet/ryzenaisequence.h | 53 + cpp/neuralnet/ryzenaisequence_layout.h | 123 + cpp/neuralnet/ryzenaishapes.cpp | 308 + cpp/neuralnet/ryzenaishapes.h | 68 + python/ryzenai_kernels/INSTS_FORMAT.md | 255 + python/ryzenai_kernels/aiecc_cleanup.py | 24 + python/ryzenai_kernels/build_attention.py | 183 + python/ryzenai_kernels/build_bn_mish.py | 144 + python/ryzenai_kernels/build_grid.py | 223 + python/ryzenai_kernels/build_softmax.py | 128 + python/ryzenai_kernels/build_swiglu_grid.py | 73 + python/ryzenai_kernels/extract_layout.py | 194 + python/ryzenai_kernels/gemm_bf16.py | 672 ++ python/ryzenai_kernels/gemm_swiglu_bf16.py | 457 ++ .../ryzenai_kernels/kernels/attention_head.cc | 132 + python/ryzenai_kernels/kernels/bn_mish.cc | 100 + .../kernels/mm_swiglu_epilogue.cc | 79 + .../ryzenai_kernels/kernels/softmax_rows.cc | 24 + python/ryzenai_kernels/make_artifacts.py | 195 + python/ryzenai_kernels/parse_insts.py | 126 + python/ryzenai_kernels/setup_env.ps1 | 193 + 458 files changed, 16165 insertions(+) create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1088.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1088.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1152.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1152.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1216.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1216.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1280.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1280.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1344.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1344.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1408.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1408.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1472.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1472.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1536.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1536.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1728.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1728.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2304.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2304.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2880.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2880.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K3456.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K3456.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K4032.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K4032.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K448.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K448.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K4608.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K4608.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5184.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5184.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K576.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K576.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5760.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5760.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6336.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6336.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6912.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6912.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K704.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K704.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K832.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K832.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K896.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K896.xclbin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K960.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K960.xclbin create mode 100644 cpp/external/ryzenai_artifacts/grid.json create mode 100644 cpp/external/ryzenai_artifacts/manifest.json create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h12_s169.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h12_s169.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h12_s361.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h12_s361.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h12_s81.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h12_s81.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h6_s169.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h6_s169.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h6_s361.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h6_s361.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h6_s81.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h6_s81.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h8_s169.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h8_s169.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h8_s361.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h8_s361.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h8_s81.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/attn_h8_s81.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_1536x768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_3072x768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x1024.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x1024.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x128.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x128.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x160.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x160.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x256.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x256.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x320.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x320.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x512.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x512.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x64.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x64.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x640.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x640.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x768.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x768.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x96.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/bnmish_384x96.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/rmsnorm_384x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/rmsnorm_384x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_1024x192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_1024x192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_1024x96.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_1024x96.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_1408x192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_1408x192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_2048x192.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_2048x192.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_2176x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_2176x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_2944x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_2944x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_4352x384.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_4352x384.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_512x96.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_512x96.xclbin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_704x96.insts.bin create mode 100644 cpp/external/ryzenai_artifacts/ops/softmax_704x96.xclbin create mode 100644 cpp/neuralnet/ryzenaibackend.cpp create mode 100644 cpp/neuralnet/ryzenaidevice.cpp create mode 100644 cpp/neuralnet/ryzenaidevice.h create mode 100644 cpp/neuralnet/ryzenaikernel.cpp create mode 100644 cpp/neuralnet/ryzenaikernel.h create mode 100644 cpp/neuralnet/ryzenaimanifest.h create mode 100644 cpp/neuralnet/ryzenaimatmul.cpp create mode 100644 cpp/neuralnet/ryzenaimatmul.h create mode 100644 cpp/neuralnet/ryzenaireference.cpp create mode 100644 cpp/neuralnet/ryzenaireference.h create mode 100644 cpp/neuralnet/ryzenaisequence.cpp create mode 100644 cpp/neuralnet/ryzenaisequence.h create mode 100644 cpp/neuralnet/ryzenaisequence_layout.h create mode 100644 cpp/neuralnet/ryzenaishapes.cpp create mode 100644 cpp/neuralnet/ryzenaishapes.h create mode 100644 python/ryzenai_kernels/INSTS_FORMAT.md create mode 100644 python/ryzenai_kernels/aiecc_cleanup.py create mode 100644 python/ryzenai_kernels/build_attention.py create mode 100644 python/ryzenai_kernels/build_bn_mish.py create mode 100644 python/ryzenai_kernels/build_grid.py create mode 100644 python/ryzenai_kernels/build_softmax.py create mode 100644 python/ryzenai_kernels/build_swiglu_grid.py create mode 100644 python/ryzenai_kernels/extract_layout.py create mode 100644 python/ryzenai_kernels/gemm_bf16.py create mode 100644 python/ryzenai_kernels/gemm_swiglu_bf16.py create mode 100644 python/ryzenai_kernels/kernels/attention_head.cc create mode 100644 python/ryzenai_kernels/kernels/bn_mish.cc create mode 100644 python/ryzenai_kernels/kernels/mm_swiglu_epilogue.cc create mode 100644 python/ryzenai_kernels/kernels/softmax_rows.cc create mode 100644 python/ryzenai_kernels/make_artifacts.py create mode 100644 python/ryzenai_kernels/parse_insts.py create mode 100644 python/ryzenai_kernels/setup_env.ps1 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..da0edb6a80dabb974bd8b4f55be067dfa55b9aef GIT binary patch literal 4208 zcmbtXL2lbH5L_xsY6J%ALk~R!hz@>0eo!C$fIh(oKOjG-3iu&87dH8ewAY>_mC!;}zp+I+mZ)-Gw*Aw5L*Nj}vcWe1348$#_e ze4i`%UK_qU^6jv_C~v*z_JJ=wM+|ySsBgh@=yR$)>cIB7RrFjJk*hUm2e+bddQKQR zga%=L>bV1R0nhabpxSfCkPD_U!%#GMPWht7Y@bVf584XH=d1Z{E#HKpamm+uu3yOa zRLR%Y7(D0scE~f6HKWh%17A9W7@6n1zGctpT)}he=(&f8RINcfxV0vmhlD{5!u(Ww zcrI%H!nLTx+IQw61)QOMJGk31*>P#S81ITe1DzkA zFyB>+;zIkXxK?}Ay^q_W?qecny=ycsmlA^-;9cYSmg_#Oooayki@DgP{LQJqNiH%B z)d2OU^S1u_g>g{_RdEY-5H*mPxOxpx2O*D2Pl!P%)Pc^Ie%GK5bk5cRd=Yz5{~sFc zLoede41*eIFDiU*FN%Atj9bv&#~tf{iJQ@jpnc%uH6TWW3ca_a0lv9(Eqq~nQNv#J z!bHyNMOv0znqlZB(ThUaUi6|xakqoV{a0M}q8_{1=#G#r=kz--8@n`*?M~+L>2^8J Rp2u&6$-IuUd3@Jl{sRxx8-4%) literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a84ff261ff5a3cd116d890e240f743d61ebbd878 GIT binary patch literal 138062 zcmeHwZIE17dFJhzR!=i(G(GlM+gK9mnNf%W1MbmCvSh@jM;a@#vCZhiloq_D8A&5q zjy@WF?LZ1>8E50gR2Z@$)vz%;K(cs=e@vh-pv1|TC19LTHBOmIHm;=xQdCh?cDDx% zaa?R>pL5PV=Y8(&5BCkOtwlMvN;A*i8 z?E4-FaNM(@OZ^J0tquL7>n6dk9O{4Y%KzN=%u9#<;mXbHwqbY2~I=-~L>&J%(!sox<1?|-Lp?kbtzmKSxkr;Y0s`KjtVf-zcr zMQW2u{s-X1*iiq&|L)|yfBDCs{a6sB19h#<_@{nv!#{QW$Lcc!2AQ9COiWG|^Tij;940tKl>{Cit=Z7NlR;7$0ae)C}$ z`C&M*X54Ud%+HDo@BgR&qbAMXiMQbjLGa7fAo%dEh1Gs^s4InqRy?%M_D$LOZy#8v z=BfS%yAZR3n4KkC)v5liNv#I&vy(kIxGtRv7Sq8*u>2}nd9MRw-@UWD7}Q6C?;s7} zlIh@`DQ({u1Pg!nQtjR+`)=#6?)YjdSoqXWYMbWzYHwNSt8M>sU+wZ!eYKDNd0*`d z-{`A->zjSGA3xi7C0~8wZ&KAqpT{NCSx=>c(u2c5PkamKfBJ{Y_g6q;KdNo|gs%5_ z6;Z@_JDyHe`v+3rTUB-ZWvaUA_j|g6D@TI+x6D@`o$vYns%p<~{rEkpY*4-Tv7Qa8 zz51wL{_roU_N($6R*bK3HZgY{HXAeM|-XngWv*2=e8FLI3xFl;FdpqLDgGG-H=E8>>s4c1EV2d%8y#t z52(b8qww%CwBZ_hgFaS+RP9u@r?w-FRuta#8~BNK)VfS7o+;m0`^=U6eJ`vzmCAQj zCKrOK=>vtw0@nvyXIOJjSH7^C%GYjw;s)J={(*I2$zx@Aj=GW@g@$v|ec?F|54m&f zbxhk;xoNRN&D%SDz_d4&|9NZg6KeF zgZp+pwC%y=T3*ezYRJ33{=jI{>ofnGF`o*rX+C2LFFkmp<$q){_0tj4aGHfldZMlr z#=q+WYM#=ZQT<4D)i&(8q423a`G-=$W9mLv>)-5V-n^SdXt;ENoSEmG3wA%tBALzxH^#|E1zjGS&Wc=6kD!1CQxC9>-60O#IWI)mPtN=y@n# zd%T*j1z*e8-j3hvzXDzZRnwFX3x5n}J&$(R-ne~zt@Oq9*Dfq&f=3?yKzDFub}sYxUmAPl;TLk#S7w(o z4}I#^wV(KL?&`G*bD3c6CsuNweD3NOR&#^TUH!%Mn}a82r#_GC>G@N;X;Z4UeN*bW z)bNwPU3~89v!DCjp^-OVc=9X5BX54-$*&Dxna%e+{^{+HRKNIO@h6q3g<$P_ivQ|Q z|NRhhQmXbm&VA>mo)_oOZz^ni?OR?fo_OuH)$e}rxBlBi@V~&tM6r(XJkq_paHRY3 zO|!X)O-Fi0Hq3tL;n&QLEp40~E4=2|^r4}X7Y}zGoBoZ>Cole9a5A-Zcu&vnGe3Rb zBext&rHdy&|6KamQ~L+^t$lpWv8Nu~yl?I9;8^PP@X60_>^hd}F7E4l9OsS=o*cV3 zb!_@SY(6=*sry*!!tlPnKf&*8@#MvCrH_4b^WeVjudX@v$q(Tgk9HmV&WYiD-MQe{ zcXFs-oi{ePuji}X$EF|IeDd?*`8~O=ccglYw{H067k-?%=R2DRzfi_qq8L>Ec=*om zd}#Br&wuQ~AO793tEg#hF1Yh5YWmT=XLtANy80&4ccQL+eINS%&YWt^$sawM+K<|f zrM3_4>sCGZ&CUC|(WAjjgC}zn_?;>4>lx|(d0}SlWbozxem|ybc>h}aORxH`YrY%W z!G_=-Fm&sG`ensewL5QFI%Zf}V>wcMgCnpZ4DAO)`@znBFtZ=5V3r28%%-)q*KJyR z+jNk>7HnIZJ6`)Q8`st{ug%q7hku!k_`NY#SX&&Zo!K^kmHc$qk~$A(PF`4F%a_)V z1jWr4|FQ5ItfPLc-N<@<5$koL`a{gtYx#vg!7r%r?<@yt4I&*#gR? z_UPC9x+?Y0buaY1SUdI8o{_F}xm#Zk*Du?6D3CBip}t*PTx_9cgW=Bdr}2_r`STcubc@?cm!{J4<$d3S$u-jrw$t*Qeo#LT7n>ny>YHed_fo zavOc3@%mJyPp?nCK84ox`qb;w>p-6xy{Ph<(Wg<{>PcH}^`y0f;#f?dj>hz9)DFHK zwX2=$`1t)8^D z)sxl^io-E|IvCTZQ9Jl{)XtLKUY`zmed_h8*QcjsKZ1Y1ud=%gG*e~Gh_WJZ- z4)3)W{r*$EkJ7*2_wV=fUZ1M0(f16pZe#g{`skYe%j_6b$h-DD zr(U0Wed_h8|Ng%J{=WbIewY9LzEWX0)c5bN+wboieW<$0deYifPg>jRNo!;OX-uCE zI=yM?i`v*P5Glug0cW?@r$b(!dVT8ksn@4opL%`j^{LmVUY{xvrjF}cpBjCry2*Od z+E!0m+v-VcWB+MyZ2xJm-h1lmI}ow4Um#**zksvb>(hh1e*dXr-S0oOe>2s8f8T$9 z-|s*5-{1G&-}m3&_ut>YZvXzN)`v>>7=3E=qP4A_w6@ig*2ezRm_8kMdehVwwXt6y zQjYxs&Tg+y_jrBkpP%~Yr~dh=e}3wppZe#g{`skYeyT*6Ir<~!l?YSE zb*)d0K2+UgJ!x&LC#`Muq_wgCG^S4no!&I{MQ!XCh?HZ$fV11{(;=@|Ng074gT++`oDkb|Ng1}`=|czpI)bb|5WQkmFkT? zHG0w7R!>^n>Pc&3|7lF0jyt_+>WkXgFAyomegS8<*Qa~DKK0K}{qs}*{M0``_0LcJ z^Hcx))IUE}B1|3E_48As4^=l=Pg>jRNo!j@X>II3jp@@-r#DS~Q5*XOBIVdG;OzGL zbgS2=UY~k>>h-DDr(U0Wed_h8*QZK^spGoVr$!&DZnB=Vw$+o?wtCXq*nb++r-M#! zn);$P_6tPHv0uR1?e*!9*QZ{edVT8ksn@4opL%`j^{LmVN`$H7y4I&gAF6J$p0u{r zlh(F+(%RU6nu+Z{&BXSfMr`aCh}hUK;OzGL^kByCKUJ*z{ilBaso#HE>mOKWR)gPv z>i3`e{ilBaso#Hko$f!?`cUP1qfd=qw6@ig*0y@m+Sq>@)2HK3Z<_j|Hueid%CTR- z+3oe|9?R z`%h!~bkylhQ(x4^et}3i_6s<>y*}OQ^{LmVUY~k>>h-DDr(U0Wed_h85@G7NuJx(W zhpL;bC#`Muq_wS{v^Msi#`Ni+)0?KgsEz#sk#g)8aCUorI^^}K*QZ{edVT8ksn@4o zpL%`j^{EnJ>bS1;snLh3o2)0TZS|zJt)8?t_Mc)~s5#X6`EMUc$M&B_Z0r|^*w`=N z?DqQfVA}6LH9UidN*b{CnH~AU%|X6)(?fkP7N-i>e_{?bUyD0_RQSlFJ=cmsa3Kha zx4lq6S?&$NEr0rg3M!;-$gBM-_#fN{Mpb-$M7eR))(>P1Dm;8_eGpvBSD$!36;y*% z?Nqj>wj&LdTzJ=S;3wKq>oTo)rhH@VGgtEWy|Cs~D&JL6`y;0h6dnt3zB;5%V;6e5 z@`Z@jY_^+FT}h6{bJBfbZ4VDMT*tIsm75kT)V#gZ2TXfY`JcD;KA}c$O{wYFss3V| z67pQ=ul5vfJa_}2H?l1Vt_Jt*dT85&%eB0kZPk!>ef@#arq^fwH)B2(UekQW6kdAp zM$7-mWa_7lvoJ|d)Rn^ccYQ$3Q|iC!N2;r~Vb2YPPwmM+lnNdTvX~wHo83Ovc{hvF zx}L&E9@caH!%b?M4o;-zKeD%2*sAI(->>RY*UR?T9#8kbRQyS%+MmvRZ?$mXFiY{l59Mo*SM#;tYx&yS@q7JOz-yptn$lt6kHW{E?kG|pcsn@4opL%_2Q^j?yPmMlQT{ZeNYFj;N%dMWYHuj(5wr>ujPsg3! zH1$Po>=%fXW50m2+w0RkUY~~dI1ujjX};F)^{LmV(1eebov!ryRAu6?A|cmTg8-jD zj|AClKCACvU8(m?y&?F+?pLp5i$SoaeCa{cTIq}HuU%Nm z1dlxYf$reS>|EyWzclv9!!P8fugorG9{SX+Yd`Vh+|_Fr<}$(BPpsrV`P|hntmX!v zyZVdiHwRD5PJJHN)1Pl@H{m-@+c%}2OASBy+r{UuKKr@f9U6J_g(trk7JpKi^7_>4Q?F04c=T~y>rC;iC zH%)y}8~X(!<=8La?DqO}tJkMqpGKa!dVT8ksn@54QUCpY|NVXc{eA!aeS99B-PH|c z7QPQv_8+J>pUSRwsn4sk)h#H$(R?N}<>`Ev#4A}B1ZxNNXU0OXC9iG#C zx~r+r*DvDpwRzrY^r4DkJ!x&LC#`Muq_wgCG^S4no!&I{MQ!XCh?HZ$fV11{(;=@< zy*~B&)bBs_`%nG*egFK_KR@-)Pn8H$$94Vu)aXOiP1cjvwtCXqR!>?R`%k+dclBZP z?t!k@{?mw!{Q?mi`vsicUY{Q9f)HLz2NS{at3-OgZetL9_s(vu_o46A`>C|m>-Po0 z!r#4AyZ6by+xn|Jpvo6M^^@ABxxU(47W!)2zuZ^5{8V41U+u@w z_Fchl%fCrgAAKH|P-i`r3Q7+S13mFAod4+`D&JoLjs2*$=@YtM?9D7aSj2fdo=#Q! z2U6c#RdxJjs=Dd-d%Ey$EVzHmeD%@!p6{=!_Wah5-;>G))q5Z7*`PjO=%af1!@s2V zf2#5uR*bK3@)2HK3Z<_j|Hueid%CTR-+3oe|9r<~!y*~B&)az5P zPn8H$$94Vu)aXOiP1cjvwtCXqR!>?R`%h!~bkylhQ(x4^et}3i_6s<>y*}OQ^{LmV zUY~k>>h-DDr(U0Wed_h85@G7NuJx(WhpL;bC#`Muq_wS{v^Msi#`Ni+)0?KgsEz#s zk#g)8aCUorI^^}K*QZ{edVT8ksn@4opL%`j^{EnJ>bS1;snLh3o2)0TZS|zJt)8?t z_MZl^{io^=l$d|`d#HtPABfo4FA%Y@U%=Vz_31(N_bdJWQ*a9&{NI=Ie_tx^|Ng1U zLjLbd`S0)h@9+EX@B8oX#|NPWHKlRT~{qs}*{M0``_0Lb02vf&({ruGEL)A^zlh(F+ z(%M!}S{wUMWBPQ|=}l8#)W&{+NICWkIJ><*-RkwJ*QZ{edVT8ksn@4opL%`j^{EnJ z>bS1;snLh3o2)0TZS|zJt)8?t_MgV|>7dh_roO0+{Q{A4>=$r$dwn|O^{LmVUY~k> z>h-DDr(U0Wed_h85@G7NuJx(WhpL;bC#`Muq_wS{RCYf$o~m=O2X!6qIkmQm=}w`f zen9^p*9zwe7YUaLmkCc2o+4Z!TqQh5c%JYA;YGqrgqI1|Lu~rDH`YI6OaI2He}ap3 z!6m|F!jpuj2v-PK3C|IpC%iy-k?<1XWy19koBoZ(`e$tE-zfD@aIr49M7T_NlJFGa z3gIf@Il}XV7YHvBULw3qxE^BDzu{Q_j4k~er2Yvm)&-XcmkCc2o+4Z!TqQh5c%JYA z;YGqrgqI1|LmaNZTx|VmTl#k(XK}tRxJbA}xJ-DG@D$++;VR)d!t;a|2rm*|BD_qv z9^!EQ#rn55*1vJ;pWtF$aEWl4@Fd|W!WF_*!gGY@2`>;{B)mj;nQ%SC;rfg9Z!Ffo zQR<)IVqI{FaGCHV;VHru!d1d^gy#t_5MCs_M0lBSJ;dSqi}i0f*1tjOpWtF$aEWl4 z@Fd|W!WF_*!gGY@2`>;{B)mj;nQ%SC;ri>1tv_wsH5b$m^je%JTqIl~TqZn8c#3d^ zaFy^J;d#Ofgck`f5nd)-4{^BuV*T42>)$x_PjIm=xJ0;2c#`lG;R@j@;W@(dgck@e z5?&&_Ot>E6aQ(&lHx}#PDD_Wpu`akoxJ-DG@D$++;VR)d!t;a|2rm*|BD_qv9^!EQ z#riiK>)#;tPjIm=xJ0;2c#`lG;R@j@;W@(dgck@e5?&&_Ot>E6aQ$Ut>rdNu%?0%X zS&Q?8i-b#r%Y-KhPZ6#Vt`eRjJWqIm@FL+Q!pnr~Ar9AHtbcoB{TrwL2`<(Jmk5^$ zPZFLYTp?T~JV$t*@B-mQ!b^mg3D-j$uD@9S#$x>&rTz&n)&-XcmkCc2o+4Z!TqQh5 zc%JYA;YGqrgqI1|LmaNZSpSA&{TrnI2`<(Jmk5^$PZFLYTp?T~JV$t*@B-mQ!b^mg z3D-j$uD?ud{b}2-xuAX^V{x8vk#LD{neZgxDZ&-PRl;+G=Ls(mUL?Fkc$siL#Nqmj z^>1&if8*3Y!Nt1Z65%r8Ny1ZvD}<|r=LpXeULd?kc!}^b;d+R}^%v{kSge1e)IY(+ zy5JJwGT}+WQ-mvotAytW&l6rCyhwP7@G{|gh{N?4>)&v!e}mLN!Nt1Z65%r8Ny1Zv zD}<|r=LpXeULd?kc!}^b;d+R}_2>SNL$>Xj3+e~(pFWyrF?qs8!X?6G!jpuj2v-PK z3C|IpC%iy-k?<1XWy19koBr&L_0QP0PeFa0`X{(Z{u1Fb;Yq?%ge!!rgy#s)6J8*^ zNO+0xGU0lNP5;JX{WG@oZaSd9N~Gw3xpR5FA-iQTo1A7 z-*Bvd#+LpKQvU=O>w-&!%Y-KhPZ6#Vt`eRjJWqIm@FL+Q!pnr~Ar9A@`x{SeOaBh2 z+oOIKny(8k5-t%g6P_eIMYuw^N_dX&JmCexi-ea5FB7hZ*z{*_tbfL~eG2O1)IY&R z@|Osg2~QH9B3vO{B|JxXp6~+UMZ!yjmkHNHZ2C7A>z}cuf1}ht!Nt1Z65%r8Ny1Zv zD}<|r=LpXeULd?kc!}^b;d+Qo|Au4zGq&_^koqUMSQlI(TqZn8c#3d^aFy^J;d#Of zgck`f5nd)-4{^BO+#VOUrGEz$wCm5|VqN?t!ezpfgr^8s2v-Tu5uPW!KzNbx65(aS z^$?r>?2Yx$*tSnWecbgaPq;|9M7T_NlJFGa3gIf@Il}XV7YHvBULw3qxE^BDzp+^V zj4k~erTz&n)&-XcmkCc2o+4Z!TqQh5c%JYA;YGqrgqI1|Lu~pt9P6L4rGJCeKf%Si z;1c07;Yq?%ge!!rgy#s)6J8*^NO+0xGT}PmayjLm-%b)P;~knxEb6`AB)waMUq62e z{qETl{92cXey7Rd*ZC{-yIeI@PPua{gv)rhCD)aAaPZT0$KAQ`({<%D8~k+Lad%zx z*PV<0I$Xv(C%LY?8-t&&E6)t!r|ZgRDfsESa*siO-E#u;*WohW1<7^gofZ6a-9c*S zAYE5J;~<`{E4d&2b=N|F9mcrm=lJ2cxH$m7e!daAK@|-Eppmt}8hdJiECEo*l-x&~@eAOEuW&c$)*Z>l*RY9(h&; zKeb0R{Cu#{)xQ8t^-wz{=Yb#BHt^#x>T%*BU-(@+;dkwX->nPy-8){i z$F(2rar2=_xvNCDNO_<{8WMhL&p5S5@(kjsJ(8E;=k~aI&>pFWatqo+^+)E> zK7n8Aq5K0s*F*eBzQVY>_F&vyJs2-{F2>8@BIS(|X*BpL+z2g1iz~v^F->WyazwG$JK-O$aN_vpgqLD*^{o;9p(e^BY6pasfY3y z{L~)FhwyWITz}CXS3l;DYXjzw!#j@rHlX`Ro_GsreDgHE0o`ZwG!Id~TQ7Oq z8-n`DFY6lhlV9==>L~-kcx2IX`%Fe(>h}s9*TubxnTM z@AyRhE*|weKk9dW)bIQl7dJOBE)Ih?x4ys|`Q?6%aUs8~M~n;kMdx5#$S?T~^}GCr zadCMM^^;%j7pR~7a$iIJ;-~v^p6<&<@`E=Q58m8$!JG4gH|Ga$&L5DTLH+I?jryI= zLH*8;`kf#3J3s1oe$?;$7#FveF)j{cT-f9npazlvWb_9!jr!H{`6~`#aB%{SFQ2){&V_G&En@xyctkB z3-PaO7C&X;v9ULLpgrrG#TQNdnrO7{Z${lO()bRVI`p%U5Ua+hvYh>X8uk&Zy~XOV zWdpDkiR!#OmG!4oL=Xtyn0tx%*6|7W*75q9{G&DBI^HyrPH4@yj!(e1j&H*^%5fOJ z4Yr)-?BA=6&0T88}HC45U+Bj32UC*oVjC*WJht1d*2)_m*u1bplG1bplG zHhiNThvC~`;oCg>F?>hMkiUsr6Y#C$6Y#C$+whHY z9ENX$g>R!Z4d2l+r6Y#C$6Y#C$+whHY9ENX$ zg>R$b4d2l+Sb$kN8b$kN8b$lDXQI5m#ZLsid zK64wsqh-k7Y0BTa4s~85-}p?Ph;JRAfNveIx)3>9^R43(@U7z$@U7$9@QrdDhHry~ zZ}Tj}@Et8f{wBVqtdZ~WgnaAx1bplG2-nJJ&9{zEz_*T1z_*TX!#B!t7`_b_zRfct z!*{d{`J4EbvPQlSB;;GiC*WJht1d*2)_m*u1bplG1bplGHhiNThvC~`;oCfWGkizO zkiUs46CIy`Zyg`uS{beR*6|7W*6|7W*70rlMmY|{x52`nr|JSfNve2fNve&hHsSPFnk*&AUj$ceD)oJ4^Xn z*P+g9!nb*MZupLtA%7F!Qr5`# zfrNbP_ym0Gc-4i-(VA}^pMY;2pMY;2--d6L<1l<1EPR_i35M@z8S*#rEoF^-W6wgO ze4^tM@U7z`Tq~nB-#R`4-#R`4-#Wex-zdjn_%>MhHhVn`-_bJU?_SE^x(;<-Bj4By zl8A2|pMY;2ueuO9TJx>r6Y#C$6Y#C$+whHY9ENX$g>SQm#_%02L;fbdrL2+f@q~Qq z_ym0G_z2g^XwA2dPr$d1Pr$d1Z^JjraTvZ07QW5iB*S;K4EdY*ma;~^4B`7(S*%aFf`Zz*f!8+#uUPt#f9EKF>pIkVjeKM8Ya+gNd;-38 zyy`;aXwA2dPr$d1Pr$d1Z^JjraTvZ07QW4%VZ(Q{4EdY*ma;~^#}o3c;}h_$<0D)v zqcz_;J^|l4J^|l4z75|f$6@$3Sok*Il`(ur%aFf`Zz*f!`#?gzb$kN8b-e0A*e zj!(e1j!(e1j&H*^%5fOJ4Hmx5ccKj6(K6(3;#!nfH2Z}^UuA%Cx<{H^Oy=QZ+;J@Se8*6|7W*72$fk)t)= zIz9p4Iz9p4I=&6xD92&=Hdy#J-z_kFN6V1EiEk-uY8$ zt>Y8$t>fG9jdC1@Z-a$z^PLUDceD)ooA{QpM!pXur4P5YkSn9ZA zb^q0VTyRaw#Ft(CZ6+Z0bN}ick@%oHtUvg81BdF=^6GdbzG~}Fzav(&G54(Qjl`F2 z{n=|x>z`P?JrciY>(9NXY5n_Fe>DWgB0( zt!aF`{Zlr6<13BQGeqRpAYl4{((CigW-wKx1y~-|G}p9 z$LI5ut$*|Do7Nv+FGUxx)?4%SsP<}a%V1n_sI^}Tv1*Y14g+iqhRGSRvK;I}SeA{I z4ZwC9Bv!T&wz{IaULjVt8Mb;!r^<@4vfZ%Nw<=ZHPAao`$o{tZB?xZD{uP|CMP03V z|6}jYpi{pgXL;sPa)Z=))SqZg;ny-@1BdWc`#~eDnNr=jvM{@m1UY;2n*P zfhRscsH#jAY!^6PQRwrAw^P1_S+??o5ii}>dGB+REO>*zd%e5$b`D9oq&JBTWW z1+g;Zx3tZt$ZwJJkZaZ5PS=TC8!1DsmHlP0GUVE{&6&uxk@Jvi)0Ar?Wg{qiZFs#c zvGXQis~2&q4`nKAl7I335`mrP-!T3*oYZ*4$0O*z*~E9Af5Z5W^RJ2TJpY>b&hxK{ z?>zsS_|Efh*#3`$%#QMJ*#6HpjgRNAaw_D%^ZXmO|Cy%s$MaX!*57&lHT8F%e@%Sn z`PamEo`1vmj`MHWo(CEyKRiwHuZizG|C;#D^RJ2TJpYFA9p_&Y-+BHG<6k!ax_tu3 zzZz5i)!#7>^KYaK`8P}XH&TZDo2C34DMS91{ROe>A^&D6|3=P3{>@VUjg%q(W-0$h z%8-Av$`R&YSJou|;`ucKJI}vie8>6M#CM*5!}yN#uZizG|C;#D^RJ2TJpY>b&hu~B z{*Lo+*#3_5Z`l58805zM9@mdkshh+0cbtDseCPSs#CM*5O?>D1*Ti?8f5Z5W^KaOm zj`OdH?>zsS_|EgMiSIoBhVdQeUlZSX{te?_HvhW!M99AyQ~uR|vnI^Hkuv1p9Od6g z8S-zA@^7RJ`B&aA#jc0^o1^?2IS=_aNBK8WhWwkO{2M7l{>@STb!AQRFZN$c{*6B$ zX!1NXjPE%An)uH1Zy4Wk{x$KP=U)@wdHyx=o#$T@-+BHG+uw2i4cp&w{tesTasCb4 z-*Nsm@tx;i6W@9MHSwM2UlZSX{te?h&c9)MI?lf)zVrNR;ycg3Ccg9h8^(8>e@%Sn z`8SL=`L|g<370SSBW1|H`iZML56>SWWyrts{fJl@ z@^6OnZ{$4W-;8poI`OPGQilASq5K;uL;lTB{&i(d@-Oz^CCa~He8>6M#CM*5!}yN# zuZizG|C;#D^RJ2TJpY>b&hu~B{*Lo+*#3_5Z`l5h^KaPxj`OdH?>zsS_|EgMiSIoB zn)uH1Zy4Wk{tesHasD;&o#$T@-+BHu@tx=2FuvpbYvMc4zhV5#=3fO8soo}7*2Qc+_z8}EEcfKDWj8{vx z`FafXqk83U^Oweyzx3ZW4f9u|3^}UH<}c)^NEvdJ{0*B}8FEyY&24x`6*&(%s*7?| zqzw78%jPz`FLPx!582Lrr`7y!jE}$1S+wz54>rcfpC>Nc_}mAZ)*pYL6QsiS=Re*w zKA!K2Hh$o}~jYoVw z6m9(jO20H7@%dJ?_2+vVgW*y0Ieh0V`~EWM0}i{Mv1ZrNnvIlU&Fa5jt=4)zb{^L3 zx|>mtD#MzMoVN|OT4t&Y&;KH2Bf$oB`KoGHkRlBK+R#5j{xtmg&|fBh7JgK$>)A>E z9Q=Kue>eH_@V`3rZzKN}_`!v)Cr$ozeK^2IO6?z58FpFk z-F3-dgug$GpCEq$e#Zm(H^P5I7{8zV1Msg8{YS{3u8$$}n|>8n#$3O4xA14-zbTAA zOz}tHm-b6NlkiJ>#D5rmH!f7qM);+_5?_E{`YZk-{5OW}xr^#a*Y^fJp?~AbUe~Yv zE&N&drC$uU8zqCjE1^A`E;!oEP1z4?mUTs-9YixUNDKdF_~p71k9pfA{D^-W{Io7y{gd#!^+?yneC`q+ zq#n%MF5y%Bn73UrAHPIiGMfz!khT9?x;QD$2ukc#eW2T>6iF7 z!!Pqq{8+!lkNB}pyIvKJ%jT6suD@I0mvte2tluulKjNQk;ok_q%uk8OdZ+e_zXZSV zDgJW3o9+r+%SN`Eid{w{JZsagP=ZKi#99 ze<%EobBf2kJMHES`El<~yPQCN+`H2*hmarl?zCGAeb5i_=;dkRg^&rQlDJMHVkzeqnQ!7pE~R-Ze&kXb7x7QRFY`zICHP$) zSP?&RJB^q4k&}s^Lyn)jTKGrcm-Qv_$kk2#hvAoXC-KO=#Dn;8FQ9gcAKHxg6hHD$ zMtB%jk2Q3Tf(FY_UUGiqpQiqu@KZi<@mQx#{m54tTGuWf`KqZO`5_}bNIQ{dGA{qG zh#z?-BRq>A`6NSm(p?vMFC*hF@yI6`Sx4eWKFqlMPuE30%*gzdc;p|7A9L3&x9~&b zsrQh2ET9QpJn{zdBYxzcrheoT;z8n}&4>r_sXaW4qy( zd@laG;FonF{yhA$zQhmhNB1f5ABNxQu@&({6Q)TMs`e~uefY!fG-*Qh%15seXhOlk zhOEm8PK!D zo+%#pl&q{BiAPS(l4f)5M9vr9s2=2Y85i>7UXZ1n@9IHL&dM5>>*8J}^MvX_t|mUm zTs=Em_>nW4#v>cp`{5_8=&lPbN4!Zr6Yxua#lHo9H_unZk9!A=m-wOm zh#&Fe-a+FcerVCGtbOt09zpX*{J2NZd=o$J5o)iwo>zsHy{^9#E&RB5G>ykSg4!?j zAcr^g<8!^Nce*ZeJB^FfgL_I-KQtlrOX8t9iGT6qo<;Lb{I~}ZZ{o*2i^g62xYtm7 z4msX%uc7%Pe%x!C`k^hG`tf{#`X%*1yHdZzk9!TZQ~bEs(0mg=@>?&hN2Fde2av~l zDgQV>@;B{K$K~F3+z> zJn~zwyC0Ds`K{O8FUXHP)+_5*>OtP?rF`qIi~QE>?o(6`@)+?v=HjtVsXgL{<|N+4 zk381Yk37?hN;RKbRwN#Isi`0NhuSak$TP&J_>os>K8PRrhj365o5RVv z{?f{@s|Pt#+E4zS@VoYtAGuL|KS9?64e9EcXyHeW6`m;`_ktYdKvxfPrtm}Y$eA*Z zqO)L5?Nf#$0>0weTaSHH}A(CElbS2~uF_gtEX;>SIg@__h9;1^9Re%y;`U5Fp|)*Rhi)pZxcduxvFt?oG(?yZ7@4f3pv z{J6KuGb{4r-kPC%tE&h1R(Xa-@wm6jvp(|U-YU-?$&Y)hJToLe?yc&3DSEEr-s-Lk z&gmI=xATMZjO1kTgF||TEPm)2;bBGmo8gzWCVo6Cqi2=kpM+o5xcD(f85$$iPCG^! z8Y8DCF-C%e4WeDik1-NWNPdiwXnyizjO4Qk`7uVKUCECzlFv}&#~6vmCO^hVZ49F&4tZiuf@Wy)+i8J$5X5X)Mqc z(-(||;9!I7#~?pAm;D3e2j{XMgZ$uJ_HU3MoXb8C@`GD>?@#`TdN=Kh=yvVI{G@#m z;@=Oy*g&d>4rK|Pg;#b;vi8IH&GGO_FR#?J4Jo!=Wfzc+S1{$u$-^QHc-ndYph?`3Ka zS!nBfB-#4jPPW!6WNU3iw$^%NYYj}c{wzVZ{#;A8{ya{$evUx4ejY=%ehx;qe%?p6 ze*Q|fejZM?em6t5e%C~{ey2vZey2#be)mhZekV@0-YY=1-lIXb-p@m}-k(Ia-iJlD z-p@w1-v39o-k(Ue-iJxH-dCz^47olgChyh1Q@CNO<0I+w!hy!Z;#zx!8a&z>n>nYnQB^!amd z85(_4X{b1J?)do=r_Y^w%h2UZC*Qbp=vV%A@9xTl^AF4%zx1zri^biQGt-w&p1*Kb z88A=GTseJw#uzYs0<9v#2q_MzgL>2s$pPoIMC z_)ziEyDI=EDwl_BExO{F*-JC$PRyKmYr^sSr!N#=-?9PcTDAb4R4v#lE!f5+jJ_NRh!zsYwzeVR*m=~| zI0_*JW72@gD2(C)ol$V*{OJ>|88~(x7ixKRT%_p$jP8AM>kqt{ni#&AN!g5uBQ9+x#KgGhg2G(9I^WrlU!`p*nNv6vfZ~xj@x~U zq(5Mr7H$5=vmM+6Qm{I+TDnhXcBs``>oxuq{!)UEHGc>bOG($M1F?fFpbF+H=P} zNAJGl;K8>YJUTIcc>L(0!{Y}J|N79y;ojw}g`i5@%^`W!V51hX+bQ`ko$k5r- z=QJ(>SEer=zaRe6(0fOQ?w^@HF@vaIAG&+`)am1J&mKQ>?DV;<2t0K9)Vb+PmoLoR zHFNINC3VWl@Ic{PXWqT%%=zQLMqXR$fB(y30JGuVbEn^RdFGA@H5*FP)3?s-m@b6} zN)MktJ9FsL^w|oEM{nJ^W5>=Nqr21$+c%@<*TM5=IYdp;w;KtE6Yjf=inhK<{Tkg4 zJvTCRw-P*R{*DaYaqiO0g_G0AXYRdMU))}_)o+|K8Opu4@44sgs0E%Q$It9JeJ-qF zbady|TX)Qy*tX;N^vUV%V<&IDb;phqGo|A@PVSmHxnm6R6EnvypTZgHY%HOR5R#B= zM`bC!_4K(DDBOYAdmt16&(54Ze7x}A(l3m)|z7tku z`rT*FPooyBKMDS51S5S8M?ROuYK=#lf zmoLt!2I)+2R4IYC?$MVTRXpj4OVg*|QE5q=$EGjN91U-3I&zy~6#Y$ljpNZvsEqb9 zm-x5ueQ!Hj$5gjNUMtfVE}howgVl5J6Rl%oibzN6*3#Iqoo&a9>W$X4wY1}8bcnXK zuSs1vY+<~n6aN>)gHsp) literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..096bf56a1246ece7b834d42d83eef3a970cac61d GIT binary patch literal 4208 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..65ee30f4177c2fdbd68754e2d11a198daa4e3fa5 GIT binary patch literal 4208 zcmbtXL2lbH5L_xsY6J$FLk~R!s1ANWeo!BL?4duX4}L&@P!;e4`h**_oweaqZ2*iTo7&--+PT{|)ZuVZ7@6FdUnslfOri=6J-z zIRC~$p9>H0)MEa4-S9>@Uvd2Ef7i@h&39$_CJeaJx2_BPN;9ebJ*upd-Q?b=N8d(+lXAPK|8nw zh0}Aw&>=Jk@u}ywtOY#RCxB|t?LsYB#tcKz;5p@s9<%#g;@f>-=4!qx%Qs;t7WrDw z^)vbIEBV?UgXcWo4s~X+&e-QRfiImwjLdUh-?Ha4R`A?1dhSm|s@9+#+>*lSIbl$P z5T9xf&qeJI3E&*hDIbD)G&)tqB;?#IC z-W7oc8Xuo9-&M2nLi?(`R(tfl&)cEzFVJ8U@^UIMr~%$Jo^L?|ylXUO`yTxlYq3uC ztJYv=YLQ{62IxP{Yx}RCnRj2Ax6lVs1Brz@s}DjQm7WlTQ0RjH7 zMGg0&!vz|&gVVO;)C@xxiM=Sa?a5v=EAOf@FZZGztGUw^p<2%AcV0GjDURh%;`nqs T9cRzux56Z@<1CJ!xQPD;!-*k6 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1216.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1216.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a55636bd00dc7433cb0be50807ae8dc4f6702c44 GIT binary patch literal 137550 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..a2f77098d1913410922edc68197a6532e80d3620 GIT binary patch literal 4208 zcmbtXL2lbH5L_xsU<3x5Lk~R!s1ANWe-I!15Fh-2{-7%0hxp)!7(ov`3VA_)q7GLa zl3KGV9T|uuYROs7?(B*Y*FLPA$alftlL#KC-{2m;`KN9ghHEoA`8|p>{p0nji9hEH)t)L@)T&SUE5?eiPq5uBzq>zj2X1Bn%yrul2iK z$ah!Cw=sP8^xKJKTdmgIA^4>bh(XP*sH=kJ*1>jnt+`h9?Q@TPgBoVB~8xcUs8zT*>#| z@ZFMchwY_usn*;s@TKO6LCp#CThJW(oaP>NVEf!EYHq7x^Ox!zw1b;>s)V6n$U(5r zHMeIhVC{9LUaB>B2(e%oGYkcS=9DjL%=Wp&_o7q%rJC=?@=X{DM!r^a{X)LSO1`$n zpt*@}hd47>;9L7`-37kX95FJ@P5CWrPHhFvt)u4l8a98a&Otl4bzJ2i_Op@ibHP5( zJv0|{e@RPj(VX&O7&8n-gXYv;&|KpCCpxa?3(d{>CJY55--6~A@rCB9_*%`K80QY# zqi}A}+}UW37}OlTt-7z$c@E!JwW0UgKKB?k#{{Aa*Pg4Oxkn%DxHLZax8gOYc0a?M zs}}i1?yLOT+@tO%za8rS13B0Qzg$WT<^bQCiEp{?)n@A+^%rBYP4TPF!NJ5L!_XX{ z{?xCnzkZ?LW2N6h9mE_+3|xKhJqN$c0Wk=LI{0S}PzP$WbpTz&Uetde2hfG~A}-A^ zm;<#J&fAOpBKK8(3%Q^C`Z{3XZsyy{KU?x-gKp^&*u7 zmu48cN%W#1nX6v3$nR#DaR29*y{N}-o^(fumUDW}%f>F*vE7*+N4M*7Hvit(b)4Dp IFD};q1+Ezy761SM literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9562788b07a0b26efa6097f3e49ce63daa1f31d8 GIT binary patch literal 167758 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 Yqc~pO&d;;^@%wZX*Yhln-x7%b2W5XH2mk;8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6f266698a3027a12a1ebdf6b54829f540deae102 GIT binary patch literal 130382 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..aed546861a1fdaf47de7bbd56423c3961bd69b33 GIT binary patch literal 4208 zcmbtXL2lbH5L_xs;06YoLk~R!s1ANWe^4L%h#r0L1NwuifFI(6{}H3eAx9%G=uh0y zl0#B!CZM7Kkwh)I%h{P-(c;>>g%kND_+D;7vDr4`5yO{HgWw|jI%xYSUb@}Xnm zwQ<)o@op;dHU{sOaXXRT?|8UYYi<|fQV8@x%`K>_g65XNc5|({R`oq_zm55<=Ab>h zb^sCok`H|a4uXBmea~DV?m8}(YR&Bp2bmA`_89QCh689l;r*ww9OhT!U0J-zhsGsd ztGUBWyvItsw+8Q;cspz_(p#^&O~6ad(FZjrY+Y>J6Gxyr?nT=Mvs^+t^b zAP2!d<{p}h+@H91n&uP_)0p{CZ_u3D3z|!K51$x$isr_6lMnR;&8fYhxmkFjxhlL? za|hj1ily{IRk33UKn zgkGa5&%Y_;K<$O|_N=(O%D4sYecYiAn79eO2;2ue0dMdTU4`CT>P0wn>00Q*_M(Qp z==1>&+OyNLv1+8 PzfVVY9cOm@mVo^~YbYh` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3fd8e30d3334fe13a7c72b461117f39f48d26103 GIT binary patch literal 125774 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 U;BuTikKd=0xQ>%Je&Qnj4{NL@&;S4c literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..39dc4093fdeb6d450f2bb408af0817a56e911c84 GIT binary patch literal 137550 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 GvHve$hb6WE literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..49c01c4a203223e8e0a1ebc784bb974d16a466dc GIT binary patch literal 135502 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 bnYcG{lZ@Yv%mVy7r#{}*;dj;pk52txN6@%7 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1728.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1728.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..cad7daadf15fda8c4077da52cad548c0999af43a GIT binary patch literal 4208 zcmbtXJ8s)R5Z$F{LvRE{MT!&#!h#3L4WdH#hzgY{e1kB64&p)w@DYR{MM}XJQl5tM z_A^>LOE5r0E_e6MzIktkwDax#(mVI$@PF+bZpVLTfB*G**NsE{Z7$yZy*SrgE?A7~ zFZ{?lUBF9={nz`35A?d=_;s9jAMxOebB}zEYs)$3htC)%XBuPuNERc+_l5fn2!?v^ zOxZ>|`1Hz1-lcIn<|2>lk%vE*Z?5_2-p@s^xgdHWuH?#tsfio;o@B{&Yc*fQ%|k^D zc}~7I?q(+6Z6)8v@ZB+P=iCraUhTQP#-$O6LC-DetAgiNI=8s>Tr2**YX1`QS*<~P z_HCq+VaQ`>p!2!*19O46n+Qo|!E4^$DI6KJ*+hf>V_58}C-#d*iuP@Z9=tvIg+niksvbF=Pl0 zbUxP}o(tNaBES^SskYT;zNHz{pcPm-CGnfOmfe4 z*f%F`Um4eGkGdb@LW3bBa#Gz3A8sWEHNd-OO0elg95qmk3SFOQTdoSfn zFsOm_s>1j7thmr#aQ_##p#2#4S_e$rgkA*gm5qVXe#QJhTva4y literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1728.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K1728.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6a2f3fd40c9f46fb78c66d99a1a9430915d38a38 GIT binary patch literal 130382 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

--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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..eed41f9256d5a7d28bb96eee6e46ace3d1ec2019 GIT binary patch literal 4208 zcmbtWL2lbH5L`M;;HEB`Lk~R!s1ANWe^4L%kR1Gg{-7%02jmGk_#sBoLyty2r#h!})6;m(RHIP2`dHF-FEDv|lmL_SENk&K^dJUs3)5f~nry(`cce ze0gQ2AbH+~wHW6OsKeju59F8kYq7Oj5WSFBYZbuM<<0nh;IeAI$jdc0CJddEug|+% z$ai1Kcjfp#F>fQ%+Kw?)d+uO)X#`@>b8Gsl;JJ;(Zl<1#>hDhb9g$~wE)G;i7PR_Y?@?4wBS*=05gf)fJalp_iG_d&Cb5E=V zJl75Y)t)<8Em+13L($+lC4(OG=Um436Ej!y-A?!>480YQZvQ7>WkZDc^$UGQM4*^sk!lcEUGdC=mG;JhzDNv68R%+zad6V0$#q z49}e`Z(3>>^c>!;Z+Z^zR*m88^`5&=o}+*>w2zl?-xWJ8O&8r=5onz+IDglEy}yC%*(T=#cm#SN2pc^`kj}}!w|=IM{#_*P3PJ3w=S;pERJsq Gtp5*7d?;=J literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..29ac688c7c1c0f468b650d8aa5876694a0df473e GIT binary patch literal 135502 zcmeHw4{%(^ecn6ZcsPR>@@T{AStOkUz&fnL*arfVD20j-B*aiMB_IFD!?E4L9}=LT zkieM)RmvH~C&x)#+mphrlR;cNh1+psJ8Fu=vEwLldrI8Ib(;<{yTA9{drRonrK@v`OGks-{^-d- z=FgsfBEa$JzCQI8SX&$VqwlqXUpe$Yr-sIV{Ugt1R{q_auRQSc$DWSYJP`RekOr>3vXF6xpk)7;=<7+1!3efIjw;>zOkl8Ra~1;_f$_ZR*mqd|C@anfh& zFHQOBUB;QGGKRv*|=VjPgUPVj8XFy zsZA>RuYgnIBm3U}4;CK#kH7VqUkHM%X6g|9>Y5W_=s#(EWhjLD>!GPytz0YzVYj(R zn2vZ~+PHPs^B+~$b0Y;jyEs3+cy0E|yqtbOpdht~KX&-OgBw^Wzk>hNHy?J9t3k(_ zal_3qFBh-<^k4lSHEB*xy%kpof={CjdyjA2-iHqLWw6l7=l9sYDZBXfvwPG$)&IdR z#q1zv=gC%es{eLnZU;};$sU~Blg$Kc*bPK5p|!g| zxp(ccPw!nj_`7@8e(qQIuKm$(?p=HBC-$y=?sI$Z-`BY3OPOHfXTA;e`Tq>`E8lst z*tqBUOyfIWM8&H7k268#y`%8{>>p(s2R}5>7XbgKKLq~pK)=F!{vgxXm(BdiZQx(| z_rOD$yMlLOX!d;j-I;vQc9;yZtR*X0+^_SI_}!Az!D`cz=gxx>~I);7>r zEZxo&*Y5oMt4ntV#kGAyd%}`WRoyxEI^E7WWY76q+TNd-`N7~{PXwO|-k?U$9BY3~ znSS@zaC6%IkNW0<`=6?99Qp7am>;iv`%CZo$$?UFG*~+__39GMvCEnDN#u;9?<>A9 zQ*D@8e&h|$?s_IzJMcTN{%-NlbB%q6a({B$&cSsz2eW#vmp=SHtgF(yKBzva-XloC zv#6tQU+L%xRrf`6uPY7Y_pLpf-S^JPKYif6&C=PA=(E@K+QdENul{Z8_IpYL?<=l7 z+bFIDzgJxQd3@jTJH@rv2C9}?IGFmY^t#_2C~bdnp!A2oIZ(RqV*{mM{oFw5!@oLE zde^@iD4qTEKxyogSofb8CJ0*9qo9SpV11)K`C?wL_r8qc`LceE&}(liga){plCRKluLtU6_6H)@JT~ z|NP$FzxbWPGtXUL%>}!Eal7z|uRim++lAq;KJ$08KOB7i*34(oMV)KcUVAXJcK5-| zS2Lqu{Kw_5KJ$ma_VXi0e)#$qe`oZ_4?pq6-y41MR&n6je{uH*8^7`1@}JjdHiF&n zF8`f>^V1`1SMr&)KgPN5I5_a)`trfj#Ooh;v3&XU6Su$dfuH@|shR%)E~Xm)3!`|k z|9I(Q|FZ{g6{Zee95}N7)`#Bzx?AI$2X2j*UN<*;eq`asg}%AjpE|T~<72@>=IH2& zf#X;I@+Us{rnyYEyztqtX6K$iJ$!2Sv%BV=fA67FyN?HRnZ?nC&mQQT%k-B|?R^&K zjt?)4KbD!B{fCDZ#t-(-Wv-8&+WXu1&X*T%{84u96NiRR^?zyC+$TPSYka(K?uE;v zr}_)Q+zSQNug)7EJ~i;A{<+x?9$NTpc>X}4@9mkv^1b{2;B()}J^I3-;m=iZS11Sd z-x_`Rg%2H?`|K}V|KvJa!KQ+q%3&0_`CnuTwF zJaZbg&1LQ$In}Rv@H2-_^`l3_E5i$gDSYS3rv{Gn|4m_LcP;qM|MEDdtD4`)fV+R- zRiEDVjnKyZ?NKmv??3%}imyh0(XupWSlVSdQhb9Wuptbc21BR8&S@}n8mwTJ25Y&4 zyVu@uaQFSQL2)CP*j&A|_Ad|YUdz3{u=WQ0mpg#(1BKG=^3dAVi6N}w^}bDY9?q;? zzhkXfx#LJsK6K+RO0UB@+V^~Hy}pR`I<>Wp+4@}Z{lASbsOA@xa{hw!54JhN{zmK| zqt^Sa`_yj~DaZXjXlT39r^_3MQU01h^QGcHnaLLWB;M4&dsvrCMnTpKimyg|RS6+9kARU2>hg}O-TzGj#Wwe<_&B$B@r zAFTUSl(Mbvv$oZJ*0#FO+ClkbOh-<}bY#>Hz89yq@%W(#!<&>Gh<4KIxxN`sb5>-Jjfg zJsD>0?`b`0^quOd(UVcz>OWg<^`Eta@@Py?4#)Il)DFHLwew{6){`S%Pb$)Jcs=R$ zq?rlk)9XpEC%vBZdeZAj|GwMa7k2J_x6ya19Y#+^ZL9xmxz&Hx#=glyMj1HN`PesE zP;agEf9Cyp#K!ych>iE>&hD)z&lRx$&+nfEw_Zq)OCy`J=X((6gDC+&S<=bld*J*V2i`p?={|5@AWKWk(EWK2(vIelpA zi`sa99x2EBb7%L~lSjRtRHWnZdeZAjGZW0G*OOjPdOhj&q}P*PPuly!&gn^`=Ttjb z|5@AWKWkh4XKn1CjOoc?rw>hiQ5)~iBjtF1?(E)ra>VONMLG_zC%v9DGr@d%J?ZtN z*OOjPdOhj&q`fcfoSrm#PPK#epS7+2v$oZL*2ezH!Px%E!Px%Eh>iE>5gYH%o!whc zo*VT0Cl%{nPyS8)dzt?41)2G~c8C2-rT*_vDn|U@pY(r!5`W9m|NTk-_b0y>{{E!a zb1JVHJ!$lvwXOcMw$*>u#{S8eo}6_0(9{>T@%}tgj`!!z?yVGFouP4n+FrQvedOhj&q}P*PPkKFR?+ZJpCyky{?O^?9 zZL9yRZS|kEv41kACx@LrH1$Poyg!eWg}q_vaBC@6VmxTThu*0%c3+E)Kr z8~Z0?dUDd~LsMVW#{2U~Io_W;ySJV^;q{~<9fyBD>7P%UnP5J>p7eUs>q)OCy`J=X z(%u(#?)jwAbE+Mz|Ez8GpS7+2vo`im#`NTv(}$+MsEzmMk#f90cXn?*dDQDkMLG_z zC%v9DGr@d%J?ZtN*OOjPdOhj&q`fcfoSrm#PPK#epS7+2v$oZL*2ezHn4TPV`q0!D zwekKuQjYiM&hD)zN4%a?q~q{<((6ex6U?XAlU`4HJ?ZtN*OOjP+WW%J=}DvKR6AJz zS=;JAYg_$iZS0@S#r99;V*4i}Hr}5{Y`i~rc5gj-F6Z}8D%QQ8^!q3M{>jF^L%Bb> zZPr8SQ(jMcJ?ZtN*OOjPnvA%k`zN)YQ|&N%(&#&DTm5HktN*Nx{gW|0IqCGFsV{2d z{duGu@6VmxTTh&!#|(&&nL}HFrWVUq}P*PPkKG+^`zI6_P(%l&nJzZQ|(~= zXKkzhtZnt5wXuIPrYFaoJ~Z`3ZM;8^l;i!mvwQ2wqh3!c(s6h_>Ghq)OC?R{bA^rX>qsvWHVtZnt5wXOcMHug`(^yIM9ho-)$jrZq~a=brxc5gj7 z;`O8=9f#MGUQe2tU_QN`^m@|kNv|ipp7eUs-WPUGPZ~X^+QItI+E)Kr+v-1SWB(+! zHJU@6U;O&nY;6Bz#K!ych>iE>&hD)z&t?7oNyD?(lU`4TOHO}zJ?ZtN*OOjPdOhj& zq`fcfoSrm#PPN16$*67hpDnlg&)V2O8Pk)KP9K{3qBh>2N6PX3+}XYLG>Gh=7llH!_b9&O~In@rp7eUs>q)OCy`J=X(%u(#PEQ&=r`o~# z&)Qc1S=;JAYh(XpOivCweQ4^7+IW8+DaZSBXZO~VBVJD`(s6h_>Ghq)OC?R{bA^rX>qsvWHVtZnt5wXOcMHug{U#r9A3#r97|Y`i~@*m!^L?B06v zT%X@RsaW@V(*ONQ|Mw^T-=E9`=Yr?zNC!x_uW5Qc>Gh=7lU`41fq;*l)00NesdgAW z8MUqcv*lL*SsVK&V|sGZ=|fXr)W-YsNIBl0JG-}@JmK}EA{~c+KIxxNnwele{qsrx zeA4SluP42p^m@|X7j{lh8a=1l!TQhIR{vSs>OX5^|71*0jyZj3>WkWVe;z5v`*Uaa z){{rQo>Zjc@OskgNi!47r`MBSPkKG+^`zI6UQgQl!p`YQqvupRSpQku>OX5+{bz0L zpN#3rVW$sGeNh|l&m-k{f9~wwdUC|;NkuviuP42pG&8|`dOhj&q}P*PPkKG+^`yNo z?3|u7dQP>2^`Et^{=IE%`lU`4HJ!urej_#k-dQP>&=t-mR ztZnt5wXOcMHug`(^yH+|ho-)$jrZq~a=brxc5gj-!s|&zIu8GQ(m$UxGr@fN=ac^V zq<=o?^`zI6UQgQl!p=RPGhl09CP~6)EBk!{yb8S_vg;; zttXFqJ*h~?;q|1~lV&EEPp>Dvp7eUs>q)OCy`Hr9g`LxrM$f5su>P~Q)qmEu`p??f zKN-`L!%iQX`l2@8pGV5^{@mHU_2h`xlZtd4UQc>GX=Z}?^m@|kNv|ipp7eUs>q&cG z*f~9E^qgu3>pyE-{by~f|CGHC8z~}gK(4ZCgCl@tq_OnFV?^DSpUYTe}c;`!4<+)!ZpG(gzJPG zgjWf#6W$=)B)my@i*PH%;rfg9Z#34wVd|gYa!YW9aFuY4@C@NP;RfMV!s~=L2sa6D z65b-*3URpp24m|_+jh+bt+Rs`7YUaMR|r=L*9gxLt`lw$UM0Lvc!O}0@Fw9c!mSX8 z>o3;7ld=9yQvU>(TY@WutAuNWX9(8`Hwdp1UMIXkxJh`E@D|}#h{N?4>)&{+e`C}? z!R40V3gIf@8sQnjb;1q8tAy7HZxC)0-Xy$5xE11X{l)q>8tdOM^-plQCAdPkO1MUN zhH#y5gYYWhb;28jn}jzBZxL>VI9z}E*!t79U2{R}Y~JD`;WFV0;VR)8;Tghp!VSW! zgx3jg5N;CQB)mnq72n|5uf7-TdE@++2SzIJs zCR`z0C0rvsL%2@3L3ow$I^hk%O~RXmw+OdF9In4u|4zpGH%a{yTy6=j5Uvug5uPDj zC)^;sN_d^{2H_^*O~PA*TOkhDU#x%QvHp!w{{)v?f-8ipglmLn2-gWW2(J=eC%i$p zNqCd+7U5Qi!}S;I-)O9V!_+^)<(A+I;VR)8;Tghp!VSW!gx3jg5N;CQB)mnq72>Lg>aQ{jqnWNI^hQ4Rl@6pHwZTgZxY@j+zPSj-*~Kl#+Lq#QU3&&TY@Wu ztAuNWX9(8`Hwdp1UMIXkxJh`E@D|}#h)w@SWBoI>^lzB@C%D`aTp?T~Tq8U~xK6l1 zc$M%v;SIt~!kdJ*2)9BUt~d8Lh1izz}cu zf5X&2!R40V3gIf@8sQnjb;1q8tAy7HZxC)0-Xy$5xE11Xy}3OpY)k*nDrncA!{wIv zD}<|rYlLSA*9kWWuM%D-yg|50c$4rJ;Z}%Ee@@2wXKdT2pf&0GR3uy`Tp?T~Tq8U~ zxK6l1c$M%v;SIt~!kdJ*2)9CP`ZpfypRuKXW7I#v<(A+I;VR)8;Tghp!VSW!gx3jg z5N;CQB)mnq6=KuB(OCbCE&Us&{s}I(1Xl=G3D*eE5Uvw$5MCv`PI!ZGlkg_tEy69r z)oR8)zpW9j;vJewEb1L#joz)nub)4Ke)sGNeyz(xztiOK>--h^U9Os`X56`T!d1N6 zlIzO*IQZ$hlkQyj>ALcp4Su@rq`NNq>&``g9j@Y?lU!HcjloaXm1lu?qCg5%b9Itg?=y#eA@p^rPezz8IT^EDvI*f6l>rT>jC+WJAblpk1?j+Yk*OeR!p55F7 z&kkc;=(_Umr4bx(ysZM;b&Ysxk36e_pV}iDemywg>fZpSdZ?X}^T3a58~AY;^|*0I zJv{EN{u;f@z_?R8haGR|m#YW;;(Dn4qR~+gwNr8z+T-d+dtCiN6^Q|d8uudMGOhOt zX;S#zyoKNO7k<}H_+2~Uck2Rv_l_6saqUNY+HmGfC}{JcD>@ zkK`rzxjn8Pv`6Zp+=BK{J(3?Pr1{E}PvDn&DF49E^$Vl{MSI+QMtdZlaunJ_^-ofJB+p>}PS}hxtJKNM3?p>Y+RaKeb2lA^hAP*I%^9)sOk(+JO1vFy@1c$2@WI z@VkD&PwkO>1wXZCn8r)q9S3NGy+0PIJ!SG&$X_LYjr=p@uah7Ba(zd?91f6U-E}G7 z26P`O5^n*GZ;{3~p!;l*<{|2L>!nD0Lr_2YWnH6w@=N|f{p6QC3EspHtOiES8Sv)( z;LZ8LoAZM==Lc`j58j*~^$S0|uE~%39iOP*#iM@bNBz!^`kf!+;^qd%#bNN~))#mq zzud1eF65W>h;bpm=p2j-`6a)hewW`cE-vq(e)7xx0`-$$?rW%D{B&O~(tWv1e(>hv z!JE4-cyoU6=KSEz`2*53sNdbAQNPnUsNeZfzw@Jh=STg{kNTY-HWbi(BvD zjr@|Az#I7`e}XsiOP&XBUa4Elf;GyrF*QNBz!^`kf#3J3s1oevFIDy%-mVF)orn zDL;cZ^2>b$d4~LxRFB-3!5jJIcL&Br<_Y}{!nlxMewSff$S=PWQNQ>}&ww{KUf|7* zJ9u+`@aFvB&H2Hb^Mg0---mo?k6k9k1i|KT5M(zsueMBmZ@oFYr&D~@#7jltN#A%+ z_Vu0O8z!Es*7(2wv+Nr?#jl%qGoW-9;@{9Ie#XROV{i08d+z8IUpDc(qS3m)Id#9t z;@^y^Lq7`%v1*JeE7*TehJD0pZ?QUT*$`|+qB^fgW&1KJA_#-ZFW>v(-l z{^-uPjyH{@6T0)Q<5Tdh<9qOpavX+lgDs~8`}ZI;-_f!mlnLKb*3S22O1^b`3chtb zF=t?RzIA*ienNM?b$klGb$k!LQI5m#ZEyy*ncpTCsxtMrJ=9^#hF}ZdQr6D**_3?i z_!NBWc-=Ps=+3u}SKWvl-TBt>Dfrg$J@`gB4#T&>meYd$d(4{eXxR|Tgl{Qp=X)4Q zD^>nh@hSM$^+&iGV6u<&i}-DZAA%aFhOgl{Qp=NtF- zRDA3B6nyJ=)rH8>oo^kVf^Qw4f^Qw)gKw1MFnk*-Y%Q z%IMCwj!(h2j!(h2j_<)Y%5fOJ4Hmx5Z*IePv<&$>OZi*Zq0VdP8^6g@@vY-i@U7!j z7a~V@zIA*GzIA*GzIA*LzEO_D@NKa0ZJuQqzN2Nx-^90+wevlhl5ZWKf^Quk;aVBp z`PT6%_}1|$_}1|~_(nMn!?(f0w|Pcn_>Pt#e-qzQ*3S3Ylzi*>6nyJ=)rH8>oo^kV zf^Qw4f^Qw)gKw1MFnk*YtHE2BH#Iz9#8 zIz9#8I=%6nyLW2-nK!&bN+F z!MBc2!MBd@!8gir7`_b_zRfdu!*{d{`J4EbvUa}DrsP}4r{G)1t1d*2?tJU`6nyLW z6nyLW9(*6}I$*6}I$ z*6}^~MmY|{x52`O$n`&bN+F!MBc2 z!MBd@!8gir7`_b_zRf#c!*{d{`J4EbvUa{FQ}V6jQ}C_hBU~$^JKs7!1>ZV81>ZWp z2j3{iVfZ#!_%`p(4d2l+SPb!SEd|L;fbdrL3KA>{&>aPjq|=zIA+rYh`rjTgRv1TgRv1TgUg{8|63* z-v$fcX0M0gJ6eYPJxKXm*P+g9=No%LQt_?hQ}C_hRTm;hcfNIe3chuG3chuG557^3 z!|-je@NM?c7`~%r$lt`bl(q9cnUZfEpMq~4AK_XV-TBt>Dfrg$Dfrg$J@`gB4#T&> z!nfI*WcZGjA%7F!Qr6D**_3?i_!NBWc-4i-(VcG{pMq~4pMq~4--BMhHhVM; z-_bJU?*ip-U57faop0=YO~tp4PrDfrg$Dfrg$J@`gB4#T&>!nfHo zZ1|3rA%7F!Qr6D*WJgr{G)1r{G)1_uw1lI1Jwg3*YA7${4<* zWys&ex0JQ>eKsZEIz9#8I$m`la&+fg$EV<1$EV<1$M@hHxK>7YzIA*GzIA*GzIA*LzEO_D@NKa0ZT`)M;X7J}{7rmI zSv%inQ}V6jQ}C_hRTm;hcfNIe3chuG3chuG557^3!|-je@NNDrjNv<4hWt%@OPTPk zWj$)X6ZE9?URxCs;xi&T*vySZa)}_Z`%3`@9tRtsoOsqiEr5Y zgRi0fqUL7+99e!QZ&xGn>oz|7t&Z_0Z=Z<7H*I|WyB*^nyge0(-?H%q_0M72+w-Hh zPetN`Y{-A{&W`c%_Lpt^&|Mwl$&WM#2V3)$Oe5`B;w$mW7vIDTy71i}hv9d$3)k`{6R*sb& zhpqlqr7Al{Wi}7lZ<}9&;7;sc!3l@e)jIb-mXE^t`w`!M#Q6>S!}`lAALWC+SVP$D z?$+~LZa*AZKUEjsIlnx7`z?|9hHZcF_V&iW6Q3UqTYpyNm-Zt*|C+Y`{JYzO;fc@h zrmerA@=N;>&v!v4;TfVUI+0S&0Z_5`pKL1?D__lmu;|pKu7$46U4I5wl zTF3Z!``2y!(6>6q$J^hu@ulx}jE}c}%f=u0K*#ua`?u_P9Z>g=_9H%CTXsH_o@ft- zCq5t6ZT&+k|F$3T`L=HBFFxEJ3{QMM&)E78b^-^~6DxbdedYrNCIdWIW_QcnF z*~JeczH>ea^Qp=@I!_^=YODwf^Qrzfh$@E#u`=Yhtj(v$Z;|tmYt`LO*NI#kDMPN6 z{bjK-`|LT8Z9_HUj8S-zQ@^7RJ`8QAbH&TZD zEBgy#*F*lzQ~r&dhy0tT{2M7l{>@YVjg%q(=9MGNzpku9{>Afa1SZeFVSM8JYvPmV z-!MLL{x$K*^RJ0do_|ez^89P!ljq;C{fYB$*#5-%H*EiN807Z+9@mdEnLESwC(gen zK6(B%@yYYAiBFz?O?>kF8^$NjzhQe4=U)?_JpY>b1q=Y=7eXYvPmVUlX4^|C;#Z`PalJ&%a@O;`|%7CvpBY z@yYYAiBFz?O?>kF8^$Njza~C;{te?z{_T`c!sibvt=Z=f8dLt&f6FJ#zmYQJ-yG%N zNE!04e&VXm!}Eto8S=0E`-oT>@^6mvZ{$4W-<)!&I`OPGQilASqx>5wL;lTC{&i&? z@-Oz^rOLlyeB%6T;*;m!Fg|hqHSx*wuZd5de@%Sy{A=Qq=ijjXiSuvR{>1q=Y=7eX z8@4}j{x$K*^RJ0do_|ez^89P!ljq+sK5_mH+mkr|n)u}T*Tg5!za~C;{te?3=U)?_ zJpYFAFPVQ;fX%-eQ~uR|doawukuv1pLCU|8GUVUEJHtAWe0_UG{(^lun{KjPbu4$ps0eDG04 zZ`%=npU?>K-deRM`}Ve2<%qwpsP>2P$@c@8`jhVm2;2WPw7>oLd)xaZ+n(h60ZjeL z_XC9OPrM(%#3$bmVB(YS2Qcx;_XC*t z3m@oMfBbz;kO|vg{AkDcc)ly!_@U2qjE}d!YU4}Kb&QX(GFhA{lQL;n%- zXW=h~{wn$N@S|c~&oS~B;NKhikCVR$|M!Ld3GyF?A6)2qvgFUUMgwf5)c&FEQP<{b z7ypGW{yhAz3F|pS^<0GCU6=f2`1ghJQ{*qf?|2~p0r+1X#-Aqt5d3$9{)^<#w#Je9 zO~1<97-1FTj( zuMTgYckRr>KNR|Fk9phY=K1!hx+j`7(#3xWez~s1W8U@&KjNQ& zpVoz|zXrcsk91wk=RV;<>cPD26F$X{dD|!RLHwBieKN1ak9E{1{D{8-zwje|%zvdP zG$*C)ao7ISUHnJj7k(rj>!MG_UHlX93qRt=dLe$qk9E<97YMpN6>85A{4$Obk99$O ziXZEU_z^$W3-KWSGw=&<;y(nx@GpL>uRfW#CmnB7UHnJj7v3Zu>yGA?_>aRcyon#{ zj@l!BtW)A&{1@Sueu@7O{4(FfkM&FZh#%{;?^WTr9NIqb`g<6DSr_8R`t6haBmP>bxkHPOar+D1Evu@6iANTI8%L(Miy*ul22>EgE&bqZg{vr6? zn35m&bhXD$w?9vQu4{~glakA(0ku>7&}PJ^_>q5d!o#R~tf6xhG+2)ElJg_~bo3vCpYn-|$2#rkN50C@x_0r% zR~`Mx4>{pM+KD`qbNPQ;{Kzvo;aU91CppTK?z+f(IT?3}M?T5PIubwfVb0}$x-Rlz zPUfe?BmYqRxVvt(iys z-k^CRerPtzWBo3V9fx1?x%kh(FY7}5MfhcXi67dJ?o;Bw0Kd~?+v0~N%#tQl?P+R# z_-FlD(uC@jk6t6tgo1jxUdCGLM{XCMDIWKfysRCGM^4U@W^?UC&KKUO9^`fz7xLp?kf)sQ>OoG< z%Nm#K;$9~6gz7=ACO*eqJ;%EEkuy8SBPZu&?MOY)Y#sfl;U}%=t_v+kyh%M%@JoNi ze;9r@&$q>odk2k|_@VuXAMxYfLE|ERXwkf^eevTSLGwraxJS@@6F=?|YOlGTSEcQf zuD?@V{J3{?jK@8K+AsAWhj;YjcfG84x-N1%jf>QSdrC(?G$Hj%;-NW-fAQmSIU#$Eil*HC-TJKk`wq4^_z+-o}ep)EW5@qB>#CG|kNQoqEHdkwWy{J7W9 zd=o$N+aRq+q+T-zkjDlo|2RML#vtWG=SP0)=*PP5=turkdjxDAbM+t}cJ!ZyU)I;C zi-%Smq&(*Q$a{k>&u>dS^4p-hACVvVZP48>$d5cWDC<}1LEamreCw`@{5I(BQ&bP~ z81X#r;;~MtJ>rMvB;Lf2Jl4^VJTr(&HJ^vKB_4UHqaXQ)+As0QGsLI(kymLxh#&cf zcoRSJD)A^uF zyh%OCY3kpDXx{J~z}1g;qXo%D;zy1p-o%gGPW=@>aw(0k`0;#zcoRRgVnLqUh#&V9 z;$Qs8?Zlh-k&}ssldfOTejWYDz0@9wN3Jf2W)?p*81W$f68thh#gAM~Jcxe?ez#7y z#gCj!{GWI2ho#(hB*O#>96>)j`p}b zwk>|Fi#@b1Ts>G{duUxaKi1bCmnW$ntfM_H?~xztWe>;-^U1iY2hYJe`mrvkeu>9# zB5J?*F>k5A;>WzD_KP3$bC1ib+v3Ok+#~twq-!VUA+<;R_$@%~7eD43wNw0I$Guga^^qU-nmV**`#ja4!2X$PdnC{|5QNx$FZWKe(0m z{^Xx(_0ztHe%DUSPudqD{?qVF&KEy8=_5{5J(iO`%SjOImpqx-@A4%2F83GmqwkVG z$&bEEo+m&0=;{RL4kI7ZeXw8q_5R`(?wTsw;fZu;XWQ&1%B!Y4+sb4sFmaEu@%dPM zK4_w_>f-YpkMr|ku|2;KJHHS+zrg1QtxPT!pNqxkI3Cx_#jZCPJAW{C{$T9$=3IFvb9zrTWce-wbmnBYhbeVZwa#X?^?3;?{TvA za|E*W^BA)Ab1<^?^FFfm^H;L<^Ki2DyBV_eyC$;rJ2kTPJ4LefyI->PJ8`o0UIDW8 z9u2bfejc**{v@*XJ}k2Jem1i8{y(zy{zS6%K1{OpzEW*t$n`N*drW_4aKlu`^X4nq zdNHHp)Z9>q`u=94A~4H&#Z<^GlbOFE1`#d0^z`%EAvF8+r4O3?8pvUw&f#(#nqvmdnTM zS7%oimakt^2F%OzPcB}XHwMg0%h#O&^T+0|FU?;qFU?+?e_-U1GY_4co_y%Rk@D5q zr7JgQufTU{q`dM}9pG~P=7_CDS3G}fWq#@M{N*3IJi9VmM)9<%YXURby>zoLu^>VJIs#>!j8V;tut+FbnR;?l}J6VoeQ+pxHF zW953MCZI>E3Ha*V1T-jF6D~bId%b*D*9I(gZ2>x|T5wcaFu^2@y%Y(E781sf_8?(y z8FjUfLP){5G$1kxW4J&v3Z7hEyxg6Exn*3a>(z0Qjsq}u@|C(e2=03IySrTd=quKD zu-o|Vzb8aH%THp{wB$B z$KNFB57?$fo9Xdv2ls%?t8Ryf&3N}KfJ>&mALPPZug+7~(7R2QfkSOFu*WV7@U70V zhiVTWO4``AzTEm=sd`lVl$chB67c45KzH->ThCvxCFvMI zGxJMVR@5mA;eo=p%s+MF>hh%@Bd;y>-+#Lpz-)MIY4Ke*=O3C<(`szt=)ITknXQBe zN-r#4n?JuYd##S*v3rl*bI3+3M1PCWWH)B?}NOIJ@UE`>GB z&reK@O^lDvP24vzH(MFIcjD6B;|urPJAU~-H2dDmh@YCDyLkm?sI#$zZa_#vvQ5iU zdduR{Wfb0n*he800k6$pyRckezPfznsp)I8izqO%3q_S%N9R>nl&d zJd0Yej_0pUuY@OSd-~Gy&7~E@szrKjT9qqFIdcCy5In8q3d$aN@R8{$WDgy3^Txbt zkj@0tN(sE>guc|6qDe=r%wB;5Xb{-(XgrRXJ8Mtg}%{Qak& z?nUdk>UPL$efIjwqGlhgF2PT)VKF|-7m& z@GDPy`^O=IcJ-$E-LV}?%W*V8>*G0r)r=QW=` zuIqQB;UYVpuI{AKt53YV)9-$HryFwqpBt~n>)Lek(_dovkMXzII9@kZl+<@)l? zx*O&8SukcYpq~b64Yy6g|IgDPwgmhFOum9*)Vtp*+$7_-BeMYi Q)~S!DJN(Xi@X@LN3-;}~ng9R* literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f034f15385c5daef4010c71b7fd34b3ef5c4263f GIT binary patch literal 4208 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2880.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2880.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..717bbcd8a8d6f0371d2199064366a18a7ddc518c GIT binary patch literal 4208 zcmbtX%Wd005S^tdLvVz|Kyt{zfO${>=^#3|5Fb>4I|u`)kLaKRa!3J&kwcDxD@Z5G zTiV3+pD|9>CL_gt$n!eX;rHpQG~eXyTCA-Wj6RZAYvq8n$Q$u)-qEcZFY?mI-(w6N z6K|P!GZXJaCEljM`^dbVNbgrXT&p#=wY(GpV^DKT>S{!DE3;jlYpzv&58NLad6MSZ z0YvzVG4vHUFni8@&srewCOAvA=5_@KNeqp4XL#F!186<@&47lbeKOyb2;7^L-P`Eskwe8 z-d!c$vd5q~kGDgeS*!{B95knRsX4|-H0SFvt~v8P)7&a(?kSYBngeKVrN!nY#vlh~ z&$)-@0{74KMJLvNTcJ5!EX$b0&}h({+D9}O@&5eC%++|;CEgfAV?lF@cSLiu@a`({ zmYUnM&K;IV;Y`rn!SV)Id!XjA$QNNetxx{ipV_|N5DEcUB87`BL7IJ_sC0C|o@Uhk^sfU?}v#MGnvhYAgEy zx(ItwPe2p;0J^ZfMoXT4Q^DFP1uXTz2Pyu79)hRz4yXz zOZ9~=vObWbYq%FZ{|5&x{D;-hHHo2%#9m}=d$t$N%Db-2%e|<_YWxWc)pAbHdCAyC ZJC>W-adbN$C-ZSm&Fnf(?D&Zb`#&$#E_46@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..184506fccbd109b4599699c9f329b91431a203d7 GIT binary patch literal 130382 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 XC7FC3nFYA*vXA$6_&w|XM<)L-8tnP2 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..cc6bec853d46a8c376ee0cf9ff9f2cba6a3116ba GIT binary patch literal 4208 zcmbtX!EM_>5Zt3_Lofuy4?prS5I$6ZJBS`CASL*r0@6VkKn0`&>!Cu7Adfr+SCA6Y zfikzexjU{HXB8SSdB?roz1f*tQWDymMG*Nc_`eguaQHiho5winhH1JsryxI1BF*W9 z#khaPMc1VTytVL;7z7X3ePZ5Dq%S*nYi^tJQV5Je%`K>_3C%5&?dn`}t?D~+|0!?E%|Uw% zZT5 zMfQq={b(lOAlb*7dtxo1xxTo#HMdQ*U>U0z8V#CLyf|aF&lSAC=dbvb%iic&aVrU>}PVEz#D|jDSNk3j_Zj86Y(7ePup}ARjp*a^` ztGPYv++lkeu3vM9lsCJk0X2trtL|&+dk*hbwW0UgK6jfnM*`7>z28;sG2F&tXV*N4 zPbKy_wZ|3ayJ}WmaPP`%xyQL5@^(1)xsZMiHYqP%8G{_)T{GaFKKE*~?;4!HT#I$7 zpPPfNsYMk-Il%eTy!QO{GxP48c_+?6=0I}c{2UxoUUI+~425&>R}OFv)Mn2Cbdh^e z{~sJc7ut*HTE!p-YM=Pto|PBeyYfzOKje+)fQ3U>@_uuH`-Df~-!;?cKz*SL z+lw0Zq8AqOvR4$q literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2dc5c5d20dc84ef9c042ea046b87af5f84c341f3 GIT binary patch literal 138574 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 P^Y><6$Jso-V-f!s&N?!D literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K3456.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K3456.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ddd739e50414f1ae963978f6da3cdf5bf4dc684c GIT binary patch literal 130382 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 bH-B&JA(?y}nFYA*vX2jS_&w{v$0q+DU^@cz literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K384.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..ffeb6e2ec51b13a8a297a9ba87bf5d11ec21acbb GIT binary patch literal 4208 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 VzL`T6-jH2sTiGfw(% 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 S>+9tC+iYI1lX?8a#ri)wBOr(X literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K448.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K448.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..4b10c225878066a9da635a26f7965c9131f21fb8 GIT binary patch literal 149838 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0c0ba6388edada1017a00d22c2dc25a6aa86a3c7 GIT binary patch literal 4208 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%0A=S4FdJbX@>FN)S&68$2J2bGZ9h%wJ4vo#@ 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 NQC#O)9RK1X{tv>49JT-e literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..82b12fa6c622c7ea3df7f9c232f100e7e28bd183 GIT binary patch literal 130382 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 *p!iRtEhY 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 a%Du6dWb$=n7T~taKHk&e_pApWo&0|?qYYgE literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..44b553df40557f1209d3e6bf65466e94fe6f4599 GIT binary patch literal 4208 zcmbtX%Wd314CTnOu`m{h4>{yuz&dOJ?jSn2kUhA7bPxsD0#bqxTYyV2f*gEYxRP|R zd7}8{r?D}z0%Ro(H6-8TBQ+M+UTvJn55fN%5!_DyPVVY{yz8b%`)$rnUe6-U`HYuw z{e>TW&tBlA#s2ZW;euT+`2056L~gl`YfGEB;TxW#oTga2=w*bsbMgl+80w>( zl8yPp*EdFT636YxMH<(Ehrj3V()^TjKT3j+kAJp82x+-XHYqpEI=33SFSo_~TsU@0g{jTvQ z_|Rq4!0c)52XcY9y}qeG)tWnGHHdtuqg%t?PqsQ_&7x3;qbJcivC*rZBgAZLG-duCTO1y_k zym^m7a}(YUJd-SZziPj&(45wfnxhZT9P3-wob8=yZtFGo?31dlL3?srV}H5?AFP4d z)7nFGzVj6ks_{Z|Dc;~i<3e+4FKBKRUTCfgZ?3r~ z^4uXk3TJ`lj+y4@gUsREs(F>pbNIHZ4YM~t&s}@Xv49Ka4K#N>lI^$pn{ibHHBkHb zMs}`R6&JOyiksISeLuzR(D$FH!Gp!+R{CHK@U5Bfmiu09ICCX6K>v9z`oQ0k{!6%s zd}s~Oe`?SBZ&(@kU|cZe_u>}%z}G-LarLwJnALzj=n8%CZVk`}YRmfoy704TAfN?( z0A1LuQOe_Q3TvSD!g+gD+{eneh1ySX$37r&3uX~&Z+Hx^`S7l6_LgQ5&Rn_|x=8v! zPOjlBdig{RTI?UQ;nv89CW%>OZ9AJqtK#k|<8l@a$mT{f0$a}MIWKy4!H#qjJC1Ji R=ji>*%&yOo9e?6t|9>Q(9994T literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..f8d38b062500a5e018bc341a94a066c9fec8297a GIT binary patch literal 161102 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 rwm*Yn)Vx;XiJ5veX0JdE=% z9Q3*H08cgM57!lMg!3K8uRbpCaO1PcGw<7DTrTKwhnt15=YX@$EixS}|Yb$&4XzNbRI_lEC=d>bq;wM((*wt+7_M+|ySsPBa5u+ORX=mWdYt)k~PPg*w|iZ!Tv zx8fu{Ck!1zgAgBkZpT`{b6o-`_S`AIyYDzjWfe@r;s;J4Hxtr-mN!1hj**Su=m=1?lF3f0?yFB?%m^1>^L=E z40lDKfyRd?%y-qIywJWVuhkxX@AEe3`&h{G@0)GN%c;bm26)$azSDiLG28d(zgUY+ zs^6Uc8`UDiPz}(38n^w|EzElewcwI(<(=q*sDZ@7m1}S^8W4j}=!2UYpbs==`vAU( zdr?P1Gx`9&(7lyYGYo2=@rm#4MS1syc_*~@d51n=;b!bb&_3`{dJ!W+@m(|B2RawN zuzOL(z39wB&d{Llowg;XW*E9i>_wq%ulAxvdE3Ig+>1J_#=qTBE$6@Uvaw5XEO!*g Vr`z>7dmg`yMsXcyas0$Z{67hAB)R|q literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..219f5f7f7740f232bd6351200c161da76c6dd4c6 GIT binary patch literal 130382 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 Zy|I^M@^xeu;I_*?-rwQ(tOp;R{Qv#t3z`4` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..208ddbd43faaf3c79109255749f5631074761b07 GIT binary patch literal 4208 zcmbtXJ8s)R5S^uILofuy2vVdl5*A98#y5xxA0Rh~3LPLf2m`20kt4X!L4+VhO2H?| z4V1UD`}QZw*bNC-{0!&KzL__}wV3{9VMM+P{_aF@>5ikhd9YW5yY;`_$;h9RNOwBn zWt_j`N8j@=@YKWKUUz)p&sV&Ec6ND%2k%Ah`5fn-HZkK{+$U>tv3`Un)~oxnlwW{g zsF&7c-@kagc_yxrH15D$=DlL@yVBxSA^irbXPy_h2o0RP#k# z`nYq%(0lSNjG`IA&t8>lus&8BS z2Q8DXsX=qSbqGhq&_}3&x97DVnG3{S2WP3)+^(oWf}v>lo^M~&09ucH|Gs177R}{+ zBZgv;Z>hPbnSA$^e6I_>Yw{hiyx1<)nuFGrFEvLDYED?+3C&^7dEc`+w+NcsESqc4 zAI*YJdX5-+iyC-)uDK0!0nLpOpjvZVp9`ij!B8}4PWht8$~hPL4j&k~MRPgdh@n{I zTWW5c$#+-Dx9l-!&hZ^E=a{U9IS0)tUuupRiRN5BrZwk%&os9Tn)~^>xdzZ&5UM&y z4A#Kg^V&mmq4ozxMJLvNTcJ7S!!#xsiU!T8eL{1Q@8^$<+@iUhZ^Te6Xin`Dnw!NJ znycblYVL`79HbEJ<~C@K1#GB2G{YrkgP0ev45S--z|^l|A*4AubO8pn6K@70DqS5|`! z*JSq@F@G)nm(?J_&>Eos)L!=AI5Y0f=YmVV6nCNzoaRsi35lz(!M>;gF$je|xL5=9 zf!fMGfG)x;8cC?351qu7<7&hAtAb$hYm;ESeQ}RT-DFXvAvnbVbOP far?aF-b6c=o7u5-JHJofzb@>0pV;xg6a4=Hr`0IJ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d3ec154d63233f1579c1d25ad4dffee9e66ce7fc GIT binary patch literal 130382 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 Z-q=er`8qNSaNA`cAMEgZ)`O2t{$Ej;^Bw>I literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1d146405fd749f79c3baaf64893cb30671d947bb GIT binary patch literal 4208 zcmbtXL2lbH5F{NXFaiU~p@$v>SMSck&N!VzprzzgK7P{+yj#ozHj}*I)S3 z=i&prG>8{_#T)T@$Msk6yC>ZE;oJ-FYeE%J5v!{U7n1_Qo;6kWNdzu8=8{fW& zo;u2iMJIa{SB}PbxCvO zN!6x!HK4iZFEzJgE#U2QNcB0lkF{VKO%BZl%_(20jqL$6m-+7WQGN|DuJVQEO1?XW zhb#GxHPW~?2iz8OPleskgKflRD08p}c-I8J^K-Ah z@w;ZnJ)s9(u3vQz_M=*u98z|N`BU8S{PhcQ50$txbC7!AQsL^)-ebgN5150gFbDta z0p>t`<2isX!dZkK^#9QV=t9pThMFAgf%;|7R*&fYB3$&o3U{XW0k;KT7Vd^QK<^VD zA;=sl72h@UbD*)!^ekHOEE-tI+s-1D1Vc>@*`l09Niwzv?a42~eMP+FzlJM*!R_&R j#>a_py&tcA4^QwTZQ;ixP1ojm{IV|mx;B3Niwpl>mKgqL literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..821fdf5369d48ff086c5ad0f2c88582484e6f5e4 GIT binary patch literal 143182 zcmeHw4QyQ3b>n5E3uMA5k)0 zNu20!i*YvYvb*a7aT9=P)<03}#dtSJ40jW-g^MB$HlWiM2#N(d zOgDiy$d>!vd*8k1dvAU`FR`O+dLLl(JLjHv-@V_v_j_mF98ymp+ZC+&qb&o! z_{>Kh3UJ(aOPBf)SX&$Ve_d}E{N|wt4t@0psfAD1ZvNZ<^393&{rxxMJ@4#68oto1vD`vRC@i4A{pXI6Z7w0a{&7V_I=S;)CZu9enUox zzrNYD9A0Of8ERv=uVCWrb?rDgM&X4p?w+vWhIl||uY_^G8`_& bMTUf0f}D`ih` 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 MxXI_NJMSC&f2hQ`<^TWy literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7e5083706a97684836438dbfe48f50d750fbb4bc GIT binary patch literal 4208 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 IzZ3lb0bRl@$^ZZW literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b660c986d0b6b59d908be4cd0b954304ec8653f8 GIT binary patch literal 135502 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..4f678d507e2ad6af9ac01ec0cd8c577a8606fe1b GIT binary patch literal 4208 zcmbtXJ8s)R5S^uILoftHMT!&#%tB>~+#o7^kErkge1kB64&uTG$Pt9Vg-gO0QXYr% z_NTS66b+cToV=Yxn$ro3asPvh zuCoQawb(yCH=MBh702(BUA|!AUgVDRxVN;4>%U*-^6+~4Da~*BJQrKb1I0=x#n8c_gMSCKBzgGYyGbAAzqrOC{gy zjPH(oJA@b7rCM{)y7Hywh~YEG`W7^YbI$gjopUR%xxEi+j^C4jm|t!s25TVXTkdw*d z@4tSb--G3XA%Enz&9kE8Y1nO(<` J9Y1lg|350s9v%Py literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..cf725f97cb8bb0cf201f18fcf2b3cce6cc3c0f7a GIT binary patch literal 172366 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..35e4d746c1d739d16bd9c90105f779a5801ce85d GIT binary patch literal 4208 zcmbtXJ8s)R5S^uILoftHMT!&#!a@f~kv=MP5EnXtZx9C1J)*(~$PtVnMM}aa$W4^T z;k^B6Z7f9t=5M%f=FPmBrNp&&D<|?K_}_@&a{3$G-IwvIn{MscoSpnVi!|pmUdH(c z4*H(Gz*CF$<8{LacD~{L>tvS?c<@=|fzNSnX%p9f!hICeenF;f6m{e`7ZD0Vr#h|dcm*e%7JO-H}Kv0%vJM+-_%vW(C6fv z``s<%yRYQiWPBg#w-f0@k`Ue9>e1oC|#aU8T8{Z@^H$S1GSHD zWZzYb{G#?%e)HO+?U`aN1M81h?w3w_{gAU<)k`oQw2^n@6MLLaF8jXqFY-UrZypG7?h&FBN@ z!e-4BQ-r}9sJ-yLy~yvO(r=;mliv<~z{Jhi|4@75V|)$6L)q*t)d1gIx)!>~XHmmh z^m0WF+QDgCa%qI2L1GqJ+g{9~MSi!HemRSJM6=O|kS*u*J1@F-!H#efJHE><@1ysz OhbDHtkL>t~3;Tb}vmxXF literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..aeacf8cbe70b675b9287b5ff1546a68446b20b83 GIT binary patch literal 138062 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c29e6b961255c5ef0768e79673e5809118dfbd6b GIT binary patch literal 4208 zcmbtWF>c#H5Zt3_LofuyMT!&#!h#P-nJy~y5EXhreh>!GLsa-57J?Kh1;4;QQRbF6 zcgNM)IGP45^0>U&o!!|zifivyPUNTH|3L(|mNOQU1Wn6#b zN8bxC@X}(xzi;>;TyMC38SU~3559^#@;R<8ZQ_P6SZ6VfzP@KK!^N|cKY*aC_hOoC zw2RL#^yDP>+c6hYzYcl$d-);FFL^%~eaHpT3w||M4or>T#CM39tL6*8Q&$N?pOdfk zyIIJ0TgkUEe0TKQi3}<7YR&C~UkZU3%-o8)DrjyUY&X}MYgOOA_OCIh>Ke3X*T!A` z=5?|X)F9ZWwI7%Z_}!!})tWn)8e|xX_89oKrUuY@;=7BXSM%*H--Mxl$=7P`xRCEt zCEr`acSF7%!b|N^t+{RBOU)63niJNypgGJrO)&bv&bd|8+$jcCU4!=QR+?=7Bn*9m z8U*`Pb35h&nj5$mS*e|K`;ZGpoM9*$G^c#gV|LCZzMETmuIAfYz6nFI$k%FaSjhKK z$=CK6G&l0?kY^?f=U467x($4(Ibvj*8|z!voZ1SSTSv_ui9G9UU9)g{O&F{}uup3b z&BfZE62KhIDIcaW!%#G6PVEKFCBB^=zyAF>nw#=X80r_AQ+q*ki}*rwReY`Hj?8oC zS!#&>r&@DQMsviV=5V%ZT&3?hoULlZ?6q_5K5C8yoH1|Ov%B{s;?{WMpNc_}*URcVFqZQ2WtuhdyB9X3QegKJW>A14e`jv$s?Od~@ku=)%sThO_AO zff}@Dr)|lt8HNUlSrpp#Y8EZ>+gJMKEE*8agGPjGIj7%w+1e#L!kyUh>2|%&-p6;_ M#IEbijx!ea|FD`O$N&HU literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..54e4bb9a379bc864b14aa9ce43c92c0a8969f6cd GIT binary patch literal 125774 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 V)9vy(SwnO&a~JI+|x{{w(`C#V1b literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bf16/npu2_8col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..dcf774dd66218c2b463cc000d024fd61659c3b32 GIT binary patch literal 130382 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..be6276a30358c6b894af465f374d6f3b974eeae9 GIT binary patch literal 23432 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..25b377b3aca48996d314e721f9615616cfba5574 GIT binary patch literal 660 zcmbV}Jr2S!427T52)Y#{28K%QzyY`c3><`kgQOBi;7AONhzqqZt&N(BKVhk{ojU%W z6NsPX0xSVs9Kdj}yI>omdPsG3JK$CUuB{ev%Qam3IxR5gc|ICjCYD+DP*TASHY{zQ z-rGM&STom3)L%4di?^CKs%eBu!j*D`#4&eo+&n24%D%R9xB{Q=;-FlcBk97VRIZzF vkH)Q86!;DHd;`lH2Cv@WG@Uo-33WDaHsJ>2{yFdY$9cVSqpbc0qb?D2BLg8| literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..fe60b539735d45f9da0a59173a6f6a650900adee GIT binary patch literal 27144 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 R|9$Q9j)PfVVXfcn`9C|qs7C+* literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1344.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1344.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6b76ab7e4d252cd51332c623ba6dc2211ac2bdf7 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b22bf81fc1e0a6de83802d217b0325c19dc7325f GIT binary patch literal 660 zcmbVII}XAy41IRPXDdhy43*k}18@TvI0Rz{4iY4ez= z1mvc30+s--49GRbgRl*^DwTTj4roe%+j0?Fe3m25>3}6C`ym9f7nxO0Wy+-?fQ9uX zJ9`89wbVL^$~4v1iA#Lrq)8#ZYTBqKo%={DkN^Mx literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ba9ebc084da5afec13296152ce13ccc8cff5c96a GIT binary patch literal 21896 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 S?Z4lWLG4m6Me literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1472.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1472.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c653c311c48c6b35faef7ab852e4e6b97a4d9dec GIT binary patch literal 660 zcmbV|I}XAy42FNZ;jtAY28K%QzyY`c3><@jfdljiLE;D;h=G9-aRH7}oYa<@A|Ap+ z96PqZ-vPPdn1CsO69aN>?M7IJTh)eo@(Q??05|0%r1&65tkVK>PWpq%$iy;>?n=rf zAp;A`i+A=0@^gu`5|wGHEfbsg!L248@mAA9HEG?8n<e1WM7&QILGI| z*eEwq-5FIVmwViuack*353J+oefP?>#?FkGvVF52*BkfGeUHlhwy#sJ7d7z*gDN6C E0m9%UcmMzZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..844037fdd31cc0cd8fddd4d903defe5ec7e1cd36 GIT binary patch literal 23368 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1536.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1536.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..180f2aa733c444eb8a3577ae5c9bdd1ce11fce16 GIT binary patch literal 660 zcma)&F%H5o3`M`)sIV0z28K%QzyY`c3>>5b2MH2K;7AONhzqq&YNMtVC?4Y2vH!CJ za^;$UEr16DavkkWIEGt0hI;Y|cr^g`%_gMyCP%E(0&`CKgNbBfg+(7FRgw_F+VbL^ zy@C8*Vy#4LGkMFzChmEhNhN;HbkLc!ZsB&yB_U3^XXAEB3(45eeg&@Z|1U1eO{Shm w)ym}=w=-_sx3rGzeXomszZy}?_AO>yZ`{t1(P!^_&)nB3*Nc4o!GIyc03k>tVgLXD literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..991af3b7eab9a3629a500285864bd9c014931a98 GIT binary patch literal 23112 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 S?Z2;F-Z7Hp71pM0p8o>@#;Ml; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1728.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K1728.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..280777836612ff11cb352018dc4084f59ff96c7b GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K192.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..54c9870b5a6eaba9884011c8afa0430f7a56e675 GIT binary patch literal 660 zcmbV|F%H5o3`M`)2pEtG5(7h}cHjWq00!;>0|yBbN8msV42*~i6(_Z!i3F<1kl2pn z_kTccG$CLP;KG1}-Fgt#A!@o*cisT^8sN5`g%Y1+i+$Q)hm-eV$;f0CmOYhJNw*G@F1DFyOgHR*`2npUc*hf2bQa!H7N?$)@|q@6_etsR3){Qirba?M9F vMUqOnoN*7v4SuihSA+c?bHAS%ahUlnGOjo7pMK8+{W|4(Q4@bKs3O7(5$YmH literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K192.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K192.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2e0cf50918aed11f550f4d1e7603ff0c2eee58d4 GIT binary patch literal 22088 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 xk*G*fD3=G^gK@B(}yB2EAR literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c502e8d6a2e435ccbfb486f36591ee2b1d301a2e GIT binary patch literal 23112 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 LhF4fyIz9gfaW|y3 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f394da966140e33b715668748253a4645e42aa53 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..892f903ba5bd2794f35c67a88c6f3ebece33b901 GIT binary patch literal 660 zcmbV|u?@m75Jmqv7SIKx6cmw?f&tio6b!%!6buq1MxbXI3d)Fu!gq29P9#u-3)^?T zyZ65#ezp)`1>oucUi;Muw&7Oxq3&)6JPN?I#WJManOj$<1$KD$hsBYDm00vtQpyAe z=9cH_?F~||8EYj<({zZ6iMXjI&3@IiQB8yHD9Ds6B*xszxLH(8S(JTm=Wr>0|HWRp z=3_90L9Sdk;vS6~{8sPo$$n2`zn>YM1oNAWxV3Tr^n01;*DJTCn(haKDiOQ@Un(LR literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..f50aab83e6b2c271ad759fdebf308cfe17be1eae GIT binary patch literal 23496 zcmeHP4RBjkcD_%RBPDUM9Gvh7PI!@xn+;wf+p=Q24v}q{_%~7Fgh@B)$g(Us3bv%! zvQc1?h;7)0WM>=NWk;|>>rNVGN+(?}+l9otL%kDb2@Ffk40PD-z?dCi2-9tyE@aXy zUGt-5nm-kcT zpls`5h)O4S7zwK0r}Dn5>Z^0`uBtrVE+2449vBsTo)DQpkh-AzVmEq^%Z3lIAT zgPM;rP1GdZ#9P<@yv%DOqz4{&6${_wIO(uwGSe+`zN~!y_4NPZqG|PPhZbOsK_6oO zFqtla0huJ&Xi9G;HmKX)-GMar09`id#GqRR9ev`XP)d^!U+iQjF-zo>nRv+TQf=o| zLd1UES)h=)Dl!$L4T6-ad#5-x_CaxK&F_j+pMF}Ldh2p=YUMABQ$PMqabrnx+e;Fe z{EKTKJ^waH8$KJiB_q>P@`+2}7*N;0OT_WbazOv{Eh)MCC5xGW{Q4VGa_pj|5anBb zAtg)9(xo)W|MUvTrPAGGA0d;gu014`lH?PwS?(b3sX6tb1$w6&C7&|dH8tx*3=8* zwtfFxIPl00Q_MR_`Xrltj_^7eKg_ReG1=s_WJ|5SvO-=>Y^jpcTU5(Accu<+Cs&;c zUMFSG)XDc3qm_>@TQgs7{T}JNoBY5Dx2Q^OH)$Sot;#R8lFvOt3XOS;|YLVZ#Y>^w@w8%gF zjYWR^l0`oFfkoc&o<**H$0C>f(jt@fa7JT+(~ewC6N2$8F4_%eHU3T6rvI`Ctdca9 znEcn{m4uvLGPS4Z?UOrXvQ-*qXX(jf$pSK-IB&I*N7r1i)PUUKCCTK|FI$dTOtI

v`^~9N_isxWll=)W1Svw8wv% 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8a9c139382dc662310f775775941791b1a266b74 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K384.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1110a1cf10d70e27a16b5a100935c65be8b85ae8 GIT binary patch literal 660 zcmbV|Jr2S!427T52-pe|14E^D-~ikJ1`g7Jg9M2qa32;1M#P26OJma?2~^=Bu^rpr zb0B`U5MTx1>HxaQo`PNUsub$!_Q0bATvIM%%AI+%by{GTXMZ$~99U-2OG!Bs99USM zx3@P)*f7>gRHmu!6%%n&O`83xX{(wB-MwI~Tp_W~Js3A8I}^&jH*>fgzyIQ>T-&1? wk-S2=Zp5vPTeB{Fx+m{@8t>c9Xu-B`HsS{3{<-gE;=W$Ffoj?xjH*QN22K$p0ssI2 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d19ecc4229b735eb9b1a9343b33a640db8a7ac68 GIT binary patch literal 24200 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K4032.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K4032.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8afab021eb07f44d951afb8eb1d88aceea4350c7 GIT binary patch literal 660 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 v;99vn;+~8f_gz`XrTIR5 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 R?<<#g9M13wt7)6({{VRfsl5OI literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..75eb7c84f1cd977a0acbd8dcbe0b8b75fc6d04f4 GIT binary patch literal 660 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 bz$Ofk%GvihN0wRiQc^An8CY3f zZf9?xekZY3qA^XyBB=(~o2W^XUp4JjQ`(&RrE*D#DYrFlXG%gBiR}BZ0_XVs7oBoP x-3ho-E>E~8_(89V2ygX(AwU2C literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3d6ae8df9a7c0d56427b84227fde4c87a4f0eb54 GIT binary patch literal 22472 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..bf6a90ca5776d5fd812e90bfa5fba4471c1887c4 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D=mEF^9XJRB2PqNr?5~#vM5<8CH z|AF|~LVy*3s{?q9@epjosfwwtZU@{;z;)#^l-!9+-=__>dA<+9k%P!AdnzesfddPx zbN6-!X*bNZ6P0PYB+W#W5;bY{tEO5t4PGb7TDd}E%598WC(V>a*|%;Em*e+e?3HUi y22+?6%5@{|!MMS1^Zv=nevf0npBcRb^P7#ht#SYKd!FdmE4QVZ{s)695xfB0xgov) literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1bad4bba129430bb64c7180a6a0949e38cb4cf5c GIT binary patch literal 26312 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1b0f11f5ccf98f9e917937ea13774120661932cc GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0e81bc25d6ff40cd7d896c8fd0adfe2c7a14533a GIT binary patch literal 660 zcmbV}F%H5o3`M`w2z3J_28K%QzyY`c9XJRB2PqOq;6NQ17!enO@7AU%5-P${5<7ML z{#PM!mJ6^1a0vj@KJJ38W>sI>9(KU31j4gi=v6pz>-wz0kI45L965^2tA~;1yx_pX z?|DZ525Hu;trL}N>d?sppk?K#ubMWdY4kEFR>l<)Q*Q0tJZYvZ%Dz(mBzJFI_c5Bn xqA;!wO1TH;s^6Mxh?eOj_xS0z9tLRUezOn1jdTC>d;ZaHqz3idaJ_%22wt6K9l`(r literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..0a5c8300e5379f3b54fddc3e7a8a6731a5ea348a GIT binary patch literal 24072 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d37991e081c2726dbd84854d1447824ad54eaa94 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14AV`Ffek1GH?(E4iY4ezyW#~21dk%%1>)US_xF)A&H$I zzwbc&WG27@z|{dfcJUDG;;HOXU0ns-*MMu*^H_3cF0D=lwt2pf!Ir(qEPE;`XMqh1 zt8@2u2MH_Yszhm?>O@RLC7ma&e)Y6bPrcVkvQ(~+m~!{V-6mq%qU~EVh0F2#FAmDJ zIeJ}~6v}l2?$Nk4MdAIEqvt&h=l%3(E!e!-fE$ea=e(DZ^Lph5x@mtfx)Q+)%b+5r literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K640.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..60c4f93c690590aed4cb153b01cba5993b944bcc GIT binary patch literal 27016 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 LmRDHoH+%jM)QPCE literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..6ede7cbf14458aafa3cb8113a1cd4fd6668953b2 GIT binary patch literal 660 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K768.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9e5a4b13e3b9d320584b383adaa705cfacf966c7 GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D-~ikJ1`fi&JqQv<;6NQ17%MJRoW!n@B2a~gBzBy< z{|&OU1pzAncLVS-Mn~BBQxj8J%^rBxfa&X{FPSSZp-&ogv;5u%f0;$0*-J%3dN1Gx?7(uqbjwMjE0E)+FM^{b|>Xv$tE$y&I?#FTqbZf=xV_M@M}l=wZ1qj1$n wf(*w>xMsvXDYx})!{jFWJ%9Ke{s>(4Ta36)xqte-P4sJp>sU>gpjSnNHyH0CcmMzZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K768.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2320b275a47ae7c13ffe626bcbba444c9ff28e4b GIT binary patch literal 28424 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..7fde63275917a2b8201e416977daa50d7cf359bf GIT binary patch literal 23432 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2e24981a29e73619f8d4b3a672e06e0387d7b25e GIT binary patch literal 660 zcmbV|F%H5o3`M`w2-pe|14E^D-~fzlFmMnC4iY4ezh*?=32`{%r;ALsST4Rq7~V00ydC-$x+ ANB{r; literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..72c59610a0cb224f3c1e5b0253db9ff697cb2a05 GIT binary patch literal 21896 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 UTEy1hZ(ZK8Kf@i?y3OwY112;x=Kufz literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K960.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K960.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..21319011abdc7e3a7061f043dfbc4af0459e6343 GIT binary patch literal 660 zcmbV|u?@m75Jmqv7SIJG3W`Wc!2k?^1Oy=wlP4k06l?Yzt Cl_f9$ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_1col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d49886968a02fbc219f1a2ea8197ce5b65e9ef8c GIT binary patch literal 22472 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..09582183ffeec0a721eff0f6b9213e185b942ac1 GIT binary patch literal 1304 zcmbW0J&wXK6okjdAc~dPf`S4G3vmE$K#ClMf_o68E%q2&>`^Ev5f_4I=Z)-G*_B0# zB+ozdy@@9$ZLPy4ff&9_od$L8Mqw)`#gMxA$yTqT&D~8aI!yKmIL~n zuzo0MAp;v=&2f1;&cSpmsdXhhd-~263u0q&6$zsL>}jVx4R&Y6Qn^NmIkzFV%@#{r z@*S?vh4AtJw`i419|ILB*2=X7_egH=+c<8k_IoP*CXJ{?zmtO7k^83KuS&nJ;Qo;7 zfsStFT+fx6`&BN3Kn-SY&RmUT?nCFMMdolfHs(8=fv0kP=A7(LRt6ezSk6G_hne%_ z${93CpgMCqpk~Pzo$yS%z7u?#J@Il KWlYRlR+|^BYe$9v literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1d2fcbfb9fdbd272664722f4ab67d1436a17627d GIT binary patch literal 39128 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 YG7w&JFOt{apIqH>yudrG9k+J=FR-?SDF6Tf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e1df7f0b93c4eea213a470933cd5c813610c55f8 GIT binary patch literal 1304 zcmbW0y=}uV5QQIU+HeuTDN?vFU?K1T*+42>WQ-Kv!wQfAGD3;(P zlz^}bNyne}-4mbS!eZ%wX8`LtAg{x9c6f2QPNU<@lFSu{yM!$XFwranJ(r?mGE&81m+@9P!{eD#X z4F&g$+(zuut(@zzGIQU?We}*r%q^L#iOfCN+`Pyf&dzJT;~8{RuFqVM{mIHmLx<%I zY<`@%hFm#=E(ug;Zf9I(F4Iso$((X0vY!0@EJ&`-+`jaiG*pXzC$c_p@AP}9^vkUG P(vAMLu`A~^Z&~ebGUiFP literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1152.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1152.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b49bf138066df8e6fe754dbc32afbfa97fac830e GIT binary patch literal 37208 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d037496e7d8655e99fb3079208ae05e7bb2c8f18 GIT binary patch literal 1304 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d61a8e023c1fdc2605515dd7dcfe4a0df36e3e6a GIT binary patch literal 1304 zcmbW0J#GRq5QX0u6K#P+iWC$`tRfD;4cLN%q~IReNI6J~93%xrN|Xzc@$9_)u{M!~ zCHz10&BJdY@u3pn8Ng-<=(KBB!6D7+Zs~n^1-_3!xE&wUR(R9S?)e1{QR7n!-0*S1 z^^cR*y0HVc+}APk4AO3N?Ke@gCPViDLF>6_3Znk3Y40`lk=f+QxuV1|w;{Kh1W4lE z)(AWN|6iP(OC6Iey4X55WZV~WQ~I`#D%N|>^$s~K8TBqQZcFZ+dfyB6#*F(xZatQZ zV$Xd#mqwsmdak0cW<0m@vt{NvTqT&l(;GDU>ss*}M2%;Vjm=~QeFHzAdafo{-(VC{ z?76*j>A6u3D?mMG+!?PAdcW*y>WcNAa=k+iOGdpjUhlYf>OB|grPo`n#=hEAm56;_ HqqY13R>nq_ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e6bd84a0c27a643961601a4f06a55c4acf8ee33c GIT binary patch literal 46552 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1280.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1280.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d7fa3ef71147e588440444de9f72f4af09aab9e2 GIT binary patch literal 1304 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 RuXox_{A)v3BGGSIEWd&YOiBO% literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..58aa65a499a4a96194863a856d4c0ef9b10d5b31 GIT binary patch literal 37208 zcmeHQ4{V#qbw5(HDaTqxrAopkw)2^CH8oKa>W^i~lVi$~Q~6&aTXx|!8AytvWTp~H z%akjpaKa{T;nu6VCsAC_ujp`dw2Klksr-(CN?pWNVc|=M`!B7r= zmj7i;@si_z-B)P((oz1W{_0HGU#I z8BGYul3OYqHuVf#)6uC+B9llZxmHpNx@+Y1%ZkMWH5gv{V-a33xN%+;$Td+`} zH+-OPpM{vjv;1m0;O^Tb*b|gjC@J}O*TB$_;WL;yY$_7i0cw7ODt<$8Y_$K~BOV9ehUC-E)c=0POYLoLx$DXmKo9et%`o2dBzvhdkf8bWM zz}VyH!`d&*6&f%gw+kE17`EEwyzjOBZoW>%3%tLGXGMH1;kixzTIDLRX0_Pa0k_A+ zd>%Hyme%N<*9?#SXm^dl@~!Me)bX+0`tR1~4n0@DwISODWbXO@%B{bzKDX_$`rH*y z)aN!oU7wr&YJKkWFVyFr{(Aj!U-p^ryRxso0+YPP3oaJCrwPmF7 zp)Y!`VVqB%&rP4Im$Ts?yyr?u<*xLs_P3q&`Wx;OL&HcHWbn#;smtfTdY$irG48)B za=lbHnDIAn`k%NT`VV^N53|#2=3GYeTR)UimYu%$54k`5+#M+X3jwR0MjliJHlnbu zO(up`4L1`l{$Szq+?S5~Ztq+*`oey9dT5SCTt5GonW}T8vSV8Fx_$nF%a^} z<8%Ff{|;d}A}#y9-|*!gd(rnxkc7S@qhEag+HriNTU-#@e8 z&pzZjo`%TH&Ya5Du;Vk&)z-34u0Q8(2fb^EWwQ^yu$enK*7*7-UU@cj z-|?A6&(Gf5wD$9#tYPz0L#No<&!4aR>*F(#Z(kR5ojLvUy7xab6Zz>4?|Z*-)!TKS z#D1NLJcV{{bBXwcd7t}SQ|{??uH375{Q|Em@Y;;mA&={OpZLy`e;UYLu>lBPhc>vr z=W2THADddQ8G7zX{2hGmnWp12zE!O)??03MyLsd7bYzaLoieU^{`o-fPkMh-x6%LB z`W}DhUEBSclRan^#h=-*{jI)#`ONc8^EY`Oad+PJv4N4&-MP~kER|!r|Y~OM4hfr|MZtrk3ZxN4m{{yXpX9y zZg%&x;QMYtZFdx*?Y_oqj%AF16t{qRG{Pp@u?MUZq(Tz+i%_(#xRK7Q^G5A5uIrTGJEy4D(=HTS+{lsxO*`d%l#PqYP_29 zx*4xA&Tpv8HE*cf8fCr**rvso@6C+?`PBNl+#`5>1Fs*iufx6?be|UE!=G07V78yN zGGo)vFZkbgu4wmMC|od}x^`gU4fto?$NpZpsrH9FQ+!tVSFB&~vY6}H#xoZKKhwjH zH7!TPV_Csx-9nz_BYiJZ_8|B8+*)7SU%OGr^$y2MX1>c|Kg4r9Wq)4oVa#Oi!I$dY z>HL#5bKVQN@n3mc-JVd5XbC-d@bQu&YuEK{^aCOSaweSg_}Tz+G5(VG18qF+2ikbt548A|^QQw0-_LQr|HNHw zINyKbZunjMzLsqljDA%#jl({?QrrZ=kq5lJLmH!=kq7$^C#!?C+G7g=kup` z!{<*je^L36-^^zeukszmt9(cC`2JH-{?umWLo$D|^SB>qljDA%#jl({wLAHflRshE zIr)>5KRNl6lRr86laoKa8}cWazo>l3Z{{q zljDA%#jl({1)TiJ$)B+7oczhjpPc;3$)BA3$;qGI4f&JIUsOJX?>~urM)4}&QM}4` zI8T53iGJsa{}z<`C4w6Mn*{m&g5|W2&<3G{gbopUh|m#2rwN@U^jSjB5_*o%3xr-I z^b(=-Ce3p|{u>SU@kyThK#s4Ej8D@>UeiHBhX_4H=m??Hgw7KBETLx!JxAyTLN5|} ziO_kImgDOv8lU9#_}a+$G;QQH9VB#!&_jfd5IRlhETPX5dX~_0gkB)@BB7TEoi}MY zzNVt_NnVd{BN?Bjjl8CVgbopUh|m#2rwN@U^jSjB5_*o%3xr-I^b(=-CN0M|Y`q7e zydK|vPKvea%WK*obdb;?LJtu-Lg+N1vxGiN=vhL~5qg2pi-cYxbl#-pc>0URCwVm{ zmd6)Htnq2uAb60_AwmxkIzs3)p|gZOOXyib&k=fo(2Im#B6QxQ<@h>^#wU3-CYEm_ zgdQSvgwSb1X9<0l(6fY|BlH5H7YV&Y=)6hG@ii5VPx5+v8_D=IZR9l_ zBy@<-LxheHI!)*-q0bU}me6yAULf=$p_d4qCv+s_vihGUbO>h%4=ntQ7$Rp&2(d}y zI)*}D_{r3_Y(k&ldj3PCtsz2(5Zkr=J}b6`5HmEcW7`5-XW@&WdBeO9utVDIBmI#% zg6yZBBiOO@VaL)pLNI393=-NP;|h|sV-PEgT}J%iBYwz|c|1$z zahBk71V=wDKcJtMe;DyU`f1^?Z|TFng~Psu!@h+x(youRYY;q0@DRa=2p%DLn&9x8 z)fW6_(eRtqANY;ndLO}W8YlfnKP?>nwCtdt7LI;eIQnVf=%#F=M^sDf<&=+meKjr-`^kpYWh4TIu`c?Q_=&#^!$Wf%f zC9Ql~r@jv${B4&tLZYN-;&n;Hh(Wb_}eZ+{B~=9YuR#tBiF0S-$K6%e+zv+1Y0TZZ=qj> zzlDAk{ucTx_#1K*>2FDEf6E+M#uK{?@tgQt%a;4QuS$Ol{VMz|^liT8OnH9`{VMz| z^sDf<&|ksdkfTU{OIrI|zSolew#yK|iNCdMxxe>U>2IN5g};S9AA+rv_qWim!rwx_ z3V#dz75oi3iuAXnwZG+iDCuvz4Dp-zTg$Y+FEhuFCvEV+WAG<#)Us>wGx^9M8Ga&M zlwF0vPc)#xRW7L?VoHCjsbRki7IxY6S&gZ`=>b?-Zhuc_c!?mnl^rx2H zZ8o#7u-B#^Quc%M%jSqz*<09W(`PQTKkNb1qWuyo^x5>Y%D(3ZCGGDh^xO19%6{#< z-LT0G6n5J57nJ?FUzW6gbKyfaedba9zZ&bp$F{>qUNT>Og^*3(Q2L(hO6vC)cG&bo zO22k%N&TIL0h@kA>DTQpssEwE%{Kk4()WF&q<(S#XO({A9VPXP`@f*{{dbnsFYf=6 z(qDI3N&VvfFRA%j_n#HbS46D`|DzSHhgoI6@tY;>7q2%%+4p^>r2XRc98vZ=A1!IW zc)u*E{n&X2>|cC88p?j_XJG&0`#qxUZ`xh5|GNu&?CVGAw|u0eesTPnRr;;hmDDe` zZz%ni%fxs~#Y6sHrE@j*AqtPZL6hbV74PA}V=>8?T_o!TkKa}ovhE_;0C@gj32rk~ zB&!3@TNJUrNY)6Rzq{u$Uy*Dbc>d`Nm-&lio51r?a+y&iYX!f-l(iJe_JTJ|*&vbG zKkwj{c|n}2?tC%zx60~8e~agr)tL4xKVPK%%Fh>5zvA;n>az!mdM?@G{g_q#ul#(G z_A5VMq<-b+i`jqpwX*X?>Q{cgnEl^c(tdG#j(E)Zt^9nE_A5VMq<-b+i`1|De3AN< zpD(6<#pjFJpGQlsx8i(bR;{j`gfrJ6`e0qzw+}%>Q{cgNd3ys z7qdUtmGpm!^To8!}gy`NEG75u0(o2%4NP;vNr=+pI{2^Tkch7h64?FK%+a z*km|g+~j<*$#A~7$@yZF;e2tE^Tj5^`QqlIG|v~C4CjlRoG&&R&KI{~*2DQ?lLgr| zkgzQG5pxk5INB0;3&BIc;WvSM2;K@D76e{Pa1U@i2}$5Vg4Y7aBe?|LP4GJ4c(jth zLj?B$$Mbyz-b?UC;D2D^odn+m9J49(>j>`2H}RZ6;QsSX*4Vqt;343aABcV}aJw_g7mN6aaS2Z3Abf!IN8A>-0^5G#m(G~NhYk5}WJ z`5NNq8f#nwz)1|T@D|{@KUyEL!cAfY*Iy8E-PfJ zKGZm31sS`>4dB+^Ij?cV3Noj|R(}vHh<%MCRuKCV7x`5lE0RAN5$|CwegS+)@*c>8 zVBt3*=llZbkjb+=0<68hTPg6*RfSFSd9h$kUOop+^YXbKnwP&*t$F#oi<+0eBcyrx z|Kc?-|DPAu@80! zw%>GFZ+a?qM?99f=`zFUO;1EKW2vc0&VU__A5X;Mk^vh_O<4@skH)8x@d+atos4e_ z?AyERK)7$$&VVryO^#3FamL#Mv4D{|kp?lEo(?E0!f<>h6HkuDM?W|k%|s1|!_rtd zF}f`foaqU+1&p!jWQ;$`J30Xutsk;d8rH`;7Pr^d}bq|z8&JYYmeN2lV)j_se0 zP9(+>@hMSXScaLzo#;?-raNGy#>S4tGn@&+{*lzN%&i)cz_8YqjZY_%nXb-orfeS) z$zz$RQeD7^co%Rf-34^0vM$7qM5m1F%61@Gwg(s_??JonK__)W+r^v!ZS91P_7$8k zl7g+}vtYWQLwCS73vFniG8Y_AB}U78U?hcx%C?S1N=`sq|D|dj4ldjJ<}$6fU$U{o zyJcJND%biY8#{(kw)HJ#TJLyAW9Q2~nvBIs9O7Y!#E9M-WpGhZqxVJ~$a-(oF|PMU z9sWS8u&Clc&Su1B*BbSlbrtcpaso|Odk7%E60x4w<82^+wF>{(SQX@vR^fG2;r*e7 zAGNBl@6_IP6Q2f_n=2m8Xq2m1~j{CMD4>_~hv8a9uYBiW25bz9kGt+SjSi_ z*529H-VObM_{j7)YVg|FLdTFuB4rEft+XeR9EGq8y0;)v1UVU>JeW$SCQ{=k!jsVi z1TyV{C^*v|=R@IXmtZ&ZHqy}(6R9YyU?0aP!x^)(;KQ-hbTR{7zDXy;T+UOk7yTZ;!jSVT*<8+eAuR6)6uC+LUG7qH`LvZnxsp`Go46>C!!}()0kWCWi`!m+8|s$%e#icL&M=c zI}hBlb1y7UhRt^jm@~Y^6Nr9GK|t%BhnQUc)`M3rn)PHV6Ba9n%lJDUC>JLHfs+@R ztu3%z#u-uDvhR#RlPvpKDw*Uv>v$q_!tM{guef)lJcWITg^zbcVQjnj3_58!OnTG8 z#ZotSiv_lcHBGB`2>aG#SehlP^HbE`IuC4<;orLY=66uGd53+|0qlriV+$orHP zYg_sqj^_p38vlQbo$*q~2t|XH@w$TdnY=-7uaA>PwcdTHcfg29)H^G9d-7hX_pMT| zFL>X{+p658HO$qX`!HS_ff)2$LtjmJ?$*xch39Y*7yTXH;ETxhp7VM?h`5XaBc}8X z?0oFGmc04~-Q{w<=QhSm&t(`9O+6QRC%iuB?HV#ydu~_i9WWvm^-g#_@m{HSU#XW~ R@3ouw*M_b{qTjMuegRk(Ond+U literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..db612767ced579fa5d6e40f51a4aa1c933db2417 GIT binary patch literal 36056 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 S^m?b=#J@IlB@+FX#qtZ@f=;Xe literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..43ca43de4d5ee0a890c0066cb7bffe595ebb67de GIT binary patch literal 39000 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 b$m!S-?O5_GlKbyZuI@Nh;vLq`yL$f*FqUY0 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1536.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1536.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..cefaa62dde399497bdc1894faf5d8bfb211d89f9 GIT binary patch literal 1304 zcmbVLF>V4e5F8tWh=c@13JN4n5f8`@px_}c_y-p$4@r@STtSf%NWBiv16wDI zzl~`r2U}pnb6ErL;Oe!+mWhfzHCeLu;&BlOQvKS~&U)%qXTh`aI$_Lt59Ezmva}`N z;c{ETZ}IoHI2tc?^iU+&7_T4jM)EdVG1Ey$vEI{z-VP%HQSW5HTa!1YG)~2O-wXAI z0q+NSE1)K;=sg#D?$dZ_1Y*#0bNXt;a|^qh4m^je^U2?hHbkWIHwaR%mG{wMq$7C) zyYG9hB5wo^_u}F=*cmT9mtiC{@m%5^@p`8BiOj{GJ3i>`FcKE^j(EN0jsMeoD%4A_ R*V0Y;YqcxqlHan}{Q#07O5y+j literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..fe44f9b17e78da930ea7b62d74e755fff8fd0037 GIT binary patch literal 38488 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 Lc!jlNZ}0yAg*B3b literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1728.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1728.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..670051ecc82983e178a862efa0023e9c97ef9158 GIT binary patch literal 1304 zcmbW0J#GRq6okiKgHRL+iWC$`SP=)v4WQs2P*CO$Y@{57f`d>{q(rH58}jUZBYUk) zWU;=V02o)VdO$J^f^h1+i;z6$zsL>}jPv^>$~)i*k(+bMA)R z_iVAWCEwwCpTaKj|F_sGmp*zbQY@5f3+|rW;P*1-wranJ(r?m;TJ+l#+?L!2{eD*Z zbp`iCt_NDWm2*8-X6~$927wyP+=RIr$lSBejf%|SW^BxNIDNDqLf3nikh{JLQ zI^WNnCs)p3lLV?Ww^A-MmuW;b$z0?PWIg%yPb61oZd>|I8c~aW2eRIAAM|^u^vkTb Q(oOtpLs!Pcyk)id1@`nycmMzZ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1728.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K1728.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3fd0296a6130bf65cce3e75ec0df46a9ba289a77 GIT binary patch literal 37208 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 NM~l3|+Pb^ze*vD8d#wNf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..aec8a5cf0e7a50e38956f5c89315bf6ba8063a72 GIT binary patch literal 1304 zcmbV~O>V+45QU$Osi@Qn7G1DF!m2nxZvYDp(gpX3EA;?9LKi&>i!M=Z4=&uz9PkWaIR#|eJ|~BlJd5qp-o638w}3xy7kSIS$xF}K0S-ax^W(W; z63At5KHck+>hRI zC;#Dip2M&4|G(H9x7T$cwKA?Ba9_!dx$>SB)qW3Gemf1-qTk7Yo5;PRF`YMMIZz2ll<6 zxk#?u!R{hZow<#1nYltk)g*Ju9m#s(_mSjkzxyk{orY@B??~2L?u~vAm42D^B;73N K&N5*hxMB literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6a9185aabd2dc8ff2811896c968bb16422d8b67a GIT binary patch literal 38488 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 PUEXn`#3!sBd;9+zB>s;# literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2ff3ce5798f0a7388be9974116a7ba1534bc1416 GIT binary patch literal 1304 zcmbV~J#GRq5QX0u6Hy?MA_WB!R>T3g0Tdi01^0*}+E?3iA!DEO@#YBowNi|cYE4cPZjDad@-&lvF7f{&5}!s=zlm}7I16) z|1S>4rH)d;f|YUIfcr*nNEb_XdV?mt#~Zz+MkZ75WWbH&KB)JzQLi6xzsOa+F?X1U zX3u>amquU>dTvHvjd*TuXVZb_a2A*S9kdq~RIjzZf!BP^?7!HDDbhEv^J~uqa`g@N zeM+~_6}8@;7Q=2Gv7*E{ZmdXJ5I>Gi1H6nl&0r>)lV E2OoV#`Tzg` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K256.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K256.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bd445a772617b336ac3b770f7874f3d5ff5f7fc7 GIT binary patch literal 37848 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..02f0cd0232ea18dacb25b06b17482e564f140ece GIT binary patch literal 1304 zcmbW0F>V4e5JkU@i6|nGf`S5xRYZ|8H((16Lcu+?Bwi*9kG@*5odd z!_t;~hx2s~zsCRHVrN|H7*vs9Wn7T6K*L%Ic%r4iv%k}m(luNxMUhlXM>OBL1BzAwL=}9U8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d21293b2542028fc9949f322d597be7fa52f6965 GIT binary patch literal 39256 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..94652c5494a07c57a72af1632a196ae74a0da9c3 GIT binary patch literal 1304 zcmbW0v2DXJ5Jf*}T5yrTDO|WPV8QSJ*}y71NDA)}1;`*NGJrO43KuC2SJ}ono$f~z zp(KP=h~$xX@4om27mAq!HUO4WK&IVuc6e-OWw*4qe+E8xfWPh@+K_*dm!7i&9D?Mx zk7vNf3D*}R%_Xn~R*cISxCd7+Wo;)>vZsa-P4dSACn-VHuRU$8rwBEeE{yAh7;`If zzXr#he23F@4!_3V-(qjvLDx~Km2rK-eImD!%=(@g*?JGgWnxrAL)1G-xHY*q>U}lt ze|kg0eIvINxj#)K+jH;6r4d+zo}1BEBc8jny=me(oSj#HH=^dFU{~395G0>TI`%bm zDR*G|L(i4u${kdFfo#uhjmtZTYG^g_oN`CJ-s`OvBxmd0r+WJuT8nx|yxwtd)O*O( TORv|`jsCT5SI(*5qP6=5R&h?i literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K3456.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K3456.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ad2c5dd4e2834a5c52622f3e846b6b6bd6fd437a GIT binary patch literal 37208 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 J%x{Ca`~rLSNn8K` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..8b08cba868b24f838efbc220b49c40fbe172379d GIT binary patch literal 40664 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 S>Gf8s(Z4oU<(&F0i`_5E?NWdM literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K4032.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K4032.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..642533c88fe99099cd2ccf91f8ea8864562627dd GIT binary patch literal 37208 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e2976167f578e7e4a7042f777eced8779c93f398 GIT binary patch literal 1304 zcmbW0F>V4e5JkU@i6|nGA_WB!E5rd(rh|fmq~IQGq#T4I2ce*#M7cn?2^r7M-}PD> zWU+T6C*E_w3w)JAY+gxu~L%GyD;Pr<4px#}fUV6Qj PZuGB>T{)+IOJes20&z=> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K448.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K448.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..759d780f09bd699da1281f81bdf2d07210ff3391 GIT binary patch literal 42072 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%0D9XObR}4Or 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 HeZBt!Z~~2W literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..919b8004285e00e466a3f044d503a58dc7e519dc GIT binary patch literal 1304 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 bzsTv>od_>^7Rmj0+1)#im&vep?(hF^(VLm~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5184.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5184.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..dc6113afc84c4f914334adb7c8bf136ea0b5f11b GIT binary patch literal 1304 zcmbVLL2kk@5FDFOAykPTIB-CXg?IozAcs7J1OFhEdgwEH=uu^rIPyicqVL} zG5#^8l_Y9l%e<@=&)~X^#C8*bJ$;N&eZ9n0Aej8Kr@i%*P>r^0<8{KA@;2mc*@>1p z`3~3n3ckkw-=a0%QFX$+HC~_bp2!>ZHfvTC>pkas2Mooc-dV=mk@rEp?}d7+jQ5kg z0qCe!=6Wgg+?Vmv2*jZ07WCDG=br6so_P*8=hfeF24Tsrif2$sJ&SZ5Ff^1I*!kFV zfxI$6OgIdfQy@fT38_JK^=7_d&hqLcR2QC*9~@ M8@qB&{g%Y;7tMM|5&!@I literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..7e59f5cee1b175879d2900a425b8aa592296086c GIT binary patch literal 37208 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 Ka!&nL#O?>aTSfK& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6cc983455d3037751870881e529da44f0bee6f00 GIT binary patch literal 44888 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5760.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K5760.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..3a68c9056a6afa99ef2edeb19e5c0f4648be58dc GIT binary patch literal 1304 zcmbVLF>b>!3_K}H5g-N9p(rv0h+E_V{eeB?AssUG7jc0;q(dLlAwxzZA4(~j2g`z6 z2=QQvlz7K8&v4;x;eZza>p39X{^=ZE0p1ujAAcM zB5x&fsaEECEcD#B@zMyypyw9!)r9Bn?QEWT4xRJr?>K{I$*ziL5Tu?(x(*l`$_(s$ z?751(GJ|FSDE8dWcCJ za&XF|6>VTb+gSp;?5G_w>z$IqbSUGNZMQW`Q8xuz26oK?I}AJ9F-*5p7-mpP>0}ue z?RW2e_ucbk$&qMww+ru0WS#S!^Ul5ZyZ4=Y^b@_==;UZT(ZLGNu_6OMpTGM~hU4(3 z`CrDAE;atweU+9kpY*90H^2Jz9e;hc1^2=GM z@EbYMzt2KU;TisH5^&G$66_7gXT=L|?L`S)mcKmS5zJBUvP9EC{vG0Ar@!&^N5&6* z=c|uB#F&Tiwl?CypS$qj$6sc?-6SRXch}(Xu;DeBIc#bY=h=V?mDwAff0(z&+kLM& zfsuGD6rYMr#B_{iEozBh#7A3u*Zti(#-7B3Khr~92A;)`Zr z@HVu-*yHHK+Rx1w8ZjWZ3m2L(VztY4@5}q$e3;?^-B+ZuBE632JSKmvaurys$rWP< z+#VP6de|UaTBEPLRxtL{-8BZwx3L#+j+bTEeZL`l=-Gy?jhSvB^UwWfcHM&w*==8H z$X@kCLw5614cVEmHDo{gd_(rBZ!{eDW}g0$EAzvb5R#wqyo&|yZGrUk4{>hG>m2(R zNMCt9yY68T^WV6Kf%CdwbY&WwT(1;(jPJNI>*i|R?D%1JWYb*c?B{BKS-69-`FH&K zF4t<7IrRD3>loJ)7qT;_8su#FhVH#uO4+MDt9|WfYJH6lilJeoIhnk&U+DJwu5I>S zG$wp^hu9;Y!T)US!eMrL&AiKKed8z6$}%(e{VC_e$LYY~yXd#tY2ry$ zV517_-e_WI)o?S>;*WDzX1{RUdq>x*vFG=@Q^WHt?DG1)$kaJkt2kz~TDR9%aCx)W zK7FO{TIS6*Hoe2Nd@*R9quMEV&PH|4A8CIVX3x2Ts{)ugd1T)r%f6%cVKw>4+_WJD z{p5-<*W9NE!oH3j-czpN8JX?d)(2LPvTU2@op<#AV%xnhsM(vdX3ry5iSOts9`on} zB_c=In9KOgfX}x>L=MZyzS?hkvtN3_`y1oU)tN@m>Q@TB{ht>xzKFm482sJW^M!kS zwWr{h@n#wPZ^84`|LDzL#dsgp#wWae@A`hN@4|O$ecyYj*4O)`THh1jsP%pN`C8x6 zuhshYKU?c-e+t*d6SY3JNvwV*@JK4T@qY{6+^6ah(dAm0o&V?4t&Bag zdf{;Wj~>|XWAAqzPr>A751h)>u;a7O*443(uRCAc0eROj%Vf@etM*i_JC)nyM$GKV z@upWk_R=%K2anG#dVcZFmbIV#cnw>a9zMm^e)dBB-yWY0fA@xf>w(k1s=xl}+3?S9 zeAo5HHE-5`9M|h?_$z4Vc9+OsnD_b5v}B)Zc4dEv$FK3Y3Xjcr9P+q+@Uibb`4|4| zRqKJ^acI5k2ds{5h>G}sUf4^Y7nF`OdwbRBm&pqew zd#&$x^&5O|tn2l4-M!tHKG};_arn~fx4+Te{f;d#kmi!-wkgcd3|CH)HPEczZ8K#qCFad-u6VE){uC>zF#<&+{kmv50T5 zl<4uFXTo&>SNEC?EcN*L-JcwL?`YlLnRAaMKDl~RG>oEi^2%e&$3Kex^6_&%JczUV zrPlYX>0Wd6@$*AG0?viC-PgTlEn~`;ORet#zJdD;!H4%_2$8a%XkMFrw0Z3)aQ9+1 zntc`eYCKx;xCM`KuCK4pwyv+=8e!gt*~Y~e@5_z@`NX>V?4x*m6OUKd)#JJva-SCC z!=E<=un1UxJ?nFZ%~UQ{7K^rTC2CSFB&?@-Wx4 zO=m6!eYTfxYub*C$1+0CxP?8#NBT~t;=%6my0yQIzjlML>nj{9nR%~7{2;IKRQv^b z4Pz#=XTR0pPUWAhnXkQ=o%n5So7)qt5$&PGyC2z#nn=`YM&>s5MGDc+Gqv{;) z#p@nb=O|s(IZ9V`j?$SiP*gYd7u8L6oxN<=>xkay!d#fg^7?6qQ$IQN6IMs|54PTO z>L;gua_Xl`RXI-m)HBI_r+uIe3SSM`q4nbBEPKeZRtPj;QXY}f0E zzHK&ysqot^R+E7$K*>(1^U9Thh%Jq}qsh^zs3Cqr@pPc&1`TWlL{LcCO&iVXKeM0|# z`T3o!XH-4pGwT_pt9nQ2s@_pLzW0PrHsxV{?+ITUKrO}}^7BBOj?V*aIzA7y^p)$U z0}S8KalZe=sWzPNKXDrV(7vzbe17MAe&>9C=X`$G+V6b-iGTkL-)H*&@ck!IzwrHt z);mg9^^Ve2y`yw||EZ{c>bL448PBfc^FW&&p9fm{%JtI@r+#wYf5NhJ-hXo5e{$Y` za^8P(-hXo5e|kH-|0L@dRS)^hdPeE0-ch=$ca)CrKNZza?N&V`>nFR8&jW3Cd>&}& zE7wmQPW|N6Pgr(N{p8e7PW|N6Pfq>h)K71R`bpL=svh#0^^DS0y`ywh?e$R6T_6 zKZ$xq>8jpQx~g}$PJjD}e&>n*7L@uWf*Sst1o{0!<+7K^29X0q4ib5o$YCOo#C)tFcwUl_5*r)7iS0U`&9JWS*;kyAv@5cv#|=ZHK{S|0Z-%iG-WrN@WA_s{)Oyn?;Q$)@X`3#Zgh&)f^9FZ4^yhP-@Da-M-6pc^n zdVCwm__S=~wHzRFkjTSC4ih;=N!Fj%O7zpe&@x(fL}{>F1-DgQa? zF9{@P!N0YXe^~mg}-Q%{wdG5@Ryw=CzR(~_*cQV z@Lz#%*l|d{rK~uuSKkK^eA{hJuxY-vZ8_ilRq`$TtKeJs6Xv8?o^RprDn6k+-@?BN zzJ>n^e8Y}I@-1Z-bh*A|4(2xg-41>zTN8B6x3(?kdw-RD3;!zk7XG4d^iO%dg+CvL z?I_Q;@UMbz;lBdku;Y+?OIdMRul~Q4;M;C%f=%-{$WH2)^w$n^e8Y}I@-1b}x2%z6KC#=7zX{*kww&+&D)|=vRq!qRZCrDuJm12< z3ciJZ6?_Z-75Ii7hvZwzns519OY&{EA%7FTwQV`y`>W(z_*cQV@aIFY9p(8J{#EcT z{Hx$w_^-e>>^LOfQr3LS*HDsgyAAo9@U3l{?<>sl<4zkq@fiG$8+Gj6_?diEkPJT& zE{i_u+VSwsGAD4{3qcC9e532Ze z3--XKHdxqc^UtaH^}i_@|CYl0ZT`%o`hP9fg_msyN3~?W`U^puzoGm+H{C#(o^e^uJ zlJal9qNIOu|CiK!HUGS#`3kG`;Crm1^)RR6H+{Qg{NnXysQBLdOU5r=&tVn6>#>sY zi?5d@bv<_7iTIbk9t{=0?S90+^z|NA@i*=++5g>zJ@)mZ{5O5DqAzK;Ui7zkep!tfzw-S>#;<&TG5ssvU!*^KxTxn+ExsNzs{fVm zFEW1R`-}9ie19?f4_+(VU!;HK`-|ECttI0Z=jX7;oZrg#7a70u{YCm$zQ0KS%J&!P zU-|xG`d7TanEiRIj>@vjyoXN2+~R@w*8#_i zOcAGv;6r8b;WBt1aNHnJ#2F@We84T932p$l_#t>RaNJHy#5qjxCg6=GK1lGrz^^p% zA%c7IorIrG!cQl!i9~$kg2wyculdn<9dO*_M))@q|DiIt54awej?)ZWk4xiwfopy= zZUDE|32C=4Uqj{#D?@Pte2pn@yr6L}aNQq`Hv!l4rSUr8I~ne*$FCz9N6N3)u+6S_ zH;6hmKR~!0u=>zd2CoCIIn@3=z%}O@_W{?OXuJuy=0xM3{0QM>#OhBSaD9zvya~9D zuW{rMo>RnJBZp`ixV2^ojvT^&7gqQqhgkl|Av_NY967|okwe@hhgdjrh})VY;*T8S zw#G|v6;>SN5I4z17LFX^t}*+A9Ae?fAw2Jkej3Zjvjkc9Ekr&%_@& zgp9Y-@(%*nylH$8xV26$XdF4jt=GTCk#kDo0pQkpAaRge$hdSI+*LOwJv{0NbBeV2eeOrs@4f#E z*SvZ1>tB9t+(7I_MB?q#U55C5+h?aHjpMQDW4IsoHh=q#0lyJTM3ZCj#KboLOnUr% zJ^t-CU(uJEPTm=drfo1MPled?pd)xAKlm0`eQjW=3VOcK=PbSdr-ovk%D>Mi=uNk+HGq*s){# zXCjmF@px=noG&6HO#Ci%C@|aOHu#djYwcbd&|aW;)!&3S14V! z5AnpY^mM5%U_`tNcq-imbf~f}M2|$KjT_2#AW^ml7$omOhwecaC87ONB*0sf(Alv9 z38P8GT0RRV1)aJBwpnOL1C>#5JQ*J=&%kIB4V7&jjg*{#_JPaQItVV?`sOmNcU-oy zgWa;Ncb9AZvW*?XDBJp$GOc&MrLptn9!W%FBoFa4L~=ymO)|NttkHLqPGo&I=^WR0 zlTLq-Ra#W}AA2)$vulmI&$`NZTe*NHtK9@pUx{4L&*N>Nezgw%wy`=;M_LCzM;*LB z^x#{q>g!vLce{_z5YAH2wrhb4$%4&64wZ&`00mS4_-gx|=4{(Tk#;qbuT9lLG~ z?b~(Wz--}9_{Je9P1t(@9OC7?j7ss>>cas z8Xu3uHjhR(_jJR5Fg7|ffiw8oxP*?OkVMHA(wEYncw!7j?t3c=MTk?ese{Q>axyt_ zA~Y3=!ywBpm;$pMF+LPtb_sQJ542R|#AGspD7cPeQ=znZvd}}(EC)goI|`^foct*QK6CXNxawS?j`LIo1Q<3R(T(A#T6Tk_rot>OWi`Ff@(Vi8j zi-ffY+A=0cvLbEnS~(DJ*6g1>P)`TWBwZ?=>3AwM899-h!Q66|)ild#gK_yR?-~vb zkA(K@JaFsIy@)&&GG8%Z&hQdXAo?W*0j*aaVsiOQ4}NmdtS6G`kXSj~#$WNkxwruE zpS;9uZ9(KRWJGMszAFk(vh1VDM1o&g$K&Y}c0TxZ#o3YeB(6g&e7qtG;j)X(qLUV3 zl1&R2OWnL$EU;ayX?l96h;L1Xg1OLBhi&hzP-3RQmkC1$^4 zh3Ox+O@A+^jZFWHq)$ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7e2edcb9b51c4f559b067aa4aafc9656b7ec1fe9 GIT binary patch literal 1304 zcmbVLJ8l9o6dW59QLIFY6k8x+MWoLSpx_>%;2zmXDRYPvIYJ^Vr?P| z7yiHbtY_iE-OK@x0NN=a)4rV?p3^M$OY8kBa9jiavc6AS{!Kc)XBRjGsZY&w!^R2M zXJeYn#u8X?U&g>QxUQA8-9)6O_7^2p`IiOgG#j8 z$#*zh=I~4W|1Gx0dsRIUurOX<@b1W){C+1z+N%BTOTQUIf#`Qq@OI?A(eHbu-%#*= zk~adKD%7qzb6>{GAP|FTnK4%*nQQE9T4W9<=QZEy4R#GxRlh-ydKT%JF?1^EOz!A51+-m;e9( literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b7310a60fdd4b572db4b364b895ea60db632578b GIT binary patch literal 37208 zcmeHQ4RBjmmA;adSZTaiE^e!~PI!@nHx##(f8y9#r;%f)IDf4ZCrp-hN0MdPQL!b( zk%Lnvt=fi8N;^wnml?G~XT4Kem=4)-%eLE^rR#1AZ5h}#3+wOW$-+lKyS#l&AcDwN2MAkXqIq%$izkA=gM?cY>7+*QckljnD0lVuUjAPH*(Z0qiX+#Wz-l~C#wQP^(y58m_=)gj zG$AZYZs~B?^fU0Bj!tC~nM5kdy^_+L+m#;;iYn*EC#P>|pA7)9)`${hBgg5cthK3BE!OUS(lQ_=?RH)2c_u?bGJ>G7QIf2nc zJe-(}j>mP3CM{}-U&OJNo^^k_j7dfAFTr<{mQ=hjhKlDW5*L>0R58R3t z7(0tTto_Vfp#cMOyKtcy!&bXo_r12?&4(!-(EUX^E7HA0=P~(Xm8-y7Os*I^;P$wf z&%*}T(i(l`wSci7?yfOdzLmX%b9^kf?pyV_L(kW5ZOC>3nS0^CbL$?e&u#lceeQ~< z>T{c)sn1P+xjy&l7wdD+e5L-lFZ=9wUD@xvije$_7hNoPZ!@H4zk_p|-{9E4K>Fev zxpj|-nE%E-44l{XiYwdD=z6`tV|?9}T{m0nX2%b+Bb#QkkA9~1XNB7tn|s$U?sTnY z*+ZYLy_Ru3c|JFNs$R~9fAHQbrIfqUv)bQwrqv|6{%UvT+y*F1Z< z{~G4YH8j4$ZG6JpfAzO&{pY_?>;LAfwf>$j)cT+LO0EBsFV^~xe!14a z|M^;f+cUT>o~re;O=9&kkr(m>#`yJ9Uv~((ivOGUEqtO55nZnNnYn*H-NM*otLG2b zefPore)a*^@ia_s_TZ^(4Ld&byw}SN7kYUmVO`|0y_e|>x=@{Q|)t_M&5yzafv&P0B4!`1IK zu6nEPW4K;tB40#1x4A_A!o1IYsyX*elPmWfJbr=46?kmMm!dpHhvuz5ms$Uj$Itct_)n(Jp3~>N6~sAR5B%hpQ)eG@2L~Q? zFSJC}nQnIXbI|*4!P)L8Qs0kz?|S^)o~~UD!7sTO>ss>@d#pX3p&mqorF6XAubygs zefHs(TKXQGy$S(v+~!g-rEbRDv+=ebjEdWj{OYd9AG=uOJuRc^`~c6NyvHKG!P26~ zf0~VWgRZVM8(8}6x!n(pzJJ8Kclz$%6+*pAos7U%RPa|SMm7Kx;k7}gYMH}eE8Gq z9?bT$R%UGc`33*g=ZdbL3xx~D7vD3m@H6l;?_+;2X!8DmSBlRGe#QEQE)R1(+jQn) z&}Vx1wx;dKcq}XQtXtT#e5CJYDjw_}pIiIO_-i)^yS~D)l9}&v#1HWrPsN{?*Dz)> z_vp*@?sWd?nz`Bwx$$4swz@r`8qprw4=I1OU-Cx$Jqu=b657KrFJna3J*v*(UcBy6 zb&k?iouhPB=O~>S{Y7pbye>uyQ+7T&Ww(t`l+p`ezNQAHM{O5`pWfF zyHh_o^%ItzQ$JPuE}!%M6VFo4`%ljMPtN;K&ihZltM{K|J;U>ite@<9C=X`$G(&v2tiGTkL-)H*&@ck!IzwrHt);mg9 z^^Ve2y`yw||EZ{c>a*%08PBfc^FW&&p9fm{%JtI@r+#wYf5NhJ-hXo5e{$Y`a^8P( z-hXo5e|jgp|0L@dRS)^idPeE0-ch=$ca)CrKNZzaZB{)b>nFR8&jW3Cd>&}&E7wo$ zPW|N6Pgr(N{p8e7PW|N6Pfq>h)KBk(`bpL=svh#2^^DS0y`ywh?e$R6T_6KZ$xq z>8jpQx~g}$PJjD}e&>n*7L@uWf*Sst1o{0!<+6{+29bkA4iR~X$Ppr^iJT?!86wXT zd5*{nL|!EF5|Q(!%xggY8x8jHNu6^b$Ja;3r)49r?k?gveuvO zle!uc%eRs7Y1trnkjNn-4-q*+&iOIYi_kB1edvCUTa@XNWvY)+SpG%`!OWOJA{%5}L9%uX!b6bc1o&J1gufLN{siBzal#4O z)&0TTaVOsYAel#lj5kQGRfF&be;uFj41Wt}1ozo+-A^A`4~%f)BQhiH`bfKs@Zcjn zWXU|9A@ev(@Hv8`pB4}3r^OE={G*>1j`)^8;#)Z4TR7rdI3w-)NV^8Xg9Hx|e2Cx? zf~N@%-mJF3neLn;4R=`RT+ zXTiUvlz&9}%O5Bu{^-w@rTh))Z~nTnK4EFQXEnbDJ$TK*53yI6GVctx)v5PaQHS%_ z9{f~D5d`nqzTBrWMmEhZMYlKbnt!>Ns-hiZ4RsQDwRq!q1+qmOOdA@~z z6?_Z-D)<)uEAS0F4#~HaHQ(m%1qieHI3ciK^3Vg$kL-H+U&9|(PWj?XnkiQAv+P0kUzAE_^{#EcT{B2xwr99ulzY4yE ze-(TS{}uR#9f#yw%9?NaT1)b6w;_KMzO`*R-}|fNTliPOxA5mfupQ<37XDT6E&QwC zTllZQH|#hh-%{3m%hynnZ@UfooA9k|n(xcZ@#9V#Jn;HZ|&S6?Ay^EZ^g=em;q{e>Mi|B&+c zZY}A*voK)uk0}4T-6j1$P`KIVpH=?850&&U?*FXvZ@iEsH8NYbF87jW-<0a!4ujh!0-}z+8_{G=D zlDZx{??C*EUyp{0-}-UHzxeeYQSmqKF4_Oxg+2E5qx?60sHA^!{+U(&t=EF&Ei|M~ro?i5~cz#)p8Nc%VMaHjue=+?l-e06Yd!(r6QZ2q7v#S40kN& zV)|FSznJ}bvgCRzt~X}YdaHbYk?||vU!;HK`-|y+2l`*p{v!P=-(RGE<@<~DuY7+o z`*U4M{!8pHW_+F>m+z0f-Zu9azJ-X~jQvH(WPcH#@$kIOifq_l++=^TornF!P4*X? z4f~6m>@PMO_7^wVUu-t)FK)8G*lgHe+1Rf-~7dURoCGc*7*8#_^l>{Cl zxDPn)?<4SDf;R&HBNOi=_(tHEP2pcha8JIO*8~FhpKrFt-dzR{0k?P{{$AjCktyOd z5`3@>K2!$p1&$j8ia0|gjvu(iGr2hi8zM|-Uz(G#0Lnz7x?8SK1gs+ zzJu`7LHOz5HIayKoY#0S{53xs_X5XFZiIgm@gFRM`+@6m={QZm^|&;?7r5p};|6eR zosf2W^EG6?urd@Uz}J}a#`7BY0oVP}cq4Et z`F_G}ztxA%GPoDG=1}{01J|5u+z(uHqVY!HniGwC^23CaVXHr0;QAWTcq4EfU*pIj zJg11cMh?+3aBIyF965ylF0AlJ4zc`^LwFt*IC6-EBZs(24zY0L5Vti)#2-1tZH<@U z$RTc$E37!kA#Re3EF3w+U1RnKImE(|LwMd7{X`D2a9sN(apV@Bw}t;E;*T7n$3<}D zoRat^;3Vf*?IMSi#Dl;so=JS<5X~FGkwe_LQJCmwE5VUN+$2|6?IK5Mo{2wl2pMmO z8daFblY{TD>uc%#Nmas}a}-- zkg;pr0B&77=QWO8LFRPW>JM@SiLY_w3KC!9qQ1&wMe+*N1wJv{mQS0(|gtRXIU%b}k z|MTLyItGStFGw6NEDV0UD4$qS^EHC*Jp=du~2-|9?EW zd#LI9pn=$nh{W6RUV`|&+h-;xjN|dCW4Isowm{nr!GIA@#!{n+PP{U|YZ#n@+~~t-PZXfC9#`=@A*MEpVePR&;9I>_aMz(ZvHsbaZqoe(c!(>F7ja zED@g)=ZnY)leiNd3eI!~jMUiJv3Q0nLBv0jI+nRrBN7xOL^9LW8P1gLLn3)B zGgYb!7!mIRo=SHC9jdGgu_MtbuZ5GBPA!Gt^ZQB4uZ?JzPU{6?U!uqV7F}R zUFBN8WMjuL%C^3xOzRzQYwUcvN0YHQ$wNF1ksQ%`qf9O;YxLfz6It(#I>+_isM8;0 zl@?Y0$KH(G>{_Glv#v7URxY5)YBvGYS0dN*^LQJmU#)|`ZLAK|k=DV_Q3vl2J@{6u z`ucX`U8*>|f4l(U2QM<@VF_ZGgSQUzTh?2L<+or#!f*IM-#!b0aJYZ(j$OBe_w71x z;MN1-fxd%%;o*aQ2M&HTa4dEtJ{b+0TVG)7M+1}5J5p1Dt;oKufyqQt$U(^IXeM?9 zcrb9XHE<*z9gV~5qk(PfFgFW4CJ)=FbEu%f19nsNf zv@?nttu-(ZADJG<8T@QqLdQ@@qGSu}OKDFcISOMJd~ZRa2yrq#c`%huO{B(8geRj3 z7-ZQ6Q*fp|&WFOwE}?GjhL(<=m`Ftt1=n$WGMq6_7J4|Anoefm%P-Q&Ft_uPGO+bF zIEQ(;0^7cw`@#dr9>Qh%Se$oAWP&iS1orF@O|@~JghwVi4uq#Ap^ik4#lz;NCOkVO zqZn_sZN%(N@QikmCjRW?$(3mB;KMd~O-H9P3Bf*CO#&yhc64weEn2tq#JX3UE)v!r zXv?S|$%?eObLBw1S+jrkK;7*)lXR(grW5J#MD#>z8gt88R?{q}4aViOylW^tG#uWu z^S~`T_agFS*nGu+Im1glf#{bM1higxh{@$IJ^0B*vz|<4!eZrc8-K+E=i&k&aPlIv zwFQyOkP)>l`_33V$+C~7l1YAL9ZzIV*!kes6=z4p2+HOb2tL7Pl|&MM$n@Uk`dzq|^Ht^nuytNa2gqV7^(f20P%^+k5a Z?vCyi_ab@y{lV28CriA-+Ih>s{{T@zAXfkY literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..217f3e399f2e9c90771a984e719cf85b1a5552b4 GIT binary patch literal 1304 zcma)+J#ND=422&RrSMRo9XezPP@%{Ha)W5dK|JIhb%7qFLl5F1L&u;OYABh6DK$o9 zz@q-hPtSTV$Uk%hyaCv(0q#!Eg|JV(Fb$=3@4(LiaDRvAH03_H$@^r32G9BFaXKM! zrQ=^AJ@LdVu+@2vUe`dwhR3oKLC@5g%~N;eps2+&?c_}VvSs2$xWq)ujkmeP-{H(h zzso%eS9R3U7Fi>Y?s8AH-m(T%@2b)}SniB%*8AD0*K=*F_e;3}7-nv> z=e~ujA4Y4a=Q{P(4bMHw+Pd-_F66Smljp*GDDI8?Dr(Vlp7V>WP>j+Y$a?9yV7PHk zX}*J`ii<>^` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..26dc9125d802b1b1f92cc3c51cc7f375334ca5f9 GIT binary patch literal 40408 zcmeHQ4QyOjmA*5c#FNI<?NCwZdHp1(i5|NO81{l`uJIpaT6>bceeR^vPwpFEgKrzTS4$0C!_ zgeY0`N`t#BI}_)0bSjg`BvMIkm6QctHS#?0kUU$LNrn8)K5W^ol4n0DqvA`SlA5Yl zwUgR#+5EIb_F4t+w$7!ev}N~MtKf!G155XxmV&BR^~38?7ubT2BLjC19aJU!Y}@5+ zRM-t2=-p={mT;b*Edn06TY}voc~-pe+Fp{-75U5ky>^nZ{1x%0o%{#H{`O$QsgI2v z`tH}Bd6F?7<8?LT!_OV~@Z)c@FE>g_{@v9-IA{h;W_6nuiR&D|3YD3gUU-Vv$Lm!` zG!c&^CZpqV1u)j6MJ@50_;Z`P*S%sg_CtL5nI7sU=Yx)W#vX2J^H$}SGsXYqlcul# zPSn8I_e{qAJ2zKsK!>~@+-T;IT`$)IukQEqc`828jS`)e=zgMepZv4RQ)G{*$<7XV zeIE7`AM0m}YxJGB35@-0ca6ykE$sf`_pz%P%QB(m*1cH2ts(o|w>)g_<~MR@K3ku= zb+$ft-P!uwmM_%j4xOvdJ@IUP?%C(-b3gh<{n0@7xqtCwfA>PIkKwAT^BxxZObk-z zE4bcU;L;BveL_gzgVc91x9-XM+~bXF`L!>3vXA>}Y8d3sfAeI|e6IF=Ece9e`rPzm z^_+VnT&y)t{mu1UW-NETZ?*BICu)s`tmq1Qc1qlmEceyUfN|AFuDxWA8_&(0^@JN+ zMQ_w~jXWsgFiwqFzKqr5M;f-sI8(1LM&dQ^W5L$Spfk}U=2W%=25 zY;f+2KVCoV3H-V9V=&Aqzhh24{-7FrI-g!{x`xju!w>sq*)cB4IkbeKH^XEGdDECd z;D^so%%8IJv(jw%)6Sr!4B0&^!_QA;A!B!YOg@uZLjAvAdT;2tWHg)*cbx50&8IhU zuavppczhCv$;@kBH|~AR3S-83wq(Xi!#~9x*#C#^7mE)Vwf=@BwSC>&kPCb}kb4N{ zP2URSZrl+#;R)ZR@&m-N2H(}jyIw^6d7;+$!8dA+?%7)7OV1+~JzHzs`=wfA|G8SD z^$Un|XKM|%IUsw5h|CH_CgOE{9nwFO|2H4Vf4U9^9?$&D+&`V##MslT=kKcf$)o!X z_Ce3lG>W|J(Gyw3*qP`3es*%*h1xdAy9QY{d*;R36SdxSezO-G=Z=px{`|r3oDV;C zbY{W#Ki6(t`^3o_hPZcvt$pHR-9H|k8UEf)An(ut0?j**4 zX80?phmSv^BF291GaGZyHhFSC!smDRT!+sVd=B|MuRQpJFMleSyKX%Yd=9PmyyDsT z{P#DuynFEZFXQjP^UrNOIulscviZhGvtOMz-$)N5?oOHS{N^`Bim+jZSW z$Nk%l%<*p2io?jP-~QX)e}3ef8|QEHecsz~|HsZgJ%8KkUwAXe?>+bQ%&BebMjCz_ z9D8hj)uq{wuHOxLU1t5q&R*zw?E_QiF6e9C2;rK}hkyCz)VZgd8_n*D6r*l`srLSRNI@kQt>1$6%xEtP3Qr_S0@0@7)`RtS5+SL2# z>^tEA$K4*~Q|gw_J*w3qjv^WlS^-QU^t-ZhY*qdx3A@HUqHX?HGWk+(S)kbDwWoI|AIhkc;Jh0ev+-oA9|E zpE0hlugh&(U$-sF0^eoL3om^lHwNUPb#=MV9h9&wSveuM3*|KjoSGdBLxkztH7j&1Z+sJPi6wH-ARb z<%sCWpSYg⁢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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..099cb6f937d928cd3144bc646db2b4257c668744 GIT binary patch literal 1304 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..114b742fb7aee566cd07d468953829840794dcbd GIT binary patch literal 38488 zcmeHQ4{)1Dm0!t9tTetxE^ZL56TT>E2*I@SpE!2TZRFT#?fk0}Crpl(kz`qR)Y_6_ z%fTs^RBcm8X$R6f+EF`n&Ri$_>Cm3}(_R}6&Jc#S9B^g^ZW!*aV;GL13^$|D(#do< ze81iO_S^T#k|SMmH^=bpMEc(Qy|-_7-|oJB`lR@qijNK^Q!Q-4DNB0b?U|EzF_goP z^LNG+FFF41zE;y$j(YUd3xBzG^M|^hIWh2_S00*pvDk902`tBTEHQR4ok@?TM~+9v zVo4#HcT0uCrk;UoCN`c;W|Qd@*Gfr2M~%F`a#CK+YLcPv_e-X4nY?}_lZRwa@y3}V+yV>RxtU3srM<9zpjkl>C;l6+EwFlyHo{>@NlH>_JM;+!mpOztc41_ zfdk!pEyN_mWS9=P_YMhm2IW=xg}3&KsedId+};t)(d?BlMr`~$=-$>q{pk-6ANt8no@Z#mKbKh-{lzi{+4TlY%!OUS(k*H?_DrBZMfAdM+9&b0v#zn1I zG7(9R#YPg^Mx!P*#W!*5rk5MvT+7&R@#0rn)F$VXjy+>dH`TdZ`g?!7@Lzn<^z`12 z78v_a^x>bLoLQ*HfZQ%@G-JSOm-D{Y_PhBy6)*7qBAylTUcz&m{I$%r!1k%d&JMUe zE*AB$UN*l%@4Suh*w1&>7_895&SlV`hg112XIJG9ePLC8&G}XN$G)^G|Kpcd<*)tB zs{HfMui93hYyY;3&3x<)P%r!h)N{W(=F7Ez)0O+(*I}5;|JB8U_pb-~i66UiYaXd} zGtfWyA?QbIYdC%N_g%SqkL&dX(9gXJy1})X-O1R@)olFx^%I;x#=bvCFvf1>?88GRr7 zyEgWDwvo@CEcySZp1$X&*uE=2=^kX;j)!NO9$k&~apn8(Kl(te-*-35H}ziQCu?lT zHQkMv(Q?Xn$`#7VRo=Ami_7j~`NnTu^S1A;<+=I|%U@qmYjE0HgC4Qg{g0l)zVaV^ zn7;Ka8wf;xH zRO>(bY^{I)7i#^@XR+@;Q|o7&#O`Gb(TEi=7Vh6wb%zj3`M-0%*-zHNqRVw|YUZC$ zZ)EK0<>wC9{p8{Oes-Jd7>{*s_VB43;?dMgUN3ua&H36E(EVYS%RTjS?WtOKW_FVs zHuEQj8-8)$t1pHgIW{%t`OQ1luYBym8g_0xe2T4n>_XjVj!i|szd7i7`1BifH@q+v zef`FF-C(@)t-1#hZ>FMOK|4JDV8vq1&ivK-{PT^j{EzYa9bVVswFR$39@mfV`{9>A z5y)S=76@L4*1CS=TL01y);C=re(B42?|bQm^~a`s%bGUb@Nn+$&lzuJqBCsexbeux*w;j>SlyJh(= z-PsdIpM84j^tLsF^=}4-A33+|;`H5XcY$7$UHjp)=evIO=i|?w*LB_sqE7omufIM1 z?9=XG?^EvCjWJcz&F*~>eD^-ocHfOq{j08%XV33$@2}5&4HMJ8;&r>N-EE;xSc9ar zyYb`95v|bs=r`x35^qn9}9c#`gkW$94Lk!~4+(OZksBuFQY7apfRz z_gp@n|0Ve4cx}Y%R=kEezqT&Fac$kU81p^HHq5>9Kz=QTSJ^U+}V+ z>)FO5GXp=>$v-n_InG~}6MW7sx5kIaI9qJy9V|{JV8$gg;uq4}8NRX(P8m5(VNzrQQW@4BsgP1>{b_`cUB$M?M! zzjS`L!^!Ws(@~uJch3Dgxf0~NbN|k{f9Kr4bMD_c_wSthcl<=K-@lXj6~}2lrg)W) zDPHAcipTHoit@W=D_@iL>^#2jwaM{)uf;E&-?cdT9d|m4lixY{om>g>-O2Bq{Labm zoczwo@0|ROp9uE+PUcq}r}>!TRX(P8m5(VNzrQQW@77uQnzU!<@qMpNj_-Rde(C%! z;N*AQ=_pQq=j3;CCCGOtzjN|CC%<#@J14($@;iPa*z-G?UvZq~V~SV#nBrAF#`${u z@Q&BvfBTOAWfSotJlCn=fAgfUU;N<{PWuRL5IRWc5TV0_juJXU=p3QX5PF)>GlZTc z^c?&>2GK2z`do(}bQO^emz02t7~e zf=SEqwHA#}@_KyDWPF-73YrcQIz;F&p`(P(5IRTbGlZTd^bDbA2|Y*Xc|sRVT8?jh z(fA~<$G47*Pt!(0(?LRq2puMLl+YPM=Lmg<(9?vTA@nSv=LkJd=z>X``_KA}M0q{F z{hSng(O1y4LFgc%Lxc_!I!fpap>u>jL+EKj&k%Z+&~t>ICv?H2<#>9E#wU3-CRXSs zgbourO6UxsbA&!a=xIXF5PFu-bA+BJbit(M_*#p`CwV=-W->la8wE`V z2^}JIn9xx|X9%4m^cg}=6MBZwvxJ@_^gN*pCN0OezG!@s*W+79#;0kcpy?o?Lxc_! zI!fpap>u>jL+EKj&k%Z+&~t>ICv<_((U8mPe}>Q@oFP20@N+Lr&Xy2jlg4!ng}(5U zsc+eYKEd^zhe%stLWdCBwf$}@wuKNgG_GUYENiszIncae-Urwr?RJy?$ecm;Q_m6X zSo*MI=^G&!Gi?S5ZIE#V$=Wf9AA%$%K;P;o^evmvC-{Di6Q7`6-5<;ySK|E-l6f@9 zc!OlG8pLnV*Y=5@p>N@g;659!`{^U=ff1kh2+c^lKGH5De((`LVc)`G-@;+v!Wn7TN7^+A9wc~(;9-JC37#Q1{ARTUzgaZ= zX7vYtBe>p2@SDa-|ItqiM?Wn)=%*dlH^fLTqWKrhOC(oSx zgU1pP@AKO|SC`TcNqw=th&ucEy`HtD^m9_5stWo){>F1-Dg9}wFC9o~L4RW@{ixJ8 z|GK=cfc~s5rEf@m^RLTm{rT;l<$Mo%aF3T4aaNc#?+lmKsr$e9T){tk@SYN-;!27 zty90J5dOBy8X(jD*0RO^?yl0`Lca=s3w`1_NtXAw(03JADDQ8fUxmMg{u2I%97XzD z(k}3FeajfkW&F1>yeL@%cO#55Q7W;c0f>u@Wo9kEMZ(-l&JI<8%x6rS`-$K6% ze+&I3{0%vZ^tYt7zh%xT*SB4U`0dvI*0RO^My^+tzlDAk{ucUt2)0t*-$K6%e+&I8 z{4MmC@HgZr(%+KS{+2ni^tWAx_)Yw+WsCjYU8TQ;eii-}`Ziy4ro6v}eii-}`c?Q_ z=r7@K$Wf%fC9VA}KWj;U+hvH~#NS%B*x&oB^taHj!rwxl55ZQ-`&;N&;cuZ|g};UV z68?r9MfzLP+TZdsl=Qb4(r0lw!^2jWWKr=LN3cSp)bCl?Vbc#OeebrC z`a2hTZTeBAU$?8I{%s4l+Vpcu-}k|i`o;a9R{9NhmDDfp|E$vY-&0b*xc~D?zwxS) z`o;a9SM$~Q>x$+ps@8-5nTpoKw6fpu-IDf;*PEg2`#xUMe(`#aD*J8El(b*GU*^?* zY`Y8gz3fu^(NOlAJ`Ver-tSRmf5Wbl{ol2)+rEC3{-zI>)Gv-d(@MW-b4mST`-alr zbd?xysd&ggtF$f0K1AWMH)zt_q2e<68MY1~Z zyhRb~i)0Pp`KNm>^A*V&!SlN>T;?y5Z2-?l$z?{7tO-1Sv>2CdDw6F1ZP7Fx^UG>X`<0(B(thRVi>Y7n`6Bh%lSMt3Z1H}~ss2}fzDWC( zpD$9s^7F;)Km1zR`6BfzKVQuLZ!2lPI6g-`=KNNEzDWC(pD$9s^7BRNSAM=o{mRc5 zQ@`T##q7^BCD&VVzA>%VTjl4Av|su8BK0djUrhbG(Ep0g7pY(Q`6BfzKVPJN<>!mp zpUoxxU*dc*?eqA!_t~Cb$9I@(;lqf#X4a!p>oWHvq3U@m_-O0e+2%_YvGv zXeIt>CH`sUIgzk$T+nzI^tFF9?gfsAXbJsBqTg2r_XF4C(smkw>v3s(4{+@tjT^wN zbwb+hD%6nq!pcxS0lvbdH(b!T54i4+#v6d^`O>%-_)f-V#XgdDB>meOw#D`CRU(fq z^bp_nSbbdyT~{Y>-`L&$hr zE&UL1?Kh400=L%51&t$yxb^ziIATsoJP6!c55x{)3mKQTgIGcQqwxmddb}EME7TA_ z*I47~1x{j!g>M3``=j*{E8HYjaQ#^kH-1~=Cb5F}q{p(^SLi8;BUX?;X#FnW+J_oP ztRQ38xB=YSI~O#LSV87=!0HcT1+lMj#0p|x;v&B)U`6srui`VT#m|BdN!|l_5G?#A zQIoJ(Nt1+#Hz94!^%6u>F>+ zx-#SGyAtv2Ems*vS7tPp9ZrvraR%&A;#e}CkPO&(dfZ~b-klgvB}R=@Y%FneVDFy( z1Cj3jodIJsmKvGFKOE_UL4O@$6 z!E`~Z?tpC;n$bXIE;yD>4wd)7U>XgTZ5@r2oPg$@E7dw2T(s!mT-g;SM=gU2oiYG`M;$euyh_0Jta8XgC>n0t@x^B`juInZp{y?j+ zsNz4)X2fRKiUqT%h_{UsXtLU)0Qr@O^}HT$1No~}_-$iVkVjgD*HMM{hZcU+s=i*X zy(?vh_m3wayznGL7K;$W?7My7ppx*br8jG#LT}(e_g)JDakyvCj{bd-z5NFc+6MCgMjDW3h;N^aZwkBrq1cD?J|AhUnWA7)z!E9R!_;W#dPH2LmUX z0!I?Dp#-!(64)CXNyY(B#YYE|sTL>>Bu7%Q?BsZ2Pa-vviLry}OnNjuay&8?OF|&iE{K9t zEeSppo^}a#3vVM6J3g9@!3y?qVl0w1D+@jnPfw<@(B+$SEW+hHr3`Gl1IiJeu0XbT z=iW#!qK8nKoJjBviAWIPnZWKHqN!%?C!vvzjR4_cNw9;liA2Oa)P!c6^eDz#Z5wfW z6Fj0_qKOZkII)ylTlug}zh+|N*`)A3yqW?|+}bLZnB~^3iFn77(?!hM4Ry2#Cs~%Z zv@LCj&!5@9B12nIbBUQwW+J1pA8JKehunXE Pa(Tyz5}&Yk?(6+;ky()> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c430f70cd93e0c62b3701df80dc04cf23550353d GIT binary patch literal 1304 zcmbW0Jx&8L5QU!|2chNtbP?Pe*9o!YZpnQt zHcMG@52woXmp8>6^xTZT8u8q%txYS>;q1KnJH5gF_XV3h7vy}FGRUFR@&>j( z^jsuY-e8*(G<$AsTvlA<&}`y4<&Jng>y3frX1%*wZ_c5)sCUHcJ@-nzheo~hdMDNB NUz@6OPW@KI?gtv literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9bcc6478178a8003997667264cbbc0cdc969f7e5 GIT binary patch literal 47704 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 JSi27N{WmxalkNZj literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..85ba2471ab5893145e77423bc982d8b0ed525e49 GIT binary patch literal 1304 zcmbW0J#GRq5QU$Oi6|nGA_WB!tB3^zeYSyJkn{2L zoUnev_{T_dnOFf!&PyM-2G=blww-8L(`&X_5T6c5NkP<~HLb0t!Rah`G_Dh3&TYwk z&NfR~au3JL9DarW?_y_M>KJ5^U};=ma9_xcdfV&GRqNfCdQ%Q9fqEwewh39Z`Ui}^4;BbAx>Nf~-K1mtm&}n%C zTOWF^Ay?j@O$n+!w>B;-&T?or@tkr;yq@%)1Ig8TcctExLvvB@h}V1Wje7T$dg=8} Ps?onTR^^=fEsNbRlle-z literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bb1a0a07e27a521a4a5f8f98ed420723798284b4 GIT binary patch literal 39128 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K896.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K896.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1e3c76cf378333b2530c4e92f34273f940582cce GIT binary patch literal 1304 zcmbVMF>V4e5F8s5QA8p|3JN4n5f7kD#}zyz1rNv%a*^_o6#OG8C{iLmMAmyd*k@fL z3m5jSy`I_e4#0)GnFF2xET({b_T%KRiC;}0+U(zepDo}o+lRR2-(}J~OW+dZejJ_~ zwoVwIjcG0$D`3feSp(1Dx`o7+iH0@3X30YFIm)T!EY2jis?h{2be(N`m$ySKAx;W?a~SAWMId|x|Q-Gd{F!%#Hwobrx%J?U-b51}8`dUvJXgrP{(JL2`8_eQ<@O1<=Y QC)Mb$Hdf`F`YnsyFKPx#>;M1& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ef156279620107971ad51a81673bf51124e54267 GIT binary patch literal 36056 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 Sy#C&Gb;s!vudsIC+Vj6m^Qct- literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K960.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K960.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..05dce0e338017b0d107579609491ce32f373ff4f GIT binary patch literal 1304 zcmbVMF>V4e5F8s5QA8p|3JN4n5f8`%B0<4JQt*g$xkz~k1rJFJ0_&j=T-fYK1ygdv0&MGy*aBaufP$z;pL@HZDAeqx0(T*n{)6gVj9 zz|Q-gYsf1-SSNsL&n=CY6=xWVCZ1E?0k0>$JNZNCMz!8esW)LL67>#vz2m)6@3vAe Sz1~VS`m2pqIj4ThV)qO1a!nin literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_2col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d03703942c28db9c10795be104056637e86a2a71 GIT binary patch literal 37208 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1024.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5cbfe311b36dfe8732fe902ba9d86f026e92bf6f GIT binary patch literal 2592 zcmbtVL2kk@5L|~qQB|oNdguX(9C$!~&>VP35B!5v>O*?yLr~R2kBAS^$=c)CCZdbr zV8^j{W@mR|#MQI86WNGJb1#BN|2w$qrGIMtGK|$ppu%r*DKbrjWE(@LsWxm=5Ns0GnW-eu71ptRsk^wtbB>jf`k!W=PlO}!;=d!ycsQEye~eIsup z(uIsMnLW1+yfgwa=(#z4HR8F4us10@*Ds*wLlMI z@7oZG$?Q4wK%>Z(VCZ{zPUo@*pPAmNp21+&`*o%_Vkj2%P7A&0{Y`q&d&U1xFZ!E( zW9YBvZ4l1jD?Eq(Dla`p40=v@r;Kz&&6+Y#B^gZkj|4}HK;KJ*~$ z=e1}MN8V0P>R|TVI`FcL35Ei}bILn%-$Y)K8JW#`H)nbyhGJ1~>2-K6@+P^O^=^%N zM?B|w8{Bg&)^(oKI?@@$NId8JJMKB%8}ZzXy-)t7%{_qU@}dv_^z1>{Kl5DV-Rnsm z%sqhT6qjX8Fcb)$3;Q{5i?~7W9huE~;kiO@#851FPWMMV7kQIh&3fTElU{nRLpBS| T2o-WpinSZoIF#+fU0DAC5>cEj literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1024.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3bb93a77432faa6fa8206ac7454008f5750b3515 GIT binary patch literal 69484 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..41743a80d07600738104ebb0d0f9ab2a3ef2cac1 GIT binary patch literal 2592 zcmbtUF-`+95L`Q#fDjTXC@7F}MIMkJa77-#6H?>>{2+(KLnwF%LKKuyJ`~1lk9}vX z;3z44w`cFn&hErwn%T7xS&K+}BZ61|+Z(%bZ>BxbxF@E6Ks>0)bGc&E&n~Qd0fJPgYD!s!xBCN`j0|~O z_F~Ly(1-8iLhO^A?!_|ng6KK*W6*1$G~-QryM}4idcn&a|4bMfQ*X}OU8r|msn=$D zH{@+adS9_yt39_3yfgwa=(%h9s^GcXus6v(*Rv)!`+4kV^$gxZO-_jZ5{8DDftK53 zy}%6O>^q<7)@sjT2Aai+JB`u;&uNg);C-m~dCG)py&t*WgrQi}JI(ZB_7~~J>=pk% zy_oOlKZf~w-WKUhKErdEukzA!#GvPdcS^x?xaTw%v(N9jM(at+w8$fGuP1e>_S`b?vW)`_1%l_4w{YJ?UfImZT&;JV>rEJnMZLM#;kn2= zsI^+}wo-4wbDp=wJ;!F9=Q-^ook5I&=lp!jp3}X8=VqL}tRhnN4B)vqIBj~u;0(h4 zAJ0YJPd%wi^$g%S#bp}@7zzZ>h5a#ahrFow<%-PJdf~aT-h`o8@SN@!JQsNfwN~qe c=c@G5b3Lk=YendgF_Oh5#W*zDhr1B}0`6~^^#A|> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5dcd0bcf06aaaf3163f64cd197701faf46b1cc5d GIT binary patch literal 70765 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1152.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1152.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..33045e378e7ec686362954960ff645bd7b7d62ac GIT binary patch literal 2592 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 Xdvw1SiS_q;mv@{h@d<0^4ZZ&ZtHsaw literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0614a3f8890edb913f209648fbc3107829208b22 GIT binary patch literal 2592 zcmbtUF>V4e5L_PzK~bboq)35;3m(7^LP41#KL`c?;3DM#c|wXj1Vt%QB3_aokh!(T z_BkhF1cmSR?48-!9W16Ejg81kMC`Q)UfpkRszv)|UFg^9DDu4(sgB!8`>A@tqUZbp zK5FE*@4E0Ko&&xg+`io6!%Sq#?|9bS6Vu!yPHJ*okI7+BJXi7w2vVJ@sgsxocLy>V zNqH@M(d9Mh!`E>p)q|Yw#oYIT=sEAy>oriC@kYJ7nrX#)!OI-?j2IeIZ_c~CQ17Zx zZb zcrNfJwHE8$6zc8qoa42)=h&?CJg0r6Gl-FR&ds;qbGp~#xe;eCZvm-z2Jqa7gVSfk z&=525`+qzacy|$?cn0vC;xJiv^wM(;s+nj-=#Vjz#U{o$)Y*r-5dQ-7m!5e5 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1216.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1216.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9efc0a1e1e33a2f2bc05573e4d450b07acbf1c04 GIT binary patch literal 70508 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K128.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K128.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5fa273b74e7d4587464ebc550cd7603c9320debb GIT binary patch literal 2592 zcmbtUF>V4e5L_P@grZ2HNRa}GD|kSDkSlly1^?h8%#Ip6#57 z5fnbJ?Va)L4i;BWXHH}-BF()Brv2~esuw?N`Y?>uS>$^sQk{2mzf`?p&~xDcKQ;3G zTn8@VJK_A)@5>_=mLdzT<6Co2T=$GPx>L_Jiw=Y0Rpb*8q`GvcBry-3PGoWt^ERwS z%Ii>vuk+ILU#`U})Pm?a?;_}RP@3@$dOOQ1)(c)s(#e3KA@%0G?TvcZg?g(@?}ogM zNOaX=&us%QjX(@~Zbn~?cN zOO|5Kp$D2p2SgaU4$tW~@4-ISyVoOrDAxOt>m4u@jC$`fz3BZ-deM8u|4%RaoBYSn z-=4QYI+LOIT=>qRzsgI`5rdu+z9}P~!#k(B=zadq)%vD-&$W8Q55+yGkFK^XKWURl z(1Wm_)}lckdAlK{*mJAE%Q8k7iU!Xq@5p;&ymBz&V!i8J?|`9T)SG)9o-^LgXv_a& z+d{n~p6huVymKtpb)M5Y(sRU!JlFSk+;h4&;<+h%FB>aHaS!0Rsb%@eCW*Y~!u}u6 z8Si08xyEyf%Q8k7iU!Yx{gk)GeNFF=5f|%)=Tf}`hJsP=i06#=V6<0xu1GIE*MVcM TJgAU!lErR_aVXh`yAb~Z{7{)~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..6d7dd74ffc2f7712392570b9b0d91c8e03443394 GIT binary patch literal 85614 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 G_5MFj$A8iQ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1280.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1280.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8242a1319f7543fec4ab84bafe1b5274eacf0333 GIT binary patch literal 2592 zcmbtVL2kk@5L}x;QB|oNdguX(9Qpu$&>VO`pU^}9fh+YPJ@61z_0S{YLv*t7IJQZt zBRJTx*E{3codhw}Y;Ht0B2wRq;IaE1j9s@+b+`1RJ&F8mMeJ$2Xt(S;20iBwaH^2s zKI_0u%o9EzySUtAVlRU zq`U@o_&%+~KFj4=Jo#D>J?C9|y#`7%-bnA1X~lZM%N#!k3|&)i&f8q6cT=d>W_n-A zTZ=e|oOwV8_*1J2?8!!}$dZ(FQ^!_Tn=)L0qrx*QA z-ZAvIBL+Pu{H6?e4&OP=Mep;`oF782fFqHyx=rME$ zJ@E0g7B%w7>zIqGjQGweF3T8UC>lKH<0)?w@rt`4bFtpdncje*Sk#+)9iF>NFFaSI zcffNUZ;ke{SmQjWymSUJBF}03kN;MU4R~(G-pf89754z1OJDRJgFW!^wD<5_;N9y< z9maT0aaqO)LxJEqA5VGVxxg#?Ihl*~!gHD4fT39MoW=({7kHz)7VCxQiuBTR4!2q8 TjZh(DBwL$)jYCNs?!x*P2v(mx literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1280.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1280.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e32e488db6cd330704a4abbd59a9b16db9a869e8 GIT binary patch literal 69484 zcmeHQdvIJ=dB3|_ujE*bSBYX4zgVx0Yl28t56h1#WM#?0&t(0gZj+97C9NDKdTeCL z$e~U)U}zv2P+HR2WSXfm83#y7DxgUdQ>efUkW8VX1Dy<=W&}eSlHrdPf#69g>hHY2 zd$qg1+qj)FoIBaw-}jyGp2zQ=^Sj@DM4s#$>KzYEbZGR%>7L=tATOB@ zih$!XE{5M+W^8O4_TH-}76LajIQ4j-c2b(Hexte{vEixHQsRl2L_J))0dul z#BoBLsZH>+Hrr(EU*unEl#u`I?M|g)k(eWgO^XcEF7Ks{$!ov*C~J?k+aeEOW-!|` zIGj0=HM_4h&>*&m@7TO!-S!(CXDdGJmu_m2vxAN`qYpQYd8;_EXYs$-r0MFu1uZyE z0)4puPiGbzFrZ)n3oUje%*MtxW=CE*6lTNZAJ|ck?Re}uVzWBgXIWs;xmj}MIETZb zfRhe6-Ol`Sv+_2Bu^;WLi8;k4=X?$gh8QYrJ-4!O?6WHi>n^M;JpB2Uh3~(xvT)7g zD+|v)yK-kkzWwU~XXejd2YT*hpl5!0Dw1#iY9Rm1FQZ~s{%-*%@u7|Ie&YLq{JIBg zgAVX_z6<pD3`7d6pSvo$+KChz8n2WkpGoR{R6FJN*`)UQ9qsQu z>32JS+va@6+02ff*b4tonZEl6!JxC^lfhnR=jqf;(?hE;KQ4d&qj!C{HX6CwDKvFo z6(w`5KQP@1&1g9rIU7jk#Vl{y{JCZKIfb=fyXwuz8{vGzrtqtaY7S28IT+$|J^IjD ztgGl<53p}iZxbXqgF1o@(Ux7T?&A(WsYPq+8Va8aHQd(uvl~7%8$I+XzITDIO`Jo1 z^N+>Fd!w~yBZbf9BL(Lhk-}f%ch%P-g=-vEOG+M0{u6!sh1%%CmusWneW5nG^M(^&mXUU`GG@G=Y4@wOzVQq184KlqsbTQ>YR_PyHMK#yf@|K^N)SA z_H1o1H@hW>Ityn88h?D>i_a$?JT*BN`q|YRS3LZY8t432>a4Tk;f4CgPfe!3eQhG} z!2Pe+zw^1t^sCps{hhJ5y;1)W=*?vMi)e@G4`wXp?988UEIhk5Q20JRzr^Pne753q zEEM?Oec%1UC*p-`*29C(vGsxP1vb9$osCUvQZIY~-+NwoZsV!R$g-v_?|dNt_vd48 zpf;40u5aIqXPbUJ{m9ohcRn!vHdKJ^)_|&0*s{+3n{M5KQL*yde|^un zCoWa<{>}Yr|2R7ytjE0mn3Ll@{-b=lE)i&7zQM^oePQ3n`rqAKcVOb&6C)oBZ|O@T zDIU7&*Tqe5AyOn8|l@Kst@I%NYKQK z`d4h=j?LzGHop@yL44c% z&fdSX_wVfeyS?`QUBKSI6VC(8{X3Cwu``9p@7%V^$5gq>$CT~FHhS{A4W9hYZ9A{H z?K)yt&hO$jzhk6hv-zFP@5D?H-!{Lq`JK)0Y<_3+JNtZ=oe|jk9wxsN`4;nw{LXEw zd`y+Ad`#JR?+&kZiH+@#_wGXMDJ%bo=e;f)&wE`qp7(0Ia(;I>goe`g{X3iA{kFa@ zXrIptohYnQZ))22?-(OYkL~++_We8i{+)gQ?tkI^JDy)Loe}w+$hVZO@-bzrd`#JR z|IU-&b?SUg)aSPGyw_EZ=e^ploZs!T`5hx2o4tQ$@85};AinMWJA41m-oLZ=@9h0M zd;gA|5!m&jxqm0}E9R&9n6gzqrfijuDI4$KdGfnvov(@d+%}%~y2|mqSKF2IyB3?@ zG19Tw{LbcgVkU@ho8Q^|&gOSEzq9$B&F|P5!JXfU{EGQ$KBjDyk11Q_W6H++cb@!i zgU;7PeQq1idtK#t-mC4(`CZ)RcZ_swHovp^otO#Y+vayRzq9$B&F^e}XY)IDMsVkM zBEMpOnvW@4ng|dUTs&-?{?Yzj**Vd-oLZ=@5D?H-}e5Uy?35#0Hm$gh~6=3~lM`Ixd*KBjEEf9J{X zHt2j!)aSPGyw_EZ=e^ploZrQ5e#c11X7f9n--($ZzHNSI^E;d0+5FDtcQ(IcX9RbC zC-N)ir}>z&RX(O{m5(VK@898HZW9~ZAMf9Zckkd5^|@_4?{$^qd9SuB=XZx4`~IEa z+2(gPzmrRj|JeM_=65!~v-zFP?`(d@P6+P&PUKh2PxCQlt9(q^Dj!oe-oNwYcbz(4 z6ZN@mJnwat<9V;PE9ZB+Y<|Z`$7b_8o8O6ci>V2qq56BREg+6v5L3&k#II@EpPO1Q#Wi>relUaB7?J9SSKNDHgC zo+Egk;G)EGz3Kl)klJQ^huG>JgJT3I2u>25A~;QOj^I4OQv^>FJVWp-!E*%9 z6I_&7jHk;pK4GgdImJ#gK7(V#pCC9%aEjnG!8wBS1Wyq>P4EoCvjoo(JWp^@Vllo} z&-jFG#@9^7XK<`&aDw0@!6|~%1m_6O6Ff!mG{G|j&k{UG@I1jqiN*Lfdd4SgGrkRE zdmCjJi${0PZK;t@GQY|1kV#(lvu7eeUFgZW_*VjRO?UUSkd?s z1Sbhj5u7GCM{u6tDT1d7o*{Ua;5mZl2`)-3#?$2)pRm=KoMNXQQ-t6c!3lzs1g8j2 z6PzPBPw*7M(*(~DJWKE#!Se(cB^Kjr^^8y0W_-mCjJi${0 zPZK;t@GQY|1kV#(lvs>!qi1}=Hsjks#%FM>XmEnyB*7_y(*)-T&J#RE@HD|Q1kVyY zNANtsMS_#bfIfex2u|V}iU|w5227D_EBJXnApLq@__YOCuz5nwA-ocPbV=TY^*;yf|I!BFzuRaBltC=)NTgj*;V=AQ}k2<_CV=F8sQm@aulUug43&ZVUa<^`Jkd9x_+a zA5xDw?g^qmmIy^Ds}2*AzKk;74;t+BK|b-=ZGKU(wt*l8e?4gxL{nw zZ{{J!Mf_&HU|hs+)-}du{A3WnOALG(IV_e#gacMusrTq>$j;LQBN7S#6 zFY4ER)UW-hU;9zN_M?972X7jKH;uuYjt6hVZ*(5K5x>zN@J9URJP6*5pR5;*OY@0w z>EnfQX+OrL{TP?_V_e#gadCfxIQ+b=Wq~^W>&#&cp*ha0aER~u8$(x?icgAoULTGB z(Y>MdrQ-7*Zcr0^cadCioUuaaynbUIpjdUDk*)!?!70 z%J&9{R#p1V;;Z1B*YDzv8Rhxr@m286{o3f>R zcUH+akFSDn9`E9s8Rhxr@m286vMN2{ z@m286<6T@cqdea{z6!p1d=-52_zHZZ9Gl=?!H;=D^ZysL--#oqo-zdi>_!ijkE$(p$zTIWeZ^E}JTgrE5m3;H~ zD){E{F0PqTo^Kvs1>Zcr3ch)K1-?;^P4F$S;al805`4SMpx=aVQ?``vLsjz4>RhHvoZd0#Wgd^^UdR{;G4%+!8ebuz&FaV3BCn3e2Zt5f^T;j^qcT)%9iqds7k(hd=-52 zcs2yrR-SJjUj^Shz6!p1dewogmbpbzQz5n_`K?m^T+OvNGrM6>5f+fFN z?T%OV*S}e^{+kxx=Zbd%k{{<$)E{wf1V^=m|IWpvD?X;;Lr;~A?^@jDichNey7MLD zcQ1Ck;?pX={-u)f?_0dd6`xn}ksp+d_x68U#W%iIGTz(&Srs3Bvt+!t|MMz-?Z->T zd;34Hj@R1Pd>yZOH6NmPp#G(scRoz3`Ws&=S-*F_O{@AN`<7M?k9R(&RsEZuDp|jG zy~K3<#}R+&^_W)uX}Y##f4u8GrsJdnY?VhrF*sNBrhn})V*gC)Rl&yu$o_w#vOWt-m7Pzy6AN|N1N9{p+uY_piUQ z|Br%9U-~Qi|5V9%uYM&1l7IjDEBpUa$@;zel~?uq*I!Y;fBhBl{`FVH``2F??^}Om zf9_a1`Qa&{zarkh{)%}2`YYo7>#vOWt-m7Pzy8YjOX@GrnVCL8e>o=l%io<~Wsau| z`Wqzr>)H?c8zlPcDue!-`@x<%p}#?*zpnkDzd@qEt}^Ivkm#?g4Eh@+`m4)I=r8UU zVdD7LUm5RPe?`21{gv^)^;g9E*IyCuUw=isfBhBl{`FV(-?#qC{`=Nn+5ht;_0*d` zrUR>G|9$JPi1)9*BHq9Lig^F}E8_j@uZ;Jtzp_8R^;g9E*IyCuUw=isfBlv5zV%nc z``2F?e@Xpis>Aa`=r6}afB8FqQh!}#(BBZzUsoCQH$?Q;RR;Yv_j5h%L4QL;e_i`Q ze?vrnU1iYU5Yb;(8T2#vCSufHnel(hKc^V%AmjeN}ugl z=cyC=YwpK-%AmhtqQ9;>p}%3~V0GgDgR2bs8z%beDue!piT=9E63!ZS>dCWvElz-7 z_`w?YZz299{NRTBL&P6~zh3$i#9s&h?@50f@z=v2k^Us{N8n#6{T;;L2>+GRzn%Cu z!H=Hv{?rkFsJM~ctKt6W!bUyD?PdIR@Lwb2kCON#{F(>iKU&6r0DjF6iEo5okC*sk z@Lw(4JwW_x;lE1y_Yi*+e$5Z@hl;Iaysc!srTuk?$DH8>3^68=@vf1LQ+;BS=v z6!AylH{&(+#NapMGX6&R4bR3ODt3|ncai>=_SYfa^xwoM;l~3MKCZ?E<39ku>8J4@ zhu`pN{Gs9z(w`%`KXve%c8$LgepA2kcNA+#e`<6+-S97${oJ%*{0HDS^ThZg@Lw(C z50Lme_;)+bEMLFEFYwQ6oUMU(tYm(yadyqiIl&q?7=Aq#;>Q|i|F$rX#~Ro1SmQym z#S<5;eYrmvFRmR^9zwSS27n)Gg56uahIdA%jwH#a_``<+BfhHLKi60sgG;7n; z1FZ;}wQ2mD;Me?*53Munl=#=euh$*%Ljy_wkLY%xfux_t z4-F*k8h=}{hV;Ki*8>eC^Tha}b%cN8Z-n2B*Z4QVZ|1-8LmPuc8(F)vTql2C6C~Qm zt~j}dKpPEq*05_&@`V@R(};)gbdw6+jGv@t|9 zR@V=0WcLSnKcS7<4{c=E>f8@))P87VNk25u^q<5-(@OgHz_0sB;-PgRqOrPNXiiB# zG&y86!Spi$zvh|LzXg7?mQ6e~(C|azp{0gr;)j-+<3jw<Q$NlHAv5=kAKGZ< z$wI3hFSN0wAKFNGF!8A}erOaqUM9Yyj2{|Hcr)?PK*F2xLo>;^j31gtcr$)zV2Eg) z9`8~3i8g9KG?4JnrTyJy{LsKqt(>=O7fgH`{N}hAKQxex*Z84nWIh-_w2>TlIT z%sK0b?kBV^WVF}#p>?EPIf_!?agw2sto{9EAHI1$0h*jdA_1C^#}KQt|@*IHnW_CwRcMANh%nike;pTtAc!bIzIJTxt=$4KI# zXXg(|%}LNk25r^mAdOj&Flsw@ducqA<}e9S=<_>4!!c z-bg*jyTWFTn0BE#h943S?J_(QKeWs6M*PsIuvu%SerS<7z6-6o|Hzk0`k_UnT@#Od zENtey@k7%H&&ChUAv_rWTKM&GC;fr8gpHP(cxVwhUdE4njEvX#p)I7JU3$F8mrDAf zE#x?w_)YNZb+KUlxRxyGhvty+ns{gnIljgZZ6WO*(fx$Bkot`u+Cu6#erO9BSBy{;k@0gK;(!f1OIc2d|OlqX=~_^NXJPvJ03 ze9)PNoz(F`8jt;hvRLgO^6Ve->>r~0JH>WkkXZ-zEKz3a&ZGPN{&F3w# z`FbWc*LY&{a}BZixt7>GXCXGvhl$Pea$@uA6=L)2K4Oc11D^Dsml<398&k#>|0V&m z>DHY(#?1gG3ERFZejMjlf*Tdje(R(!g5S5gz3Y*`>4-dbaP2dPum6{e9ba!tyx}-= zsFbx6y$tnt+&DQr6g!n2J2^NyazniNxxOJ;{&5(!_0u$pFK6$mlX!gzR@vlz`Qd%Hj*8Rjbw(iH^dJf*n7CA zbMNkWY$!8wVj^<_zP@;D{B#bWKQ|FqweX6wljGTu{%rqy`ZMF17>avDWj%xaH^dW@ zI}*+D*uca{-#EIS8G^c0%@HG>6e;=@sl*Nkcg??#6bliTC5(Sd=J*>PqhQ2*_tC&zCw9^p7*qDA8qgCpbZZ9U^<`!G0i za(t{*7ce5$1^krm0y^Zc3w^g|#$wl&?Z8Oc9$=8H2Q8)tZIp!OOOb$RLqcmy1rmBk zQPWb|{pA_x9YsTBTSp@$4?uI*y*>um0^ks<-F&QEn(Q&;H7o{2<*Bc@0xZY@7$Mr`3 zfR!vN{l|3|v^lVRQEp1{b~1n_t34mE#6s20e)-*OSqZyvQ5$kiy|I1N#`;4ymR?-0 z`Yu;Jtbe#x;Tya8B{mKCF!$VYelT-lun+FZzM|WI7-zc-$PI=2v!{0r zjrQG1ysFgx{%$dV*>G%R@UDsM-fql>w*E~2wrqPQAvcsB9URUc8P5#oP~5z2dwcu# z_H8@1q2Q)0pI?VZhiM3#r0*9g9Co;E0u{Af$9|f(BA;uDA7lv+o4-x*y(8nhel7F z?itPuqCliwC`wGWWZ6(y+QrSStc_ge^w4MqwO}1*hkM55&fMU!#%8= zrIhiVw<5TQr7I{qxcgvFH`IfNOq|TJ4sj*uVVS`GUA(Dg#uJYi&zyjV$r3kvGbgh> z@}$Ni+XSN+Z?$doxtm~$c8Mnbe$;9s)9T{P3>(t=*X*VHkWifh0`6yN*rarETda&@a zljx;pOwg(Qe6q{+qMglrR@2>EdHwom=*W`0v-7CC^|rUR`_{L%yCCO(+y_mfDqf4a7xs%I>E z&L7~TM!tR5g&*-8@qOp^A~Sx+v*wQGI+#5}m! zk;zEP+prgXUV}b-?dMY6$>Clsd@qQe^Ul0p1Em>n)Z31kR;(Ai%yG|%p)vL5yzPm4 zSA}}3Oz$Ik8h^s{&dFTN%#M1K)O zL(D+St+QTW24VKC%d~5;=P(1!V#TdSae?PF$Y-!g^}bG+P^|Yo*Bdbui+abIUd;X^ zz3W1~m~ZbthWR?)2Ia9?M|ckNRbBKPG3YtroigA#+;f_X+2{9Mt#_*R+$JCw&!FC# zT7kJl4E=%``2Bt_8sw3;W9|{2TX{Jg0r6Gl-FR&dqn&bGkR+xd~@4zX7Ru2Jl?CEVStn zgER2^|2!9XKlG$7#WR5C6qjvGFcb)$^ZR|?7I{JM@|?`Ydf~ag-iV=C@SN@scrNfJ gwHE7z=Zf^wa~-O=){4*}Vs{{R30 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..90818655750536885a534c0d73039fbf9e2dd52d GIT binary patch literal 66920 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 a+Z=C??)M_G{(kTBj#FhmVePu1`+oo}xXD8R literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1408.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K1408.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..976a5d6637a0bb029d0321a81e57245cc87ecb21 GIT binary patch literal 2592 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 os5{*Ykdz@ONqXwF8Tb%`J z;I)6UP;_C>p#~boj0+5%hv&4fYw$MGd!~EPg!R53>2(anqTbU=FKYiUy{Nt7|E3r9 z9erb{@4(w3oWXza9O|pQ^c*qhIpLi$;W^xM8jIT3_gt%Y>Z)IMq;L(|ZE6+R8^_QY z)WFuqXVD>!yxC*po?93%kFmf|G@|^Q- zbf-4q8Z3;Lo+~gE2%b~k3C}sNWc=|Np0M8KkzU78BzR7FCp_o88zV&**1HbsrROrh W_1{TvtCCNP=lDkOxVY1HqW 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K192.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..736fe8c8464b2e3b5e6603a728ffd7bd49fb85aa GIT binary patch literal 2592 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 Ci+3&n literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8f6965981511671de3ee4308bd19b8ad7c3cb10b GIT binary patch literal 2592 zcmbtVJ8l9o6ntJBM1D$&6e*C{f&*}aY{5ZNa1R_Q2gngp z1%>}_#`E5+5o4z_BeE8e`bGr9_P00H%8%-H8rte8^1BtOj@w7SRK20mbKw9xi+DfQ zhKuMY93R?!dBDO#WX^T;mV08{Gv>*iTCR`eFetWGz5zk1b9d?m=98xbnT({oHFMGD zHORxyaUs=y)=P@3^3daoH)tQWkD34O%SIrZke&4qf`g?g(@?<;w0 z5f^TZuGn*%z)K?#gPxnwR|B5A3wx8ybB=fNwQq=A?z#7Hrzoex&?VGBL2Z@`)F9Tr ziNR9rIn+R-=zs)6*Wo$s^BR2i^xof8Iq zP~VofMmU2f<3Q`8{rpLj0v z?#PNSam0VC;xdg1hN8i9VZYDY;J%$+pD6u}@m!`iVki*x4tOr|?pjXY7VCxQiuBTR Z4&aZT!9Q-sh{GtEn{Mupr2B9e=6_#dqlEwf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..eb8a8b3737af3ec9fd9af2cfcd112da09dcf7eed GIT binary patch literal 69484 zcmeHQdvIJ=dB3|_ujE*bSBYX4zjD1Y#srb99+qX-NmiB|9+M0gnqfcKw_|l8P`~TfrbFJeD<99SOdUQNHJ~Dpdbl+%t zn3pUBMZj?<&c<&xJux{vIXphbqQ*o)XN~y%$#2B3vzsu;cjP~X(Yr$Y){!y_k6VH# z*{>!9*D;A!^j5OD9U!nq?ZekCugweJbnCHZFcP2(69E=g^=l79p2X^S=7|Nfz4 z|Ma!TKV?}V&eUf3S)1)n=wIfZYjhz0+1ry$+7a7whE0n!(=PADjp=K?`3P%I9Vy`S zaHel~G<_nYcVDleMr;v(dh3o2o!48|HhkDG-Q*%?2OVoh9c~))W^tf*>A%>d>F&7& zEm&3@eYpS6=9U^TpkM$C%{~&AV`FyY`9ongPx%LS)MHy7yN=kbPWD+5Sh8-GlifNT z4h5`K$m+2cR_c|v1&sY{UyW@Qo2~O%G#FwizwO-W{IM^r&TqJ|I{)yOSLc8H%z(!czby90Gr?${@5*KvDnG5_${ z)q?$K{)1}-%C8B9qb)PF(S`^4P%yFxUy@e-a~+ZB+KrLdXHP_5z_K_OsGGBH4cL~o z&VtRi+|-BO$wnEqtO#>N^D$L#BNI*T>zBTc&5jSPWP_rGUszY>KX)o}+uyAieBn?q zo1C*!fk^c8mfUBJtjDRXHW-O61tR&iPhAmRYen)6jh8zmpHHZLWIN^d*(~?@J?-y3 zsdrm{+irc{+QN>W*z*5RnZEm{!JxJ36TyCK=jr5J^FwPeKQ4X$qj!C%HX3QN^36S0 zM9CZ*49s>xGg{9^&IS@WG0U5`d~wBnR(}1ru6QHzS~%CRIsEdHoP)D!4u<$#k3Mu3 z>neKJ1MHjB+YAX#qmE!hv~@SD`?xsQMQiIC@?Q)!+}8EW>pxhC9{METJI~i9&LO}1 z$Kukx(b}_-{1U)>giHEemR76)_gZ@9O$v&{Fo_`AFdt^{6or zI6po2&-ZV!tjEIVkJta?fkRR2y@69q>w?w;XLHb_>1XQdtPgLvP}>T;H)-W^kAAoI zY;7=G*cwEg`7=X}KfmwUrxOpJnw}5+^2(-F4}ZAEIzN#-Ypr^CvHmlsrc>X)CLVa; z{#WYX@ziwc+F|;G8H+hP_ZLn1C)Wq^KgQ=(e6GT08$QQE zfgj!X!>@cimcMEvJop^j82C}3>6sriHLpuP^A&veKJ!%5sp-gy=B@8|Aous@?bouY zIcwE~{kCs>Bev_MUB9c}6#eyv9ntoCZj4Tz*@0HEMJG4j`0K8J`Pes_&fgIFY_R>F z_n&+0{0-q3gOg|Odg8I^`*&{WZ}@d==)v8uiv(^yvKi>OVz~#9V<6k*(WaS`{>}i`|A!&oqKHTqv5RsDI~=s zSDaiv{(khAji2!mLOuJQ-SV!L9V_p8;zBR00sEq~CEBram1W6ThPJ#5{!J{V7cs0K zy{IYwk@c(cpIyJIAO7HcejxuM>@YrC@VN<}A!cu^&u`gSzcXz`zGQ8l|K5l4L-2fL zLw)|U_~C@1l2^{LbWeCciWJ-CH}q6ZsZ9 zQ;7V|ZOeR2mdkuh+Lqns$?sY``JLOgo_E`I#IBs*wVM2nk&eyecP76RGeLZt{Lb9J zGxzVz{ky&9{$0S_zZ1^`^!+=LZ?Q9l$nV^?%*SN8%*Ui{*-f7OZj&d!bKBPQZo7`y zmGirp$?q8H*i3$B@;fmT#J9=sOnztbJCom;{LVa|WoHETzK725M83uRBENInG9Q!W zG9QyR-n+wVU1DSVGjcW>4A19KkL&b)tT-oG>N-~BJVf5-DHrZXbH6Zw|3Wj-ctnU6^u@85ay zyDpWliTd0&p7*-S@w`{rmGisZCck5(V>9>f%>6qt6U4WzcjoWknZJK${{EelUolmr`Ixk2J|=CMk4YQv z-+A)8E|sr|`rJ02_qxjQyjR(k^Sj+9zhk6hGxzVz{W~!e#J9PBXYSvb`*-I4owT}z8-s>vI^Im0F&hJ`He#c11 zX7W3e--($ZzD<5-@;j5?nf%V=cP77MX9RbCC-N)ir}>z)Wj-ctnU6^u@85ayyG<%z z6ZN@mJnwat<9V;LE9ZAHlixAYv6=kN&wE|vc;2h*%K6=4%e;RlcsBW+ z$?u#c$A3(IXYxCf-JroyqUSOc38Dzccxr$?r^lXYxCf-?1}-JHHe874y@4 zOxiLZleWyqq>cCQJo#OV%GX4FZX3^gUFCS*tL)18U8~9O80pwderNJKF%!hM$?r^l zXYxCf-XR?^Sl? z{4QqlJ4QM-li!*APRs=HZSp&l-msx1i?vyQv_!T&JjFA@GQY|1Q!UNCwPJ2 zqJzcwx;^6)wj7gH>>}gS*e3os!3lzs1g8kj5}YG=hTvI(=LjwkJWucf!9@p)@wIuz zCu}{w7BW7K?V`qUf)fNM2~H85B{)a$48gMm&k6a2~H54BsfKImf#%0GX&2PJV$VW;CX@<2rfF(;5fkv zf|CTN2+k6mBY1}3S%T*XE)YCV@B+a_2aEA^d&VbhIVP*vMaHMGP5g0!69gv-P7$0X zI7jdd!LtO<5nLd6p5O(7iw+j!Yx9gx*m`^|WPBRiMUCSGCkRdwoFX_&aE{;^f@cYy zBe+2DJi!YD7ac6d*W?+Wu=V&hk@0D47d4I(oFF(!aEjn8!8w9w2%aT)j^F~p^8_yt zTy(Ir-qimiNNqj7L+td(&xMhq#x}umf)fNM2~H85B{)a$48gMm&k<=kFxJ30y-lVPV&RNpfukKhFmozuFgmu2YU*X%hULKgX}QLc0p1U4;|4w$bhC z>oNFAyIrK+F4ArnX}62C+okGHB`_dttUp-#tIs9ylXmqS z$9Pq{7_Y*!)_T?M9I)(L0@nz-Kl)k*e$pSEW1$}9M?Hie@&D)v{x_+1Q4i^-o~x)w z`B9JJ%}xYV-{J(@5n);zVQMC;id$2Y$kjo^SAz z{^kNTA#^(#MkQy9D{4Bk{ccq4wT^Wcs6wf=xN;@9Uv@TUD_yy1Z0;Ld5g>X#CIa4Q(tH zpA+#kl;i*So6xnT;%7y?Ae`)l_${U4Qz9NWuH75@v!+zME#g4rZNUW%cs?1>7fR_s-cS%Nk)b64`zcQq~Y)5tgO-#@wiiZysL--#nhTNx#bT z&ErKU$qwcD=J8eV&EqTZjdE;)Z-FJJ_40jS&bPa)5oMZhUACO>t}6NF@m286;|X&D zmgk$t2fRC!=bOh@!8ebuz&FaV3BCmmz!vjcXca4C?{>3ImNmlGeCx91d>^WkZysL- z-#ni8jeeEqo5!d}W7kA7k&o_^+f^QyQ1>Zcr0^cadCioUu^DS~7F~8kq(C?t;TbC{88#z%` zeDnA!_~!9!2(GO>-#oqwzIl8VeDnAUe4`wj;9FqLx5y<0-|jN#H{n~CE$6$dO1^n~ z6@2q}7uU=v&o_^+f^QyQ1>Zcr0^cadCioUu^DT08!MD2%`c3%OWy|?KR3+a$z6!p1 zJR5>*E6+ENuYzwLUj^Shz5?GU$0qm|So1BeeFWd`GUzwqTbC{88`qRo=?Raof^Q!0 z;+h%d`R4Ie@Xh0^;G4%+;2Y)G1m6N{zQwh;;M-jW{SFcR=5?_Bmh+8k^{V*h@m286 zZcL4Z*dQ z=bOh@!8ebuf^QyQfp3&!6MPG-`4;!&1mEs5=r`e8mo4WT_d2W66CPg$-#p&MH8aZd z&Eu=!o5xqdH;=EtH_EXIz6I8Ni)R>uZ+98=JIoFgE5rR0UI*K6Ip4U~T@~Lvz6!p1 zJR5>*E6+ENuYzwLUj^Shz5?GU$0qm|So1BO5eUBBWzcWJw=P@GcUP5s^Y|+G=J77B znNgl^9$y9DJiZFPd3*)FQI1XUEwJWWJgXFZyUU>8gl}E8obN+b^3CI`;G4&@A-J~k zeDnA!_~!9d@Xg~Z@Qre8f^UH}-{Kje;M-jW{U&_tGR^m8&iL2jeih(W{91L^)mFrU z0$EE=>E5N@`x?;TihzhuSTcU66XE{pUE1r4w`!bt`w`SqXRYS-*ID;EyX{}v=Za6L z`18v+XS?iM+V6_b$^KY>;_irJC6>C}@v{EVPfOOnd#T$MUy$|J-CeT&o~1qRcv*k_ z8zt+%Y3aSLcq`!WV?BcUBi4=JsFv{GwUlth+cG}%c**$grQNRhgp98{Uow8rQjaS> zCFAR#D;fXZrJG#wIT;`MX~}qR|7T@<<1b3ad;4FI@zFO*#(Vp}Ami76tYo~m{|oYX zt^b9uRzkKt~hgn&F<8vkJ_s+LjS$|~T^2*`y&gYb@fAixd>-Vk~Tg872 z@fTl@DcPUqYfARVyWVXTe;MLS>j}Hp-X31d>tos#cQ6|Oe+C7c2|Cw2PuVWmQKzia zQ&ta~)ynnIQ`QJu%{NGPRlp%@vv&vig^F}>%{xkUlH$Le?`21{T1>4^;g9E*I%dqkAO^H z`s?)n@sjag{YnHJ{{8E()Bop6*6-D?oUGr!{)+nj>#vCSufHPRzy3P$zV+AX&mGGr zKRhM$SH%0*UlH$Le?`21{dMAf>#vCSufI(BB}@U)O%n-yqRnR~hs-Nc7iL2K@~Z{Z(Zp^cVMwFme3r zuM_WEe?`21{dMAf>#vCSufHPRzy6AN|N1N9{p+vOf8YA+^xwDsI{iOiQcu14V=A!L z>A!FN74iP{SH%0*UlH$Le?`21{dMAf>#x%v-})=!{p+uY_piSq-oO4j@xJv}#QWD@ zC;p=P%T$NwhtOY+iT?6;{v7>vl|g?)M1Ngn(BBZzUsoCQSKrU|ve;NuZZ`rzfQbw{T1>4^;g9E*IyCuUw=is zfBkj(?^}PJ{`=Nnr~kh7*Xh4+{T1>4^;g9E*IyCuUw=isfBkjhee18&AK&^b;{EHd zi1)9*BHq9LI`O{sSH%0*Unl;e`m64%LVr0X`pf^{0!M#cWzgR+(O*{?^p{`hv;FEk zbwYpj{a8;K^fyfO*HtIj=!Dw>*0?${si$y;9u?dcM*Rh{FgiaPU7DT zKYGslQ%C%vViUVp!~N04CN;*+GX6UFuX5s#lK2GtiU;C9TE>3>e#H-oZ-ifsm-ub? zuXNfyK>X|BzrykN5`Pqa#Sig^ifv@PZDhQq{dI`PoZ$S}i#k35{~E`CocP<}Z*=@g z;*Y|w$E)kH;n(BR{zmvU&)OdUiTAgIk?K{e>15EnxOe7erQNguT5PK zv?8e2ruJ`!U-3`sISxP37R3X!OY=|Sp)GozEVik5Xhlgsv?ZwLwvLa(uX)h^-ZK8J z@ayBN%9n~vWMzvfN*o8i}MO8cQ*gg5O!0Keu<`=M#U2In~T5PqO(gr9E0 zTWLQujm$$G-wQv{G*wR&em#G5ybZrvzl+)rt<&q2_}9a))*bOf14;jnsCJ=&q@UUk z4J7Sqe|xcp^uI>c0}UkeMEjw2gn#XCgkO(W`!~a{=fCzt8-qj}S-SEyNFP3=xf0 z^+Oxk{Q=%jXruB&8`-rw_d^?%AKF;b4-M4)C-Kme#YTfJd^sj!mrn|j)w+nen>pDRP#*y&{BO|h##69(wd;_$GIS+=brXM8}&R{ zY*XWfHkR~58wn3OK3T>OjUvZO$L}iRhsF}#bUZYW@TUFHOfoL*ho%wUv>zH6B3h@$ zdlY`6jmi%VBs_F0e@_`dG%!@_%-i*gI=&r#eO$C38c4>g{m?WrAG9CZNRGSqL+e8N zoOML?6IvJ2+N=H0I?}H8L+eO4^3m&+)~q&ADYIlf2F1=KQyhRADX87x!9!Q+u>L35G|$8j?b5svKQt<=*P5;$TBMKfVw>te@}-h~Xc1{w$0HvL z>p8Fe&@{rc_Cs?B58A&Tes$bQf1oX4t))61T11YQ_9Gu73+ZRK8ZYvtl746l zIgUDhGyG~@ENVZlB}@9DIb^ @;{Vul7S*NV`W=KcOw8e(i_0kovVB+Cs)vqw0aS zgtc~QKeUDLul>-FFwqcJkJOMb(-3~Is|ZEF;I>#5m@0;EJdTH;|or&Ea$@NEHh&=c0f%t2dHIGVJ zJJCx}|E?RSM@Q^anTeCb<73yyTCR=9?9AA}_~7u^iR)uilSA+6jNN#{WxKKy<9B2R zCU3aRws&Pm(vw5u6Qj(4IhZ*$JdhCv%z^Oj?R}GF`!GCqa&n?n z7ce5$1^krm0y^Zc3j?>OC+us=c3`Y*4=_m9gI3*xc1l9a#YjN3CZVmh0tx-&sB8IA za42Zg9dI3m7Bt|Gf>YzegXJ0MA4fxFTSp@$4?s)zrD`1nmu-Dpnbun`+1SBu+15MC zwSLLQj$xE-eS4YK+uqdJ*>q2j4P=N8F&QEnvFkb^E>bmiU8jX?*L7Osc3r3C4_L~g z)PG!eL7M|Bmz+&1-cAP4WVPo5mRQKT*)PAF?Nq`pT;zsaQ*CS?xv~Dxjincts=iBA z59=SURrtnkeu+&1KFr=*jvSRG>{rDVl$XaHIox$nc>s=gAK1P3=Dve_4Z? z(XPHDN4pLm{Xp#G!0nmQbf0tTi|zbCY&3nx_(W_c)VDb{Iy}a495|bv9Jn3+ci z60a;ZzrSA$U^W~Z8@_8Qv$qGcp|x$OZTnzHI__*JJvuy^IWn0Z&7!zvduK;S+m4pD z9Voad!{^uG@lhJWCh7Y`3WptTn?gmc*Rr3MZOG@EV+UEn!{%>uZ131)W@0EkkU4gY zH!d43_lsSUPP+HL-8a7vwZLcK;%PG(q#xDxcSOkn?R-c$?YiAPMPPr$=uiJSfDlbJr} zq{buL1)~^mwQUTzn_!A|ktY81%$Z8Gwy|M5yk^rAlf#^SusQ}mp|!1z5vgb$+CJD> z@oBTXbVZELSw5o^}zpSvQ^%@3~XllM>$XZuFdr^lyoa2d_=IE&+k!sUl~ zZ?Z3Wq;LP8!#D3afW}7qoJ$5AG+g6xkG`fLPIc+Qk1o6RU^{yb``GwoAD=p`j9u~| z*qZ^w&RpbhZAZ=J*ywlh+CG3#GVuq-$Hv&&IyF3b+D!;sS&SZ0K8}@$sgG--J}kV< zGV4e5L_P@grZ1Eks?JTuHXUuAXo5^6#N56%0p7*At*|b67eB2-t+iub3%)t zu)X%}&W>lWxOTp9A{!Cu?nSU1eh1gA!>Sv?I5sDdznw^P+C7D><^zL%7eC;p9XU- zp4&!T8i6(FxdnYS;kk!+Hmf}6*;A0XPfeLM_>4WJ%&~@UK?7~Kt?mLEB<-^lv*)0J z)~DiG4c&+5bgnh{D)=&6%zVGk_@)|)N4|FzUub_5UuduOiPmd04&)1ci~kt(9dJ8* z%jEFB8Q(eRt043oYtVDTH)X z?I7>i>NTFzd!*-BBlFy#@3iOiY{GMMYA<`ewlG}dxp~S8i+vFV&&BgI&n4U}#jF85 zr*(OaSq*Ifo{Q%tZjZc?FSG4@;kn2s^4zByx}e=%-DN4t_%j)Em^ zWXZ@dPBt_^NSIc%q_fGCA|?%gWF|#G365dtGG-vj099t719ZqJ6qtm8&MJ`94Jqn( z?|t{4^PYCsZ);DRn)fF1e&^it&b#+}_kMfc4=Gav$NGmy+pI-@tIEK)UOjcUh3&4( z0^-Bcwlw5F!K(;gJoN6Ce_QdZL!Wv5Kc2krV}G~i(I2}r*V~RTK1Z@6hsJVa$HtDH z>>J4p%a-||3OHiN#qgQSj86|CZk8(15M zM}DU)eO%p79wYFq9k50;|QwLhG+vqV%ME_96ZER zn7E?x%D96EdiEKQ4Ni+sn}GZ7RL-u1`qaFLqdlu!7v*1(ZwlwAcu}%ZlAi$fw#SD*LU$z|1Fiq@r!xA`b+TN7T1cwEk09w47Xi z-R1xJM(p)4*5Jm6&P6}@9kKrx=4@H${rx|c7VnGJH#8N#W;GS8-A#qR!ROW6nhIB0 zB3DX{%^u;~epeq|c&$GA!a{wt>-+W5FZ{Yb`pH-7qxby0KDz&<`e^G<>Z46Rs*hTm zB5Dt)hjnhzvIKuC8xKSK#D8ZZ#lLJsKp=2tYWANW+-O;khtC{o{Ncm$Q1j33f9`bh6DOwTLch9l z{fb9EQfHkRPd#9*cx0jRvnQs~-@QH&c=*BJG+y`gRQi=0-gaH=n%5gY0==0^e+gZ< zGaxksiZlCH>kD6A9Vq+&Kd<5ED*SB5&*4zu`}e=_#lMIbu38HZeh#krr*Yg zK5=H*xtaH`-3`2EV(kZ>INSa5yT_k8OZ&W@z&@QHf8~wwrydU`dOsa3Zp`RCgVueg zVfWmQy@Nw5E$ij(d!IPFr*l`+k+0&!bS{6znQKo+vJ2VJQa<1A=N@SJ+03Kg+}QK* z%r!`W?aqMCscbvvo(*?)VN|01t~c*};_>rk-m`H~?;jT{O!Qdhk6Ag{<3Gu#8xn!e zSeB%kO#W z>`svZ`=Yfq+PQoM){q@5(8hPbzfQ#LM2zUiPP7(2x_U+7bE{YM!ylY03>1C=JB*)= z__+-~L&9F$SlGC>acjnk{Jphd?%6*t48il!HI0SO;pbcU`Nf(>tgBq`K{-DB(-Pd7 z-)^;7u?@dD7k%5=C9CIL>`QO&O_#vWnaHNENtzm75|!s^$*-Khu+?VIXNQeS3iec& z_}Zj)d}CU9Y3GBoJugOjrKR(sJroI2yvn~~oouHSj+tylu0Z~zs2O#BR$qMj+be^) z(iiJy>(3RAzFFTA3?=L2@o@a4j*nWFtr*DHRkYPf95VXox0f)Y>L^_|i6~J=>AFeV zx^B|8uA8)N#kRZZupU<(=CrLBopuAWn*ul&_O`Sh+ve9}7JXa#^_X8jS{FDU{CZ4? zP1LW){Cdo<$NYK>HJHBQ`oFBlRDC3rN!4RcTh~vzUDr?AwqotBdaTt|k2!7YMW@}s z?CSMcn_rJz;P&Y zN!z-9(zX>_@2bbvx#}^eZN2EU8<<_a9*g_+m|u^HX@`wJ+wz~UN=E(%&#(P@Ofu)+ zAM@{z`S-{C`(tmBdQ8;o{+O#C>oN6}{ruBm;|@AIpANa#DSpR}#(CvEHcN!xgT%vF!In)*uR zbJ}?R>1fCEPh(fF$J+dQ%&*79w8Q4tV~PjA9`oxlzaI1JF~1(Wbm}ox4+(we^^>-B z{iJPOKWQ89kGblxb*8>j`J6VMe>&Rn{L|Rg>#?|BkNNeOn0DCwdQ9=)*JFM?=GS9> zJ?7VAmrgyV>LH=;ynfQQuAj86>nCmF{W0_R&cy!s`x!yk`(q9p&p#bDo_`v;o{+O#C>oN6}s_&dOo_{*p@%+=+)$6fsem&;j9~09Kn}2^y@o-`FxnGaTx#a(T zrT_bt{_j`%zhC(l`Ta^&4+&-B^^>-B{iJPOKWQ89kGblxR#RW8d`=tBKOOCO{%P#$ z^;nxMNDcY2*2)qaDvbja|JSi~IGMUyq4tht03Y6c2tq=GS9>J?7VAem!>S)MKh1 z68g^TCvEHcN!z-9(l*{7!~aQ2ZDN1CKc@cn7+fl!)5h~pM?0Q>8oPQuc0l}J9{s;R z=KuXM%q+hiQ!CD|$NYNCugCm)%&*5Toq9~wLqgwq{iJPOKWSUnPuj-&W3GCv$JAFU zpVP+kPe(hRe;T`bJ+{rS$Nc+aV%lNz>oLWHUyu3qm|u_i^_X9eT{`ucs)vNW^ZH5K zx_;8OuAj7x_s3lISgWb8R6eJT=bw&tJpVLy^?Iz$ugCm)OiVj$em$mm@ar+Z9`oxl zzaI1Ju}h~OQ}vM0cV0hfTh~w8*7cLN@&1^r9$RPXE0xb_J$C8TW2zn!`p)YoZR`3;+q!-db`xG46Z_yDGROZz zT-ze1E`YyAR@yJ$dJ;IoaE##u!%2oy45t~+F`Q?3n&BCSXBjRsJjd`n!zCN5@ojgF zPuVoS9yUJ0u@d0~!%2oy45t~+F`Q?3n&BCSXBjRsJjd`n!zCN5@wL0gr)(NuD;po- zSc!0g;UvQ;hSLn^7|t_1&F~DvvkVs*o@02P;gXHj_}06|r)(PEIyOGSu@d0~!%2oy z45t~+F`Q?3n&BCSXBjRsJjd`n!zCNr>(Bg6Wp2~>_J=f%lnBQdPB5HgIK^<9;T*$x zhNl^xVR)9|BExeG&of-Iu^P{I*Z7pJ$7Gdy*!T#?m_NaAlHnA?X@+wQ=NX=6c!uFw zhKmf(F+9(3$;N7Y?XK}Do5t75#z#0-BAj42$#9C{G{ZTD^9)ZjJj3uT!$pSY7@lXi zWMehH^{(+Lo5r_}jgN4wL^#24lHnA?X@+wQ=NX=6c!uFwhKmf(F+9(3$;S42GryC@ zZ5rQx@h3UucVVPNIL2^-;UvQ;hSLn^7|t_1&F~DvvkVs*o@02P;gXHjc(%L7r))hY ztJK5BM>xj(35Jslrx;E%oMSl8@HE3S49_xLWO$C@d4@|iR^w}TjZfJ$zE(Cq!m$$J z1j9*&Qw*mW&M};4c$(oEhG!WrGCardJi{d$tMRROjZfJ$zIAMTgkvSb35Jslrx;E% zoMSl8@HE3S49_xLWO$C@d4@|iw%41vr^js?-+lr0`ZG9IB7cJ6B*Q6&(+uYr&NDpC z@C?JV3>O)mV|bq7l8x1Pw!6lsY&|Bc)MLgJVK~Ncg5e~?DTdPw=NQg2Jk9V7!?O$* z8J=T!p5c;>)%e<7<5M<`ua%9DaI8c)!Eln{6vJtTa}4Jho@RK4;aP@@49_t<&v41c zYJBTm<5M<`Zyg&S;aG`qg5e~?DTdPw=NQg2Jk9V7!?O$*8J=T!p5YS1$z;HMf2SBu z;u=Z_i@5Gfv1=>%Wj$c~&A#wUowEH#li-*9*?z+nj%zTEYj6_RHgsIN27{j+w}&0K zhaIfXZ+B7gP-+><|q1N;?W=K zKbvFd4;wF?_XN{{7`~HK7~?YM1><6Vnuiz{^V534xR{^THO57L zHV-i_Gu{~UV_e3MaT%U5F5}0zj347Nev6$)F)nkyFfQZAxQrj;GJcH9_%SZ& zZ&IgU9&1^kL4I0u7(-}I@~Rx_-}zfZmzRrAs(6`?$N%)c(AskGc@@t?CI0zmLN}C) zpHcCOaJCoXHGW)~Me% zzZAZA#y7Ps<$HgPe9QP6_?Gcv2#&2X-!i@izGZw3 ze9QPMe4`zk;#*n10I~V!x$)<66BYzGZw3e9L$-1jkmHZy8?$-!i@i zzGZwBzR`|N@vSiNt?qFszMXB*Z^k#ZE#f z3g2kQrubHv_*VCh6yMG^=r`k=+LrRYzec`gd<}fdcrgUWR+(=ZUjyGVz6QQ!d=-wG4o>RF}Y+t~*FW_(lIQoi@s$hVBIfo~ZvhTzyL^DX0R;9JJmz_*OA!Z+Hn zDZUjZzST2A#kaE!`px*JHsbp-d;F_#zY1^@KCK4p?N-Es0$Gc8>#oI}_c!5y%K|Ds zY3cZ_c7*d|=i)9$yj5q%#~wqL25Y6v-(cNm@3v=gw_~;vD=$*lZGbHVShU4lZ7s0Z+HIR$ZN0F?6GpLLlC_o5U)*m(pm+VX#-!Q$~MPym$Ro@!s`U#e3IZ zJKnSYs(A1EYsa5ge`U=q^a=VaG1Fi9?u2NwTy47CH^}tYw3X3c+%Lk!@vgsiyl4GY@!s{#yB^&-!ck|4dmub=QySz$&}{p7mG7d)HqT?_GaYym$Ro z@!s{_pHAv-n;(V@t*Zp#e3IZ74KbtRlIloRq@{S*Y3Y({k8k=S%2;Rd)8mO z|DN?%#e3IZ74KbtRlIloRq@{S*N*qBzjl8->#vIUuD>eYyZ)+p@A_-Ud)8kS?_GcG z`19(oxvvWSm6++T{M`aue;sYm-!Ri(M;r84Ug?Yd8eBP{zjQy=)du|yGyQesg#Lzw zL*&H$2S*$9H_Y_c(FXkuGyQe6C9G@3S5IEtYq0_h!w=S^e-ra3;RiR;A7cIx{EfCh z!Tb&I|B>zQVE#tdfFYj+aJoTUAlknpKiX2z-0{QpCPyHnS5%`Hu@`p+XS$__i{xrZ($0dI= z{FI;k-K9F#pE{GL7yjjTKQ}Cpe=qzrPsksE|4KW4FN<%0e}`oi<@!~Agkc zXhK;(G$%-Np8AQk99&`dzlG(2CJ_J34-E;@+N3-b`uY+DC>u|1Zi$ld;)&rf&4ow_&32%=a=H4MP>caBE}oVZ-Ae8BYzA0 zw5G@p?P9!gN6d!}% ztltIlL+farGXHA$&AMZLXdvtVL33PaAnPajp@HnUN=BVp@Wam_0IG3JLh;(zz3{Ln@d z4{Z!FZ8UypW5{sJ;-QTpvo@I@+88q0!u-(25Yt$bAKEDH56FH(8;u{@D6Z9|AKGaA z(8jWUXdv~U#Y5A|`gg)_`pM#)^f)LF;@fs8luLo?a9$PZ0pypbOo7-Cvy#(M~Urj5oA4P-oQH~!uVerRB*-k!Is z7bw01emXDYhX%6ok{_DJ<^%bmjqJRWA6gfp@2rESpU}DxX)pPqb?mt0ht{$9I+F)l z$MTbZ6Z}R87RV0`3^7eJd7x<_rfI@ov^6cnG!08%t$k=3Ve49P9jGME(ytDp5Tf(HJ z6b~(8=ZpNP$Jltu4{c%n+-}B;da0}*+QQBw#czP$tcwNm<65$;ADY9)OYzVac7DkZ zZDGefX!;3lVfo1qZDIMz4{c%Nsxx_@En(6w@>sq7_5LB({vp@?A-=y=3WQzp zVI42tQIvhg-){vJ*X6b?&l|Jlyk)jr&&-w@&usZ!!)*Co%WPS*Fk9Bc%$9XIv*q;) zv*mRkv(^8@ob_L}k*)q8PGqb9hk&s8)|)yk%>X8e*uJ4YEbCRpjgA+e4Yn_W&kNmN z+V98K>rvHRPpFI zNZAw6y8U7u9RycA`sNBpZ@Xw?2fG!I-dXAB7j5hqM#ZDwRN?6D7c_P;-7}*DS*Alm zhL}cl->Aezt48;YBxKz;lE!u4Nb(1)Wl`%tuDhVkf#r+#rWJ3i061i=-v^?w(7DB@ zyqj$&5f?6cL#=5xv5($FfA}WKi;I=-V&xJ2!?lXs#LX|Y86bzb^Nxdubc^^jaYf^m zaR(3d>@yyKBir|G+jV>2zFh|n+;O0`121{_2Zw{ZM=) zbNASId@IzqB|b7dDscihmzfy23;sm>R7?D>Y-TWvs1L>WWsVLHz&$l^tbcg44S@%T zkB(+0CdadTv!h2R#4bbjhQ>YFliQAs4ZNRub*umRhs6M9!{O24dnU8HdNCUYI)~bB z8tlv@>>>8X5;~4T5+z$7 zEu}rfql0J^BfK4jBH&1N+R5e=L z#jtH&bD8mpVaYyN9fhCK+TJdRG_(%24Q{D=x>#CgqM=Tdi7eCRj_QfTVeS6867|b- zYr5n<)5E#GW0{jf}s6;U6SU3LncG=wQOjbBc6d$ky6tDMt(_jZ}zoD36L zc6aeD>O6YKh3&ri!gg2W{Es^?PS;4E_ubEP_S-6-e&_;@W!6HMppBjWqvKFD|pEq{9m30t`*>~Kkp03Mcu_-f2;<<`eNUXLjzrouSfTHky?L$aCOJ2 LGFMnTZtwkX5}f?G literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2880.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2880.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..dead816e095fa10692838aa6f5d5f155b62b2fb5 GIT binary patch literal 2592 zcmbtUK~BRk5L~BeRRMxZaNtm>IrIVifE@Y|4t)SWXpr~^J@5byJOCjM9IL*7pOo?1 z6DKBuMa{v^#@-pv?!@BC$<&FgM5H>Q(;%O}JfFRXxXX+*9!PTBj zPP)7mYtiR*sKdu$A;qoyUW;X{1<`ZfdDQEmG~-Qr>rw| zxpO6xbWRu=q6cxkUyBNPlUt%QAK_6b+tJ-hun3<&`hJOZ|Sc-c_zQVJI*4 z=3a;ATHZ!?>R{HpHtHSlT;Q#6&#_ql^PJX^o+C!bbD_V(p3}7f&rR5Sxu3Ec<{rRv z6DH}LFf>FD;`$HIwY+Z$z}y3PPH|br4u+z^b8)@TTO+U4`*KNUvtD?vuQy>R7WEEz juI25V)vOnuGwG%08k{ElQK*n}lEp5?*w|Z#yAXc^f2^o$ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5b0d4cc38f767f1800f6e7c67a946992ff688e6d GIT binary patch literal 66920 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 X_UL{u66@~|F7G&1<`dSg>%0F4Md!wB literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..a50f9880fdb54acf2c59800fce220105d6d78f33 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..860cf18c5bef681acef2b91e2bbc312f30c85cec GIT binary patch literal 2592 zcmbtWF-`+95L{o5C_*4oM1mqxuE+!U0axT9De{jT5)Yx^A4G_PGD=0sPr`WZv3=$g z9OVl8_UxVU>`ttRsmBu|vJ#QzS_H4|*_-OozBMlNV|5hy+KN=i?bLp%o-yb?zkySY zeEY5gKVly7{ovN+4j&dGbAHEMb4^V5fH*mmVqacwQQT81&qPz8dh{jb9sOp6hrf+xs<<%02hu&t!$@6EQSI5A?Wo zRtxkX^uBeOb}aTBdZ1Z!K&w$4;5iNQ9=xV{f7I7@U$N)ja=j5l`Kb3Q(~I6;q!+zc z{QvZ#zrEiW`s;Wbq%-*p&!NA{OV1G_IE8o0fah?}X)b!7-*dIzsn&D5vF^c8+=F^= zY9{F%F*HOE{Cd9@4f4p_MSx<@Ej=&Gm|!RxJg2+^_f6oHc1Gr6y{lYr#852i&AkrK z1>WSW#dl^~#7I2n`aA47T^sP+n7!9O0zbAdNG fYq4Hy%S{U`c{MmAfE!BLZe_FtU7&BAefS%|$@ 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 Y-X7iWMPmK^!Q~yND}2J*byN5M05a9iLI3~& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K384.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..fa403ad1a978818a408dafefdec10bdbdab66a85 GIT binary patch literal 2592 zcmbtVJ8l9o6ntJb2t|=Xks<{WTX2BfAX{({3hu#1%0Vb{kDw?;O2i3r6Ec45@h=uK zg2L<1zBg~)%o;K6bY?`>BGTQ9U^@Perg^cmZd|&tIg9-4M4Iz%Znv5@4EmmXfsYpP zcCG_A@tkme8qehs8%vP|_wj6bCT4iXI;v^JvYX-8e2RP_1)(n06ru{VrxTHk#JC-M zk>VQk;rqOl=2b5DV&!_l>^bzp@ikzY;Re2gkFMqm+!QM0(0%gFar+zjt}FRA8Q%?Y zJCPw&UhTQ9!=(|JgPxnwR|U^KxU)&-xq&rVVK%;~Y7O39O+GT@&@E`7<+fQbpn=!E z_rX%_IcT6!bU>6t_u)Bx<{Io{zQ2r?YQ7&i-;hJ`$oDSe3+->>3+**OEADj_2J(fz z$u|alN8AqYGT7d4mG>O6>YZvmchFbtP_03GG_8-a zlS8r+XyDG%UUY~f?hrz%J-2eWY-5x|vq1yJE!;OAS9;&cYQF27Z^)szu_0MAXe*&IR+-GK(~ z{GaDM?t!uR60i7g)x4}Y%AwidId`7o_NdqM-LsSR-xxfX@(no@mwXGJ^SDv1)qLT( bD!%mGfNJJi5jtdyWNQ=FcqutYPq6+2==h#{ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K384.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..699c5ab5de91446b17f5079418a7c110ddba3df7 GIT binary patch literal 73838 zcmeHQ3vgUldA_?^ujE*bSBVlfiEXadj%$KQb|qP{jgzb_ImoYM{bJmPj&?1r90hB& zktHKToor~Jc`#H^(%EFnRGmziX*y{Il;9X9UB*ly8K7bYI)M%ug#t}7rL!WBaRWvD z&N=s-^WUr8^cIp7ZU0k5A;O!Q)3qavj#9xoR@-qhFoA%fgkj z1MI_+HaGYm!7DVrcxdBwFYSA2{($}IS6}=4*T?_!DsRn=jw6iE(d_7=4L2)~x6$r6g`)@yZh*qKE zO3KUQ4j$;)r#ucg!#*7X?!7}ex5mY%llDm?O?#%rvX z1RYjk^4uS?{)sDE{P>ju6|W32iNl4F75S31ieK%HM7I?q=k4L>(^F3bO05Y#HW636 zvemgGT0AOi>E57gIUf`?yjr@v_|=n<5B<}Mq5Jj+^Ql=Y9f(BFSn?iKkEl1=7>q<0 z1Cip@Z(bI?+KLogS}%1<&Lq`6vYl%8Y>@X9W9lB$U&fZNX4J})+Jf14_c`bqorCT8DmrQn1!g|8GZpRF5xGB*JR-jJqm7@t zto_u=YcKtux9m5=(725cosWLzJM8{1&N;H%_uGFiFWwt%Y-%Zf-D)XXyIYEXh0iN@ zv=pzfSY0VGHfMxa{kk!_@J3_w`wNZHtv_gte({%$(a*fn7`^-FjnVxtHAWLZX^gh~ zs4;47iikU)&er)w%VPYkZa$3f7WUuSNa-({5fBKRotpjE2R2&PmSSP2RX=<`QvG!bJ2k@?xRVaM^TaEWO2J@v&LDX41J>2@U`<^?K{M5;* zxzK-IzJApspJ=eoj;HRoRz0%N{I@5k(%-!<9(eeH*P5?=dMf?O^;cbMzw6EBPe9M7 z(qBdw?g(&AhN91Yc75?HYXZd|;^z(gT!Ej>_&FR3{NTRtf9cb);uY)Q!O!7!fgc3c zKl8oy?boE9`4ax@f9C1+C#NDS+BaSMaN(m}{jO)9jctE<`)`}uqOY&r z8tuC0mgvOkt!NcjbYk5tulM}hL(i^1dvoXu!LEBg^2Fn3Zw~(=IC1*!ryierVB6ZG zEw9IhKXrD+`I!%|+YP*SV%fE#8j;$CKE5GwM_dN0Vg=*fjaY)`DV=IjHnAdMxdEVnc zDx{m@f$o)UR{p7TyB{2S@6o2clTSRJdoa9dFpZal+IE-v08t`|Q`i&)LWe?71PUe~D%GXE?un{=ycQGoM{H zGF8}9TiH95E=NXU6}Vjp^6~;3>E)KJ59OgqP{)h5k4YQ5si^qP`*d7ce8+dzYKPls*mgOi0>f2g!)QL42ee_#P7!i4@%u87m z%Tr}uDs7pUN?Yco(zfhgPoCT3$#dPd^`hHuB6dpv&%(Ku=DRygzH8}kOOx-K{M<70 z!BGpE%PpVxHIwhM#}hUAuE}>zzH9Pb+p;@7 z`EJ6K@49X4MYr8V?ArNmhsk$Me#536uH~8EnEiA2JIFhIzu)A$e65;%*W|k<-!=K} zGRb#E{>hX{U?~44BDU--|-L}k6Wx32xrHymDID9HDc0bNX zgxIMB{v*yuxNMw{aM?H?q3qiE?tu^*GUs>A`CZJe<(c1@{av%aOV7)je3yMMnDY$g z{H{5_YtHYsFOz&%CZJm-Vi-{ou7?C+ZWU9-Py_IH=b{;tS3nKIG* zRN68>mA1@JrH%8u>i7M!`*D6Z=sCaZvT;7bW#fE=vTNtN2ZHAOuE}rMyfgW(`TfT7 z_c|}<`C#&0zE(}XYw}%_@0xsfndG}7-(<=p@?Ezr^HW(a^HXW#{H`b8?NRxwsLyTV ze1xkU=OdI|JKx=5@?EpP%cdQ!<+-0{&NG|4tGdlQTWT+8a; zn-KXX>lV#Vr7iPQY0Lan+Bm=K$#)Yfe--t)ZJdvAmE(MbvTNtN9VXv3`7WDwxJ6qWYYkvQ(`Te`*_wO#7-@nWAO{PpVKb5x3Po*vM zQ)%P;t|#B^QTeN=&u!y;gsU9qBa~e`-`!#IU9-Q-rX4Pm?+PAFzAJcGp7X)vyL_#h z^9<%ZgE`M&&ND2N^9&;2WXeSIQ)$cmRN68>l{U`rdh*?b%3no&ZX4$#T;(_)q3qiE zZimTtO}@*f9j@h>-3%Himc?OYhvTo7*RN68> zmA1@JrH%8uo_x1W<*%YXw~g}=u5z4@Pv8n&26NX9+G5JV)?6!DR=F@%4JfCu}(;tK37zr?E}^ zae|WsrwC3HoF}+I@HD|Q1kVy&B6yDAd4kIh7US#mj8E8ldjqS3=ae|WsrwC3H zoF}+I@HD|Q1kVy&B6yDAd4kIh7UNs*8K1EA_}a+$G`7nc#|cgnoFX_)aGu}-!P5lK z5Ijq8iQqYc=Ls%5*jaz--)y0_9^d|u#F4VbHoGh0H*m6u(xrdBTW1INn1Sbhj5u7GCPjG?YX@X}6o+Y?M@EpPO1eYBw z#@Fc?pRo1#5@dWD+hvX81Sbhj5u7GCPjG?YX@X}6o+Y?M@EpPO1eYBw#<$)xK4I(e zwUO~@Y?n2T6PzSCMR1znJi!HmrwN`Rc$VN2!E*%96I^z%v)|n+hy&K6PzSCMR1znJi!HmrwN`Rc$VN2!E*%9 z6I^z%7*DTfe8QGvvdTSbOc8=@g5v}y2~H85COA)Uf#7L^X9%7pxJ2+A!Se){9W2Jz z=^3A}_4pEGd>Y$jjpGC-2~H85COA)Uf#7L^X9%7pxJ2+A!Se){9W2JT-ZMU7>+!Xb z@o8+AHI5UUBsfKIn&3Ra1%jsuo*{Ua;1a=e1kV#(CODZ4sPFF-!AZPBF=1ivfGP5B z1wYRR9KX63ey&rFUuhEjoIl5}xI()Mqg{oQc(>8*>i04DNxMCy-5%0z4{5iDwA-WV zPbV=TT&zENf|GdX(CzAXBlt$mi%8z;oKjQ!K75ulUc2N)Mr=F{*NBL2Y;>}J5RNvwR+vNGii3Y;2 z_<>)w3%}|o{HmYutMS6G+CqO+J?M|Fhs;&Up6*svh)5wQG?%6Cv0l^+ZTL78!5E*$-fI*dqE6 zA$uYgnLiOSf6yN_pV1%nT+kmi7W7A9^hb>s{ULt+T+kol*SduM5Wk-1=#Tc3`4ge@ zhxp^fpCtYi@u!JDPy85{;vC~r7~@jU1>+)qJr6N1;@9g1<05{&t}!m{C-V^FQscFW zALCMfj7#y1aVbB>rTiF|@>}FNqJH%pQNMb=s9*U}zw)DgkNTA#yeSOc6b5f9 z9=s91)_L$o{91p&8}aM!LGY&iWW8WqicgG7Jui$)`7ti#$GDUq<5GT%i~C!|!a~My*IS3QhY(g(@>6o{x_lPE5*-Iob&B2YekvnTbC{6yQfaRd3+sw^LWCXfYtft@d57*)%oV}b@0vOYw(S7 zT!L?b1F*&X7Fxy1*x7$}$+A}1nr~gUl<)m@^3CJx;G4(uzR^Fb^UdSgFkDx4zIl8d zeDnAke4`wf;9FqHX|w!&H=J*GSu4sk-@0rm-)#`By7ZgH*TFZh-^Cp>s`Jg`>)@Nm z*TFZBufaFUaS6T!)_jYcN6c?`8T31-`POAi`9@Au7vDU-4!(Ij8-nYq&Nq**gKr*R z2j4ut2Hz;hCHNLt^DS~o!MD2%`c3%OWlQ<)sgrLWUkBej-o-UDs`Jg`>)@Nm*TFZB zufaFUaS6T!)_jW`UGVKLgMJgfb=gwB_t(ickFSGo9?yp0x~lWd)@NmySQdXb-sCg9enfnI{4=CHTXt3 zF2T3Jns4zgF8FqrLBB&pzj+<(zNLKQUA->8d3+sw^LRD{*HxWw9$yFFJiZRTd3+7N zQI1RSEwJWW>~RRb-DS{k!nZD4%6CtleDnA^_~!90u9;DtZysL<-#oq!zIl8NzEO@# z@GY?BTkIVPzTIWeZ^E}OTgvzTI{D`Db@0vO*$`Y;b-sCg9enfnI{4=CHTXt3F2T3J zns2cuC-`=kLB9##x@;-m*z2rIPk4MCeDio0*UYHSH;=D_ZysL<-#oqs-zdi=_!e06 zE&dKe@a-;xeuvqEVrAGr;dQY4mhz3g?z;Hq@pbUcwrA_&WIJ@iq8H zIWEDsz?yIIcLaiOcNz4X@U6?1^4(J>-#oq!zInWhYi3mEo5$C|H;=D_ZysNRZ*Slq*TFZBXG3sZ)%oV}b@0vO>)@Nm*WerFxCGw< zYre(b5emNDWzcWJw=UCsU*e4aYV215Zo;S4WWC#pSWqBq(J9@v*neLO8e9<&@kvX@ zZ*wBtAN`BFT=7yOd{P!#-UGcVz4?S5izISnlD?TaXo6c5@-?`Z5icib<=I1NMe_-)eSA0RnM}Ax} z-rN5f8Q=P9#dvT3OENzCR>gR4|L0}=nujXJd;32xpVyjKeLb&vIUk~Tq5h?pcRtL> z`dgo`Sig6^&B*#AyO&lDk9R(&W&InTtXRKyz1S-LA;e#JJ*H)U+OMnFAMbj%Rs1E0 zudF9*ue~dLHLs6pSKPsD0Q~QuU^7AIn&&Co4m;|UZSj;f!)CQ|J@k~d!dCf}r)&*u z_BWsGzNn{c18gS1tjzY5wZmTLlx^~q^}%L;!^rMSlClc=i~S}9`qy74ej9FDdU>CR z)o`_l_piTByl?##@&5H!#QWD@5$|7rMZACgb^8Ap$n>SZPXC{*81L1uWWeFyzy3P? zf4*Y%?DBe|gT#^a=XQG0|Usc7l~zo-*ifkm#@LKIm_d=&!2``m6VYJ#|8V zgG7H__d$PyM1Ngn(BB}@UsoCQH%RnXl~vGR>=$9;_}5=2-nagWc>ntA#QWA?5$|7r zMZACg74iP{SH%0*U#I`R_1EdYZ~b-pf3~8Ydh^G0;A*G;zV%nc``2F)?_YmKynp=_ z@&5JKiTAC)PJevsuZZ`rzarkh{)%}2`s>8|)?X3tUw@tW3+gXZ9iAUTe>o=l%g_8d z`s*r#{)UMDy2_xxA)>#oGU%_~&-Jti{S6WQb=?R34H5lyl|g?)M1Ngn(BBZzUsYB? zf3e?Fm;O5OzV%nc``2G5-nagWc>nq<;{EHdi1)9*BHq9LI{o*pzfS*s>#x&)-}>wH z-?#pXc>nq<;{EHdi1)9*BHq9LI`O{s*XfUM{T1>4^;g9E*IyCuUw@r=-})=!{p+t2 ze?k3K`>N1ij*0&A|F^)=UsoCQH%#=`RR;a#Z~E-MCQqHvU%emeDTDroiT=9kg#Lz^ zgVl-s2Ui*NH%#=`RR;YH6a96S#jR`DS5JZMwO9dy;RkEnzlr#h@Pixf4-tO|{$|G? zC;le*|G@Eg5q~rM5yzh-{s{c59shRXZ-xI-$G?U6H^7gc^Zqmuf2h2k?bUF9bYZ<3 zaj8;y+ZyzZZVR4~cJuUyYaeZTK&D+TBb1Yv8}k@%Iyd6n@1I z@rTNtWW1eZyp{b;h{v4Z{MZXRJ_-Moj{gYpcfsH4_*29mgeekRP zlXjsA75&hhpq}%(pIFPmRZjogNj=a6%|G!&LxOs3>Uy9RLA^G$e*^rAe^Sp8_=&bC z9-v*Ce-aOE(eq@XQ^i9oD*B-nqwgZB4V@o$1(KVKaWEvo2;77^Zb{08_n zZ`$7uzg|edZO^_ z`J>})_|^Jd(0*v0UZ=#r27a~fh#wkA`hQTh3k@Xw)P86nX;=HZ$_=Fd4XPe!AekrH z53M8oYkw>Jdc4}d0e(IIwIA9TB-+T@EpeUvRYQi&~>Xj(;oKm4knBpzB9A{wjOh2~WBLz6>V6Ldf0@GG84{hQ#| zYgxxb12sP+9$Kn-CVptCelElhO%7>I(DmcHAf)G>_Cp)>JXz>e^g|m74>~?o z#Se`l&r8Q|ui}Ts65ez?G?4J7{m@J@F71b=5#F>P8WzHs#;g6%G%_EwAKFNsyY@rtLi#)Fpz0^IE~K?r`=NED zUG0a~k@yBx544Wdul<|gS30nu{m{S=(KJ;LG%Z9ljrmKCriF;6Vd;yt4^7k9x`w?6 zN=;LKXj)jUH4+a^3lmLK@zAueTKgm(nieKnr{bY$VKqh)4^0abO;hpEH1^IdHBI@U zY3%)1YMSyx(<=I*X}X^a>s5Rg{Hk5zhZcp2cBy!1T17uJO7lkQLEaVCYecsT&C&dj zcxadAnfReynm6KyMuqiS)Ad7(^z&WlRQ*T3RM8JDBJJvU-h zML#r$j914)Tgda(erOA6_n_)0w1w2K{m>RtzxG30$haC*J&&RzUV%?%4df5u49jV)OM(Y_9Rd=HE5M=HIo% z<~a+oc|J^Ro|hAwzpoIRzxNTF?O^z>u&$oL$+h2-bb#BMk{%-L<9=^8e(Ffy=0c#GGvYMk8q5kc+OpPA5 zPiDtYjEv=OiY2a($LwrwaBOHKckHIv{#aCSVGJ#ObRquHBc`}XcSFwnDWXUsmH$sL=_9D{E# zW>1{T0}SOSW3m=radv7Vn;Xgwy>BQpk+D%cASxRe8M-MJpV}Hv#O&e8+~5Sdo;eOz z%sw%BR8*FT-QcP#Gk(nJ!&n}p%f{@?(9n4H#EJcrnd2kFBiV6&Kd%|pjC>Rwicf8c z*<-`QC$baFh@<{H$4*S#u06tWP)Cc#Cr5G<-CY9{Rr@fKJ25d{sS6kp>jFM1cL5#p z*M-45GvoGkRXdQY+5-%d^`Jxdpo@}_xDW}5)+BUx)F9#L80uR36dVdVbq8EeA%O<` zQE+l>WT-j=N5{}m)z;BS#Rrh+y;!Y-;Hs@}uF`tPMH@TVt=f8bwbn1%*fET%t>0Ls z_0G37b~fEJxxp;aAtpmaBevfl#6_yc_8YX2ZNEWl-1Zx^`~gc@luD2HE@*RL<)U** z#oNXJnymNxfF%~PZuZG{vzS6uEy9&S9=9jn> z;KS^{{oo;4!ah}8NqKqP!2><}ln3BQ@7^7|ZX4LQ>%f8A4-EA69O@Z3c&O*Vp^wE* z4BnX?%?vnSeX(sHi;ZUP8XJ#ogZj3|Mn`fS$AR;iiNQPJkH=28$L`E#hO&tISZrVB z*vKHItYM;0z<)nKb z+;Q6nQ42gr29NI;$vHK2ba!O3iLRk+A{*b_(GlO0&1Qx>Ge?KJZtTe3nAnQ=zUAM0UXWQsa?bf>DgO-Zlo^ zO)y2fKofs*`gAQ?JK3-uUh|ppi4o2|Sk1vtXzlD|L@HVn@hwAJYCbPgue+v1d=QBu zscUmr?V4D_P7ggbB@+Dcs$O{?_DFu0JtqXE~=iAxys;Bh}JpPUv&%cAq zk6H~|8E@qI9~&Q=%&VuobQUCp0-9;S*6@-^_-B43e-M8{Uw Xm!$XWNG!m2T=sFg!h6=v+xq?wWXEut literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4032.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4032.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b55077e0127f9a5762f249f3d18d4c770b365654 GIT binary patch literal 2592 zcmbtU!A%1(5L{o5BmyKNfdmqfa*q^12jr1Lc%+XU5(Q8~9uz=1t5j- z+H>}qQ*e|#?A!D0%+Bt_V#@x|h|EQ#Iu*gA`)y2dXP+t;`nA}Jd@MzZ-Ew4K6^~f- zJO2T<68ZL77rw;aRZ^d4;c@6sTzMDvKFZ+8j^}Qf^$~*RY4U{IlLGRi&N`KjU!OI-C2Mmp=H|3oj zsdt{Kw@CCpkhc=4UB!0I_T0kr(g?($=Z5rEhv&}ySugQi&6@1&zloIZxhG$f6{5d@ zp&@3V<(5e=FoS0HGnZ-CY|mi^nnef9Gztqmr$IV{Rjl{*k_p+Kdr9>M48@|}lSD6O zf0SO#Uh)6ai}|+xW0?YXJvWg8<5MT6&*x8uHPcx81>=4`$5RBymg zEb2|Y4$n2bQLWi}7nyoHJm+{T+;eQ!VV=`I(sRU!Jm==y?KwT`@LZp>m(AJ1Gl1v% zOwv7IXowm3^FN+zc-H|Sdj{~F;*#c6hGg hjcU!-3(sZgrRQo?Gt!FCA!8(oO^ESP>m2Sv{0rRQvNr$# literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4032.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K4032.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2b2b5328294e2685c9573096e5fb267c64461c65 GIT binary patch literal 66920 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

l+9urJ^9@RPk!gN*(+|l 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d6995a53c06a71411af2179a4f33edc9d8a88161 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e7919b64dab4f0c13e0534948eadb991c586d0da GIT binary patch literal 66920 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 amM+KJqx-!`tiM0FyyJA4Pgpzm_xuleLDPW% literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..58832296bc62c050b422a0a655be572e14c0437b GIT binary patch literal 2592 zcmbtU%S{6@5FKw!6d@#X;J_hLd`JOwz#dXa4)l>lq5w+ZKmnA15C@J?Dxrhr?W~`F zS_MbR!MpbCyf<&=#bWGyVMMkf;;u#TI{pr(c^KZ@xbsO<7pWa)7@jA)HHH!l8-^LHu41sQk|+PODs2cM=}{n zc^!L^^BVNwyI)K5D5ra|@x35=$-DA;4U`tVQEy9m^?JdZQ$-9tr{0pcy-@GAQg2h} z-I3Rcbg}Yk&pmlwc8VDE+=9NE@Z61$%?i(TtZA72YbdJPb1%N8kQp)b2s6-fZP5$N zAk4lE$x`h(%s{i~fCNL&;W>SlGk8n&9@xox&%Kv=BZl%(?^U4}v%g3$X0Q1F>BW4r z{}|>w@;an58FxuvdCy_K${RZ6G3YtroigD$+;f_X*_Zd6)jM_YoC`%&d(Iw=RbVa= zLr*XRAJ2Q?kVoE*x#-Fn_nhLg;sis{;5i@9dE10ncA<0Cdbg$Ch@rgHTY4RyyGSoQ zSEYBtb0e?AJ;!F9=Q-u2=ZFzH$N5fsPID(bH|Ol-BNSCV19)z(&E^s@I0GNgXAjQ> z-cRP9=Q+h?#R-O@!E-*I^TKn1SAIk1s`bKix!#DOyzrdHCp;H;lUl3)WAI#+UV5%W WHA}4s9Wq9Wy@`8#l*QpL?Ee7BLYmD0 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d9435ba4db4b4b67af4dff4285247522963fe8a5 GIT binary patch literal 82286 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..62ea5267ba404a411b4c91db30065f39cf498a6e GIT binary patch literal 66920 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b08ac7a2d58ead5007277362cec8423fb75be1f3 GIT binary patch literal 66920 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 D2dT(D literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8ebccc8870058c056f47169aa9ef8068f7ece97f GIT binary patch literal 2592 zcmbtWJ5Iwu6nyI}QG}47prDA9Ehs3t0WNZo6x<_5;vgwFNEA^}MmYgDG2`c*{mBX& zCB@qNc{6X`8?Pe9&KE{xEh6q#1h3=oXqwmI&5ct(HoeHtR;1~-55rRPfkDst1AJJ- z5AQl~5ziUlPvgGaV__w-~dt$mL%#)l(u9xI6DBg@5070sAIc0(6+qaD%O31fy^fWu_uN;hH)1Fs_1+YE(fh0PqW6mbpI-Dg`^M1U zk=G%d!MIEM%6ks|RbG0I7@=~!Qzkrzdro7~`|_T%dZ!MaYeQ1ip0h_|6_`WB&=vH+ z@8`8}h$C;uSXAYLdrongae|>}@SNYzdE10n_Mvjsde^1ih@rgHTY4RyyGk!SSEYBt zb0e?AJ;!2Q<~il1=ZFz1$No-xPGcuLH)rqVHzZZv19)z(#pVz(*aN?x_a2@LynDu8 z<~hY>#tDX^!E=5;=Y{72uWYm=!})5x@LaApVkj>>r~4D03%q+hsYCTQ2G3RLrRO@p V>%S90g^ZD6ZsHsVvwgS=^FM|gn~?wj literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K640.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ea96c931ca73d3710bda4ffcbe570c267f85d910 GIT binary patch literal 85102 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6912.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6912.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8bf0e5df3dba3ca8b5d07e058ad7beb3872b11f0 GIT binary patch literal 2592 zcmbtVJ5B>J6nx$+QG|#{kphWGF;WUTxB*+_AQZVr7KwvUaDW^kLKKuyE)-^;JzlS~ zL|#E*uRm|*&3h9grW{X<$XZ0~wFo}l-@z2m&6jmcKNcsEpRGu7+RmD-;thk|^A|Xk zh;P1i;3nn~zmM)*Zn3cxS#Te7$ulwa9oA7!j%ycony6wsl`lY$>QYY4{XhTaN8%cZ zc`a+vc)UyUx^G zBzj-TYej0GF{W(KZ9FfHKn!|rLSOZG?#7>u63^AlspXDnh%j^?p3^z)!AD2$gWkcAt@raxZ@^G2>b*+zqWAyOi{2}~ z8$~KzwFC8{zn$M0`s;Wt?lO3Q=g?mzq34J}&k5g@9?#*O(^&LAedkJjQ+GJ8r+NoN zb`Q#fDH)`5i=j*Oz@K+(VG&2(x&_Gg+{*K^j1h*Sp$E#_^WFqrsUOLlt#^H5j=K^n(Yqs7^rrsXUIbMtQvRK1Br*)*~h!J_t^|#-1de-B)F?%o7d~grox$rn@ zaEqZ!^uV8=c`oqo$%9D5R literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..f0de94e698608cc744813322c719ea7e52332b86 GIT binary patch literal 69484 zcmeHQdvIJ=dB3|_ujE*bSBYX4zqnot*94KQ9+oXvAuCG`ekSV|<2LDNSJKK+qQ^#- zj2!A@1BQkqfYOrACM8p4GUkyXRDmWWrqB&$2+0&GW}w5+X+|)VAq;=42nm^#qW;b~ z_nhYqID6mocV6eMxz=%n@jIFsJvyEp9~nP!x^FZ+ z%u5!6BH*|aXX7`Uo|qh-93CHIQDdTDM~(RX;cvvRvzsu;cjP~Xv1f(&ts`X=9=8Nf zvR&Cv8pH6M6L-KVSmzCpc0knkDaT$b{hr^v6DQl1;|Pk~5v@Ro?YiftBS&c!Dz2cs zJnqQh?t{wXfM?mSL%`iP3uk9s{7PO}Yu^^GOY+U?o5nFJT$0*!CI1fC+ZJoM_X9)6 z{`spB$?G9TL ze24UKrf+yOeIlcGU$3D?Y!SC@ePR6$tdwo|uwS~#Ma~X7){HvbH0G`1z@DZ5Vw0w) z_a?MpS#k8?-oKbzYQTVk0W388NSKX{ZOo3md??K3DgVHZdTh&M*Abi5$v!IrOV*8Y zvRjA4p@5YNS-sZ6O1<*7fU%$KtFf(Ovvod;215+xx1C#^Klb_6`3)CV=O21%b^Zs> zt zklXM;ZO{V#?)QKntgT`A^6vz44WYm*OTb@z5x6mMwRH=Y{^hUU8K|>z$39iNj@x64 z`G?M~W~^9NH2)Y=PbF;8d;B1TWv5BT?$0&f3C`p4jsLPno{+N5P=A>XX5KYv<|YT=Ro#Fh4GR|D$(&xHcNO z-O4xjUJ)g8Y%nm}4b5mh8#xIY)f^1* zxgLG+EY?-@j{Dg+ska#toJJkNhG^?9R`+pnu8Y>zHRQh#YPhBQm)Cu$5IyuMzIUFl zO`Jo1_fN&8yQ8&dBl$1nB6;guk^JA_cg;5<`Kv5eOVT-*{3rVM3$@Y3uhmAs_grnX z^V7A_r=G5jKKN8^^o}QMqlZ3U8*MpY_ zY{TbRDDeGzzW1e1#PU~dga@Bv8w1}DY<}*$o151qpZgNN_dNH^=2O#=70p}Ud4KLJ z=k3?CsX1%ag#EU!e?8Xq^RD03Z;JkULua)8uIr)>>wn$-ulId@^ZECN zJ`-%e>jUQ=KmXqF&w`U@?s)R?>3er>=x_LSZ0LdWE8dvBed9jh4U-!`aPC6a&;MlN z$qRa)*W=iy<72P9Iq~G(u`(8ZT{L|TozqzIR{@J&o0&F)2WSzox>fGOSb0dEz_H6c#~##_|LFQv`OmCh)enDgK0lEE8SF4VTkyF7pCM*%tj}-RSiduEMZRb?&42sD z`5|~dx}iS*8GOEl&(Aj0V_oHg_ww=Kt2wwQ*Mk{oH@*4>UtzA*^TyH}_Ltw$Yb}DG z^O58~a+>OX%re<$Ilp}V!WNq|pItUGGuYFe?3zKB-xwo;4EfEI8`Kt%qOm=*b(<6PkyyC}zt%OxiLJleWymq;1(fp1iKxlh?Uz>t(lH zN9=|Gj)k)=&+m4b{LbOVjTQ9rqI$~GO?^;cM$4JL!@;j5?iJ2h2 zO@3$Y-$0s8)($hX*;LgaUDTjpc3T;^law(QNG{BDyczjNEx z%Wk`l*p>6Un91)L>DWwuXYxBS6U4X4?@WGY@;j5?nf%T?pJitR_P&SC??k@E{35?| z+cF=M%f|CwmyPGW%C4N>9S)(PlzIQoj*)S4?L_ekbxRY0G>}+A<%L zHr~JU6ra z|IXaMV`l_*y{PZsiTsNBX+9=xnU6_Z=3~;v`*)uFu0`c*qCU5c=e@3SJnvO@<@~PI zv;@jkRCciWJoyqS^erNJKc1CdLcOt)HewvR-TjpcZmid^p@&27B zzuTnpHBq12#`9iRIiB|_yK;UPGx;4O9h=GTOnxV3g7`N1oyqS^erNJKli!*Aj-3(Q z`JKqGn4jij(w6y{v}HafZM=V{{@xzjAMfAc4`-n+_7U&jxokY|b=i2{tL)18-Qge- z$&`8j&g6II{X6;o8e4_#zwl=MJ_={V{QW!g_wUT#zcYXT&iws5C%8Kh4LaE%PyH%Y01Qc>m6m-?gZGP1NVM@x0enj_19~uAJYs zn*5HDj?LtECchIiL42G1&g6F{zccxr$?r^l$Ib}u{7&Ro%un+%Y0G>}+A<%LHr~JU zJroyqUSOc38Dzccxr$?r^lXYxCf-?1}- zJHHe874y@4OxiLZleWyqq>cCQ@GrNCjqQ*3@5H-zaEbcdHlFvo%JIBc*_HFV!&wE|v zc;2h*%K2T)v;@jkRCciWJoyqS^erNJKc1CdLcOt)HewvR-TjpcZ zmiZX78}Q;C+XwI9h3VhClQxT~3818SC@gV=V4L7L!3lzs1g8kj5}YG=hTvI(=Ljwk zJWucf!9@p)@%4DdCu}(;tJqD(r?E}^ae@;BCkajwoFzC%@C?DT1kVv%Ab6hO1%itX z7UOI4j8E8ld@W>r8rwyU;{+!NP7<6VI7@Jj;2DBv37#XkK=3@l3j`M(EXKFlGd^MK z@oggG)7UO*949zIaFXB@!C8WH1kVsWOYj`Q1%l@ZULd&WU}ycQzY$JtJ-$OBi6cdg zZGz(jCkRdwoFX_&aE{;^f@cYyBe+2DJi!YD7ac6d)8iSRu;rMnVmBF|#y0WC2~H54 zBsfKImf#%0GX&2PJV$VW;CX@<2rfEUjIYfzK4I(ewUF^?Y!@|-6PzG8NpOnbEWtT~ zX9%7pc#hx#!Se(!5L|Sy7~f{k_=K&;w~35TW4owvoZtk(NrF=ZX9>;`JVWp-!E*!` z2%aZ+f#9Npo%N>vA3SeH zFA!XGuozE|XMDnzW3r0fWPBRi#2+U(L2#1b6v0`7a|F*2JWKE#!3Bcn30@$$=wLCv zHqZEkt;g3w#;37e)HqIXg5V^E=Lnu5c$VNff(r!C6TCoh(ZOPTn?2(bwjSRm zGCqy%qQ-H869gv-P7$0XI7jdd!LtO<5nLd6p5O(7iw<_yo4Q9xZ9Tq249fMVuwB&t zIKc^mlLV&-&Jvs>c!uCvg69Y>5Ij%t0>MQGi}Cb$#wTn!Cac)3#uOpgCOA%Tg5V^< zDT1>E=Lnu5c$VNff(r!C6TCoh(ZOPTZJzN7TaT}Wj89{`sBxU&1i?vyQv_!T&JjFA z@GQY|1Q!UNCwPJ2qJzcwHhab=Y(2hBWPBRiMUCSGCkRdwoFX_&aE{;^f@cYyBe+2D zJi!YD7YR-z0_yyoBshUEYRfa6#D!q0We@heS&pY!MV6<26iVYI7o z0@pUWU41r%fL_iqjN0Oqx`6c@FV^oJ;DDb)h_BG z{nT?6^(a5;QM}oSfa+VEV4ED@IMG1(6+iH+cHvk3gkSX&el=eBRa@wfst5hi^^m!W z{*Zd~agP(tvXL`LKH=B(ka-0^t%vkS&%+!!UNhu)fgi;c`lGN-=0lul4E&@&dj7yq z_|fwXe$pR3KhYl*kN)WXlR1X|kn!r{9w$0r zMSqB29~bn8__Z#fKg6%+Ir^jhWd20x{2~50@h6BsN&G3|&k{ezr8vj96vnvJalyEV zU(Z8~i}>|=!MKQDuWO7;`^h}SxYT%U;>Wm@ALCLyV_eFQaVbB>rTi8-j;LQ9N7S#5 zFX~r*)UW)gU-?nL@}qv`2X6|4H-*8QiU)7RuXP^05x>?S@J9UlJP6*jpR5;*OYwqD29icg4mULTGB z$=#uirQ&lUo`!P#AAc9Rrd0f_h!=#Dy%4{pRD4RrZcr0^cadCioUua#}C{UIpjdUDk*)&9^RF z&i5vWR#p1V;;Z1B*YDzv8Rhxr@m286{>$2s1 zcUQ?bkFSDn9`E9s8Rhxr@m286BTajjkz z-#oqwzIi+wf@>?!H;=D^ZysL--#oqo-zdi>_!e06E$(p$zTIWeZ^E}OTh4cPm3;H~ zD){E{F0PqTo^Kvs1>Zcr3ch)K1-?;^P4F$S=3Cr55`4SMpx=aVUACO>Lsjz4Uao}A#@T?YLoeCx91eB)kcReHkXtKgf* zySQdXdA@mk6@2sfD){E{75GLuHo>>Rns4z8L-6e`gMNqEfnsI2f5Piv`z_}i_qwa% zo5xqdH;-pSaBb!J=J8eV&Eu=!o5xq+8|Byp-vVpC#WMoIx4R7bP59Pj%lYoEl5ZYg z1>Zd0#Wgd^^UdR{;G4%+!8ebuz&FaV3BCo^e2Zt5f^T;j^qcUl%a-$fs7k(hd=-52 zcs2yrR-SJjUj^Shz6!p1dx#E(oOt^Y)KX`y=JnTEcRRc7 zU)tx2PpJ6w%Q$Dd>|5IJiqFaZSbyg3h+`#|y4~@z{?Ly~*1v11#}!|Y_1E25vi{zs z-R^i%U>?eXe*b;P7KTg8C!Y_28(M@ZY_ZaK+m)KJ-M%_@1R*uK0wEuRC8d ze)m$ZD?TOT>t8Av|GuRgT=6*>ANf(qcyIq_Wqji=O2&KpUy$+9H%rEQ`@bOL*WXt% z-rN5LdA!#D!q@RyknM9KQS z>%~^__aXk`>oFz!(|mQw{&?5Bt>Q03d}%#l_uAXTYk7T4yW$RJ1K`h~U^7AIn&&C& zf*p0rc6iF_VY6Df9(u|eVXOSgQ??#9d-BQli+akMU^4+`WwxiR8TLk}Y^$fN7dCss z$o5N+vJ(1>`%MV+ufInq<;{EHd6YpDp zo&MameDcFnLVrcPfBhBl{`FVH``2G5-nagWc>ntA#9vf@dCtuA3Hr-1(O>@V1S_*V zWzgRs(O=ho(BB}@UsoCQSKklz)Cv6!68&}U2mK8a{dJW=e}hDSU1iYUAkkk{RziPq zzX%h@zy3P$zV%nc``2G5-nagWc>nq<;{EHdi1)9*BHq9LI{o*pzfS*s>#x)Q^Ck7v zn?I%kYn}f4)?X3tUw=isfBhBl{`FVH``2G5-nafb{qe28BHq9Lig^F}E8_j@uM_WE ze?`21{dM9ms=rKiczy`|<(TL%f9KE9UsoCQH$?Q;RR;YH5&d#q~Y$HAAn!+L*g6Z zSK}pq8~!Vub`KE$dibw!{CkK$3cuoq_(R1uGTt^a-qQX$#A8lye(XgZpMZaj<3CRP z?eI4`{v`27;n(BU_1N(1acO@e{F-O&4;6bz|9eRPOZ)2(uluj#6Y%2!3LjVFqV^wv zU-wh{kHfF|)c#QM2v^L6 z5%{lk;t!DcI{0^6R)Mcy;TQNwu&H6A2uQ~9yRgK8|K9<1>o(F7HbH6B#Qg2ZEuvwIM{KUm``9&4Q458!^R zaplLFE$MHDpR8pSkF{UYpDg3=g4)Y7^_VYO`{)rzN z64Yx`*8{Bx>b0r;P4FxJNj=BmC)%QTfOcvANj$Vg&y&SA6%VZ_>4&xi_1xC+ariY4 z+P|lae=Gd@`099QQAt0vi14Q4o8Z^HX@4{PdQE9Rw2Sbj{RiOJylFo)E!f~3$6mq@ zG>!1nLwGCgho+HvsN?s*Pc%){6NO*TA02PQuh#FP_CxFRIwk(~@T+x4{Lnzs|0Akh zXdvmQ_Co_nyV~DgtRelcQT0Fr$vn}1XdU5S`y1icCWo{p==yOk2l9_8;X^Bv_Co{7c(oszM&^U|LmSC) z*M4YSNT0KgsD480LRx#ZA6iG+)qZFliLX)hKKRlCFwEeaFuQt{BV zl748E=8e>Yyeq8Nh;A2}qxm86&@Rn0@k6^bZ^RFc3hT9|>xUNUj0onpCv$g_XQvww*0ZxsV!PkdO$vv(AEpYiuw0oirAWAo!i zY(8&^&DS%rxyBQlpKFNC&$YznISa9QK1^($mlK;`uMnGG_YqtC8}Ow6yiD8T-VGhN!a$h__3_t2ySFN`>k_)5&XW@?RS5h**Wm$!LE=0^zKjheC4r6 z;;&oQJSt`FL@z=8UDr>Kj@YL%6DNnq$F7UDToaGknX!TK!QrtJ*TtqLhu*UzcKv%V z>&i}y-oa2gWCq0rU3E#8_s;9!rmAu8SQ! zu=j9Z_ukzxdn7$}Vk&(CzJZuMc{&R)n4OBrT6o2o>B-F4U}o?=gXzh%jp9C0S>N#B zb+Pz#XS^k54^52?Orq=Q5x8RZ$*F!(Sxf9%S6%6e6HXt-vlv|_W~T=SCo(5b9-2yz z3=a)wCiwomW>hnLCpr|L-Vw9MhlWmOCYcdO{kM*voV-bUgyV>g7L890k4<*8_f3}V z!|>S2$%#^3z=&8E@Kd@A=#alI4BVQYu&*xLfw8hZz#v%=U91WFi9gUPc04+V2s&x=tw)JggT5r8% zV+XrsTkj~>`Xw7XhEcZl?PXeTdrM*;lkRdw6WQb@)*R?`iq-u0stA(uVTCH(i z*J}9#ma-`IAJ<*b=D^A&XOoJzlL0hY?fHNu7P4;k%kO48m9PsJxgpn78{0>2tUq*P z>BXh0?^4yn`iE;3zOkEMVpD(*bI(mjj>;1DtKtgE%j1q5?mnnI0LOa{?Am){-@(0y z58rgSuebYXci)kt-G`5UFm`g_*34+S&pGwQc78B6n!as(BDNFi+Z-Dm9^*I;oJ~&- z+zNj@cBVOYYbHIILDUCh2h%5p2jHF_80jA#YenFZ;S*!&$*GCVfy~&6Nw&+7v!QT* z=Jc+S@qyckSC*RJKP(0?8;*?)-!YZh+l$%I-rwJ{J=2knI~z)m4v%JzOr}S(C~n!l zqoZTT_8l#qD7YcR=hxx!Q5wP~>H9?rhaGO2LPf3Du%DJ~$mg142U)_y=5KRs@7QE! zVkkY3Id+UUE*mZPi(QgVy7&HFH@+XWz;k?HWY_SRQ^StIj*fI^e}CIRCf?dVv@O29 zbFi~>dwfTFpk;fyZ4mLjnf|F0*n{njC3F&rBvQ6My_EJ3j}4-*1F<(EQ3M>#j2<1& zj*pC=INdjz9!7ykyHFILZq2Zvu(XSt+jhXprcaNIr%?;mab~n{(%G5YeFNiDW0Qzw zi*&S)m9vyGw)18L_px*ZWe0a3?CXVk@Q|sK8P*}L1br+M*uRT6)xvn<5tHc?@Gx28 zW`Fu*rq4O4@yK?;D8^fD8w2hpn4(>zi9bJcrV_1fY}gL3+4RKZFlQgEj=@i8ZEIsh zDq4rO5ALXVxJb3`iiY};CX$-AwO6i)HS6@xT@mQ!2UqpUd#H!AeIx19<5M`ejAnV9 z#c@O7^25A0*_S-hw}1EH8+RW-W21e}B?Ar`uJO1>UsDjLy7b^jmtA|Xojr$rY<#kh zPaRgqE_o2_%>ZI&E^@fGqvmpK^t*U%A3!LX_ygl(V{C1m8lF7uCWNglMvo{T$4bQ1 z$2CzO7G7o=y;O_|I+dSKc4xgPXA7UzboVx1zd9N!vgGdUJnC+}{jKf3?XB%D$oU_4 zo*l2zKL5L4X>~2A(Bg t7NGwXPVo1Fjv literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..5376402b8ec2b228f44938f60ff531801c297f19 GIT binary patch literal 2592 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K832.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K832.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f873753c0cf56f35da05213ed632918eb176d424 GIT binary patch literal 2592 zcmbtVJ5Iwu6nyJAQG}34K|z5O7dZe0JuY$(iX4CNwO6dZsfAVfhKKBF%*eUhQvhs=MK>u~Rozy~y`gr0TbeVX1n?py%8H zK5E1d?>cZ1&k5fTc3-ZruoSuFI-WK6#B?{9M>$!p`{*zzUX6SLf>g(HN&@rA^?^)A zV%~cfyx4Oa$4es+gO!`pS0kRgbbFJ`a~*RUdcXHc75Cu9<>Vs+hAyE8nr@xd z0zL4(Z+);7dk#I&C^{g*&~s)WZP+scIy$;WL z-YC~%y_-V4Bc8Lo4emJ>>om`4k?1*MM4q!n9QT~=jd*Ux-pdn_%fEYgZl=ZN5HNHF zJ#hPfJm+~o7>h6Qg#T8>Wf>z3MT6(ue#+Y-U$6IlO6F5Mm+B1|ibcI6p7Xp>uEl!c cxgx#vT!(BHnh`2wjAU~Y<~Wq>!vmQA0?~(`+W-In literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5d6a238c7cdfa9b20ff5fd644d4a148080d83c59 GIT binary patch literal 70765 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

`-ORunpg)Y%$*lYUG>8 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 YT!U;Dnh`4GoMdYk*SIt|hX=6!1#-inp8x;= literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..44301ec54caca6740f2d285b534a7867cec661cf GIT binary patch literal 64616 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 u0si{)zJOezJJ;)v^Oo9jD6NVQsyx_x}J%@Y+`Z literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K960.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K960.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..07303920c441d2968d139a06d81c45e9aaf58bbd GIT binary patch literal 2592 zcmbtU%S{6@5FKweQG}4lfdhv~*+UAT03>oqAso_27Ks8Vfdd6lLWDSQjM4yOusc-EZ%T+xDyKmVPW6kav2m~PTm1Qs$)6z0`tZ7 zflN+P-io#8^E%YwqghCCFUM=K^tB**&O7&d9h7FgQSUBP&a4-_eX59|`_!BBuFllE zHtH=hy$|HAMCzEi*>fAuOCu12m7CI61D?C|XQRw>HFIiv{}Ylj_u$Fr6e1&rZlMR7 zZkg2rJqW#Dg$&fcl(`4x z-i5{~LB!A{df?CdwWttB-db+oFQO>#Bs-5B)_c&_8E@XoPVr+H56NY4=?@m$y6VbAH=fafOcz3ho>|KG!N6E;rg zh@ngLz@Pu|T;SbB0CNxEImKle6AVRz=lpq}cZIm1_c^3~iswR*5=9JMQtyE00&kM5 eSuZ?i(o4_P$Y!P)p+e3{wsvuiOTBY=0PA1ZuccoA literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_4col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..8950666358c2c009a3d42f9fff2a4894173f43b7 GIT binary patch literal 66920 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1024.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..674d9ec659882afe76e0c743c1e8d91b3b7efcfc GIT binary patch literal 131918 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 UWESARIQQ{Ho9|h7-+$!)0Fs_HQ~&?~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1088.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1088.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..da0edb6a80dabb974bd8b4f55be067dfa55b9aef GIT binary patch literal 4208 zcmbtXL2lbH5L_xsY6J%ALk~R!hz@>0eo!C$fIh(oKOjG-3iu&87dH8ewAY>_mC!;}zp+I+mZ)-Gw*Aw5L*Nj}vcWe1348$#_e ze4i`%UK_qU^6jv_C~v*z_JJ=wM+|ySsBgh@=yR$)>cIB7RrFjJk*hUm2e+bddQKQR zga%=L>bV1R0nhabpxSfCkPD_U!%#GMPWht7Y@bVf584XH=d1Z{E#HKpamm+uu3yOa zRLR%Y7(D0scE~f6HKWh%17A9W7@6n1zGctpT)}he=(&f8RINcfxV0vmhlD{5!u(Ww zcrI%H!nLTx+IQw61)QOMJGk31*>P#S81ITe1DzkA zFyB>+;zIkXxK?}Ay^q_W?qecny=ycsmlA^-;9cYSmg_#Oooayki@DgP{LQJqNiH%B z)d2OU^S1u_g>g{_RdEY-5H*mPxOxpx2O*D2Pl!P%)Pc^Ie%GK5bk5cRd=Yz5{~sFc zLoede41*eIFDiU*FN%Atj9bv&#~tf{iJQ@jpnc%uH6TWW3ca_a0lv9(Eqq~nQNv#J z!bHyNMOv0znqlZB(ThUaUi6|xakqoV{a0M}q8_{1=#G#r=kz--8@n`*?M~+L>2^8J Rp2u&6$-IuUd3@Jl{sRxx8-4%) literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1088.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1088.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1fb42addcee217e03b699cdb786c4a57b680d2fd GIT binary patch literal 134478 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1216.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1216.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..65ee30f4177c2fdbd68754e2d11a198daa4e3fa5 GIT binary patch literal 4208 zcmbtXL2lbH5L_xsY6J$FLk~R!s1ANWeo!BL?4duX4}L&@P!;e4`h**_oweaqZ2*iTo7&--+PT{|)ZuVZ7@6FdUnslfOri=6J-z zIRC~$p9>H0)MEa4-S9>@Uvd2Ef7i@h&39$_CJeaJx2_BPN;9ebJ*upd-Q?b=N8d(+lXAPK|8nw zh0}Aw&>=Jk@u}ywtOY#RCxB|t?LsYB#tcKz;5p@s9<%#g;@f>-=4!qx%Qs;t7WrDw z^)vbIEBV?UgXcWo4s~X+&e-QRfiImwjLdUh-?Ha4R`A?1dhSm|s@9+#+>*lSIbl$P z5T9xf&qeJI3E&*hDIbD)G&)tqB;?#IC z-W7oc8Xuo9-&M2nLi?(`R(tfl&)cEzFVJ8U@^UIMr~%$Jo^L?|ylXUO`yTxlYq3uC ztJYv=YLQ{62IxP{Yx}RCnRj2Ax6lVs1Brz@s}DjQm7WlTQ0RjH7 zMGg0&!vz|&gVVO;)C@xxiM=Sa?a5v=EAOf@FZZGztGUw^p<2%AcV0GjDURh%;`nqs T9cRzux56Z@<1CJ!xQPD;!-*k6 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1216.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1216.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ccf4dcf69cd9dec171340b14b31381f3e2106a68 GIT binary patch literal 133966 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 IFD};q1+Ezy761SM literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K128.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d69fed509b1d206dd6a14dbbfdcfcab4695a42d8 GIT binary patch literal 164174 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 Mcle%l-$O_L4?p)c)Bpeg literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1344.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1344.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..05d4e0835a9237290ee1624914c2cb170330a812 GIT binary patch literal 4208 zcmbtX!EM_>5Zt3_TQLO0k38})U_MlUJBS`CAdeK_hYCmsVE`474x)z&F@iku6kI_{ zNC(Pr@8<5fIvYpRfJKqZo4whYT~gxOtA!K!D)_$@!B_uxbXO0FAQAr(hF*dOAwJf=XDyI-9T!Wr=XOSe3`5cG0^inX0Iw&$Kh&1P{ndO| zmT$t)yyR;=x1Y)PP|5ew@LiK{hwVjq>piy#eCau2&~rk43!cNAQ|-|QcFrxL=k^h~ zT7&lJ7Fuk6Bn-U*4MKeExkuIlp6j_5RjHkG+fWOZF~d+acux7E$LyR-eE(iEb2ZH(hdQ%Z6Xx6|@TD_|k$KMRTlSpB3Z7d=&;5%?)f%)% zx1?}-Oc>N4#K+phb5Z-J1Te*O%7~Yg48@L1 zu8 zzbXAUszrvO8le9)Zu_sFnRgdz!7aa(x6lVs1Br#Jf8HOA2E-r~`rt(k&<7f`eE?s? zS=5uzgg$^T!mQDf=g$;spz*@{_N=_y%De^becquDShxwZ2-*iefp5TwP+|6#W)a@G zbS->gXHmmh^z;S|+N0C9h?DBUH;deb39zU5aD7 Yqc~pO&d;;^@%wZX*Yhln-x7%b2W5XH2mk;8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1344.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1344.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c161c138134ec24eec34c21c205e95fae9a2b295 GIT binary patch literal 126798 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≫rSD$U3mT!oPvQAfc>WZgKW&BQPbPnH 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 PzfVVY9cOm@mVo^~YbYh` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1408.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1408.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9be10f268467b63d2b92ffc7fc63663fdcf18556 GIT binary patch literal 122190 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 U;BuTikKd=0xQ>%Je&Qnj4{NL@&;S4c literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1472.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1472.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..64bfefcf874c14d2c915c8a4c5e35d87b36e1a1d GIT binary patch literal 133966 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1536.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1536.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0636bfa399edacf8db092e5e1091df478e8bcbdd GIT binary patch literal 4208 zcmbtXF>c#H5Zt3_M==D%MG6-N!a@(o528X3QK1Lq2Vnp|#DyMW1SwJq{*W@-+c_SW zjIjy>MC9@Ac5ZfNm$anzZk0s73;sWd;5Pp|rMs_}yDksyw>c;Ia~5gNXDr6`Cw_FD zE#Rfa{>y#C2X?*T_$|-NCp`Ef^2F!3ww#mHKVn>+DP!%c#h0@*@(Upd_1>9A8~xz( z8@AEfle#rZ|*jO$YeFj%^mB7^DR(y5IWowu(a2-^Mq0hw|s~OL&ZSH33xmNwX$AS8i&#(sVDYXNYQ4D*qcQ_u6bNQAC z_PL|smaTR}&*9yw=bHPT!@E`I(0hHKyDy%jfat=}?<#mslU}x#n=B_ZFj2;y>#%PL zF0>EfdhJp785bJ#C6RFrc81HXj6n_XuE~7o>t5&ly9V`Fa+7#yi2EGGovDMO!SHI0Yj8ANYQPxO0Cn(B4NwO<=j#BzD7}ci9LWo70AE4|*bGDmcF(LBBhrsHb;t((_zHIKhN GvHve$hb6WE literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1536.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1536.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..41b5214718dc25b5a742f2fab26874ae777d429f GIT binary patch literal 131918 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 R|G~MBr#gJky7$2&{}=v&JAeQH literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1728.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1728.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..cad7daadf15fda8c4077da52cad548c0999af43a GIT binary patch literal 4208 zcmbtXJ8s)R5Z$F{LvRE{MT!&#!h#3L4WdH#hzgY{e1kB64&p)w@DYR{MM}XJQl5tM z_A^>LOE5r0E_e6MzIktkwDax#(mVI$@PF+bZpVLTfB*G**NsE{Z7$yZy*SrgE?A7~ zFZ{?lUBF9={nz`35A?d=_;s9jAMxOebB}zEYs)$3htC)%XBuPuNERc+_l5fn2!?v^ zOxZ>|`1Hz1-lcIn<|2>lk%vE*Z?5_2-p@s^xgdHWuH?#tsfio;o@B{&Yc*fQ%|k^D zc}~7I?q(+6Z6)8v@ZB+P=iCraUhTQP#-$O6LC-DetAgiNI=8s>Tr2**YX1`QS*<~P z_HCq+VaQ`>p!2!*19O46n+Qo|!E4^$DI6KJ*+hf>V_58}C-#d*iuP@Z9=tvIg+niksvbF=Pl0 zbUxP}o(tNaBES^SskYT;zNHz{pcPm-CGnfOmfe4 z*f%F`Um4eGkGdb@LW3bBa#Gz3A8sWEHNd-OO0elg95qmk3SFOQTdoSfn zFsOm_s>1j7thmr#aQ_##p#2#4S_e$rgkA*gm5qVXe#QJhTva4y literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1728.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K1728.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2609490ed6d8fead31358dca69476e0137cda747 GIT binary patch literal 126798 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2304.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2304.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..eed41f9256d5a7d28bb96eee6e46ace3d1ec2019 GIT binary patch literal 4208 zcmbtWL2lbH5L`M;;HEB`Lk~R!s1ANWe^4L%kR1Gg{-7%02jmGk_#sBoLyty2r#h!})6;m(RHIP2`dHF-FEDv|lmL_SENk&K^dJUs3)5f~nry(`cce ze0gQ2AbH+~wHW6OsKeju59F8kYq7Oj5WSFBYZbuM<<0nh;IeAI$jdc0CJddEug|+% z$ai1Kcjfp#F>fQ%+Kw?)d+uO)X#`@>b8Gsl;JJ;(Zl<1#>hDhb9g$~wE)G;i7PR_Y?@?4wBS*=05gf)fJalp_iG_d&Cb5E=V zJl75Y)t)<8Em+13L($+lC4(OG=Um436Ej!y-A?!>480YQZvQ7>WkZDc^$UGQM4*^sk!lcEUGdC=mG;JhzDNv68R%+zad6V0$#q z49}e`Z(3>>^c>!;Z+Z^zR*m88^`5&=o}+*>w2zl?-xWJ8O&8r=5onz+IDglEy}yC%*(T=#cm#SN2pc^`kj}}!w|=IM{#_*P3PJ3w=S;pERJsq Gtp5*7d?;=J literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2304.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2304.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bd544ca7454883fceea2241edcd1cef75b5552ba GIT binary patch literal 131918 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 L?^*XgIQjno{ir)C literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K256.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f034f15385c5daef4010c71b7fd34b3ef5c4263f GIT binary patch literal 4208 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 ZJC>W-adbN$C-ZSm&Fnf(?D&Zb`#&$#E_46@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2880.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K2880.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..20df4133004185f1cd3499866aaa4743794c7d40 GIT binary patch literal 126798 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 E4+H3w@Bjb+ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K320.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K320.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..cc6bec853d46a8c376ee0cf9ff9f2cba6a3116ba GIT binary patch literal 4208 zcmbtX!EM_>5Zt3_Lofuy4?prS5I$6ZJBS`CASL*r0@6VkKn0`&>!Cu7Adfr+SCA6Y zfikzexjU{HXB8SSdB?roz1f*tQWDymMG*Nc_`eguaQHiho5winhH1JsryxI1BF*W9 z#khaPMc1VTytVL;7z7X3ePZ5Dq%S*nYi^tJQV5Je%`K>_3C%5&?dn`}t?D~+|0!?E%|Uw% zZT5 zMfQq={b(lOAlb*7dtxo1xxTo#HMdQ*U>U0z8V#CLyf|aF&lSAC=dbvb%iic&aVrU>}PVEz#D|jDSNk3j_Zj86Y(7ePup}ARjp*a^` ztGPYv++lkeu3vM9lsCJk0X2trtL|&+dk*hbwW0UgK6jfnM*`7>z28;sG2F&tXV*N4 zPbKy_wZ|3ayJ}WmaPP`%xyQL5@^(1)xsZMiHYqP%8G{_)T{GaFKKE*~?;4!HT#I$7 zpPPfNsYMk-Il%eTy!QO{GxP48c_+?6=0I}c{2UxoUUI+~425&>R}OFv)Mn2Cbdh^e z{~sJc7ut*HTE!p-YM=Pto|PBeyYfzOKje+)fQ3U>@_uuH`-Df~-!;?cKz*SL z+lw0Zq8AqOvR4$q literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K320.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d49df87a587a294a47577663afdabaedb447bf57 GIT binary patch literal 134990 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K3456.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K3456.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..698019297ad9cc467dc8a668c558847c4ca99646 GIT binary patch literal 4208 zcmbtWF^=0X5M1hXhH-F^D-OsN2SkM*kRQZ_AL7Cf$Pc0beuxYIBSw%SrEyit{KOe8 zIV81aE)*odmMCgxIXlCZ#I=j16Zs@-*Nov=jAt|`c%G3v?$&dy`g_oRN2E!fYX=hX zNEmtx8ie_=_C0HXyqg#-)t);T4KfTxdkK77qXE30`2JB}56@5W+?a2|(7fbpJ$IbR z_f*OE-tgU!Z-?cj?NaSIcwPC@bHs>Fp}qyrq0fcbn?ARUo;z!67;0CoL3?q_As`+J zLvKNYFhBO(jH0M&hNA8NreW*CYF&ne%6=MvxJ2WFn)xiQ~_p;+Ww@Z2oE@SO7bA7AUa zBkSB@c{I)h&z(Zv7#c3APdhQ{5j)c&KYrm`DIW=kwjTc@{Xb_A% z_FRX!IeFKWd9C)?_dYK)=wl)4zi+l7FGGnz4TOBl`(A5d_dWJsti>kPuUdn>sYQmN zB4Gb%Uc3MLnRySDc?Y9O(2^%|T)UTQ!LLSY|x&lNPlKF~S458#W~i`dIiylM^L z3++XeFTam(fT@k9~oPOtJW0&T!+|fKf-EPO( P^Y><6$Jso-V-f!s&N?!D literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K3456.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K3456.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..7b84e78c18fd6d72e49f1ab480eadb16ceeadd4a GIT binary patch literal 126798 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 t4H8QrEWjij6L+}U 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 E3lSvki2wiq literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K4032.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K4032.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9fcd1454b66f182b09314440feb779506ad96e0c GIT binary patch literal 4208 zcmbtX%WWGm6ntE-ZNU)`0|}4-F_1l|fOHTYT!;@UARS}_sDPB9g9=CqLXbm_f*VLm zNC5$q;UkAX5f0ZYz}n@$&>o8fGJ-01tkYFgmu^>ZRw15uC#MRy>D&&d)vD=N7?pzpp3Ppg)=g zC+Rg}=nysV@!WF{%mq9*Mu29|ZG0}6#sovr;5pTc9xL~`sCV~<%u_s<>x~$SMZKlx z#+iDzje5%-gXf&y0eNP!ChT+Yoa&|Lh>>{C<)iL7KljXY%iy`=i^(;B=a!tL*NCA* z)WFB{+QW09_J;^C#dE5MX-qH_4W83@#dA^b*LP%|;<;RJ#852it$1#hUU;raZ|S)m z^E_aAG|mLi?F-KlgPy~0tFEhdp2Kge#<2I6=ee8UITjGRaO=4Wp1ZNh4pYO8eJX+) zXxzS0oU3N>t{QpE+N19s?|{C4Mh)&gFQ*cNH4y5p_r2xY`cHYw{u^iVZX0UxdAAd`1o6 z3*C!2HNjvFG+sGx&*DYxn|Ld=cf7U_n79dh5o+)CsJws?p!i!;sR7PhIv2jk`aq7R z<6d-NBB$*|Y6(tFFm#dFi@asd_M%z5E3DfR{EwG=(TI0%?F4IFWAvPtjLnFM8v{0r VY;jue|0>!J#eY^Rxfe^v|AVNcy+^ z6;pov7DMK#jNzemO+Mlo3qGqptpM+NyCDx(%%{^uUG3Kl^{V`<>U$hx)OuBF zlS=*@;IWC(9q<3a3y=N!FTC*KD9UN2c7s>fJYZe_dGpIVEz}L1vpgdHX9JlU#F^>fR>&1jFC?9r)hxq+ydi;hL>x5~=f1I7O6p)KX8y)XJA&M8LA zcm4ME<;Om^{r(-zgJ4!a|G$>+`q1{}H-2LK^6j76zI^Yew=ZA&#qG;K^@Z)rpZ?|T zPZyh?`Tc?B?|unYsx!VY5LJG74Cphzi*v`mp}5}y`uT4x-}St%^AD6q8Rs4RwSnf2 zodaLHsp|Okf#zK+TL+`3ACI2cyVCr~zufxgH{TIOtK0taT?0c=^Rb`adS|5U`Hkgk z&u!N-MWy3E{5pe{UzZyyjW2C2?f8)H8hY9?!E5?*!gzF2y9{dy5{w_uslYP~P*+KQyIL^V*O6L#0Pa$$_Kv(x|`AP8C!&ch+$ScUulu zEe}TeieG8HX8C8IF23WyE$6>*aQ}xpRqs8Y2s!Jx?@4LG)bT(SvmwW9yCjab>Km0{EdMkePa(b4Oo_bEz`P2uy z)I1ZNA1MFiRH<}S*IYL>m$v>&arqNpEPlKEt)b?Q+|buNa_y|D9Z@BPwes~>v$`daSKUORT%PrYwTbmL0xx#+f^+9>>+r?1z4 zA<_+Tv~kgFs_QDw0QTM zzd8APANc&(jW^|fX7IqffAC`;z44}@KOS6s_Nh;P^!oenzw7LdZ;oF0(2ZMOT6yQ) z4*}n`c=r!}?8PHr|3_Co`J$ZjtqRUL_+x+a?JJ-B=wRj8M+RGaX55*B(R)4%d-747 zJvf8V_w^(1{@9BTAAE2}-oyS z!COb7#wTBV=*P}~@7er`YajdQ{ErRoJy%E4dFeG*JNthY?N$9(dgM^gLtonSJ+~gb z^{G$3cwE(hb5S~8I(X}CQRI9T+Vef&N0iTT_^5UqM@`E=y6d*(pV@WWS@45v%jcH= z81@i;_Tc9&__?6$y9>*E?k?Ov6BVD2cCY=~k1SsR^P_hamVX96zk;7XzN>(Bb$sys zx_|g*-{A4)RJ1QD@BWLIO5gcnV)eXq^QH37f7h{=`l4{782v{rQ~nQCrubQ{ub#iK z&0*(r%#H>k*w+uM+nSUk;zdnuHwSfjQ}y(Yfyhx z<#?|C8)gk-B$q$(tJ?<~?VsDSy7i^yi+{Cs-(aq~MPCosuR4Eszf>0~9d6m^q^%GC zYKJ26JV$w{yvOA^&USf@vt6F!?5I4I$eSh;c~jhuz8bglWbYWjSlFX8e>xiSr;tBk zb}av$&G$n76!NE#KfPR*6Y{5!KaFgn{K@1qDs3_OQ`~m>jw^Thj;fBpHXqf;aXU|T|NLn*HO#pAz}gxX*{|`@oou_kl4R?*qNvKY!XE z@~4nLVcLcKDdbNfe+v0i$e%*~v>EazlfSrpsATgQXS;mI*)HF4HugUy@~07>51ITa zZsUDmtQ_wHz1=^58V&hV$e%FnLjDx;r;tB|{3+y5A%EHo`IE_CTt0;TPdcA*w##>% z?eZOGWB=1|V*k@{V*gXj#{0mSjrW1x?w>!M8V>uP!ry-i`BVD8vK4;+PDQEk`*-2@ z@51ljh2OvX+xq=GlfS4qWA{Jle8$->-*L9fcbtv=Pl^0#(&s~V|5MDy`@oou_krH- zpFbT9`BQlQglQL^KZWN{;rUZ|{uG`+h38M3;rWxvUtB(f{ZBfdakk5MobB=*XJh|U zB7Yk9`HR1O#b5X zA?$zB`HZt&zT<3{?>HO#pAz}gxX*{|{->CY_kl4R?*qNvKY!XE@~4nLVcLcKDdbNf ze+v0i$e%*~v>EazlfSrp2>YLOKI3ec?>O7#JI==br$qiV;`1T9|0!nUePGPS`#^8^ z&!0v^{uJ^jOuLXjh5RYxPa%H_`BTWBHbeeo@)ws6VgHlPXPoWw9cR0I$JyBbG?du? zG?du?6tnR@FlOU@ptt+yPp5{${-?12DdbOK|5Moi6!t%b{ZC>4(T9 z?Ea^ijrV~u8}9?X-9LXC4f#{ZpD^u0{uJ`3kUxd|DdbNff7%TBlgVFPK7{>GI-ha2 z%XggZ@*QVm{}Z+)nM37E#jl>sCH6nXY`hPQ*?1r5?f&`Gsa)9q6!t%b{3+~z3j3eJ z{-?12DeQmRB>SIq{^If>?0<^cF5hwGF5huB_CF=^r%9g=+5Jy38}9>SHr@w%yMO+4 zG~`d=`4gsHc>WZgKZWN{;rUZ|{uG`+ZHDJhCVz4H5cWUme8$->-*L9fcbtv=Pl^0# z+~-4f|5MDy`@oou_krH-pFiyn`BTWBFzrJA6!NE#KZX1$VQtGtPGTjWZgKZWN{;rUZ|{SHr@w%yMO+)Kjcp#f5Nm2`BTWBLjDx;r;tB| z{An}fPbPnH`4IL$>3qi7F5hvs%XgfO{ZEPfX~gG4cK=h%#{0mSjrW1x?w>!6hWshy zPndQge+v0i$e%*~6!NE#KW&Em$>c9CAHx18ozFPi%?eZOGWB*eke;W7sklp_jv++JKX5)RJxBKT$`$PT|@+VBY zkUxd|DdbNfe+v0i$e%Vt{$%nOmk(k8lg?+H?eZOGyL`vl*#DHspGJH>WcNSCY`hPQ z*?1r5?f&`GXvm*J{)A~4@~4nLh5RYxPa%H_`O{{|pG^MZ@*(Vh()oq+~#nRaG7w0aFuY4aGh|2aFg&7;T6KGgjx3JGn}nALuMl1(+#EFqM!^O7XGT{p0D&ZR8I^hQ4 zCgCN*D}+}Gw+OEhUMJkP*si}s|E3cCo232;F1H0&2v-T$2-gWW2sa5Y5nds@O1MRM zjqp0*w#9b+CHgm!=-)W?PjI;{xI(x}xJI~6xIwr{c!}@|;Z?#d!fS-r3AZh_>o3v2 zu|)qysDFaXZNU}7Rl+sGb;1q8O~OlrR|u~XZV_H1yiT}nv0Z<|iS?|bu$zg|! zgv*30gsX&WgzJPGgqwty2(J)cCEOysMtGfY+hV)^68)P>^ly^-C%D`eTp?T~Tq9g3 z+#uW}yhM0~@G9XJ;WfhRgxeO|^_S@1M52G=)IY)Hw%`ikD&ZR8I^hQ4CgCN*D}+}G zw+OEhUMJkP*si}s|Hcyi8=?LQF1H0&2v-T$2-gWW2sa5Y5nds@O1MRMjqp0*w#9b+ zxA1D+x3^|-$bH+Az8}T5;4aQ{jc}cCgK(4Z65$oXtAtyG z*9fl@Zd+{nH>~Lbyt}Mz~J6LAXhHiSP>HRl+U8YlPPcw=FjPn@IG}*wVjo>Yw0pTX2PN zm2i!4op6J2lkgJZ6~e28TZGpLuM=)tZ2C8r=%2BreO4dxZD=LLbyt}Mz~J6LAXhHiSP>HRl+U8 zYlPPcw=FjPnM(A}*sf1ed(!u*NVrV6Lbyt}Mz~J6LAXhHiSP>HRl+U8YlPPcw=FjP zn@IG}*wVjo>Yw0pTX2PNm2i!4op6J2lkgJZ6~e28TZGpLuM=)tZ2C8r=%2BreeT^%Zi8?Y@3!Q+@;(kcU3b!-3!bhk-`~K~btnCG z(O-Wq`s;BO@0{ei@@@<~U00qNf~V`scPa36UAf1gzy3J^`s;BO?}FsI^3Do8U3Y}q zIYQT!?>O+M>q_iLfBm)4Uym^^`Z>NG7e5EU>*pJmXMddsTHfb;@Yn0Z@_sGgy50xZ z^%&zq*PW#6PSSNJ>AI72-AS&8t}8JVI{Uc?oju05&~@eAOEcQ#bz1^<>l*&l9(h&; zp4uZh{7SUT*S`u(^-wz{=0P9dHt6Fq>ha@_dU)J@{WW@*fpMpHj(FYBFJBM(#r078 zB}Yd+)J}Wh@V=ek{kj0}-|?b7 zzWr#ApAThm=o!MOW+Fkb##jF-n{iW?Qm(ZKt9!25c@(|C<=J=7kFV`z_` zw`h-F7Z@);m!OZw7gZIZg@&4d_zra&_Bwm51_KeVY$-CnSZE*L;BDJSX ze1-Tb@ipS>#5agXzkJ`(FOMU{SbtrLw-Mb(ilkda<6EThjp#mGq;$=NzT!@!E2jfD##5dIM;~U1s$34_f zyxcEPKk;&3L;b?jeYr^Y*ilJ{#hAW=&k+x=#6q5MsI_irUm!={#x&N z*-n&+-cr`7_hd%BwSNY^wLd9mU~j#(|3LDD-g;~Q40>z-K6;}Zhtb>M0oZ1Kn^>sI z)ZcDUhb!9&TlAK)PQ6cN)LZ*!&|CZKw(&o`_16BX8?mFe-r7Hd-rB#9-YCam^fuUO zT5x|)RqGuu+leyKTgp219zoE`6u*^!2EBFtG3}JmTW{^3L2vD!L2vEfM{ktlFnSv- zdYgNoH>OGlJZ|$E!Z|xt`S{c3d*8Umv*8Umv*8Y9;MmY|nx51*fc}8UPj+Y^RlipI+ zsrSi@dTaj-dTW2xh1k(sZ|$E!Z|$E!Z|&blZzWzGQ{s8HBhPy&rft6 z>by?9@ys)m-r7Hd-r8SvA$IiETl;6wTl;6wTl@FX8|65R-Uf@_=2@}PJ6?wPO?pdN zr{0qp_169w^w$0{t(DPRZ|$E!Z|$E!Z|&blZ(qNPqu$y-gWlRdrnNG9 z>#hAW=&k)T=&k+x=#6q5MsI^fZ?iYa=p8RZ{3gAntW)ok8THow8T8ivstd8Bx8B-6 zgWlRdgWlS|kKQQ9Ve~dw^fr6GjNb7w#Bb7D$~yJN-p5SwMEhsZTl>efRz`2VwSNY^ zwSNY^wSOPIQI5mtZLsKV_GlWt<7J571&ZIg4s~9q-q`z^NpJ0+L2vD^x)3{h>#hAW z=&k)T=&k+x=#6q5MsI^fZ?k9E=p8RZ{3gAntW)pFjCyPT40>z-nAXbZt+)2iptttV zpttt#qc_TN7`+V^z0L2+7`@|Vh~K2Qly&NTGNazwKZD-dUv(jN^wwMZXV6>wXV6>w z_t6{WIE>x~i{9pUqKw}0GQ@AvTgp21#_v94iYMAXgWlRdrnNG9>#hAW=&k)T=&k+x z=#6q5MsI^fZ?gy9=p8RZ{N6_KTi2n^>(m>2V3j>G6}u;^`mx4`HfFGKt$y``*E@5zjMYyS*-YyX(m%IK}P_RpZV_RpZV_V1%N z%5fOI4Hmu4?`#;o<7J57q_>oH>U}b!-r7Hd-r8SvA$IiETl;6wTl;6wTl@FX8|65R z-Uf@_=67L?-tjWTZ_-=JL~oteqvkuXUlSi?d`9``yP{%*H*nESSn7E2=JEILzy)s^ zF#c8Vf4^}^{CoW7gE9YTi>*I;zC%NGYW3!1%)jaC&;3B6W@8?`ITiD-y881sy4HW} z<^wVRmaD(;uCDdJ<>p&s{!LeZ^cB=!jNS~5wvs-RH>)xK73ZJ()2{wgH;=~rTh2fK z?XLb0+&mWZUw8fm_3JR5?Ro3Xx5WIToYlX0M_2!3`^(OM=RIBhlkKlM|I+X4|O_&NzS*jtH1bxuJtG9bKTXy z`<|}#C)Z2a`>XZVeLbqZ+6RU(t~k`%uUM=aq<@D2HU`7Qj6_)hcFC6I6JsfBs#a&R~-ByXERHsQA)(B;#E)VD*WfhjV9q>4+E3Klegc|BiU! z{PQ=u`gg<&=U@18SN~+ZXgdGmSGxKq+rQ%ccm8Qt|781H&cF2SuKvmPuRH%;AL#0z zZ2!6&uU+c?(Rn1tYu(L<(vzLeV3PA;#nr!4#ox{&Ip0=X{l$kmoxvpMbKTXyyL|L*a`##0q_beuvw)mRB+0rLL>b~+ z&c##2x7c}zwd!uC>qM-Ll_A#3{<1_FVr|aFOvKvQd5E<+inXz_eJH!zUT<&WykoG{ zi#XMXDwTDKzj%KM$Mo^n`rnU}I*;UdL|g7K{^{ed^-mptjeq+1Yy8v4U*n%X{u=-E z@z=Khd5D=R{@V7x(A7T~zp4XP|Mcrck7rmH`F{5AEbkH5x0ef%~4>Eo~U zPaS`4d!Fo^{9wAoU*n%X{u=-E@z?mLkH6MGb^JB{>Eo~Uf7$r!_X!~WYE1E0|Bkth zzp*mJ-#o?NSQ+APp5kw;4Dna?7bLES_?xHr8#@p2H&5|5R)+YSr}!HyL;TGv!p2`; z)+PSp`86EV$6xE8I{q5}^zqmFr;fkIKYjc){^{ed@lPLrjeq+1YuleX{@V7Zj=#43 zH!#SZ@jaP8)(7se?N1$ljeq+1Yy8v4U*n%X{u=-E@z?sNj=#1&spGHlPal7cfBN`q z{L{x@>z_LQ8vpe1*ZRL~{PpjN5PvnM_^bbBjg7ytGQ{5k#ot&N;%|ZCZ>$XQSKcor zu7~(rp!gd*5AnA^@i$h6_*mXD3Uu`iBEhpE~~9_NR`&#y@@hHU8=2uklYGe~o|o_-p-B$6wo?)bZE&r;oqJ zKYjc){^{ed^-mptjeq+1YyDp~{wfC-e>JA~tN-?(jlZ!n#NT0xzp*mJ-{CuKoru4& zGQ?lmADbvc{2iwF8#@p2cbMXDtPJsYnBs4&4DolE;;%335`XdcKhWs1YI*1L_%8Xc z^}iqfoky4Fzs5g$Udh{WB;O}ABfPg(?aBQ>hp!@%?<=ZXtbh9b0H*%*`vGkGzk>F6 zet++HzvSAJem{VzKmC3H+y2!10gQk8{Q$;4{eA%BpMF1p@lU@W!1_Pgbv`8DkKuik zZO;o`=Ud0~SvTL(?*}mTr{51?{L}9Tu>NYvc3+P+e^jshUHsCR;+Ov0rZ#@X$`GRl zUHn3fij^To$=|R^lp#h9y4Z$yRI&3AqXsEP#mW#b2VHE#`!ZkV;*k5K{Q%exrh2BX z)_El31>P?i|6KR@(h)Br>!0r)zmoF<@x|0%=$;QI=O5yiZNG|NDdL6m&#C#{>7RU` z({lbgAMEr`K2KbC{)G>8tv~rbCmOKrFFxPZKN;`J&VT0%UHy~ouR8zIjjsO5_Tzb| z(R0^BUHy~o$NIPa-PeC|yy{M$(mklZ^GMEzva5fm%3nH<tF>NCoQE~L?GDtV%CKf*=N*8pmYFKU^S@ZxzUWSM z`KD@DG(Z^qZI<6hd=7lk@>SyV;8C%z=MeD)@Y^kag!m%(e_;6o#P0 z2pcIizjI^Ex4GJbKhuNHgMY29=LFUBICy_u;>+N7SpQ?hm%w`+h~EYNHP-()@jJo4 z&hn2FpKDJb@|%8@Hzs_)j`ZO3;BUA7XUP9?@X~&%rv_fyBm5cgeq5-YUErm^;$H$U z{T03p{0x$g) zKG!}SVYTXcwRhvRZ)YC-PRrMbFM*f#i2qLTGQPrN-VXYCzA>imiDr%T;CF+U>xw_- z?V#u*`~mQ^E`0qp@P0kgbupg@MF*(|^L9}56dv<-Q09a1nE!(^uY|`s8WeqmuYebQ zgvb0>`GnS_v@zk^f4m3354`9j{#X}-GVa1305AFokM%mTYNmJftPUGN*-huDh zu6W#|)$Lo)N!+6agQt76=MRDRnv*~7-8nyJh{wG<=VJo#xOeA#3?Ux(?wnr>#P0;} z$CP;7)72h3-TplBh>ba!V`IMkh-qDU#Fno7UhuN^r5?o0uKW@3a?ch2ec)wGg-0yS zNlXy_1bDCWhVY1`q9^f)nW7Kzh_N}D!%`1obx!7_@MpmLaiMw;V{;Ufy`G4%q}zn& z5gWVmh=E=Cz2K#tQV(KpSN<4yS%cz_m`39wJYp>MOL)Xs(ph-KOqqup!dJk{S`!{I zU)BrxBPNq>;*S_hI!uvn-TA%nml!4fh_PLH#Kx{XVl|Ds)N=;B%s1f?OKIK;k623M zB7648L=MjIp@`u1vJn{Zmr(Jo(t07v~-XHO*E06dv zBsxet5od;c{NE5Bab`$#79R0rh~lKbF5=#hjJxnbPyijl}JzF5f5pe2#Jc96j@lzU;s&)}c*G6TQ+ULmA%Fkf5FYV_##i_g;ALJ3k2pj9 z5*~48NaDZnhy$eCY2RP0M{2+DSnt$+;UDk8BL}1Fia*vh=_dSc@G=jDN8F%!B0O?7 ziep=R96JJD;<@lAz{|Q2z6f5{m+;8_=sqR<8Sp+I+YlZ(VUBV_)t;8l55KV`M>(N- z<)haKazeq;op~PIE8a-L$Z=MVJY5sSL|BbG{gHpYBCh{;{~W8i(i$RD|)+S{w!StcH_ zF)w2+^&_^6&g74KN?z8E_#-CgDQENTM9df6s2;?285iPlFUV8O_w^tq=Vgt{b#X6~ zc|!FdR+F9+zMexpc*M-E{)owWSvyh>a<;DgaqyHY`s*T>Bi*E)W8kH~!tVv|=lO>4 zxOdQa36I>5^bsES4jLEXk&EVK?F)~41kE4eagU(+COqyDYOlGTSEY?9-``_Bc-%X> z`r{r!?U#BG!@KhMUN7sNu8Y`C<0AFop3;>^PDuR{f8?B`zwo$c(R>pg_aM?uc-*sS z+=a)zhT3!5>xO#`%^%@$uj$Gox9rN}`2h7x>Ot;G{SqGc8fvHTxYy8p6CUwxnARgg zubBggW5X1GJde0BO!3h3h;Lnatn02k;-}gp;NqCC2l22ge;mB5uQBhBTydD(d zk#mx6!Xu7#CwQK{B*?}qpzE_LM*f2jT9k2phm3Xix-^FesTAJR>D#8uKwc*Ggf zVan@ppa+ljNY@pA#F=4<=fWe-P#;T`@|!MEch5mJaWi_U*p6hhg842pw}RBNZ)?M*aF2&&m#tQfGO5HqFy#2*6h+fO`Vqx$^>T@P|dU(c}~JYuZqO#ZkR6etGzdJr>3AM!`c zlyM{;v9};|Puhc6U645@JYuYjBh`Z#OS(Jfj$aO#)vh`rQ);gRE!{=#FuZ$AqagTVcmu(Qs#*+zO51xZ{<*_cPe(}e5B5J?zn77nl;W2Ni{la5@ zZu4<t-ni4X%t=~0~t>3AUt=}n68Ut>1~0t@jF$t@mhiB~Bh}M5^K>Mk=p$_%=b<4H!`AU!P z{m>hZoOtBnPyGAOe|*R72mi+(6jA4zz0OOoLj6bHeEssJ^3$_duFfsYzj1W@^_9`` z?EJZf^Kc zHtK5870+H@oSi>Ed;a^*&n(WAQ9Nxbo1Q!W#?i|4!j=N8fQnM95*{fGiUYofzcVTY!iauZ0jB4iIg$7lw9~vz$ zT)1#`c2OA>)c?f7)y207V~Eq@Z7zOoZhrCLf$7DbZJ3+Cx_G5q6VM~o1blRF0veRA z3Fn@exl+ETX9MPYwg8<}E!ZzDIKU!|znlp077-@)_YvXj0_y4<1uMaXG$1w#eaeB1nznDdwX1c|Etz_sN3`E2YX%pRqH#t(evu} z^|<=PE9$$N?lbe}W+@J-Fhnup$Qw*>aZ%&Q8zhh&d4t5bBX5xK2kgS4i}ZN5gL}Zh ztvBuABHsN9;F4MI2SYa2tMk+~^lnpS;82?k+;NKo_*Cb(L$!wwmD;$rzS8<$t$I}Z zR5Gm&mB5?B1KrKzZ##X)m8ehe*Yd3PJAG>M5zhcTK6T>ggO5%>^5CgcZ#y-8Z1T+H z^yxE`r_TJ)=+$#i%wC?Ewzs~~`+sQk^30P9S4Qtg^xZdld2U|g3UFg)@!S*OE2Gcu z8+~GS=KL(YerWWOnTvDhKwm$1>FnJ6emI_uBvQ6%SxOJj&7Vi%LHIt3L=o`v z?Bz2HjfG1K7oVBFJTr#^lXjt~a((}->WWIcw0W;mrZMx(rG**Pf^|H5d3w>FtnKM@ z3)kis;j0>Rd0LgLlyda`x5If_r7I|VjQS>+KHO|E^p(5JLT;iWR`)og1Csensu8o;1i*s6i zs5%dxWSy8$LV8)p&);|UP~Y*QdgC>XpP#u9AEE>OYf=}sElkujTZy+SIoNZJ=}R-u zEL_9zDxuv-n~_6d=RiMLo35Rne)xe?k3Mh$7rQ)dzcgUj@GVa>@~whM|K&rEuln|( zPEHK`{KDe2o;<2ded&R7G6xua_GJd_KGfVxjl(fr51fN5P5pBV^YdzTJw3PhOk5DP zwv;@kd;x0_lONxTrm^&9ucMV-F(aqv^>nu@#*^cEUi0Y_x_&P{NJ`hiz= z`n|90bR*8+xbbSdE>EXF{bh!Kf4}jMhrYu~HyZzoR~D`{{3v(Mf^ic8!!%H9xMLFj zU!DeuB@h;1`W2Lr?$us^l!#z`(JgX(7U>u$f0In!j?4o5dzXDY+vR)K1CJj2KXo*p ATL1t6 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K448.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K448.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9e16732f593ef7ae03b9d3b4d59f0c5e6155714f GIT binary patch literal 4208 zcmbtXL2lbH5L_xsU<3y0Lk~R!s1ANWeo!C$fIcAyKOjG-3iu&DcyP5Q!4S9nS3RN*34Nt(?fS;C~~6;rKVWyGK9j#!EXk7bm|iBF*K3hjIRn zgFa^u@YG_xA2+;V=Nn$Xj`Q*XH$ICz@IKBh=fw4&aGmUF#7Z9q#BY%w2tla#_LQJp z4?n&V$w`XaQHv?AgAPA0U!?ga?`yF&Ef_sV2Ci!5z%;{+e9vKZHDBOPp<)cZPrfnqV_T0g6X#~cg=T`Jp!E=C|NE^f}Ev>LBlPtKhjemCYaKcy1L|`N7-d zN{|DapL*_zTEKICTvF}1gK0q-lNcHeo>RW4vAoYkzNesMHD7pc$~VSPT=LC5*DvII ztmK>57(6%f?VvNoLVj!Ct?-=krBaNMcy83A>^WO|<+*k6+}E(F>KwF#TdUYS#2Czh z%};X=&xPEdxfYdJ`))m$7Tj?XL!-fS%D3RT$afQztLD4S`NkNE3(qOvg69_TJy!C~ zJ$Itc9kxf~%<$Zc;fAF)pmKP({?&7Mx9S{vZ{FwbgXfsQ8M$u!Bn@iWi7kMvg z*o)2-a$YaevgFbvhHetQ$jbJr7cIiw4rAPZ;j$O?*v&?F1ht&g@4V#N#d&OZGLKKU S>+9tC+iYI1lX?8a#ri)wBOr(X literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K448.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K448.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..0b4a43b539506febc31cde36c3ee7b0184773ad8 GIT binary patch literal 146254 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 S;6FR}@l>1dS@%73`2PbW96px- literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K512.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0c0ba6388edada1017a00d22c2dc25a6aa86a3c7 GIT binary patch literal 4208 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 NQC#O)9RK1X{tv>49JT-e literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5184.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5184.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..250fc9f6a388406ecb3babed9760f53d5c1aeb00 GIT binary patch literal 126798 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 H=-B@T7=@?( literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K576.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K576.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..44b553df40557f1209d3e6bf65466e94fe6f4599 GIT binary patch literal 4208 zcmbtX%Wd314CTnOu`m{h4>{yuz&dOJ?jSn2kUhA7bPxsD0#bqxTYyV2f*gEYxRP|R zd7}8{r?D}z0%Ro(H6-8TBQ+M+UTvJn55fN%5!_DyPVVY{yz8b%`)$rnUe6-U`HYuw z{e>TW&tBlA#s2ZW;euT+`2056L~gl`YfGEB;TxW#oTga2=w*bsbMgl+80w>( zl8yPp*EdFT636YxMH<(Ehrj3V()^TjKT3j+kAJp82x+-XHYqpEI=33SFSo_~TsU@0g{jTvQ z_|Rq4!0c)52XcY9y}qeG)tWnGHHdtuqg%t?PqsQ_&7x3;qbJcivC*rZBgAZLG-duCTO1y_k zym^m7a}(YUJd-SZziPj&(45wfnxhZT9P3-wob8=yZtFGo?31dlL3?srV}H5?AFP4d z)7nFGzVj6ks_{Z|Dc;~i<3e+4FKBKRUTCfgZ?3r~ z^4uXk3TJ`lj+y4@gUsREs(F>pbNIHZ4YM~t&s}@Xv49Ka4K#N>lI^$pn{ibHHBkHb zMs}`R6&JOyiksISeLuzR(D$FH!Gp!+R{CHK@U5Bfmiu09ICCX6K>v9z`oQ0k{!6%s zd}s~Oe`?SBZ&(@kU|cZe_u>}%z}G-LarLwJnALzj=n8%CZVk`}YRmfoy704TAfN?( z0A1LuQOe_Q3TvSD!g+gD+{eneh1ySX$37r&3uX~&Z+Hx^`S7l6_LgQ5&Rn_|x=8v! zPOjlBdig{RTI?UQ;nv89CW%>OZ9AJqtK#k|<8l@a$mT{f0$a}MIWKy4!H#qjJC1Ji R=ji>*%&yOo9e?6t|9>Q(9994T literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K576.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K576.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..1ad0ff55f09820bea0aa8824d4548ade2357713d GIT binary patch literal 157518 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 MG>EhAy!YV$0+n-=egFUf literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5760.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5760.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..3fec8bb87bd9adaa08953130450522951c1c9054 GIT binary patch literal 4208 zcmbtXL2lbH5L_xsU?c|GLs9e)pei7s*Zv?r_#r;{&|`m474SoR@I#EEhaQEzpg(a( zOAbk`<$!_$L=v^)EN5qylEu{zD<|?p@c&)}m;SGJ58sBX#t*}>x;XiJ5veX0JdE=% z9Q3*H08cgM57!lMg!3K8uRbpCaO1PcGw<7DTrTKwhnt15=YX@$EixS}|Yb$&4XzNbRI_lEC=d>bq;wM((*wt+7_M+|ySsPBa5u+ORX=mWdYt)k~PPg*w|iZ!Tv zx8fu{Ck!1zgAgBkZpT`{b6o-`_S`AIyYDzjWfe@r;s;J4Hxtr-mN!1hj**Su=m=1?lF3f0?yFB?%m^1>^L=E z40lDKfyRd?%y-qIywJWVuhkxX@AEe3`&h{G@0)GN%c;bm26)$azSDiLG28d(zgUY+ zs^6Uc8`UDiPz}(38n^w|EzElewcwI(<(=q*sDZ@7m1}S^8W4j}=!2UYpbs==`vAU( zdr?P1Gx`9&(7lyYGYo2=@rm#4MS1syc_*~@d51n=;b!bb&_3`{dJ!W+@m(|B2RawN zuzOL(z39wB&d{Llowg;XW*E9i>_wq%ulAxvdE3Ig+>1J_#=qTBE$6@Uvaw5XEO!*g Vr`z>7dmg`yMsXcyas0$Z{67hAB)R|q literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5760.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K5760.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..40b05d9b30b0720e8a75fa9cd92417740b0075fc GIT binary patch literal 126798 zcmeHw4RBo7dEEoJ0$0$MT-vm=ktk&W(kiVm_JW`&Ql;$$0XdXJ$;%(5YU~acBtQxZ z39Kkkp`4MuPLzyec^V|Cr?4iTB6XBxJaGq3#*WQ2?z(b*>`79jN!*M(^}rc7bu#H> z;W!@ElZHL__dD0s>*>-R6MeQOWDYhR6D*Y#u2&^XJ3 zoT}o)JI>>4}FtW5K7@rxoD6?=E#rD%!YNR^FXZ>`xxpR*u>SqR-=;VzhGmAM9Lt z{8bLI9A?p%4xFYR1;-6wXg-2KU&D_4Jg=gNmZw{zu_zp?YFV)Ijf zJkb23FQ7_w#^(m2$`9`a`qUrc+`ZpW+8gk&1(bYJHPo=QyMj|{>VR8dX$tLI7%;#`s?ggK~;0-9Cvu1<#5&VV5G13 z<<@Ife&MO&yAItn`?*ttjoMmNA1Ic7F>>d;-qmAk+dfz<-54mY-1@24lx~fRE4y~@ zuqD4(_2;4_h~Y%0;%96$*A>hSEq>Q7GA zO9zh^pB<^!vXyrieweOnvi?{sn=iTV7`q9hjSyFo9Sykr~&vmJJCYl{6 z|I}oubX?b5H#L{G|7LOJmp)(ocKKUF&0V>nuiYq}`Z-<4FXI2|nEKm)-@ftQ()MTJ z*DS6?@P9i#U;iJ9E3b=G8{G|8dzZfR54M*!e|LN7_rI{cbo7_Dmp<_u+e<(Bx$UJV zetmoC)MvJr#y*L4@rmuFXuqEQk&X-P8&Raz&(6Xlh*j#p>&4bj6j0;9!1Zfu|MC5I zM$t!yu0LA%$objyb}3qSkRwfgVgRT+5h z{eM+>!>6v*|LjfQ`G)d$e5>%ISg+UWzk=($b3n&0jQiS8?Oplgo`ID=!p~ph=XLnG z8$XZa2LAAUzyHhsVszzocYwjqBXO8GlJ``OWBUqAM@g^|)XZ$DZ(^q#ksmYz9^tKujv-SM_>PJHPD zpWS=?t+}5cJoKI)eBqMb6tW14muyyB*J9994@26o;JdCpkXAt_n ze(XIjy!hbZ`*&4-Z6Jyc-~4Csx*j}KJ&M{;(!IV1zVPgUudROg^LI`>xB4BZ0LMEA zT%E?Ybw0T7ok!6tRsPuDyyu0FzFf@@-Z|^eA64;FwOH3*jvBhf|EyWhR|XE>JQ6iN z{^A2aKKtG0@+Ysp@X>`IAKHJuj->O_Yo6@v|2ec*^~7%eJIZr2gTpif6It2mlckg92H-K`l~9(bM;?0 zYZxQB@{!-#IoN3b^0u|@FRfhso9zb%bJcD7dbobo`Mdk2x=870%SI<{efYOJ6ft>^ z%X5^M%6nX%<7}7bINRkp&W_5HiM(kdkvGNd=qqtMPxh_>jDe+u~%X2;6k z+k7wNPa%H_`P0i~IU#=v`P0Z2%AZU=qtX_WKgDgA@3?Z8?>IXuk0!6hWshyPndQge+v0icz+k(--Y*g;r*R^L;wHs z{hi5YTs~B?`HZt&zT<3{?>HO#o(coXz+v}271Uce{bSw-#%#O~jM;b}=X z9arx19cN?zQzCzw@cEE^9~iUoJ}_qEeW17d=TFB&{uG`+VcLb~PvQAfc>WZgKZWN{ z;rY{6c>ZMa7ncu}Y(C>`m+v^+c9CA1c{=#@R04akk5MoQ?fYiTr8A=R+ociraV} z7%Rv7KyUZYpGHIe6!IrbyO2MH{3+y5A%6<_Q^=pTLjGj(7ncuV|C7#VobB=*XS;mI z+1URyoY?;~oY?;qv++JKX5)RJxBKT$r-#G-r||cmLjIKguWW_izf(~v{Qh0|{k!n{ zcj5Q%{;q!i&g3sD&e;7=I-ha2%XggZ@*QVm|5GA=n(+CM-TxG`@jftS<9(pF`{z%` zL;e(=KVjO1=TG7JQ+WOqoPvQB~R(Sqo@)ws6VgHlPXPoWw9cR0I$JyBbl*pgP zd_H9NKgDdk4~*G(AL#A=`P0FWKZX1W(=OysA%6<_Q^=n}{uJ`3t&l&N{Ke%%*#D&S z8E3nE$Js95aW?ipCGw{cpAXsnPca+s17kMc2YS1I{xll$r;tBk+J*cnHO#pAz}gn9qmo{->CY_kl4R?*qNvKYuzH@~4nLVcLcKDdbNfe+v0i z$e%*~v=#CvlfSrp2>YLOKI3ec?>O7#JI==br$qiV;`1T9|0!nUePGPS`#^8^&!0v^ z{uJ^jOuLXjh5RYxPa%H_`BTWBwnF}7@)ws6VgHlPXPoWw9cR0I$JyBbG?du?G?du? z6tnR@FlOU@ptt+yPp5~%{-?12DdbOK|5Moi6!t%b{ZC>4(-ztPr1KY-4`KgP%y#*X zD|h*hv$6jvkv~oNe8}#9irIJ{7_;#{(A)jT9?Ea^i zjrV~u8}9?X-9LXC4f#{ZpD^u0{uJ`3kUxd|DdbNff7%N9lgVFPK7{>GI-ha2%XggZ z@*QVm{}Z+)nM37E#jl*oCH6nXY`hPQ*?1r5?f&`G>0H?V6!t%b{3+~z3j3eJ{-?12 zDeQmRBKx0o{^If>?0<^cF5hwGF5huB_CF=^rwN}A+5Jy38}9>SHr@w%yMO+4JmgQ| z`4gsHc>WZgKZWN{;rUZ|{uG`+ZH4DgCVz4H5cWUme8$->-*L9fcbtv=Pl^0#%;!UP z|5MDy`@oou_krH-pFbT8`BTWBFzrJA6!NE#KZX1$VQtGtPGTjWZgKZWN{;rUZ|{SHr@w%yMO+4Fyv1mf5Nm2`BTWBLjDx;r;tB|{AnxX zPbPnH`4IL$>3qi7F5hvs%XgfO{ZEPfX~gG4cK=h%#{0mSjrW1x?w>!6hWshyPndQg ze+v0i$e%*~6!NE#KW&Bl$>c9CAHx18ozFPi%?eZOGWB*eke;V`oklp_jv++JKX5)RJxBKT$2Sff8@+VBYkUxd| zDdbNfe+v0i$e*@C{$%nOmk(k8lg?+H?eZOGyL`vl*#DHspGJH>WcNSCY`hPQ*?1r5 z?f&`GXvm*J{)A~4@~4nLh5RYxPa%H_`O{X&pG^MZ@*(Vh()oq+Tn1KaG7w0aFuY4aGh|2aFg&d;Z?$Ggjx3JGn}nAMuM%D(+#x4H5w=K5oFP~U{ z+IDL$YM;tGTqIm3Tp?T~Tq9g3+#uW}yi9nN@EYM3;dR0rgxeO|^_S@1WTJl))IY)H zw%`ikD&ZR8I^hQ4CgEkmtAy7Gw+OEj-XPqz*si}s|Hc#j8>9XSF1H0&2v-T$2-gWW z2sa5Y6J8~}Mz}?Io$vDtb4bl4ZxZFPFafNV|aE)-CaD#A@@G{|5!fS+E zgx3jg5N=y+*I%N4lZpOK_ndqOfU7w=%1ocmFnfMCfD&ZR8I^hQ4CgEkm ztAy7Gw+OEj-XPqz*z|8a(LZBL|Hi0)g3E2e6~a}*HNthm4Z=;r%Y;`6uMut$UMIXk zxNWiN-`+(3j4k~eq5cUjw*^-SR|(e$*9kWWHwiBjUM0LnxJ7uK@CMb#+Lq#QU3&&+kz{EtAuNW z>x3JGn}nAMuM%D(+#fQ*p~jCQqZkGkIQZ0D}<|rYlQ2B8-$yLmkF;DUL)KhyiRz7 zaNA zj4k~eqy7mlw*^-SR|(e$*9kWWHwiBjUM0LnxJ7uK@CMORSKf_*r|ZfyL-2H6`7Q;Xt}FK#^w&QpKz}{1;$4tjSKe8Hr|XVTJ4fic z@*M~MbX|%4=&!#P`s*>qML);4R3C^6ankK+F4_5B_?6Sl+J%T-W>Hx*lU( z=(-bh-3hwx1YLK6t~JqQ4f#1ufIm`GBEDc&JnL0`sM3EzqlT1zvSqs zhuSHz3+?gsqdmUq8xe%^xj{RQva3EsC8yk8gK{X1T?$G0Et z@$;cfv8zJ3OmUz>IV5;$&jhtc;tc$$Jrb9|b9;O}XphuGu?6j+dL%wnDCa9vJOMBD zQ2YVU^^iUiuQ2YuJs5Xi55~)%i}CWfOmU+^IU0Ch4|rb>cp9$}u7}zqaSZM8^A_## z>jLBD=Mwbs7~}5eA;w)zF+In?`*8;^<4*AkJlEr|3*KKB?eX&&?Gb;9QD_g+`9S(eTmmokP#gnK?U8s0 zp4;R5i}v{XF@Jm;Fn>J8eDMC5C*B{t?-zJ#kHjnR)SeLKA=@T@#P`y`HGw`=fr( zqkhk$e$QiE{M^8}cnsbA`hsr6%l#VTLcFX;j0^FS=U`ljm-vSIeSE{X__&AqiI@8Y z>L*_AYp7p%x-S>$zFa0Ax_N)-=C2FgJP+MG58XT;Q9gtE{XH7>`#cBrdmiF zCtmUp)Gs{U7oeM;575oeH|XYh=;nFo=6UGmdFbZ(i1HTH@B4-Ny>6)A^QhnRsNeIb z-}9*7^B5N&doeB^V_YPDQhbJP#LImIafbK_sz>h2(2aQc-hpwEc|zZVFfPQ)_cDwN z@$x+p^$Sn=40QA31>O9(LpRSuH_t;i&qFuQLpROuLOgWGO(w)d(fUXf<<_;Xu1tMy zye+q*n}5~#OGWmiKY4HNj&A-<$~}vjsHz?Z{6P^b-&1APq8}mvk;3_V^mqe{r(i*8>_v=>TqSdVJi{Uc||JQHK07A zNc6_s%cQsV&!D&V*Vp9#_10Van?}+Jz4g}q8T8ivee^~-4x_ihPSb+>eSfWYylgkh zL~kkU)O#YM-r7Hd-rAp(GqAVb+J7KV3j>G6}@BnNxzfCMuW$JG? zsKb@*hAnzaS*PBoGU~1UGw7}Tb=&xVz4g}qsvEJRx8B-6gWlS|kKQQ9Ve~fGXNAX+N zq0Z~n8{f$@>8<@U=&k)#7h*?my|sS^y|sS^y|sTIy-|+C=xwm*ZJuQqz2jww-=w#c zb?QBlQE%;^L2vCJ(^?t5_169w^w$0v^w$1;^hP-jqqo7Lw|Pcn^p2Myev{r()~WZY zjCyPT40>yS)rHv6TW{^3L2vD!L2vEfM{ktlFnSv-dYfl&M(=nT;y39nWu1EC*<7Z0 zqWv@It^H$KE2FpG+CPKd+CPKd+P{z9D92&+HdypF&oqtR@iN5kAvI8{49`z=9qPPJ zz46R5liu1tgWlR-bs={2)?52$&|CXw&|CZW(HrGBjNS%|-sV}c(K}v-_)U6CS*P9; z8THow8T8ivF|C!+TW{^3L2vD!L2vEfM{ktlFnSv-dYfnPM(=nT;y39nWu1DT%BZ*Y z&!D&VS6zr5z4g}q8T8iv8T8ivee^~-4x_ihqPKasVf2odA%2tIQr4+A-l=7ZC)z)Q z-r7H=wK96^t^G6Tt^G6Tt^NDxjdC1DZ-Yf|^Dffp9WO)t&Qtu>b*S??^~Sr(OnPho z40>yS)rHv6TW{^3L2vD!L2vEfM{ktlFnSv-dYgB=M(=nT;y39nWu1CYWYk;xXV6>w z$Fx>PZ@smD2EDa^2EDa^AH7kI!{}|W=xyGe8@=OYh~K2Qly&NTDx==oKZD-dUv(jN z^wwMZXV6>wXV6>w_t6{WIE>x~i{55Wg3&u(hWJf-OIfGh*t3u+o@oCJdTalf*2?Iu zxAxDVxAxDVxAyO&H_CAsy$u$<&0Y_qcf1Vodzj+4u0x&IsWwt1iTj z-g;~Q40>z-40>z-K6;}Zhtb<$(cA2yF?z?#5Wh)pDeKgGBBS2gKZD-dKc=-Zdh4zI zGw7}TGw7}T`{<2w97b=0MQ^h=$><#~L;NParL0r$QyKNv{u%Vv{;CVHqqpALKZD-d zKZD-dzmMK1$6@p~SoAh~zKq`SGQ@AvTgp21#@@$F@kIM)&|CY*v{puMy|sS^y|sS^ zy|sTIy-|+C=xwm*ZT4syz2jww-vx@_x(;<-r{386nn`c%pFwZ!ueuOBdh4zIGw7}T zGw7}T`{<2w97b=0MQ^ib*ytTEL;NParL0r$iHv${{|tI-|CrXw=&iT*&!D&V&!D&V z@1r-$aTvV~7QM~y${4-lWr*LTx0H42eJZ2g+CPKd+Fx}ccJ$U;`)ANw`)ANw`}ffs zeT9uiI{)W)t~$RM9s!Leq%D`Uv>58uXn9~>c)LB z|CX!2@b0elzx~Gd#{8SE{^-l7zZks@8f_(?{;SSE_vc;xCvO~&`L~>Z{@Y#s z@4GP-^WSj(1@-GNo$dMF8*h*KM>(s1@z$>X$@Z6>|L(iG`X}38b^fJ$yZR^FUw8g{ zzSycR$eS3?@0>%C7$62fEguoX>Sv|GvAr z)}LH2W$&-nTle*-_G%v*!nop4YrkT#YLNaN2G|%36EhNJ1=uB9mQR%JhV65ZMA;tL z>Wb=mr9|02*y<&nDk~?-j=@&HRjJC3P??KE?$gDWD7qE&-J|!~Qy;wXKy3X~y?^)k^1zJ;WByIo{^bfXcRGVf&hM71zo6nv=aGze(SX$_dLGW5@ueePIRD(oy83s-3+JD| z-qpV&UO4~47rXi=<3-c?7r)%qKiU3O=fC^UyZR^F-*Wz?Z+G=iwtvI<@A*Ji|780& z+<5I#_m9paIbIuXK9nBsbOw{0538>J-75Ze9?AK(>gq2((CG{&IiKsU{(ar!Z*skq zy}yd5FTWn^u003t>e`;{5AgR{@>^el=bF>Eo}dKYjc){^{ed@lPLrt$*tH zYuod9=i~>|CH@-!^zqmDr;oqJKYjeQ{;A`y@lPLrt^do$U%yWP@mFJtzxsE~ZTyXu zA^zqm{>I7>fAbW7V`YfHvcDj4J;dKU#oyR@h`)J?zp*mJ-#o?NSQ+APUJ*9_`m!$Z z7tgQZm_Ghm|J3o<_@|G*)<1RpHU8=2uklYGe~o|o_-p*r$6wq2)bZE0KXv@I?Z1ve z?u_rr{INc8t8IVk_-p*r$6w>0KK>g2^zqmDr;oqZKXv@I?MWSfjeq+1Yy8v4U*n%X z{#yUk@z?mLkH6OcW#g}ZPlWiZF~wi~H*0MCjg=w(7AXG4$`F4G6n|r7h`;iFDRDi- z-vY(o*m;P*1&Y71GQ{5k#ot&N;%|ZCuP^Hof3g2s;&1Z#K$qvC)<1RpHU8=2uk}wI ze~o|o_-p*r$6w>0KK>g2^zqlWKXv@I?N1$lZTnNlU)%oF@z?mLkH5x0ef%~4>Eo~Q zPal7+f9m*a+mkx}8vpe1*Z8N8zs5g({I&k6L;%1JUoAhl_CDh??)uc5Pyd#{>IKj{2fw+suRz8V`YfH zLll2wWr)8+6n}kLm-vhQcbVd^^-mptjeq+1YyDHlU*n%X{u=-E@z?mLkH5x0ef+iU zPaS`4`%}kX+y2z?*S0@({5AgRzw`Th z$NMGMp7i?xO#SKi1K9Sb-Vb2>)9(i`{^|Dv82|M90gQk8{Q%bg@vieB`F;%VqilOV z)^)yhJfC&*E&YA~Q-AvX0LDN4egNyQmTdR+X!A$)%HPE=jVXTVzin#cSF8*%YS6_m z#Hd&qVwC(1n?xC6)S!!Pct;gG4>4+xVpOaQ@p90`HoPzMWiAf6PudTF{a~tR>S~=w zGG5^QlJU=Vk1rkZBC`JZ?(r)*KM-F`{e|xNU~>K;e%bb`_?04FIRBiQ-<|%+_c<-+ zuk*o9|K#(;4d-9@K-c<{?{lI7+y3J7UHy~suI&7Gf2^y2vi()(U%KAaKiPgf4>fx3 zd7!I*vi(^9*1!AuPmWjJ=~KE3^>-f0`A~NC?^gLs=aHOmWmkW3xYHSon$Px~v+VmD zLLYFr^^7&UgVt=U3~N^Z{c5$=i;45FW_R3*dQ=(KZ0x*4u+=hCWqAG%Y1*7Y1Az5srw<&P0x1pkjLe~9?~;Gu=CCr5m)y*I)} zO3m-y-0Rz1?ZKbz!RNuh*4A^9>Uk8rzb^4*@Vl)46!9hSUI*g$fPankKSBI%@UOT0 zqr~Uh+jm_&oU6S^u--|0sBAztmF$FYOWjEOsp(qHi}ftUUY zUk3kL+n$qDPp&qB@yEKOc_sWY@S>aW zSa;MO;jvChf8iemFZ~jJA9$H>!ejlCKEh+24&H3XW#8r*-{1YNBCL~ zeh+w=pW=`8PVE=I0$%hKzS`bK_o;0@p47n0I0~N!e_s@}^!;~J^9FxoTXgrpckNU> z?$PS@t>+}}(SpI#J=*g}zVS$vP4q@o>n;f4VN>;gHNv@kjh2 z|8alaY7ZVco_Y_d#{xN__eb0yeS}B+>B=LXkPhOH+>CS(9^aKnPvH>{X`Tp=ctZUZ z9&v-lebTod>yGLX9_xBfyOT;55%=@)ZJaWRkkEO&TC(QfULOgOp zweMHAA333KKVov8Vz1{9_23bUy80uQN_#f<`g#zPyYf@ueZR;bxuV+JtJ_&79k9$g9){giiCg&+<^X){;7u~2H#C91M;&Cs?Q_T1EASUN!jmvd$FOzvf z^&nQ0p5wlrBRzP;%&z{3$$42jQV(*ruKWq`lq>q{B9|lGq@F48(qG~CgZJ}%Q+V7v zXuO0+?nn9vk9!A=i}1)r^Ro7Z$324PkMOuh(0mgf_XxGuT+gf0=A`fMR1Y5aj;{W= zM^O8v9>nmjJigbf|qh|p{1 z0OHs%#UIZjZVXdA^gQBQS03xSE06f8_6WE*=IcQ`?8=`2FY9Zs_eZWcOmWQfhg#3POk%legi5ch^D-umkzz76~P6xD+`Mmmpsf2>n#kMPJj zNjKpU$GY-}GsCD<>$!hZ{1KPB@`yjwe(^_~Aw7jhT&4LSJmL@OCOqOQ=_Wkl4CyfG zbvV?6$9kmeia+Aau*7rW5of49!XsXh&cY)OP&zc+z{IRa7ox+#F%eoLAIV9Z&xB0k)9FpRd@MZ9F9}yloB*jDFcY_yw zgg*gZ;)(FcA@h_&s`j*O4wlmH7W~>I9yw&euLa_fLl%5Y zARakn!LNPdkwX@I3?v>oWWld-;*mqD-(Apa5ILl8KVocwVy5R21H1BwnO%9r*aA-0 z^;b6c`g#yErTxSo0q@&SJYu8z{RCYPa!6m#R1Y38R&*wR+zSd61ARS+nW7K*BWB7t z5|7whkhv%AL98yw91|WfR>qO)L5wBc#(jGZ_23cHy80u=l5SEDVw(DW5Um@Y1Ni#! zZnPk=NO;6p(oJ~8cIvP2h@~{X!sGb>=_WjK#ezJy5gzvx(qDMQcG69F#AMQ8()SCw zUsoQnm)ax#h}8wjnT1CVMmh*z0x$DZc*JVbLHOO^{W{$g9x<8pKjYhvoT@92m`wGE zKVmrbOL)XyYQONv@koE+vEFw`JNE+Gm;he-D?HZG4j;!hg~z(sLF>ZTgY~t8)`jP> zzIOOHN%deI?eKArc&wKl5X;7sabFLfgLUPxE~tL-$9E!Xzwns1)L-E-Z>jylV}9=N zadlI8%+DPXuO@vvF%PLd!sELDwO@G5H)^Nwm_O9cGgSW>8b{%gOH)0<g&P1Ri2@dKklvatdDryTjkj!@wm6jGehEWZ&kmSqUS2^t^T^uoSuPi z^E@;kl9((!G^A(9!Xuv%9X5sE2VT~i@OV~6&nktlftNKdJjQ5<#z?i(jnNQ|krx?Z+5V z&b-a@7$eHzg~z%WmbfQ8#*T7w;W2jfoke(zh3K#;JjP;}#zM8njm0pH1-fGTg0T=B z-6s1nh==B~e}H&sF8eWvhvu?>gLr5z`#^|?w({Pe_^I|b+843Sw-fV|_C*MP0=&e0 z;i1VOX`lLNQ;IElW?{e^h+UE(M4=)1&u;?YN6Cp7mM@sRF=+cdBD z7q@ZORM8Gkq^+Inuv;jvn(|zGAXkBjdyMnXC;anK3x!qhpJ#uZpSQ*C{6gaVLgM@a zpC7dch7$fm3I8GX$MuF1*BefpKb$y!IC1`P;(YwW@{!g{{arJySy|u9)E+Wx>w6^G z`rb~q&Q-|Pxe?hq*CSi!z+~(15@hS|wPfq><7DgS2xRN$F=XrKU}Wp(ePrwBuVm}z z;biM~Gi2*`O=RnLYGmtoie&3|zhvuo;$-W+0%Yqw8f5GJJY?(rNo4DNSY+${Y-H>G ze`M?ZiDc`2m}KjHrP{`j>tm|+i2fYF4O1PTGau2$mj<+-nj7j+pI^6J8=tTAI6U{? zfA)!=u1@`%8^8OnzVzJhy--A*>-IV?y$baod)u|km&#AgU3qeTap5haV{fXAmgg4E zFV4;{Tzt#u)ujvHb7b^wZyi3?xU%^8-1()q4wuWv8kc64E-YTTtPGg5b5G5mpECx` z^NUx!0rLmut}M)5Dlg1jo_ovaLnrS)Jw0*%eWT?|GYc25&Rhg{ezd&wbOT_vadp(y zqAQ-ewludeJ2(41volLGWfV`F%BJUM-!fXccC<1!TE1{~;rtSsK644wX!*&j=S*c| zqi>GYHFM>nZNp*%y_*{?&&W6z>{Z;Eby3zCM_w=~> z_$%tWn(i|T=jSL6sW3z_;@F!_aB)%N*qbGg9ecCHxMOdY@CWR|qKou+wu5`Xz|A-8 z;UeC>3gD7i?*~IR)~oZ>HS}&%W#CYo4BT;(1Nc z1H`)0@c9o*0nCO+7UrM0I(PpRX2Ztb&0KDvc0w{W@q6)HFxgnMVz6|#u9oGi6m0CX<14S&M(ZO@GyKIMxqFKdG7Mr z#m3^L#fwi*U!Ivqfl0eiRJnF=PIX14UD~|+2&~4;)0Y-!Pz%=a+~w&dd$P8t&o5qG zSc0!wq?e~vxk@QV?|mnnr&YRwvWM<_XnG3KL%Upka!xf!M}ldU2|RdQUusP0q&=2q zE`m{ENt@?po}8PuH#O~f$S8{bX1&Jw_$5?Cdznl8^JkvvC+oQCw$-&Ub7g5>s}EHd zz>}=w<4Q;`>)7l)=Z^FpFRC|Q)7b3Hh4>I1>R*$(ux(+YrnySIRms7gZ%kjBd3y0G zhF1ygM%s)V3Ofh-{@Qfy%=ClzoqqVflepOBY5S!C!-j8pnvri6MEWludVJNl4|Q^4 z;1?E`ruF1eW$H^0oRc}g=rb=fU}~lJQsZb$*F)#wN>l&*;=+PjT~Ey~JslTBtt};w zDPP1|#N@}fqG>F>xoc>pSIo%ic|G0jit*%_p4WW(xUS!ihWG4xy1J9buYTy2oqqQ# zJKc!$f82OAUYDoSpZ+q#f3V;9$3x#yr5la^#VdfMFV_HQX@?|1VF2 x#1aS#F#QTjNcU%NDl{x|A1sxtrp literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6336.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6336.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..208ddbd43faaf3c79109255749f5631074761b07 GIT binary patch literal 4208 zcmbtXJ8s)R5S^uILofuy2vVdl5*A98#y5xxA0Rh~3LPLf2m`20kt4X!L4+VhO2H?| z4V1UD`}QZw*bNC-{0!&KzL__}wV3{9VMM+P{_aF@>5ikhd9YW5yY;`_$;h9RNOwBn zWt_j`N8j@=@YKWKUUz)p&sV&Ec6ND%2k%Ah`5fn-HZkK{+$U>tv3`Un)~oxnlwW{g zsF&7c-@kagc_yxrH15D$=DlL@yVBxSA^irbXPy_h2o0RP#k# z`nYq%(0lSNjG`IA&t8>lus&8BS z2Q8DXsX=qSbqGhq&_}3&x97DVnG3{S2WP3)+^(oWf}v>lo^M~&09ucH|Gs177R}{+ zBZgv;Z>hPbnSA$^e6I_>Yw{hiyx1<)nuFGrFEvLDYED?+3C&^7dEc`+w+NcsESqc4 zAI*YJdX5-+iyC-)uDK0!0nLpOpjvZVp9`ij!B8}4PWht8$~hPL4j&k~MRPgdh@n{I zTWW5c$#+-Dx9l-!&hZ^E=a{U9IS0)tUuupRiRN5BrZwk%&os9Tn)~^>xdzZ&5UM&y z4A#Kg^V&mmq4ozxMJLvNTcJ7S!!#xsiU!T8eL{1Q@8^$<+@iUhZ^Te6Xin`Dnw!NJ znycblYVL`79HbEJ<~C@K1#GB2G{YrkgP0ev45S--z|^l|A*4AubO8pn6K@70DqS5|`! z*JSq@F@G)nm(?J_&>Eos)L!=AI5Y0f=YmVV6nCNzoaRsi35lz(!M>;gF$je|xL5=9 zf!fMGfG)x;8cC?351qu7<7&hAtAb$hYm;ESeQ}RT-DFXvAvnbVbOP far?aF-b6c=o7u5-JHJofzb@>0pV;xg6a4=Hr`0IJ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6336.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6336.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2f0b58a85d0dedb585ab410304a5d6704a24f31e GIT binary patch literal 126798 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K64.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1d146405fd749f79c3baaf64893cb30671d947bb GIT binary patch literal 4208 zcmbtXL2lbH5F{NXFaiU~p@$v>SMSck&N!VzprzzgK7P{+yj#ozHj}*I)S3 z=i&prG>8{_#T)T@$Msk6yC>ZE;oJ-FYeE%J5v!{U7n1_Qo;6kWNdzu8=8{fW& zo;u2iMJIa{SB}PbxCvO zN!6x!HK4iZFEzJgE#U2QNcB0lkF{VKO%BZl%_(20jqL$6m-+7WQGN|DuJVQEO1?XW zhb#GxHPW~?2iz8OPleskgKflRD08p}c-I8J^K-Ah z@w;ZnJ)s9(u3vQz_M=*u98z|N`BU8S{PhcQ50$txbC7!AQsL^)-ebgN5150gFbDta z0p>t`<2isX!dZkK^#9QV=t9pThMFAgf%;|7R*&fYB3$&o3U{XW0k;KT7Vd^QK<^VD zA;=sl72h@UbD*)!^ekHOEE-tI+s-1D1Vc>@*`l09Niwzv?a42~eMP+FzlJM*!R_&R j#>a_py&tcA4^QwTZQ;ixP1ojm{IV|mx;B3Niwpl>mKgqL literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K64.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..8f206f8984c19175e96918569676bde368c92277 GIT binary patch literal 139598 zcmeHwe{5XWb>^Glm>koy;>c#wi7dNAN)c2?O@^W@OIjr!N^~OIvNM$A!rNpaQWB-e zk;t)3xpE3Slg195IB4m%2F5{+<-%}*1a+5AVaHaRVhjgyYV-$Fq}#N`227DH++zP2 zrcGcN*>b;o@4NSW@68X-Ym6Y9+=nRq&bjB^cklP^{oa{3hxDbB=T4lR+Zn9;qbmcS ze)gez0vvaaq}7kW+S<_nmwt!fw-5b~t(iSv|LRvJr+@IxOZR=^p~-m91EHfIKhMve zKQ>>TKR18of#c_A&gzy`Gu+_rFs_K7)tL(mXBW=S <6)3B${{Cx3Bb3%BUank=c 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K640.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..7e5083706a97684836438dbfe48f50d750fbb4bc GIT binary patch literal 4208 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 IzZ3lb0bRl@$^ZZW literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6912.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K6912.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b92d525b1fed44c488a39c36e77235d2013b4221 GIT binary patch literal 131918 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 RKRfsFREO_b_dIy?{{i+wLRA0& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K704.insts.bin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K704.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..4f678d507e2ad6af9ac01ec0cd8c577a8606fe1b GIT binary patch literal 4208 zcmbtXJ8s)R5S^uILoftHMT!&#%tB>~+#o7^kErkge1kB64&uTG$Pt9Vg-gO0QXYr% z_NTS66b+cToV=Yxn$ro3asPvh zuCoQawb(yCH=MBh702(BUA|!AUgVDRxVN;4>%U*-^6+~4Da~*BJQrKb1I0=x#n8c_gMSCKBzgGYyGbAAzqrOC{gy zjPH(oJA@b7rCM{)y7Hywh~YEG`W7^YbI$gjopUR%xxEi+j^C4jm|t!s25TVXTkdw*d z@4tSb--G3XA%Enz&9kE8Y1nO(<` J9Y1lg|350s9v%Py literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K704.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K704.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..435228c4415512123c7cf3893c814814b6aea1d1 GIT binary patch literal 168782 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 OhbDHtkL>t~3;Tb}vmxXF literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K832.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K832.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..bc7238a4ab521d41d1d8fd49011dd28640bb47d2 GIT binary patch literal 134478 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 M#IEbijx!ea|FD`O$N&HU literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K896.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K896.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..ac5ee290680dd8042de0b7113f7dcc92f2e8428e GIT binary patch literal 122190 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 V)9vy(SwnO&a~JI+|x{{w(`C#V1b literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K960.xclbin b/cpp/external/ryzenai_artifacts/bfp16/npu2_8col/gemm_bf16_K960.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a19732d82a3665db23259463ad8993df7e014694 GIT binary patch literal 126798 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/grid.json b/cpp/external/ryzenai_artifacts/grid.json new file mode 100644 index 0000000000..4d1aa7a4c4 --- /dev/null +++ b/cpp/external/ryzenai_artifacts/grid.json @@ -0,0 +1,5991 @@ +{ + "grid_version": 1, + "generated_by": "python/ryzenai_kernels/build_grid.py", + "note": "An xclbin depends only on (dtype, arch, n_aie_cols, K, tile). M and N are carried by the instruction stream, which sequence.cpp generates at run time, so compiled_at is provenance only and imposes no constraint on dispatch.", + "artifacts": [ + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 25352, + "xclbin_sha256": "7c969f34b6fd4073543535cc5bd8b89d537e896d7b56f0e47fb3ed4cd746ab8c", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 24776, + "xclbin_sha256": "eb9f1c6462381a22b24d46d70b189c9f8e3857b008c32fd88030168e54940b07", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "45757df712f937fbf4ff8b399c0414954e55296560e017b47c4303c2fb3dfe4f", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 24328, + "xclbin_sha256": "c334af214fe8dde1d1b8e5f81e4e2054da3003b3ea0eb891188c1d034f3e3772", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 25096, + "xclbin_sha256": "03ca1327e93a36a740479529a016621d7a2081e313271e5ee9b1395ffee951ea", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 25864, + "xclbin_sha256": "62337215efbe1cb12c418e2d83f48bf16b234b8243a0626b384738210f960468", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 26632, + "xclbin_sha256": "fa0fe57d4d518804400d60b9055cdb7ef488b8f1fa3be1e724866f9ccc776d58", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "61aa1696207da39c5e50237479101e5c3fdf5ab93146b8f03dcd89aad742973b", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "c9f04c212c62bbb3a2c1717710620657e438fa1cef3c4eba8bcaf3e0a85b1d34", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 29896, + "xclbin_sha256": "c1c243f3f9a1bd06650684dbf4411d18e0274abd49fc87ff4aed6d099abf7391", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 36616, + "xclbin_sha256": "f55254eb8ffad2c3bd0857e4fae26f9fe95d08366d2099912feef96f9421ab69", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "ab4a63fbd020f03533ba5980be353e11f74f35d0f2f2275d65f61a547edfa303", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 35976, + "xclbin_sha256": "9d4f24d14bcf822aab91ce85752f24721d147003c18bdeece8688e7d7f56c39e", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 29896, + "xclbin_sha256": "a850384e185434d62b46cd34e7cd8124bb9bd053d7b9328300654754b5d7a97b", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "d3e8cce386bec42daf6e8abbb3f356f67eaffe7a85baf82061192c7e6a303d6a", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "52829de6e37be5d857e206eba73bb3704b5ea090e0337758f60d156efdbb2b07", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 35976, + "xclbin_sha256": "9246e6e3f094f358b3505311e0ec98a58e2b7c00d38b38b9d6558c4638097ff0", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "1d2a4f95fdedea7917d77671a667659edabc8b32044c115b3c576adb1ab088a5", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 36616, + "xclbin_sha256": "9987e61e67c86a3e23989403bfd538696b1c49254b06e3c689031f4bb24b622e", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "cb6ae6307f951dd387fe394f870bb0e405deb58d3f5403e34397ed28d993e34f", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "c8e1afc2af7d95f9a53a8774a36f7279d304e84d2d8150347e140a439ccd5e91", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 29896, + "xclbin_sha256": "e8a8c800a23d779467f1bef7b6d471cf00134dddceeab481f758112b03b085a9", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 36616, + "xclbin_sha256": "4d7f15310e4cd70181a5ba2287b12a8d2a1e76b8871b79150dd985177876b62a", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "11f489c75e18bc82f833ba5a64988d0bb5b28f8243f32639965beea2c78a2ef2", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "f5fd1871a7ed7363211c3f40f27652254fa983eca71fcf2f02090b294035d335", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "6c42a4b2886e851b45dc635e4fa7cd84fd6f652787bbfe7cdf0660937b7a7934", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "e918681710cd34c5888b59eeb32bf7169a6404f976839b03d18df8d2c1647545", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "fa4ca0b4da846d0eb8bf16bb0f9524a58022a3d9e4629364562e227d648c5038", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "fe09ef7ab254dc87ea40500774e59ffc905713f3a1210eecefdbfcc2e7a501f0", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "778907658262107fd8f258f2a014f9f4daeda74f450a1ef4a53628b72d35955b", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "b705d650b22dbf086e63528f4b8bae3d8824b9f445de53ce6d564a06dff739ba", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "519041fbda3ae57e2ed71fc37e174f4c92a80f4c158807d29283474cd233396c", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 32776, + "xclbin_sha256": "7917f4746e698fcbad5eff28906767fee21cfd3285c42298484f981106de784c", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 1, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_1col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 36104, + "xclbin_sha256": "0d40fdc41f333b2a066248dc6e307fab5c82a0f2c5b522d0607aa7a9d6bfee40", + "insts_golden": "bf16/npu1_1col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 42888, + "xclbin_sha256": "5b332c3214a4036238c5a07e31870f46fb40afd2370c7c53e2919506c2318d27", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 41736, + "xclbin_sha256": "3eb70884e0f2b1ea6a2ca898827c5023610482c354544a9e91d95ceef0d47ed4", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 39304, + "xclbin_sha256": "51ce027cbb472b4539e6a2edf606b4a16c22e4e819938dbe19a29dd72c90f49d", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 40840, + "xclbin_sha256": "74f99246ff3a45dfb30f12082b13bdda532206242f32756a5de588883112d385", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 42376, + "xclbin_sha256": "cb14e2a10bb90475da949a3249f115b2eac73ad6c67b4e9c3da108bbd2e5b205", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 43912, + "xclbin_sha256": "a03e9672692fd1b95fd369c8375e8cab037aa8d6e6a7b6ead8eb2385399f42f6", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 45448, + "xclbin_sha256": "b034f1973b3804cbbe7f7e1ecaeb2ead8ea20628387df3b3c44d337777f2e16c", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "ad44da70bf4970a7d2b48233d982af65187d777d851027cca5d6ed0fa079a5d4", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "cfb8b606d1f38ae4ddc43f04e5c92b25a6e635a9a0f5745677f53bd66618fe14", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 51976, + "xclbin_sha256": "498303d10d0a46c43600ee821c5c7bf1f68e29e8e47425d6ab7115c1a55567a0", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 65416, + "xclbin_sha256": "833ee4e1afae81e04c5387d2f14da21166154e6fb17d1f6fa3978e6f7b834198", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "0fa6eae1c482f0450abdb22fd2a35ce00b734205c48d7f7a7f4ed9684d4478e2", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 64136, + "xclbin_sha256": "990d28e7242ecaf4ed02abe7040e0498eda3d8532cfccff7f8ac6a90beb306ca", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 51976, + "xclbin_sha256": "20d02ae5dd9440a05e99c6285ad9906f74fb4dd6874e0b847bcb458e3a0ea075", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "69ccc59afcf8a1ea244260457cff38e956b9aded292da8d19ae8f0a300f9c710", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "389465d465c1a15dfea1641e376601782452fa4a6dc85c8b5d7d0b8f9e3ca8e3", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 64136, + "xclbin_sha256": "7d07ae03fedbe305e610c567ab2b9977eb133bc81566957e79fff5c912898bd2", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "5e25b3acd78b45a925545ba3215aded0f413a1447d477cc4c8d22a08153675a7", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 65416, + "xclbin_sha256": "f13a4bc86520edb1de85a2cf53a2ee301745031139336e71b8a27c312a222f2b", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "3b872db2707e866ad747a2dd01feaf01db6ee4f1c4cfc5b917e22d62bf20bfe7", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "55c56d76ce1e27eeefe33c773ba2776c4637e2f310971a027ffeaea3f66651e3", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 51976, + "xclbin_sha256": "1ad0a7ffdeaa6767cd89f6a17f5f93acfbd6228a53d85e490db760b6fe618615", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 65416, + "xclbin_sha256": "6c27471444672a9702cacbbd91e9043f72c0edac968130f30dc5b57ff47d13b8", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "1d4b9501e380e3e97fe9d51b385c8aece716ace1f3530007679a28a147a5bf06", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "4a0dbb55d0461214ef8ae4f63e2740977c2ecae33cca5a0a17936bc4c3ee01f1", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "d83a9b52d7d3ece51e736fdb7e14334f442304a34990ead4c3a37ec34f24f70f", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "df5a47675abad7e4fab4d323b1906852b7a6ff5be329e4e4aa6eeef794ed3eac", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "decc1dddae857180a2901207249194e4b5a32edc8a18f4229f9691880995709f", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "e7d0a21426805ee7ada99a523c1243d84ca3ce74f56efe69d43a88e8987f97bc", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "725ceb63599929dfa84c4cdff249da1dea9f0bb233d2cbb47d70a6d786f5899a", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "557d93053a0d4c07aa3bd67da28efb440d37f0750d384152e501b466557598bf", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "54d9fb3e866b00457a97c4fc0db3f8d3bc2da0348d6d928165ab7e60f7be1bb3", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 57736, + "xclbin_sha256": "cee452c7a7595d9594053bd7e545eccb5bc5ba370cf49abca8b2ba0934cacd0e", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 2, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_2col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 64392, + "xclbin_sha256": "ed1c9c92a5ee107710077a51cf02ae0447b693dd6a065706bba2c32a11874344", + "insts_golden": "bf16/npu1_2col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 78366, + "xclbin_sha256": "003a016e289889bacbef273f76cbadb389c50e66be2bc7fd090e48d6f215314e", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 76062, + "xclbin_sha256": "ff0decef376d05b68e80a362bedec423afbf078a16a2de35a858e526fc431213", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 71197, + "xclbin_sha256": "ec78ae484cdf1ef4d0caa11184c7fe1e90ee80ba4386d847854f8742e0f99b21", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 74270, + "xclbin_sha256": "2bd5e1d582128447a6bf6ffbee067ee985b28e8208fd469d05c0c88f9c810fc5", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 77342, + "xclbin_sha256": "e211855cc4b732c59ed2fea1ef23adf33d603340f3ac7c8b213c111f35242faa", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 80414, + "xclbin_sha256": "20d55b6f562badbdc9f91d2a21e010a79e495490eb772d07d2c20d81d363cfa5", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 83486, + "xclbin_sha256": "37c688366e679927165d4e398a05de63988a1344cf9a7aec8409ef21b1284620", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "9347fd33202aef08625767f94f78f9c4cf2bd981a8bd098099438beed1fa3979", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "5d89770e92970216544d06859d450732a064a08eaacb09b04df8efd6ae55b498", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 96542, + "xclbin_sha256": "4ee82d5d59a05cb1ebf76c31f995839f60e1e5f5516a6eb949547abcc6f86000", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 123422, + "xclbin_sha256": "e6434bc2c4d65948f4f5ccc89ed7154b54321a3f917665f8c157a2dd4e6f4b35", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "59505b9e1d682fa4176da7dad877d413425857f71b843c8dbbaae65342ca1ec7", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 120862, + "xclbin_sha256": "1b5647c8a1666e15aa5f98d89e9e994c663223c20e9b8ed74e6938e784377fe0", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 96542, + "xclbin_sha256": "81e73eddafb95c1794e0b8db6d1fb2046fdf5b5cb21f25b107f53a17cadebb30", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "ad56f3b47b38c3af84744a4925d5ac5da4ee279b43fcce5b33aaacd05c7e3d5d", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "3461b5892d225c0b1bf1c62cf36f878348f1be9f4a450d7129dfecf1e32e2ef1", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 120862, + "xclbin_sha256": "5b0ffbbac9a44533545fe0441a4616375fa7cd58261ec4be241a8a3353ddf5c1", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "47e696f4ce10571e4036b0118c6df735c381a3a6e945f7cc07db91cae5ab9ca5", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 123422, + "xclbin_sha256": "ab1467728cf873b3e7697a1590b2a89e4757cdf334a52fbaeb0918261718f0bd", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "5c4cd599cda361acd0db732a838036ac99c41c98ab809317200979297c3b2258", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "1944f3beac4fb17623533d158c582f10bdd60005b7a5d9ee7f5bc9721ab61d4d", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 96542, + "xclbin_sha256": "eca7e3cb6087e95fafd040d489e9cab00580d704d1b04ecb49eade4356c620d4", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 123422, + "xclbin_sha256": "c71fc305e5df7652805b06171483625502b8924fc2a10afc1a6760c418741d9e", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "a107a9f1fc06866f5c50ad12a292141093aed1c6460c7b2ffb4f2a1598361718", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "52ed1f4d6551aec1d18b1c560bc82ea418df2df984b31d854fd2e1b79e4b6856", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "9879673fb966d76ec4815db94c1bc8183fd998404f0798e10cce84cc3ac2351d", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "9a9ab6db21097d6ad19a661480f190e441dbd7ee945e2e0a3f43a99d476a7346", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "18bbdb45d60b3a75b18fbebaeace4fbf9e7cad45187820d5548e4b4f08e637f2", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "4bfe5846d244a03d66bbde0ecd3daf6fa0824d201c3db7bc7d23134517450023", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "4c97987205d07d9b0882e01141891695e69092ab2a4008327f77b8d19705844d", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "cdb4a58ed81caf48347843c3dd7e9c89098d32ccfa1ff59608384fc877647b67", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "5596fa82555d16ff21502180039083c44dd84062fc69fa85029bac625b0995c6", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 108062, + "xclbin_sha256": "caacaa38cc225cd586f91185adf0572610e4cba017ab379a4b6e229b01f065a6", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu1", + "n_aie_cols": 4, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu1_4col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 121374, + "xclbin_sha256": "bc8588c72108ca6c10aa49823d77563955b03bfe54a977c9517cdfb58aaf294e", + "insts_golden": "bf16/npu1_4col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 24520, + "xclbin_sha256": "e4bf1e46f419374054cb46b97903b10b914187500c1f30a6ebe3ad65ec2c44ba", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 27592, + "xclbin_sha256": "9b3ae189f7412f5d57731bbcdbab62176f90136b67dc4559d60c4bcac8f52b28", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 22536, + "xclbin_sha256": "508c6a00a33091e9baa63e022fdc370011dd00c0fe37b376c3da9ba0776575ca", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 23240, + "xclbin_sha256": "b0a61e2b07814fc394645de64a71fdfd0f8e3d2b0ddc58a8aba3d0ef06e6b274", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 23944, + "xclbin_sha256": "8a1ff9f99fb9fa7c9a23016f15fb76086472b153dc3d46a5eeeda3cfd2acdeaa", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 24648, + "xclbin_sha256": "51bd46329159262a63263dfc9d1a0cdba0d168caf7471b725e9092c237734993", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 25352, + "xclbin_sha256": "fb7d11766f238d07090f7c3f109aff732b3f3f4ea448388863d232b7c8da001e", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 26056, + "xclbin_sha256": "990cc7fe77565cf0e1cfe1de58840cc49be3c0ff197040ca7ee4891e1c5cc221", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 26760, + "xclbin_sha256": "ed5fe165764bec49fbcbfaad40c6c0176c54229739ebcfd3cc4c4455003ef899", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 27464, + "xclbin_sha256": "61645b488f708fccb4a52123939f39e9a2371042e744c40231c2ee3867576149", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 28168, + "xclbin_sha256": "00ef0fd9b726bb57aa9e118b8b953bd15fc893a5ab8d30a08e762ba5d6a78af9", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 28872, + "xclbin_sha256": "58ad70211e7d60509ec2645eb61654858f68db830351804f5066e9afa5f2afd4", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 23880, + "xclbin_sha256": "d11e93bf53a881387c0a94c038f0f696e79ba510f0ef39fe91422f5fb9164428", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 22344, + "xclbin_sha256": "c2737c3612fb1849e4134a9faa5adb6a12ad98ed3e377c7c00ad8f9a12579a25", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "e5b0d210cb6feb8cfc875be6116dc489a3f28d3e97042f621d45622f4123cab3", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "79c2df60bb24998fbe0894d43795a0155a074ebd15b391260b18890286effad8", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 23880, + "xclbin_sha256": "be7fbb5d3de823019a4f90ed72666423cd50ed453aba5933d7042b8a4eb12340", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "9122b4d17395a003aba92563a774cf2a9ff43f0b6c51b3d27f84e4dc8cc231fb", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 23816, + "xclbin_sha256": "1e52350f7f84adcb5ae02e7e3e2d968977f6554c629975b312c1c22332d90646", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "5d2e8c05126d66f1b1ae6eb9f565381e3038310d619ec87f49ff8e12da9c4915", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "f482d0d0c91cfea68c6ae032a4bc3c03da6370f5787379f28e813d87448a9484", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 22344, + "xclbin_sha256": "c59ef27ce3d2cb5a6aad0bca05d7c7c48420dc442b3bc9925079b742bca0625f", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 23816, + "xclbin_sha256": "828b64993ef33fc9c661d7c8b0df3c263b7a20ecd46b2008ef87b8f7a24049b0", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "ec712aa979972ed68edb6a839d1bdd8819c1d1967bac98802194b6fe405e2c58", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "e5cb6bc8439e9e09684e163d3c8acf6fbc87a0fbaf3e25cf8922e06362f2dadb", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "c2e7b754ef446033a5ff81f9f7c3c7750fcd4a0ab3ae3c98ba749eb30900a66b", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "27971e0059a690ec9ac28920ef8cbf55f6f0e2bd55f0bc6d9e23d065f38337e5", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "e6e71f4bdeeec397550acbc070d7c25a5074c93af0f7d99ae7eb9cb9c67889c0", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "0f9b0225639014ec6075d300192cf0948c117694d4a337ad14588ca4fbfa5688", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "893bb1ea5a3924fbf077e979199115ac020600ce5d484f26dd7fb3ff4a71158d", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "77df7410fa90109357a8a711315e7611705565b1baafe8100619c6033ef7d154", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "3c47f724a6ca2d18900c42d03094810eb642b78f9b1cb516b120eca77d0208b6", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 22920, + "xclbin_sha256": "0886077d518b6e66a17f3a341396f6976e26f26af162db6c4e8e167cb0a56735", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_1col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 23560, + "xclbin_sha256": "eb83e3acd2fd6e24da03a8d694b1fd8528bec5831b8faab729ff60eb8da255b2", + "insts_golden": "bf16/npu2_1col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 41304, + "xclbin_sha256": "006287507bfd8b051d57d99c0853f85a8a37bae2e77383ad748ab3125e6ff01d", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 47448, + "xclbin_sha256": "80dae6541cc475672b34c7a2bc56df733d97a25de0baf54527e68784e7514a15", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 37336, + "xclbin_sha256": "ef8f9ae50e8277a8bd03bb1231b5e8a37f425d83f435f98399d3d5c2a20d54c6", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 38744, + "xclbin_sha256": "255d5cf6864d467c65c0b4311f459b80fe5dd0d5b3fa15c37228aa7033661997", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 40152, + "xclbin_sha256": "0cc2b4edff23645d9b82333668ba32292381f2c4e40d8f3e689253062b797ca3", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 41560, + "xclbin_sha256": "f3449fd32de835ea66ea4f870969f9f9cf6c513192badb485deba96f345ad0ba", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 42968, + "xclbin_sha256": "90dc7cee8ccee5f2a7e43931eb6ee90af55dcc1dba2294c65d889cdfa1918f43", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 44376, + "xclbin_sha256": "97c83dcc3eede5661bc32ddc8d48978db1e7b0d42a08c414ca19718c0a5e4052", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 45784, + "xclbin_sha256": "52bc1a3317aafe725a2cc20b0b040d59b5e43650f6c020f93aaf491f42b487d8", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 47192, + "xclbin_sha256": "f7d6cc7da150a1193901c0cf3d74a0684bfcefbbf1ab91e377e15059b6a65ac3", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 48600, + "xclbin_sha256": "995ae5d9660f660b6683d8f0485d807f7ebb92e4984d38a0d29246e7d5d7829f", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 50008, + "xclbin_sha256": "87126c39eea1b12360f5b02bedc5f84b2f0924cc2623a025cc23a69f1abbd415", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 40024, + "xclbin_sha256": "665ee05045a554324690aea483a439420281e32387580d2870b0f1a2a39087c8", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 36952, + "xclbin_sha256": "e43592fcc91f5c33c22dca7aec3902feee4f0e280fb6b48403af15949cf50ea4", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "600a067fa014d031ccf3e11b3447edbdd1f2e42ace8db1332667af9c676c0643", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 39384, + "xclbin_sha256": "e7604da02d7ebfc25ee8828fe0a01f9988c973afadf0f531c8d49c7013857d93", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 40024, + "xclbin_sha256": "a902b8c7c04a1aefc27586aac4f9185d0394b9be7410fb88348d1ba71287c9bd", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "0fe956ce37da767fa62dcf93a1f2e7d9d6e4170cf5367f179a96d49b98568209", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 39896, + "xclbin_sha256": "4b5d3af9966c3377171cb7fb98f16a315796a4162aa7178edf077f47136253f9", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 39384, + "xclbin_sha256": "8f18befeeadf27c1f35b773f4a57833a3580216541b545f7258e01476b6169ff", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "636114cbac8366ae0dd795fcce10042c88acdc8f853b3d6b043e3ffcddd06162", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 36952, + "xclbin_sha256": "347dcc0f0a47279afc8a3a2b07745df34ee4405869a5ea63d08f57fba79c8438", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 39896, + "xclbin_sha256": "663b68104bcb6865631516d9b33d4ad7a31d9b464b95fabb8be0737862f6856c", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 39384, + "xclbin_sha256": "f1ee118c897a0574dd506bc4ebbdbe326d5284557f433a231f2db1607a557235", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "402ade6814723f900f9814ae66a1f9aa6a5eb3f1e638a2cd42e38a883c87a9e9", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 39384, + "xclbin_sha256": "f2054cdc6b29c721dcc20b32c79f92b66bdecfc0043452a37cee3c7293e0d288", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "b92e671ca1042885d76569a155eebf7da2e756b63ce73508cc60dd588947442d", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "d172e0568e22425a4072361bb5d3b1c79e8cad35cf400582b43bc23ddccb6434", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "57b7de3367d213c8515cce2d4d85537a82b3cdb77885544ab6a35d1dc4999ac4", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 39384, + "xclbin_sha256": "2ed32a5823cbdccd2b9e7aaa95eb340f28810b8242599fab39bbb82f4df8b408", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "9f6af645e032d6b44b76408f68a4700a44ae3255b3bcd86f87a8fb4050d1fa39", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "e923f4a4c0a9314d402a975d12d865eccb6dd8d3af1d3d81099cea25323aa328", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 38104, + "xclbin_sha256": "fc6676bc65b5f4c26a76021635dd198ee9a5fb53b292b8342292aa1f0709d7bc", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_2col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 39384, + "xclbin_sha256": "4bde66b816a68c6b30bdfdb2d0f4bfe02744daa692c2e12bc6128483a164e424", + "insts_golden": "bf16/npu2_2col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 75118, + "xclbin_sha256": "79ed75cd139c6510a296eb27752bd16e02b7f3670c1cc1b33d086982bc169e77", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 87406, + "xclbin_sha256": "c78300c611ba552f0723681991cb9071e38f09632937d8180667125ae4b740a7", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 67176, + "xclbin_sha256": "84320cd5480206476d6461c90580bb7b436054f9d9d47528ba8f5a698c30a645", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 69996, + "xclbin_sha256": "a93f125eb4d47fc72812f4fea46a1011239a91bf8e1bcabb7f871923c1b3e42c", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 72814, + "xclbin_sha256": "286518b2e71f67cd220092112042fe6b902791ddd6de16c59a56f528b2b4f485", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 75630, + "xclbin_sha256": "2eb4c11c20639c09ec51d45c343315f847da19c7e0b4e0b8a444a50013ae0c9f", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 78446, + "xclbin_sha256": "8185b13d5e984837702f1826880bff09bc0cfb94edcb6b2a9eaba56929217431", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 81262, + "xclbin_sha256": "997933eb5b8ee4d0cbaf02c7191440420aeda56c0710b52803f65e8cba14ddd9", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 84078, + "xclbin_sha256": "999dc70d57fc9a9a75b4d010c5e5b92ac7fa0d57e16683ab50b8c92dec30c559", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 86894, + "xclbin_sha256": "7369aabf82ac1d041a15e98a3e12f715b0686e37813db7075e9090087d36250f", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 89710, + "xclbin_sha256": "76f5c6d29ca5ddeb65c45c51381c69fba5fc4add77137759af05a847ecbbb0c6", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 92526, + "xclbin_sha256": "ea48f04d1dd86eedb41040baf82db7e7246f85d9726a7c2464bc01cab0ba3d51", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 72558, + "xclbin_sha256": "cd258a75f834645722fb0b34a5a0b3613d7cac4146b786780b717009013fcc86", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 66408, + "xclbin_sha256": "416b67d158d0b435986d332000559b313f71752e6c8074ad51822649ef99009e", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "3585d74e25051fd5626e7ffb806e6e867029799487137f3496c158a773b44379", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 71277, + "xclbin_sha256": "ccd125add8210554cdd61fdda5aa908bc4f8a977f32d0170d357db40e202353a", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 72558, + "xclbin_sha256": "9806f58665e9be2b02a0519f684c662391c05508af2f6e6eee7b0c4ca3b0add8", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "7890a0de7c0486fa01bb16f3ecbacf4d93f3f3144f40f9da0ae75c064c25a4d4", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 72302, + "xclbin_sha256": "2aabca7da9748e0f04725c3f52f7dbfa1cfbdd5c015100584e288df95bb7736e", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 71277, + "xclbin_sha256": "abd5429cbb5b217daac9e99209fd9d343e89927299c07356e5e1ee963ad7a11a", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "a7f971cfc44be7e9547e2d7bc91e08bb2136d297267876e80d620e9b22564004", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 66408, + "xclbin_sha256": "07df015c64abec4ed272c9b4c61b5a276ef1165ef9acb6c9424590c66b341730", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 72302, + "xclbin_sha256": "09a4cd9d53d4cbc812920976d49be8ab9793850362ca0c0a95e8617603947eae", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 71277, + "xclbin_sha256": "7ace62757304ea913c5a2edb36f1b9aac07d53392fefd9c259f656d58d8df82c", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "90f5178fab12b7f9d941b52108e5069d0cad7485bd3445920f8e286c846cf85e", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 71277, + "xclbin_sha256": "d8460ec6e26280e7ecb3df68e80ed84215a3c6284686db65bc4c701c573673d9", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "604ec2a6c214a7d27f3af4a2a784ec71660fdd907cdf48bba02c915593660777", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "37b374a8c6e4a464fca9aa093500dacb5aeaedb8b3849da9ce50f705356a6b28", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "bb4b2db8eff8f17716e4eb83f32512f5efc8c33cbc70453c0f5c6dd5cf37010c", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 71277, + "xclbin_sha256": "8b4183a5274737e87a72b0e83f7e7237153db9ed66eb04f11a1b6e063d804a41", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "8f8960fe592eb4188b69a3cde2816871971b9d381d40dd01913ba5388df1f859", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "9741bb442e0f66a53ed75a936361ee03651170faa71c78b1e355d3e7d6c7518f", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 68712, + "xclbin_sha256": "55dcae8b4b5521089bfe2f11e6a306ffcf4119be8713dfb7c22dd0efa9c97dee", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_4col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 71277, + "xclbin_sha256": "691d1aa4684a6d2585dee3b7bec26dfbe4df37a687bcf17031a5e596442d6439", + "insts_golden": "bf16/npu2_4col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 143182, + "xclbin_sha256": "e2494a9ac0f4287c0371c638fdba60f2dfa2c6ef72c7003ac20bf74f5853fffa", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 167758, + "xclbin_sha256": "c8b37dcd46b57a59eea73927abf44245c8520795400e793c4ea2b73ad056262c", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 127310, + "xclbin_sha256": "feb883195184247b3c833dd22a82ba210755fa6ab89d8b96096b23f3e511d5d8", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 132942, + "xclbin_sha256": "6951e0707f4e78f77c4a2aae6bd2d95e7b42ab62d92191489b8f84f954d24104", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 138574, + "xclbin_sha256": "d9d23d5ef87e7d9d3bf1073aa5618017d29f65c1a9a99a461aca04c2d1276f0c", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 144206, + "xclbin_sha256": "8b0f4649cd80280e8545987dd5e6ba8f5e0008bf8a0ca843b0754f6ff1c0da5e", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 149838, + "xclbin_sha256": "8d4845d4479815293fe2e2e85d475f57b48ba4c8cc9a7388f55c90abaff10350", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 155470, + "xclbin_sha256": "d84ea0e15a2a90f9b8f055108736c6c707df0e0ae747ec0677ce093823341fcb", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 161102, + "xclbin_sha256": "03268a8c721b44bc06bc5ceac53908c5bc2373bd394f6a8f8aef5ddd27ad97d2", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 166734, + "xclbin_sha256": "e8ad1bbc35287c85736da2d3129c4c83c9c12a781fb3792d72a38e935ed55891", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 172366, + "xclbin_sha256": "16c3dc40940532cbab463205f40bb636ea0177a1e2dea445cccec2a2fab91f78", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 177998, + "xclbin_sha256": "968cd442ff0fa83a894fb26128f41b9f7698fb7c5be738174863e47c12b69daa", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 138062, + "xclbin_sha256": "187a740d0c9ff85e6b1e0b0bbd826726bd4bfa3bec46f0a35632b3cff40195e6", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 125774, + "xclbin_sha256": "e556b913088f780357c2237b992b8edbb0a40a808890ff965ec4b1f322662eec", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "3a09a4f7cb8f8c666dc4cc9ebb023e71027ac35826ab01c1e1b4326557b57736", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 135502, + "xclbin_sha256": "da757c3b29dc7a9b027f25c5044f54b668f818b4005b832cc5cbc2dfa915a7d6", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 138062, + "xclbin_sha256": "f9094b909f91a6f07d7bea10f7f149c3bf57396bd849ed494a938c4acf65fce9", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "cce71962480e758359f1c8638be509e069ca9dd5460ec6fa98efa65024e121f0", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 137550, + "xclbin_sha256": "c19665555ec548dd73c5cffc3b336e9638e91d115e1b10f6b2f5dc860b7e0f70", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 135502, + "xclbin_sha256": "bddbac9382b2c0d5bf984fa5ba8d01754ca0a670822ce0a2654812be9399e3db", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "858b27302210793fbcdbb31fca79a195f3c85dfaa4de9ff19c639fcf39a965ea", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 125774, + "xclbin_sha256": "652ac1c37a7b0c5d4119b15b2901600f9f20a328dfaf8f9e47b6242188ca2db8", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 137550, + "xclbin_sha256": "aa57283c26a25af1fa4cebfe8df10873b65097cb3c46e8897af47baae0cd059e", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 135502, + "xclbin_sha256": "a52d03e5daf406326e717839ba0e16f7ac2cfd774e503d25027d414c1b95ce13", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "9f5f7899847e6703af6ae484f9423507770c82513e21451c56463476cc8aca09", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 135502, + "xclbin_sha256": "bcf5f012d20c120cc6d94246f440b56b04a66f64f900a361246236cdd5990df5", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "c7f369c2f8d54c1487a4a28a34709956056b9dda6d0e155415902af412c23dac", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "3aa3c9fff07a4a422de82d8c77018c329e3900b385cd67bce41e384ea502dbd0", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "113018f5babafddb48e33bf270cbcb5db3b9ff444d996564e475ce41aab57763", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 135502, + "xclbin_sha256": "952f906c44520dfeab9f56af71c8da380720a23868c52eda4e91a40eb3421ea2", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "8714b4eeb0f9785549c1d35302d66a872730451aa2409d979a512f5ab042754e", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "6214a18bf25b4e422160ce581536a3fb2d34a3b39c7cb89c0c10ca52234ae6f4", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 130382, + "xclbin_sha256": "3f0ebdae543262421789ad5b1f15dc59049f510b5f9ac68fc927a70223117c05", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bf16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bf16/npu2_8col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 135502, + "xclbin_sha256": "c2b08fab071deb041f99fc05e95f2f2b6ef4ab7b9c5ec314ca4ff07b297625a7", + "insts_golden": "bf16/npu2_8col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 24072, + "xclbin_sha256": "d1d07825a5634c4d17ff5c391ce954e967017ba9284859a0031671b47a60e377", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 27144, + "xclbin_sha256": "6c8aa165c94a6720043fcc41ae47822b890e78da0a93cb6c71d66a112a3f49fd", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 22088, + "xclbin_sha256": "9fce785b2537dbaff461de54da6a1ee622676c4a3007e54bba3625ecd6b4ee5b", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 22792, + "xclbin_sha256": "fcdd89760327a3dbacaf7a5d30902620aa054dd6fd091236633ae08fd8762f7d", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 23496, + "xclbin_sha256": "938a4b6ff5efc14236674f5c1a5c777877d656a04e36d875f89a2dfc79732596", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 24200, + "xclbin_sha256": "958841a3c6d452f31fbc969b1a14ccea0d6f381eab4f95ed987af2527cf0f31b", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 24904, + "xclbin_sha256": "3c9771118902ecea046cd2f8d1fccf03a6caf33b5b6635b291bf159a731adc45", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 25608, + "xclbin_sha256": "44fcc1d31574c9941c978f3710b0ce9d7e1a6dd92d4c393d2862cd13c8f9225a", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 26312, + "xclbin_sha256": "17337a6311749172875c6e9d5779fbff2075b04b9feab5a7215d28ec2bda7770", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 27016, + "xclbin_sha256": "ce15bce3f8768fb80da470c815bee92d3cb459ef2726a95bc71820b001e9874e", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 27720, + "xclbin_sha256": "3add96796905a3c32a7e5ba212a7616e75decc42d7c15d282f21f73597c66505", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 28424, + "xclbin_sha256": "3647569a6a6b2e0bb6c32f3f24e4ba639f9f4690525a9770af8df02ac409af37", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 23432, + "xclbin_sha256": "755bc99e0d9aafa6e72dc27626bd21ca234396c740f18496d108343a0fc4c85a", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 21896, + "xclbin_sha256": "87ea1c9c21aac198a4e3f00b51ead3bfcc75b2404051770ff7dcc12718d4056c", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "f50ca5b20e5df24510d6b3fc7330d988266c374059210559e71b7b6c05d5d3dc", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 23112, + "xclbin_sha256": "2728788f56768714823dd7b48eda12a7571f9ddf9c468897e436ac7a3f8dc419", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 23432, + "xclbin_sha256": "9a9031de25689824564cc0f30bc42ee34d9ee5245798054483690775f8285f79", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "c101c667e4ce88ff2d0f7ad72fdc5cece635d608e85134b2324ce81d61caa03d", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 23368, + "xclbin_sha256": "1184bad54724dabee4ca003b0f709a5b7e61a5e6fd41c9a4c876be9798ba4caf", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 23112, + "xclbin_sha256": "fbdb12913542cd70fff4dc51f26281488c2afd61ac19f6c0e1a0ba67a5f505d4", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "fcc432a33e32b744aae674fe9c50850fc19a43c5f64ca71c8c30efcf947fb860", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 21896, + "xclbin_sha256": "ade98b2cf7e758b1f91e94d6f46c2c3e16e1f9e1b946828138f59333a2bcade4", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 23368, + "xclbin_sha256": "c205ad292a5edc11963659f481379be338da1eace8d9b378416602a4cd3c2c6c", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 23112, + "xclbin_sha256": "eb17eb62c273b87e91cb6e091ccb2211f15c1bc40de94147338ed7b7886009fe", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "accd3dbd800b1dd53e98b4f380a90fbb64ca141d6fdee682dceae3ddfafae744", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 23112, + "xclbin_sha256": "7a3f62314c612228c7f8198abe9847fdc7f1e80a7772e47ce0a9e0402feaff20", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "9055df355135e13a2afeccb5df479d8ff5e313e22bc461e20e12e2bf0a7ab2de", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "10a268e077ef34f8764cb11cb34895fe93efa1f3095949a5bf92039928ea3502", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "db84945621154a4eb06a5bc092c1c2a519dced2dbe0bd5a2a79c2deed2104606", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 23112, + "xclbin_sha256": "65de9a4fc1d67ee75eaf857c798e499b655c5e450654f7148facd38dd5feb23d", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "410141301ecc3593d7abbd6bbfc11790edf1895bb91569a40006d6ba4471f63c", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "2d5d251aff5d2502f7d7ff90e3564fe7e33e164f2cf0ab36da1cab87acb6c570", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 22472, + "xclbin_sha256": "d0582fdc36ffb093bd36a76cca4e7561b9829145ddf111ea5a1b3274ba55244c", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 1, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_1col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 23112, + "xclbin_sha256": "ccdb87e23377c92864e11afaefb7988f45e3b35f2f46587fabafea2f67e52e7f", + "insts_golden": "bfp16/npu2_1col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 40408, + "xclbin_sha256": "02c60093212674f55574c12f17dfd85338b03b4222372732de24964d7fcb529b", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 46552, + "xclbin_sha256": "60a58c4fff2f321f04ecad61ccbf5f160e6b62b4ab87308c7f67b0e747a2209b", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 36440, + "xclbin_sha256": "3afb1e417673640b5cfff123546aad909ee13ed9b63822828911f55b789fdfa0", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 37848, + "xclbin_sha256": "d60b15eb3d0dbe7e39d687fbafa40ffe0c891b983c9a05f79a6f5816c832a2ab", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 39256, + "xclbin_sha256": "5580dd4a6bdef4e83450031be47b536cfc9124572b90669d7bd02085db3f90bc", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 40664, + "xclbin_sha256": "fdd7131056501c791a51d17ef28e9f25f4bef5e9eeb2439f91969e6f3911141f", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 42072, + "xclbin_sha256": "59cc28f4cff76955d8aa517aae7b09d684520569ab2f6fe6fd0264ffdae0d854", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 43480, + "xclbin_sha256": "86d3ab7e8144a4c835586ec73813b2955274242a72d2759dfcd7258ae257e542", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 44888, + "xclbin_sha256": "cef09d28fc42ff9e77b67df6fa267ab6aec1eb0127b351c24b42580af0074494", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 46296, + "xclbin_sha256": "b27ec1f20b276f6239e7c48c7315f14ee5417a9c5114b28de0fe5707028b5980", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 47704, + "xclbin_sha256": "76f2c3c277052d44032b88d9a514eb8653938a32e867cde8c68cef0786fe663e", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 49112, + "xclbin_sha256": "a8a8840f67b66ba9fdbcf8cb7a8f277e4ed2148cc27335ebe704a391026edcc2", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 39128, + "xclbin_sha256": "2dd283d80d847bf5f1d87da4f09dae2200aada3af2f7e83a558fed3b2a628d3b", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 36056, + "xclbin_sha256": "68951377cb1d842b07bd0f5de858db6b3f185897b180d551404dfac5e4e93152", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "1e7af2879091caed4338ad7605dabfa7fa9cc90c53f342a63f5e5262ece9102d", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 38488, + "xclbin_sha256": "d34d034096f72584fd613a22e59a6011d6af0b5b909cf4c565dbb7a7def23f81", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 39128, + "xclbin_sha256": "49f40b1289e938377f4944b46192a643c0dafc99336fbf4abd7450a63026136b", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "5e07efe8f3ef6d4b48142bad27ed85873fd22b43a4d852e59f73836b6d847a34", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 39000, + "xclbin_sha256": "e7fcbc21a3815406de047e5e16723fa6cf8a3c8627e400c57445472bf26fd74e", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 38488, + "xclbin_sha256": "02cca9bae9b3b9f15821f04f8f79b2477cfda83003d433199725bb47d54223a3", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "007c4760fcc7bcd918fe2aa1c6e8a108dbe78b620acc337451a7b8b8b799d8c7", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 36056, + "xclbin_sha256": "d26fefb8ce6f53eb136988efc73ba0b98e1a7f27da86ac1bc936caf9954f2ba6", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 39000, + "xclbin_sha256": "37d739e791f2f1bc4d2dc0776ede5bddfdb42c5f04bf5b477ff6387e370b5a07", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 38488, + "xclbin_sha256": "890a20e2dcd4e08b8dedc2b6dc8ed5216c12654d7dcf9321b449b65a7541b026", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "c1d59385f0a745f5f46fa226e31f5bf0cf952cf450098cc9b4a81e7df851a292", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 38488, + "xclbin_sha256": "627f6f569e88cc63cdfc42802a13bccc353785336bafae00d468aa64e5fbc284", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "ae14438dc9c5a1e39025b15f2c7710253164c4e6655d8138a6ec82952a6c29eb", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "08577e771a2d672de3164c0ae8db73affae5be5d50faf06c81b2f34ae7f87452", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "ac8e6f2ff145dff08f8dc5d1c5d29c24c653729cde2327576eb829fd0d6803d5", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 38488, + "xclbin_sha256": "9dba6a1c509f719f48d6d14fc687bb5361260f51e2548af6ae663ce2f00d3ffc", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "2a2a7e4463b4056693204c344142f32b9ed7761691cf49f35aa54627f36837fd", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "d3e6012696f7521f7c30b6f85305d43d0f3018cea6e65317960d0410ff8ab37f", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 37208, + "xclbin_sha256": "9e775c0e8b989e7b3442dbcb04dea8c319a5310407625d02c49707e2cbe10ecd", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 2, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_2col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 38488, + "xclbin_sha256": "e6c6bceb3389776f49cae4f8655c20ef00d4a418494015c63da25507919e4166", + "insts_golden": "bfp16/npu2_2col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 73326, + "xclbin_sha256": "e819628fd9c26a5565bc71d448f549981ea5c6564fa9f1ff4f64b1bba1ba1aaa", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 85614, + "xclbin_sha256": "a10a927edb41ee27a123986f40f5fe32b4de8556f567317b13710bf0060646c9", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 65384, + "xclbin_sha256": "961b9722c18b488fc18ba1934bd4cbaa0c885c3110e3d7a45ea5f05f6c2f3f1c", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 68200, + "xclbin_sha256": "be22adfde4a3cf2f8fe3c3d0fafde7bd3cdcd1f9ecf5bfe34a894b4c3fbfee13", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 71021, + "xclbin_sha256": "01f1c40ec38fa51892389859165be2e5af2913b290aad9da1c3723bf4a5256d3", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 73838, + "xclbin_sha256": "1f26b37b0f2d53c212ee855daecf70c7e348dc45dc4e06a67607f9c36b24f206", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 76654, + "xclbin_sha256": "1b6cfc4668f57f17d4333a1d535cfc0013f611c0fecf7617376c9779201c4333", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 79470, + "xclbin_sha256": "a202a1fd78737020bcd939fc221cbaf281a96f0cc6967db52b52d846f15be87e", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 82286, + "xclbin_sha256": "bed5dbce60fb1b98d73d882ea8551c3543f9666484007fed103f30b68b34e4be", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 85102, + "xclbin_sha256": "ce01c70e311ed3b780ec61b3b95e8cca0dbc2d643b515ca464de193aae586c67", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 87918, + "xclbin_sha256": "1ffd95b5f7e44c2ba2b69924ffa6f072291baea974f580016cb74ffc6354d36a", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 90734, + "xclbin_sha256": "1d16bb804bb64d864f8d5e030b6e465d1f465aea36b1a289be7f958a3df6b081", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 70765, + "xclbin_sha256": "69eb90b890db50603199feffea62ab01313d4885756da0cc498b730e5d066f0b", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 64616, + "xclbin_sha256": "a54d6630942977d1a1f07c7c616ee6882fa3b63c0741c234fd8045a74aaeb8d9", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "917dce7623f484e3036b8663f78943c54ba36df3884141a3d68d8bc98708e9a6", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 69484, + "xclbin_sha256": "6177618da825fdd1dd228fc75bc45943bc4f8ef96b7118dd0a3b77167ac7b315", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 70765, + "xclbin_sha256": "58221bc28ac714e714bfaa8d24f78a62f16aa64ecab838494bf3ff343afd8d35", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "0f61410e90b8f51191afa18adfbfaf79d78cab367142d5e27d9265fd06dde50f", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 70508, + "xclbin_sha256": "977cb054bb985c9cebe960889bcad5afc290c0ef41717c08e486400a4a673e41", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 69484, + "xclbin_sha256": "a109377f0552449f7c81ae9303593145ff8d61396a5948acc4762a8e6d94e9ec", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "2227922cbffee3e5afed5fdfe189d709520da1d8ca7f4f033eb12ebdf1724f51", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 64616, + "xclbin_sha256": "fd3109a9b8ba6d7132fe44fcbe6a8e86fe2cac57aef86d8f5108536a98fda91a", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 70508, + "xclbin_sha256": "57c9bf4358005911864e81800f80dad73fab479a69dcc6a6280d8fe3d21ea1db", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 69484, + "xclbin_sha256": "ab95dd844d12354f07e4661db4d2851d51b9bbefd38c74bb79b9b8f0e199941e", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "e40d30a59ade6e6fac5eefb9c8126f47b5b5a65fade7bd35717be5870ece2320", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 69484, + "xclbin_sha256": "c500a5f2393fc48ed7cb84ec53f695eae893cbb72247c07c08186ae08a40b898", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "76d4daadfe6a0848385bdff242aa3c7fb383b9e75b9837aa4485901aca1c2ddc", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "7eaf9c23477614a670234bc4b93cb0923ef58a8d5cab3a612183bc5b4e8a0f19", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "f3ec382d6a480c344af37544961eb67ee7c674420bf00e9c3a0d5c9a794856b4", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 69484, + "xclbin_sha256": "05305863cf8c52704deff169b96956626538311605c23dd58e438c79f1cacdcf", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "bb714eefdd789fc427f395ecca0c29efb50cc7ddb13df89ee78f944db91b4602", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "a064bac7accd69565f16e176738b7e9b6175300b5bf202358d0a06fe39499efb", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 66920, + "xclbin_sha256": "2c6a36192781aaa2d5c111ccd1b3d5dd7d6894eab5e76fd56e3cfc8f11e8305d", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 4, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_4col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 69484, + "xclbin_sha256": "4c31467c43a633a2b46c86ec696f3da70193e2f3ddb0dd3cc28e67e14115ba29", + "insts_golden": "bfp16/npu2_4col/gemm_bf16_K6912.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 64, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K64.xclbin", + "xclbin_bytes": 139598, + "xclbin_sha256": "1bd01d897e944442a1f786d0e2f45c266b86daa36fc85dc0b857553dfc2ee446", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K64.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 128, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K128.xclbin", + "xclbin_bytes": 164174, + "xclbin_sha256": "ef6ff050b6861792b071d9d43243ad28414ce3645ce9abf5792a36abf238079e", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K128.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 192, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K192.xclbin", + "xclbin_bytes": 123726, + "xclbin_sha256": "8ccb6299dbc40bf9ee957eac738becfcbf8cb54b1373d54b4c516f5edcbe1197", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K192.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 256, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K256.xclbin", + "xclbin_bytes": 129358, + "xclbin_sha256": "8456c5495e23e97424f92a8a844a77337120020135055af6bf6d849d0198e7aa", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K256.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 320, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K320.xclbin", + "xclbin_bytes": 134990, + "xclbin_sha256": "5948a5d6c55ae1b4add12ed4d586187b25f39c69c0c765120d3ae79f610dee3a", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K320.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 384, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K384.xclbin", + "xclbin_bytes": 140622, + "xclbin_sha256": "95692d6313f0c5ff18e4349c730035c53a13cadd6428652079883f917495994e", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K384.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 448, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K448.xclbin", + "xclbin_bytes": 146254, + "xclbin_sha256": "b66ce2192335ec5e7b8457d291ce41ee0d21680f1c73c655f0bc002827e1a8cb", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K448.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 512, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K512.xclbin", + "xclbin_bytes": 151886, + "xclbin_sha256": "02aa5976c23dcca376cd98031e4aff4a2bc40d3f52ffd1586215a82e4e67d865", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K512.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 576, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K576.xclbin", + "xclbin_bytes": 157518, + "xclbin_sha256": "c4a390f9ed65c90e798bf34e8ba42d543b0a7fbfad854bab272f41d63ef31744", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K576.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 640, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K640.xclbin", + "xclbin_bytes": 163150, + "xclbin_sha256": "58931746df02710ca37f5df8233a19bd3de2c00da4e3dbe1c957484ea57e7ca1", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K640.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 704, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K704.xclbin", + "xclbin_bytes": 168782, + "xclbin_sha256": "ac2078220a88aba00da4e8d5bd8a7689862baf426aa8aa1d9ae009e38590eadb", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K704.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 768, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K768.xclbin", + "xclbin_bytes": 174414, + "xclbin_sha256": "3f7157cc3c43d368805eff95b8e759dbfba060ef5a8fbf68bc6bf01c33b59b83", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K768.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 832, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K832.xclbin", + "xclbin_bytes": 134478, + "xclbin_sha256": "5b70104afee64fe26d33cb0a5c78ac9d118bb96905351496fe38df8c2fb619d1", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K832.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 896, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K896.xclbin", + "xclbin_bytes": 122190, + "xclbin_sha256": "fa4891601074638b98d7a2af867861b68271c3e5ab8f2b630302b3835faa3839", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K896.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 960, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K960.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "3f011c299e2d512500cd465b497b3d0316565842b26f6d3e1eafbceb77daa3d6", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K960.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1024, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1024.xclbin", + "xclbin_bytes": 131918, + "xclbin_sha256": "c57aa38b1245dc331962dd7dfc1d1c4babdb740eb023581a861dbf10a919109f", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1024.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1088, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1088.xclbin", + "xclbin_bytes": 134478, + "xclbin_sha256": "556cb0a47e9ffeda26a982ce511602dc529084a24607c4b19ed74a6f83b5e77e", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1088.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1152, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1152.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "9c628a99f5eb15cace83610eb84a31dcc0e9bdb83dfbae2b80df56c98849a918", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1152.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1216, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1216.xclbin", + "xclbin_bytes": 133966, + "xclbin_sha256": "9ec5ec561ff9036cca86b0293276842e8ca439b418ec7577de8fbe81bd18457f", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1216.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1280, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1280.xclbin", + "xclbin_bytes": 131918, + "xclbin_sha256": "282c5a6bc70c69a0c436d6a272427b8e43ce490f75e2da26f49d3f226524ee40", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1280.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1344, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1344.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "b2c9440ab12f508e501881ec2a5d1daf0aaad95c92b8d44522d610d466fde32e", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1344.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1408, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1408.xclbin", + "xclbin_bytes": 122190, + "xclbin_sha256": "cb48d7e0331a95fb56f3c456ac71dd94dab389d0e39d718eb90fad00c193aa06", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1408.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1472, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1472.xclbin", + "xclbin_bytes": 133966, + "xclbin_sha256": "fe17d33ca2fbf1500d9f0a3cd43929d21aba1acf7956cd384b0c8462e0b332a7", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1472.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1536, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1536.xclbin", + "xclbin_bytes": 131918, + "xclbin_sha256": "8573fd92a2e8ec244eb1e1c222c8d44f68218c83a44fcb3806ee52707bbde099", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1536.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 1728, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K1728.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "360ad0d2f8dc4cb7b4c2e063c8adfcd1cdb2b854d3c1336bf8fb60c2d47785ab", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K1728.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 2304, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K2304.xclbin", + "xclbin_bytes": 131918, + "xclbin_sha256": "b91f6f975e9e57a497f960e99c488577058648103906b4a07bf38c74af7ebe91", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K2304.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 2880, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K2880.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "f0a2dbc010168d29e19dbe6741de6be0604fd0b142cc3fa0b517541462ed38c6", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K2880.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 3456, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K3456.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "31f09dc17e003c01185862946ba0fcb57c2aedf6d6ca4bb1f86bc2448e948d0a", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K3456.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 4032, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K4032.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "ee895895fb295052dab9538deac03aede03fb6a85525d172455e2f861318cd4b", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K4032.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 4608, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K4608.xclbin", + "xclbin_bytes": 131918, + "xclbin_sha256": "93168c53a58ea02c9a1ea27d3020918aeb80be750ce10d29581e2b13f9a15505", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K4608.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 5184, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K5184.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "c2fe1daa1838285d3487a36c180577e27fa9f617d6d84e29c6893b7366e774ea", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K5184.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 5760, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K5760.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "207ff29c827a7109c122385c93785d92b1d869faf7de806ca7c859aa5387e89d", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K5760.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 6336, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K6336.xclbin", + "xclbin_bytes": 126798, + "xclbin_sha256": "beddce21342623ec8b88c31f6890dfca9165b72b3033f65e3487c2f0f17f0b0a", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K6336.insts.bin" + }, + { + "dtype": "bfp16", + "arch": "npu2", + "n_aie_cols": 8, + "K": 6912, + "compiled_at": null, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "xclbin": "bfp16/npu2_8col/gemm_bf16_K6912.xclbin", + "xclbin_bytes": 131918, + "xclbin_sha256": "500adfc65f86f4b607bbef5c276d5ea6ed2e048a8b4e7797cfed2244a4ba03f8", + "insts_golden": "bfp16/npu2_8col/gemm_bf16_K6912.insts.bin" + } + ] +} \ No newline at end of file diff --git a/cpp/external/ryzenai_artifacts/manifest.json b/cpp/external/ryzenai_artifacts/manifest.json new file mode 100644 index 0000000000..4e03285389 --- /dev/null +++ b/cpp/external/ryzenai_artifacts/manifest.json @@ -0,0 +1,894 @@ +{ + "manifest_version": 1, + "generated_by": "cpp/neuralnet/ryzenai/kernels/build_kernels.py", + "generated_at": "2026-08-13T02:43:20+00:00", + "design": { + "template": "mlir-aie programming_examples/basic/matrix_multiplication/whole_array", + "gemm": "bf16 x bf16 -> fp32 (fp32 accumulate), row-major A/B/C host buffers", + "bfp16_note": "dtype=bfp16 uses AIE2P BFP16-emulated bf16 MMUL (mac_dims (8,8,8)); same host ABI as bf16", + "n_aie_rows": 4, + "lookup": "artifacts[] by (arch, dtype, n_aie_cols, M, K, N)" + }, + "abi": { + "kernel_name": "MLIR_AIE", + "arg_slots": [ + { + "slot": 0, + "name": "opcode", + "kind": "scalar", + "value": 3, + "note": "ERT start-kernel-with-instruction-buffer opcode; pass as a 32-bit scalar (xclbin metadata declares uint64, only the low 32 bits are used)" + }, + { + "slot": 1, + "name": "instr", + "kind": "bo", + "flags": "XCL_BO_FLAGS_CACHEABLE", + "group_id": "kernel.group_id(1)", + "content": "raw bytes of the .insts.bin file" + }, + { + "slot": 2, + "name": "n_instr", + "kind": "scalar", + "unit": "uint32_words", + "note": "official mlir-aie C++ harness passes the word count (insts_bytes / 4); the Python iron runtime passes the byte count. Both were verified to run correctly on XRT 2.21 / Strix (the TXN control code self-describes its length). Use the word count for consistency with the C++ harness." + }, + { + "slot": 3, + "name": "A", + "kind": "bo", + "flags": "XRT_BO_FLAGS_HOST_ONLY", + "group_id": "kernel.group_id(3)" + }, + { + "slot": 4, + "name": "B", + "kind": "bo", + "flags": "XRT_BO_FLAGS_HOST_ONLY", + "group_id": "kernel.group_id(4)" + }, + { + "slot": 5, + "name": "C", + "kind": "bo", + "flags": "XRT_BO_FLAGS_HOST_ONLY", + "group_id": "kernel.group_id(5)" + } + ], + "data_arg_order": [ + "A", + "B", + "C" + ], + "declared_bo_slots": 5, + "declared_bo_slots_note": "the xclbin declares 5 data BO slots (bo0..bo4, kernel args 3..7); this design uses the first 3. Never pass more than 5 data BOs.", + "group_id_note": "group_id values are assigned by XRT at load time; always query kernel.group_id(n) at runtime, never hardcode the observed numbers.", + "data_layout": { + "A": "M x K bfloat16, plain row-major contiguous (row stride = K elements), 2 bytes little-endian per element, no tiling or packing in the host buffer", + "B": "K x N bfloat16, plain row-major contiguous (row stride = N elements), 2 bytes little-endian per element, no tiling or packing in the host buffer", + "C": "M x N float32, plain row-major contiguous (row stride = N elements), written by the NPU, no tiling or packing in the host buffer", + "note": "all (r,s,t) sub-tile reordering required by the MMUL intrinsic is performed on-chip by the shim/memtile/core DMAs; the host buffers stay plain row-major" + }, + "sync": "sync instr + A + B + C XCL_BO_SYNC_BO_TO_DEVICE after filling them (C sync is only needed if the host wrote to it); sync C XCL_BO_SYNC_BO_FROM_DEVICE after run.wait()", + "dispatch_cpp": "xrt::device dev(0); auto x = xrt::xclbin(xclbin_path); dev.register_xclbin(x); xrt::hw_context ctx(dev, x.get_uuid()); xrt::kernel k(ctx, \"MLIR_AIE\"); xrt::bo instr(dev, insts_bytes, XCL_BO_FLAGS_CACHEABLE, k.group_id(1)); xrt::bo a(dev, M*K*2, XRT_BO_FLAGS_HOST_ONLY, k.group_id(3)); xrt::bo b(dev, K*N*2, XRT_BO_FLAGS_HOST_ONLY, k.group_id(4)); xrt::bo c(dev, M*N*4, XRT_BO_FLAGS_HOST_ONLY, k.group_id(5)); xrt::run r(k); r.set_arg(0, 3); r.set_arg(1, instr); r.set_arg(2, insts_bytes/4); r.set_arg(3, a); r.set_arg(4, b); r.set_arg(5, c); r.start(); r.wait();" + }, + "artifacts": [ + { + "xclbin": "bf16/npu1_4col/gemm_bf16_M512K384N384.xclbin", + "insts": "bf16/npu1_4col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu1", + "dtype": "bf16", + "n_aie_cols": 4, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 4, + 8, + 4 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 80926, + "xclbin_sha256": "09253c368a044ac44d5ee1776956ea5456d0753ebd1104cf72fed909b59d2166", + "insts_bytes": 5168, + "insts_sha256": "6ee5b46c5c3093571a731d70608455fb3c3009b2830c005cfe37c1f383ed3697", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": false, + "compile_seconds": 11.7 + }, + { + "xclbin": "bf16/npu1_4col/gemm_bf16_M512K512N512.xclbin", + "insts": "bf16/npu1_4col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu1", + "dtype": "bf16", + "n_aie_cols": 4, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 4 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 75294, + "xclbin_sha256": "2355c501070130d288f573306c401e409a833954d845cb557a1a5907e74fbc34", + "insts_bytes": 5168, + "insts_sha256": "e8eba035c40cf34dccbad9b9308b618e15809c6575ad813940377d7ea9ca10e2", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": false, + "compile_seconds": 10.0 + }, + { + "xclbin": "bf16/npu1_4col/gemm_bf16_M512K768N768.xclbin", + "insts": "bf16/npu1_4col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu1", + "dtype": "bf16", + "n_aie_cols": 4, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 4 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 75294, + "xclbin_sha256": "d5927c3ee36767b7967ef33ebb592195786fea05f29cc148828cdb1873dce77b", + "insts_bytes": 5168, + "insts_sha256": "0ec974baa93d488a7616563445a8da5863370ac03ce3206328b736ea8a7c7626", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": false, + "compile_seconds": 9.9 + }, + { + "xclbin": "bf16/npu1_1col/gemm_bf16_M512K384N384.xclbin", + "insts": "bf16/npu1_1col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu1", + "dtype": "bf16", + "n_aie_cols": 1, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 4, + 8, + 4 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 25992, + "xclbin_sha256": "5877ac0160d710727cfa784c134937dce32505fb8e23a5d4917f9fbef74263f5", + "insts_bytes": 1304, + "insts_sha256": "2ebffa614ea2feb73cb68f41f15d9af2fb2aa9cf9571551fd8a0d205c5955a16", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": false, + "compile_seconds": 6.9 + }, + { + "xclbin": "bf16/npu1_1col/gemm_bf16_M512K512N512.xclbin", + "insts": "bf16/npu1_1col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu1", + "dtype": "bf16", + "n_aie_cols": 1, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 4 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 24584, + "xclbin_sha256": "ecc71a1a490366bac779a9ad7a70a0cdadad608a7cf9998987ad77282e93a1e9", + "insts_bytes": 1304, + "insts_sha256": "dcff95ae97b99ee11f823f30dd3631e05a62a78fe300ff9127386aa45c78caed", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": false, + "compile_seconds": 7.7 + }, + { + "xclbin": "bf16/npu1_1col/gemm_bf16_M512K768N768.xclbin", + "insts": "bf16/npu1_1col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu1", + "dtype": "bf16", + "n_aie_cols": 1, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 4 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 24584, + "xclbin_sha256": "26ab701bb20d6cc48887eeafd30bfea4779eb7b3c5ad30515fd9e2ccb08d11e5", + "insts_bytes": 1304, + "insts_sha256": "69d9ddceeebaec17d92a1766008b67377463a215a67be514dadc93b0efb3cbca", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": false, + "compile_seconds": 7.0 + }, + { + "xclbin": "bf16/npu2_8col/gemm_bf16_M512K384N384.xclbin", + "insts": "bf16/npu2_8col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 8, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 2100, + "xclbin_bytes": 145230, + "xclbin_sha256": "fac999294a6d1daa779e3c8315655bfe6317e44352604c22143eb2332d5b7f90", + "insts_bytes": 8400, + "insts_sha256": "274294c4864594591c01afa7fb5794ad66fe4df6e7db17b6322e72994201846f", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": true, + "compile_seconds": 32.4 + }, + { + "xclbin": "bf16/npu2_8col/gemm_bf16_M512K512N512.xclbin", + "insts": "bf16/npu2_8col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 8, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 2100, + "xclbin_bytes": 155470, + "xclbin_sha256": "fe38a588635df848f7e427736e6b57d24f8e19ed1700fc7100cb02e48e45e2bb", + "insts_bytes": 8400, + "insts_sha256": "08d5727f5f47de1315af95c8a2f30e96787608d4576ddbb2663b60eee3b1aac3", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": true, + "compile_seconds": 36.0 + }, + { + "xclbin": "bf16/npu2_8col/gemm_bf16_M512K768N768.xclbin", + "insts": "bf16/npu2_8col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 8, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 2100, + "xclbin_bytes": 177998, + "xclbin_sha256": "ca6f9ab1edb8960cc1973aeefe1a72db06256f8e18dca3512b0a73ab275c934d", + "insts_bytes": 8400, + "insts_sha256": "e8614292674a4946074446354f86aff268ff9bec581dd8cd04441b1ad68f16ab", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": true, + "compile_seconds": 39.9 + }, + { + "xclbin": "bf16/npu2_4col/gemm_bf16_M512K384N384.xclbin", + "insts": "bf16/npu2_4col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 4, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 76142, + "xclbin_sha256": "fbdb691f2b846213dc8341e92cd635043157f70ea7c3425cc866c4767c7d407a", + "insts_bytes": 5168, + "insts_sha256": "77aa4246090925aa8a8580dcbe702f636d059806886b6ccc07f594290e75d8db", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": true, + "compile_seconds": 24.5 + }, + { + "xclbin": "bf16/npu2_4col/gemm_bf16_M512K512N512.xclbin", + "insts": "bf16/npu2_4col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 4, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 81262, + "xclbin_sha256": "da7b65ac807c2a5883d376b035cb113548fba3ae20f256d04848568e83f4c0a9", + "insts_bytes": 5168, + "insts_sha256": "e8f42bb5b265fb51d50191844250afe8321ea7d2b735986fd882e62de8bcdea4", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": true, + "compile_seconds": 20.5 + }, + { + "xclbin": "bf16/npu2_4col/gemm_bf16_M512K768N768.xclbin", + "insts": "bf16/npu2_4col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 4, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 92526, + "xclbin_sha256": "d45773b5755dd9359a96096225f97e104ff8cc8f14ebcb8d200f2144ec88126e", + "insts_bytes": 5168, + "insts_sha256": "a5288db6688002b9b32f169e15ae32c473e1f05fa6090ba7764ebc87b0306118", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": true, + "compile_seconds": 23.3 + }, + { + "xclbin": "bf16/npu2_1col/gemm_bf16_M512K384N384.xclbin", + "insts": "bf16/npu2_1col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 1, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 24776, + "xclbin_sha256": "b7b0ac807bfe0fb0920e28e7bd4a36461a1e0a507836206b13add7f0bd3a8389", + "insts_bytes": 1304, + "insts_sha256": "cf1e307b8a68b83590126bfde26ea157530cd219c1867eb04867f5a2f4fb1a2b", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": true, + "compile_seconds": 18.0 + }, + { + "xclbin": "bf16/npu2_1col/gemm_bf16_M512K512N512.xclbin", + "insts": "bf16/npu2_1col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 1, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 26056, + "xclbin_sha256": "90ee826c18937809151e0ff4c43d1705e426ebf065e8531d45786b94c3a40825", + "insts_bytes": 1304, + "insts_sha256": "2382f2e853c9ba939466ab84acca02b3087ff261972eb62d38402a1f1d77a909", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": true, + "compile_seconds": 10.0 + }, + { + "xclbin": "bf16/npu2_1col/gemm_bf16_M512K768N768.xclbin", + "insts": "bf16/npu2_1col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu2", + "dtype": "bf16", + "n_aie_cols": 1, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 4, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 28872, + "xclbin_sha256": "347637ed652ca26cfba0d9d90bd513cfe68d8f3ec8bd43666079481774b397e4", + "insts_bytes": 1304, + "insts_sha256": "6b4a2a790b460eb92efc46aaab6e2ddf080178d40e75affd1e9cfa0f0e9e0d17", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": true, + "compile_seconds": 9.3 + }, + { + "xclbin": "bfp16/npu2_8col/gemm_bf16_M512K384N384.xclbin", + "insts": "bfp16/npu2_8col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 8, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 2100, + "xclbin_bytes": 142670, + "xclbin_sha256": "6264bd24fe75554fee7164a8ebe05e74f1b72684d598f9f4b9984970a205cd0e", + "insts_bytes": 8400, + "insts_sha256": "274294c4864594591c01afa7fb5794ad66fe4df6e7db17b6322e72994201846f", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": false, + "compile_seconds": 17.0 + }, + { + "xclbin": "bfp16/npu2_8col/gemm_bf16_M512K512N512.xclbin", + "insts": "bfp16/npu2_8col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 8, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 2100, + "xclbin_bytes": 151886, + "xclbin_sha256": "759e4c06fd9eea81055e649d1255fb54fc1c8c9ba8966c9af1dd2d3415132ce7", + "insts_bytes": 8400, + "insts_sha256": "08d5727f5f47de1315af95c8a2f30e96787608d4576ddbb2663b60eee3b1aac3", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": false, + "compile_seconds": 20.0 + }, + { + "xclbin": "bfp16/npu2_8col/gemm_bf16_M512K768N768.xclbin", + "insts": "bfp16/npu2_8col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 8, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 2100, + "xclbin_bytes": 174414, + "xclbin_sha256": "94baa0eae6363ed609b834e03574407649b86ecb6e21874732d4d64bdbc463fe", + "insts_bytes": 8400, + "insts_sha256": "e8614292674a4946074446354f86aff268ff9bec581dd8cd04441b1ad68f16ab", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": false, + "compile_seconds": 25.5 + }, + { + "xclbin": "bfp16/npu2_4col/gemm_bf16_M512K384N384.xclbin", + "insts": "bfp16/npu2_4col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 4, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 74862, + "xclbin_sha256": "9353f2bbc9746edae37aca13441e70d4d1c3618b5b68a852fb24184197586bf4", + "insts_bytes": 5168, + "insts_sha256": "77aa4246090925aa8a8580dcbe702f636d059806886b6ccc07f594290e75d8db", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": false, + "compile_seconds": 15.1 + }, + { + "xclbin": "bfp16/npu2_4col/gemm_bf16_M512K512N512.xclbin", + "insts": "bfp16/npu2_4col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 4, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 79470, + "xclbin_sha256": "24eaa3d3ef86293b83fb571b3f628ab6cfafc72b1168843d344fd2ee6e505de0", + "insts_bytes": 5168, + "insts_sha256": "e8f42bb5b265fb51d50191844250afe8321ea7d2b735986fd882e62de8bcdea4", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": false, + "compile_seconds": 11.9 + }, + { + "xclbin": "bfp16/npu2_4col/gemm_bf16_M512K768N768.xclbin", + "insts": "bfp16/npu2_4col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 4, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 1292, + "xclbin_bytes": 90734, + "xclbin_sha256": "b91967c2a06d25291179ad748655e40300f5b7afb356c9bf272507f85c3001a9", + "insts_bytes": 5168, + "insts_sha256": "a5288db6688002b9b32f169e15ae32c473e1f05fa6090ba7764ebc87b0306118", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": false, + "compile_seconds": 12.8 + }, + { + "xclbin": "bfp16/npu2_1col/gemm_bf16_M512K384N384.xclbin", + "insts": "bfp16/npu2_1col/gemm_bf16_M512K384N384.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 1, + "M": 512, + "K": 384, + "N": 384, + "tile": { + "m": 32, + "k": 64, + "n": 48 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 24456, + "xclbin_sha256": "4a81b7e99e330c8a95f0c9dedc6224ff6d779bd65694b7b62ccb984db945948e", + "insts_bytes": 1304, + "insts_sha256": "cf1e307b8a68b83590126bfde26ea157530cd219c1867eb04867f5a2f4fb1a2b", + "bo_sizes_bytes": { + "A": 393216, + "B": 294912, + "C": 786432 + }, + "hardware_verified": false, + "compile_seconds": 9.1 + }, + { + "xclbin": "bfp16/npu2_1col/gemm_bf16_M512K512N512.xclbin", + "insts": "bfp16/npu2_1col/gemm_bf16_M512K512N512.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 1, + "M": 512, + "K": 512, + "N": 512, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 25608, + "xclbin_sha256": "fe666f21f7a0e09e69507096a37487fd50401a56abce51ae716a4d90715a48a4", + "insts_bytes": 1304, + "insts_sha256": "2382f2e853c9ba939466ab84acca02b3087ff261972eb62d38402a1f1d77a909", + "bo_sizes_bytes": { + "A": 524288, + "B": 524288, + "C": 1048576 + }, + "hardware_verified": false, + "compile_seconds": 10.2 + }, + { + "xclbin": "bfp16/npu2_1col/gemm_bf16_M512K768N768.xclbin", + "insts": "bfp16/npu2_1col/gemm_bf16_M512K768N768.insts.bin", + "arch": "npu2", + "dtype": "bfp16", + "n_aie_cols": 1, + "M": 512, + "K": 768, + "N": 768, + "tile": { + "m": 32, + "k": 64, + "n": 32 + }, + "mac_dims": [ + 8, + 8, + 8 + ], + "core_kernel": "MLIR_AIE", + "zero_kernel": "zero_f32", + "n_instr_words": 326, + "xclbin_bytes": 28424, + "xclbin_sha256": "6c3843f37343c3c3d110929c607ff6e6b2cf59a1849b8a3ec9ba1a7a875791f1", + "insts_bytes": 1304, + "insts_sha256": "6b4a2a790b460eb92efc46aaab6e2ddf080178d40e75affd1e9cfa0f0e9e0d17", + "bo_sizes_bytes": { + "A": 786432, + "B": 1179648, + "C": 1572864 + }, + "hardware_verified": false, + "compile_seconds": 9.9 + } + ] +} diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h12_s169.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h12_s169.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..787435a2b3833c3d7804c52fad7f4adba19e7326 GIT binary patch literal 4864 zcmbtW%WWGm5al|GA{Yi@AUWhrY1arVMX>pu_XZ z1Nm7YpPJ%Hp!|ORQzJy7qrlZR(>a1VzsvpdMvl-$y@@}o)%$ahd(Jb#%^h;T$J(T?=AnO;r)$e2yI@cMz z-mk|<;N^JaovhzctBnL?T(f?kqhF6fyo8nB;j(_gTmAmzDRRr`^zeGW9z*>`-gFpl zxSUALZn@tT@=2&>dJL*((eC_$cf-7NelsCx%jikYrT4~0GpLi@hoJIz51K6@ZReA-PLSN%eZ=YZ!xbnk3sdU zamzbezmwCN0XEBv^XvV34C2*z;H`dtE%ysv^~0t;hWaIB%e%FH^K!pW(XYp#x?;by zaDlh_JudePUhmgq5HH6g?_~XsT6(l(8Q1LoK1aVEL;c2c1m5cRUTBE6o7emG80t6j z?he;|KffTKnp2FiR*HN-f5gMDDLv5S(pDvgRo>aX-&;+S%;w*WyHK5dhrUKl6X!0{ z^gd|HRuieHEu%ZD>37sbS!l9On+xl7S7Pg+>1Z{L%g@N)sHtEq(exo`LOoseJ%@VY zwUh;wZ$ie=n2Qs!ms4mr$*Hkc;Xlm3`)wC4}R1tmW9rffj6%5gY zdOCqN)(Q2*u|_>rP5b4VP)}Y{!C0cHQBPNWU!b1!|Akk#oH)^hdOE%28|#Gk6UQ3$ zR5eYC)V+7FQB%QCqz+Auda9bTB6Vv*J^6Ji7=na)I=fD&Cyq7hscITe>8CyDt8vtm q*Hkc;Xp(x`f%v|Vr(sAl;~~V&81Gq^-yFyJW{e}^@|)v0fA|jwp7LS< literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h12_s169.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h12_s169.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..28460dc0636b01411f43dd860338ef16a33bf25f GIT binary patch literal 87038 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 Q;Z7g7oaQ-e^|k*03-kedW&i*H literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h12_s361.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h12_s361.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..e65ceb22ecca80e76d40d8f7e2bd304cc89b00e4 GIT binary patch literal 4864 zcmbtW%Z=MG5TzW)F%|(5AUWi)KzwikDM1Gp;=>lA09(i&QV0(zz(@sqNFjL~ku&oq zvQ1$Lm?BNh`;3N^(y-m_hm@WZ+Lx3toZDqcKgvkD`rmxXxNPb_o1Yl`e@jYR#FwUc zGPCaMA6xn6@4E~;!7G1q%b51??l_ER;MH}{d+>e>leLWDUEX8#TcTWRev9kCYktoz zAf=3153l->=(F_NHNTN}^nNFM76{Dv-Q_(+zl@O{>+>x@-YH& zQFvuN@}9ll@jX;&%NX7Di+v>b=o4ZL^&9sQc+KxiqY>_2UiQlv>NoPH%doZmOGiK# zFZQn#h5Ai|QR+&I#y?;1KIr~U>-Q0OA0#{45k}$FbDyy{0RGlu$&yrcI!eb8)S(8YU-ei@_Gl|0|LkHBkw`Hbu3WxtG3cx65Ep1t3Z zwnP{2Q}oLi>NoBq@S5L)mORqjmuK*@U&c_sk$3Xn8->kU#;_eESKmj^^?Re;*uu3! z+xPP)tb9-DvE6{{wyweLlr;l|FrwwU(^_s>eLGsn5>2K6jG1h3pi9niAPjC93Lp_NRb2F=Hno|3oTdpSw zTc{_~#OFX)o={J$sbZ|rv`|l`X;dSwlxPj`PVhu!!OB#K|0$NSwJkAmVC=kfmGA3Xc>Z~y=R literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h12_s361.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h12_s361.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..365be9a7bb5e3d05076b34d212041803d25040c2 GIT binary patch literal 88574 zcmeHQ4|G)3nZNJNBr_%{c>@6-A+ax$s8OeNk_-^iP$n>B1A+z;ZL0JnGhv1dJ7f*WThV}oktupXZ(ex{S;{R05tZdH?9mvJKC*0H87whZpTeq>jCm2;rj*6N= zn{KDz9t-vlMhByPz0|5#E2y<;_pZfSe0ntvWIlH<)ykW4G|0Kw_j$1Tvfmgd5ywKJTYtTjcr2d>3qtr$5W;uBUVxY$Dy8CY zs$OD=mP8lvLzN3ke{};P|A~L}&R)hMr-P0)V-7cK^Fieq(&Q;RX_f@gI40n~;r3c| zWYUFzL;(v;sWIE7y7X$5Nav~g54xPClPulI=+r0umm^G)<@%Z=q*}BKq%DsG$k9uz zm3IXgdu_Q*A!!deggQ==ocqhdfD*nB4nTVe;Ma!sNs67bX{u6((o? zqOjnae<~EoutfHr6cWGqE!;t#3)xlTutA>eJ2m+Y$Zt&!w+T&O980+Dj{nJ7L&(Uz zzrRh$C5amkJM3gNq9!9dCz3;{LXBTJ8B%vMk626Qkj)*}kRSL+@|#!C-eL9$WK2N+ z$5IX=C&gI-a#(agKYYkRCU%$3nZ75XTT*YyS?^e3QoZ2$=}C!5N!L3@YkL%Z?@Z3J zpTpK}*e1UTTdfB~Z=Lpo?ZcnD{bPj09~1mJzFP!!JY_)#I2&L6V%g zW5%e~8+GjdlzzxF9)b^P!>_ND2v$J#HYxe5tuwX>{x*!FG;fAAqUI>=@mnLBE8m)O z$oFG%=$C1~^m%EUK$^6DT6X+INpq#zjMgr;|}>}zjeq9#vJmKZ=o0e<&bYZ=8#vt z;*hI;>5yH&aLA-m9UY>syNO9cFn*FU_k=+7@e7dMWcPtU|DtN_!vv#=&+i|coTTft znbf)bw*eZt`rSHL^C+N^@4q`NDSO9-#Dh;dipAmhGxy#-vSsgHhpl7y@Z|oy=B>YY z2CWXq7mPWEH1eD((K$J_nX{5BAETua27aDPuS5Pae?`V*PFS~52j-CXPE@&q_q;6yLp=7MU z8}ip}9BW8+c)g*3UccXHZ#a$;;Xd773dpWP)gCn!DyjYh$&T%=ayM;{(w``O@OO}M z@<_sE6LV9;ZRAaoNIbmV(M(3$Y?b#Y0(pvz#ydt1`vvkYm{sOtgdV>CciXSphx)h_ zqWpYZ6R}Hu?rkaA@%@=%tYfa&actU=hFR%?Ey;DxoaEO_bB=5|u=(Jl@;fDq@bsO0 z|DNxEzE0}cgt}d|&WTj$vQa7htboJZ;|JrFzS8)}uGw+V({h`wwIp6yIr~Uk^WcMv zk96EP^qBw18#S>PIv&Wa9KJIY63RA2PF_Vq2mI?J1G8q>2ff)&mT$RYeQ4l&{f{3El|`bFN?%TB%RSwZkzGQlEUzo# zd72n}#XXh9@saNq$4|}%hedP#(s|17TK4Qly8r3xr%~f8-#P9fH-oLc{vUcg!p&f7 zZz@H8g7MMV3TbQ!A&o21U@8QrA_LzOo4`{OIBEhv*zpdFBiQN6OY`JMOY-FM%kt&& zlKeG9c{+4b9Fgs$qPQK=#X9VTR34zqS;}Gcj#Qt}Hx#9}%G*V{l57;l}+jV|W9v}0=ouyOf zR42C69ilR3mnl*>}yZuy+J$d)SX;mw2zB zwl|&5R76NGc~&al^f0@Ytdd_|PiBV}*}LA@34Eu0wrZAPNk}ablHFxB+Jpl@tveYD0nZnY-?iX-B(_kAU9Xn{PN06 z*K8&7r6pjH?Hx`ym3csD%dNH?yC5b@r%T5h_KfUoLVVgq`HFo34AJv=vUr|!{PH{f zuBN!lDIdA~PBGyKEwmFYE~3VzwIk2+<15hqEdqU%nQc>*1c{(754UC__Z@3=|g+qQ|F zM3#M}wRD%E_coiL>P^C%w^H4>-wa)>n1$!aF{9gAV&l54W!%tGeQJDw}jxUuu?BuwR z`{XyAw7nfExk%LK8}?_#X`U=cSO4qZkZI(~yfi(7;<+)c>@#AjX!7;nh)i>2hR8|XJSzxuPA3a@E&9$0zQLloupae3F*=yx_ei$>c>Qxo=xwUF$4_H+>P zBEff353QG`60C^Qasub^`ObMl!tUSKMmj3}f^z8}3UZEbc?FwMa%QQJoQr=C+6A1q zfB04R5#iDO&zF1V9NzyEd>-1rRT++V?As=l=l74?ATq;I))Ri<0YKF?KmBOOAM7Y z#U!=Fh@<`=w|RECbq**6BxpcBy&p(lUI}$)&+@FA-czQyq^4aNntYg zGH3D%{L3xDy~K&tQ*m-ao_!F%SNs^iSK!xy1rOo(ioN)~;z|5o@jd)r@g4kL@fd!u zcqHrhijhg8|2~(f^sBo;vUs25xvEHbeNxUlEG4fVmgKyYl>F>_5`IG&$8RWk#Fg}6 zE&H}fo@=`4Z<=CCqQ8RRcMc(Ohv&0z3l&7QDtQlei3|IOpZ?}->=&akgeKCRBKh!( zg<>rIL)(aBBDwAl4v%Q}+vt9d{RegQ{fO?blnr{x3-Du|dC9w8%!-Hp{z88*eO^C9 z`G4xgUcfKT0B3+Rz!~5Sa0WO7oB_@NXMi)n8Q=_X1~>zp0nPwtfHS}u;0$mEI0Kvk z&cH{90X7eTMn!ca55drlJOo2G@(>K2DCJps4P{w*4VgN5HB)yox=XPBliZp44Q`&_ z!1EjEw7ZCz9z4In?^h|+KX`rv&u`%Q4LrZ$&yxqj^BZ`61J7?Tp2t(q572TwKD_mL zegn^Mc!TFR@cagz-@x-5cz(lQTqX$5Z}>3fHz?MRsm76z-#G)E0nPwtfHS}u;0$mE zI0Kvk&H!hCGr$?(3~&ZG1DpZQ0B3+Rz!~5Sa0WO7A7Tcy{01%GfQF&vH)QHYK7vth zUZ@b{{ZxD>XN39*i`1>39`x`!l?~~y94LrYr=Qr^8HyH0r;O}qX?{DDm zZ}`i3(*@6O_%P)+G;7}l_$Oz8Gr$?(3~&ZG1DpZQ0B3+Rz!~5Sa0WO7oB_@NXMi)n z8Q=_X1~>zp0nPwt;3L8Sn~y+4V)GFU-N;8UbR!?Z(224nE5D&3E59LAC$DDePDVd} ze#2s(-@xDBK&KtgZ{Yb2JimeGH}L!hp5MUp8~k`6>VNP07=1X>i|04+{05%iK=QwI zpG{v6+4(!Nl9i@541X@ap z#nHo?_b>Mn@^#uSO1}GoS~9Zb)Tp$7Gir?FoaXrrJimeGH}L$1wfy}J{QV95{SAe6 zK_XR%?y()OC%;`%n9RM*nY;r3a!YV8ae9bSadJYQeb6C~|JWh_>=}o=;30?nafWEq(xgg&o-;7e5c)zd+;c%S6Csz`W! zQqDUpC9fWqzp0nPwt zfHS}u;0$mEI0Kvk&H!hCGr$?(3~&ZG1DpZQz(<4uEx$p_H=rSD`3;%6k&j@M8~F%^ zPL!Ig{D!Km{Dw@Oyqc*y8U6hE4b?oqf#)~SX~**$czy%VZ{Yb2JimeGH}L!hKOTrY zzhPD?pOA^|^)lY^Rhb7$YKb7X+H&lIm@J(x9dFn(va^Z#|I-x``@(7beQ=yzlg0C- z@2Azp0nPwtfHS}u;0$mEI0Kvk&H!hCGr$?( z3~&ZMLJVm64O+ed4NJ>!$kdH|1f$%@M=*4vlxO8Plx5{NWa{MAOx?-o=g)6&^ZW*$ z-$17w&u`%Q4LrYr=Qr^D2A4LrYr=Qr^D2Azp0nPwtfHS}u;0$mEI0Kvk&H!hCGr$?(3~&ZG1DpZQ z0B3+Rz!~5Sa0Wg)3~2ccTD}2|O3QD^)Qx-uquj_xpt=k1d8c*o4hK=B_31xGr#3bL zXu66Psj|e#3L|?N+0V$$jNHM@(xDc&B!B+oMPlLMn1~OXe(~X!& zx{Qg>k`)H`GP0kMn;E%-kz|2Tk%yf@maEx zwq!3O`x&{JkvkYU#>fdq-oePb8F_?}Q;a;u$VVADt;_oQ%Zjf&E50%&K1){8mh5F@ zKO;9Yat9;F7&*bnI~aL4Babk0ijl_{`6wf&8QG7$MnD8~uWV-aAjL1xKSi$MUPks~ z?OOKMenS`=iIM$S3zogLX5k-ykKFWc%6`l(%f5k{sC|Hc(+2)c8U1JMtvLn%>R*$j zaiRaFjQ%tBWvqYG2L4T1VfgVf{B-yQyV188BP$F)US`kpGd9hPtT6m|nLPyl&3zsI zO<7_1@iJ=?{!JVBH)ZtSj2Hbk@n6-;@c%o5b)2|E3N6n=)Z|lNjFM-;4$RO&R?sRHO3;{kL$&2L3Ia z;SK#)ahKM-D(7fZmXI-&3H|~VWIm34+@59PQwmf4|GS>5-t$_k)UGHDq-htZ4Lx&-=3|9-2wBoQCDno@kQ zpHh5P7l=||?gYM+kQDV#G+dKU*vMSr0btp|It*%{S4j;+=|_@w*$xFMYWe1dmnK85pESPVels4Gjx0f zgFAuG)bUmZm(%Jy6ZL-9nEfmQZuQ5)?ZBxXC$#m!!*?7|Tun3UISO z;}*UGxHShX9Bayoi?Oc&&a4sBzaO~SPsSc=O0?#l<-Z=d$pd5W0d9@8Wsfx_GHc3g zS4r0}{j4!@tTiSs3vU8$wQJ#6YZjm57G4Q_mOd_R3|;};ip#Rc8f504h0EzBB3@Oc zj<08YiP_I4;1+KdUJu-w!xmnYZeiAJi@9d)z^(pRxD&Y5e+$Rjw43vG+-7IirrqkN zg<}oct#PsNO5n^IH2o;Rt^Ql~c#hbuep)!zvYlC*rXN3WYuqh+tXVs=W~sfgX6?+H zwKHqh^occSH|Kyb$Heh`v0`CxtW7(!Hck6_;3ij$J=UOwkC&VFSUWToRGkBOzL@_BbSdYy7v~VAAt8W&L zbRFiTDd>LFUd*a5>cxh= zm{niQs&CJ#Z_lc4&#G@{>!W|US>?G|<<6{fXI6P$R(YOL?n0<)%=qs%5UuZXiuw#^ zboCj*=;}F-(Y1GXQy-c??QdOConC?F8`ZmjL8R9K?M8Mq2&xamj^2|xwj1{kdd+IT zq*#2RasQV;-|^DuxcpS9gRf8{c3&HGu%XPLx;TaTDQ^{i424Xsp5tIuD*f68!SWvS}bd= z@u6t%;5=XZ;5qvc?Hw5GKU)_N5$ytQXYT?!^v89fvn$xITz$?C^q#W^2$J@o+UkLi zC86p&#KmDX6hJkTD8XXyA{dV7M>3_S_7F`q0ohTSp^j9e}DO z7prv;e9qSAo}=~ZixxZBJ!k9l&ei%wiydK{v-SDsXuakG#ZIStu(vbJ>_c=LV)lso zYqibA*fr{}wKlT)Ypp%5{#tAMgKTVz#!ip31@>m)l1cqCcDy<&pvkE|4|4Urp4Ovn z*r=di^bllRICGd6tz%rYKkP-12}WN(sK1NlhxU&i%;}{*#8t`gPER$2G~LkBs>1q* zX_qol)vjfA!%7o@(6(g7;$_#juUxiz^$n}r0}ZVW?Jcbht6Mj@2RggLJ;8SU(dVw) z%$OEP&ZiT^*^J zAD$QV>K95|qdno4!C+4e#Z~ib=gs%}=FRt^pfRk@uho4$tO=c@H)%&WR9G_vN7bLC zx2m}~&w1P{>4AsNUyplP?_jt;66_4$c%$05(dfDEsM4$-_ikEz{Y~%!q^+}iakN+W z5L)1i%nPm!*7~YzeZJ1lDqmG~_599xK5tE^rlx8h>;vJ@&^pwhwXuW-aFE22t=(Em z*F}5RqLA8NkAot_o^VfVU#zdYZ{5cBo?sLO+OZ2o-gtGGhC+{Bsyeq8S}eG+yDtbY zSjXX>_CdX}s<(Ic4fPJfmM+qsc3Mu4l;|46Xx0w&@%d^2gccF0Qc<|7_j;9d=553z6@S{oiJslerI2A zFI`>3(ZP+GgwVA`>Cwvjuof}-@vW#GOD`NpFHOcYI!#=i?)r)`!76oLv(;-<|K@0z zmS?R_pQM?s)6K1?{ZFnw_k&f}$oZ37r{gu1&R<~otIs$73o^!k0p*Pu|8@O+Losud z&zuES+78I40bRpqOv3-?X^^!9_yYWkS%Azz1nY}=L{|AatIzv5(iY%f-Ra}@vwY85 IdVS!30lQ{K6#xJL literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h12_s81.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h12_s81.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d117a37e818f8658ca9f04d8bd20ab09103b1658 GIT binary patch literal 4864 zcmbtWJ8s-C5T%^WW?>kJfuu-bAY1qVKEf7Tr1TL~_z)>KfDhm!q)3s{M_`cyEK;R( zkpuV$c{3vC7uuq10xOX_ocAGzlG3nRZ-$g^6WWKA(4E?GNLSQ5D`UN7bWh6gEZo9(?Ee&;+A)7{dz-PyqD3h$4J#L zxemPQmjc={y0d=4D}FfDV-PRLBk#`o9XYdJGCH%o`{;M9>C^q9>@NXXzu;BBevLAw z_V9YY9wUL5f<8;fo&H4qe_vbDa!M)7G}KkaaDKtNVO~-_nuPxIyKz|_gX&r0cAdA@@1sM= z7*(xLKCdpLUynh&vL1m~{eFEBulV6?k0E{==U4Z4E4xGx8NXS-`{>tWP+c(wU98`o z-QPO|wPkdBc)eebLA)G~yrbRU>*aoNj#!&ydJOR!&k=Zae}Af3^t$|l*ZcJt;y3c9 z|DtR~bGpZbGd3t^?R;ePn_1MC)M<*g3#;IgnIIt3dRymje1f| z+vVpS_2e}bjH(IsG%aCcols94Yt)l!x?Zjc_2e}bj3t^H_4KOm3)GXmUwG#aldq}? z^~CYiSSLK6IM%2q)pWmnols9+Q^8oGsZmd=$-iT}Y8>_CH5H7i3H8MB);gh{IM%2q z)#TrUU7Ao&UQ@wXqN&!?0h@o0AGcvh2Xvkp4 B^4b6Z literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h12_s81.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h12_s81.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..2563b756ccaab34202a892c9eae09495e7fc5b16 GIT binary patch literal 92702 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h6_s169.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h6_s169.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d433a723b42b60f5a576a2ce72dbef98244e0c0a GIT binary patch literal 86654 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%0D;)90861M}Q;15#R`L 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h6_s361.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h6_s361.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f4850c7e572ef66e2d8298f761283fa9b25a20a7 GIT binary patch literal 2440 zcmb7EK~BUl40M)iRaQuF;J{%e_P_&p!V2+_J@Aln<5_vaiWl${#%^rKp}P%{nkKb9 zV~>+k8n$C1dLyE*TOusyaZdEgE1Al-`IYh7lrNi4EdII>4T$Gqc(U{9@!Ks=wcj~y z1&=?*k+JRJ-NvxE1FzX@-a}n4Gx^9^uJXRL^>S1-_N88~y5aSDPgMX>#;%9g>XGP^ z%r=2n>@6>y)5iKcc`p!{@vQQqzv5$&5rd$!VuX6ZJ6eC4$w$UgW3HX6(L=D}sA_=M z?2XP|?@?(aFk{va7kSZN@v(X%20>@DH@sf&!J?VCm)GjyAc`2wD|SY%d7<-Q{iPcT zEmOvOwO;ghV1LgzU~qrM&OQzA&iXrfG~6x~$!v)LP7ulMKw^@7*xk)k68^NPLg@3H=0xmvu+cvkCuFaIlbg*51qtE9jRbw zPNe_2Wt}uO&DydV%Mux_gb}bQD`{oRs)$$iT9q9eWJ?eQNTpqQ*IHXY zi~hRC#jG8Y5aNI#kc=B>ObDqHl2imtjcLjnJ3-};Ml|LW&IueF90DypS=m6<5~F@^ zexKHV5hiU&-khVId+)pNzIVU(?wdDb-N?rEC)&DSb)8GDcW9KEavn{&}K`zd{(cZTHM1N2JhRq$l;kZ_E zMAQ}94Lt?tM0j8*J{0foqgs7>L7hWCzY)~^GpgxA=2r>n<;^*|(9M*wWcNy4&urK1 zC#ys0w4t}!C|HoKVDQo^-QGP0Uwj6=J%*myuIY!US4S<2a8eV^SGTsYrYya*CDrs= z*EO!OBnGjMo(%wQxn378@#|+37uwpGF8WY@slD4UM(Gd5nr-A|kf9o{=eEC!UGv6~PAfw#EsCTN!)><6MtYj`+)VPa1Ajx?vqlPZI3DeY z_l7q_?dl~qX;UW3@|p>6I#x&Qt9Vyqv|8EZ)uV)F%DQ5vEAJ5tD>ei%x;m<&h9M za)BLr3xU|Hs~if+_{bsDaTB%n`9k%Y7YfzV-xR9DFBPhLj~1%$yjiH;f1*&ma;#9D z`?JD=%bzTCkP(UOJt3rC_!Z27t_AHWaXCRx^`D&jCg?Y(M%snuFO8=>PS7>yTa+(&dbTPNN%g#KwzfynTBEwoGw3=^UG-bg)q6mU)@eW3 zKKy^Tf0U5qLqaeoaJ`_7pG=7K`$ZyqEcQ#JdIGa1Ow_qM=lEKLlXToZNFU@m_s!X# zls5hP5{Y28SKlhBzuZ3ORw3Ae5tJ6qu}9Myp*=x+G;`$}F*rEnyD&LO=>4S=Q@7AM zvg@a)4;$Zq8fUjh{Tj{-ogVe#WfH6h&9xeH!sDDJ?>ga<=l{kfPrT`ppZ}FhUNYvA zA35rh?|RuK-}sVCUi*Seu6o`jdw%AUNu`E1(c)%uiV%#4q|_c4h%p`^vYYHa5E@uo zjUEw<4t{@laB7OiSqrK6C^tbgdf7Ym9{+xbMt}Iuh@|YD5K{L(;wlzLl26=m+vv8v zdtHvsk+G?Lc`e&tcml1CB$rIYJ5yKQ=ORJqB%ZxEHTMD6KjwfQ%R9QQ_90glA~5=; zzh3u`@BG+xzXSRg`0jh8^q}kZTh0uOw<`LCrDO_o1^=X)i2%^bOZn zTq8;8(2KX+G4Czc9UHce=e}Q9?-p{)F3deN1^+PL-bxl2{@w8I!J5de^_!(o`z^El zkrXW-KLDFX`Tnt6p1}HrSPt!e6Aq$WN>NW~Iaxt@YA-VCDX*Yfl;7DX3t#a#G#)(( zsUC30eWZSK%ON#U;Ex3BH;*@}oqm5LWYixp+Z#!uM7Yz?mqN0qP}4_Eg;JXRklMM! zQ|_hhQTS7(_x=~CoIH~9IK$ASWR2goY5 z7@_;``mY_AK92f06r%iMLMJhcKKquWcK&d#nCPq(JCDvf+&C{&uua|I&QZTnnsa#D zfvpE0l;18{imT_;d$<4abM;bi3+i^)xhK<+i}p+7PYT$KJ$x`(87NJT?wX(UJtnt1 z+Dej@mGcj`w+!98>~QBb!w&@yzh0C0N#{Mel_Q^zM1-(qgq(QQCDQr+$fQ7O-gXHzKCwQX z(APJTp7Je7A&TlfZ%v87KHSNLav zda>AP;Dhqyco61no*Jh-alG#%Thn4vz3|7iw90NVP%>B zh4~fE&M<8c>yhjc?+~>1aARfE1YYyf`Id$Gb!4sl;zlw*veeoA`rVM>?*3$t&VKrdxh+mxn< z*%zJT{LJxiYGX<9!z?(0Jui`@hVF($$8UjV;G#PHHUZ#`#>dRczb2I%@uv^2ZGX$--$i>yIo-dD6}d}^ z0yQUEM`_+sftHeDasSxXeXDRw_zl`Glzi_eTFL0PllvugD{749yuS**9P4TQ$?QmI z_x}J5F#-E&aH&JDx-8C?BW8M9O9^=_XZQBU9g{tJR8IB?@?-B1O@jFAL;QvRbLjOR zfjm}fN+U~e-PGg|h*omDfC{C+w;9rA=<3{iWjAcu{4tXYcArG0RnR$h`vsA2m7C?0$J>iT>65_4E}J}FT&&5p8FQ+f)dj}J zF*#e25#!yj&n^>Q6og_^z6!EeXDe84UKGeFQsuPLBjj|tyQfKMdxtMxCZtF*MdW?k zM64jPQ!w_=Z+l7VJC4b_i7W?7>*y*&&+QID~qh_};AM5FS z4;u6R!4hpe=zN^`^}n4Y+Fjzcs8=Yu%Sr5>a`mKB()iixNfCUAOaXD!pELdx2%|pi z)9Zn?pSRjG%Hf2BYv={=1;6?nEg_1ND3Fk{CC3_ta7$V}8N&K2cD1TOoBi$uS}Kk#D+bdppx|k!Z{}tj~(u+F9;j_pg6JW|2$sGIS4$>&C3I zPmAfIsn`Bp#CmbWqwlXP_vKjg)#~r5@vrp*<C_7mmy5{0S)Z9 zNpmySi1nbHd-ik^@(jT}rjORkPzqW^X+4hp_+s}WA>|A{-cC9zgMxD5ZwqpcZF?Du zkvg|jP;2pbuT#K&`$u2%9u^+l_jI{$!Pvf^;`h+L?aD~9^YL4y^8A6(FL?J4v^dF^ z)#C+a*rkgNZ`2QbZu!>Ey9UH>H+_=4@#h0yU5+(4`Q`wy2UD}~~uPgs!jhp=nEZGQ66@#1#Ja|_xX6>{Y0s*SNnW$c14!|uDq899m_ zt?N1LzMa?|e_M={wP4SyIwB9y-E#|xl-+^d`D!8Zz%1;Fv5Tg=?-MHY!`Pia2Y!1` ztmb*_@*LO?SD^mosK3h**|rgT=C!DQCwAvI2$5~5?+EDi2X|@pV~;+s)o*hBQm^j{ zh}S((9bf#7Csvf_zI45!-w>wrTh#ys?^6y>w%&AU z5xwI(UsJzRQmE!$4sp{~(@M{20$G@N{6weRy867tbpm!SjkA z;CaP&@x0<8Jg;~l>v_fK6#m^pd)}6+3~H-^TKu@=yR=AnZA#7?lhn&bBsniFsh@dQ z3cddno~Foo#G?if%Yj=Z-{n2@nWUJO=u;3p=MYl2_&)QNP(d`Ul6O&;c(8s1=`&+< zz1W|CYa(4K)cc<)6cd>rIYwQR>W1ICe4;bxpzAr-AJj3{Bf7p)H0U8O(Vy=a+^%P` z{GrcZ==08}jXhNGSwGeSesBah0vrL307rl$z!BgGa0EC490861M}Q;15#R`L1ULd5 z0geDifFr;W;0SO8{&)~z^9ZO{lsEGTOy0~RFnKeNz~qTio|TtSmX((eu9~O@d1(G`3XEff#)ai`~;q#@cYQ);Q0wWKY`~b(48?oX8!;C z^;`|T_D8Wk&rjg_39s|~1fHM3^AmV}0?$wQgUjUL`3WDT`~<~*7;0__`I#fY5#R`L z1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$@DWBp&ri_v1*jW( ze!_I#%qK9*&3por$J+q$-a!4(?XA_nnE;V)Z#qw2na;Zz{_Ob)>*&`2`1cbusQLF3 zKG>Heczy!UPvH3pJU@ZwC-D3P{{4j0eHQ`$FW&mng8mf){`~}fcl)Q8Z!pt*37((8 z^AmV}0{?!3`Mm=E{RIB~1pfVmKb$X3@ce|2Qhq{h%@Mq6YSjO`cKHyga@P7_fai0Ev^Fw4zbP@a>a*^44QVZ$V z>h(jN_qNL*wUb)#^lViklInT;Jil6SruL5#l6*)A<^+uQZOVj5wCUepPk4R;&rjg_ z2|Pc6=O^&|1fHM3^Ap(p4$nWBX+A=>KF?3!`3XEff#)ai{Dk%V`w9H}3Hp@*{g)@?DR( zL z>Aaia&z_&)<@pIbKY`~beC=sTUFh_v7cY};6@o$HrjbYw)#IEc?>ga<=l=%pBYYF@ zBm5QKM>vM}5gx_+2w%qg2w%ec2zh=2&rjg_2|Pc6=O^&|1fHLuUpe((o}Vz&e1vR$ zo}a+;6L@|C&rjg_2|Pc6=O?uA`~;q#a31*y3cESwG)I6Vz!BgGa0EC490861M}Q;1 z5#R`L1ULd50geDifFr;W;0SO8I0762jsQpCBaeWdpP=UpP-pb~gz3DQPhggt`2>{r z;5+NI4!)rvinKocV|c3L5FpJ|(ISnO7+PUyKSKu@x`m-T89KqxDTdz3(7PFWl%dlM zJFnxLF@jtPRl7Fiq6~qt)-+fem1RSY}(JzL56N&=uU=CFm#HccQW*Dh8|_;G((Rw z^bv;67_{!+@+|*!-t>uN8X5m=T4CgVh7K}x3qyA@bb_H%484<~cQf=TL#G*foS}~} zbjF~Kc+2vyM&oV&su=%lTFKb7pP_>c-NMkF44q);6hrT1=-muG%Ft4mfVyzM2 z0bMIwm^DZV3VG%j`WZTi*tPZT^@cDy5<>?O3%0%;v#_sax6pQB-=c${`1qMMFUaV$ zFtozp<7d_o*tgbo*tckf!NA=24 zD~vCGh9(Sd5`!CIbR>o*3~myG8|+)Yz`jKj1~-Yp4fZV^*tclH;3hG+!M^1S>{~SY zPbf#{5BhJ*86DWSeXMlF-M{H&1?IQ3H2>_fQ~hh4p?}by zk$;Wn@DKKI=>F-nVEL!7ow|S1%L-m;WX8`fJJr9nGxQJoGxBfkIsAh?%RimA{aee- z&*^0audHSKv&&BPuS}fT{Dl6D{3{dB5r5j6q>mqLGuJ8{8{x* z^$+(uGmF0&`d4)h|MdGU-9MeS{nPgvx_{Hl5Pyt+)61lcgUli%MPs;b0{46dT?9Fj zhBbKuBM(5HW9l&SI>;|Dr>&4~)DhqvhIb`p$`R%f1Xb{-dcT4>IyL$Zg+keJAADylDC| zqaT1AFVWWIC5*fo@;QclH6wRJKG%@9F>*PheY4Q$XN}d*BFOFj*m5W2_E^~R5aifk zYIZ6oY`GiqB17K7$QvM^WA)S4U!7S_DQdi5`OvP1y3)kX!SCkz-DZHV(Fa2y(kWw!8sy8wXqNhkUltZZl&ab68~N zFzshro6pA`qB(~v$O6$CBVmE%OC{u%kBl61US#IHrH{ESGIQIK2O-DCL&L|<*r|iu z8f!-GgWSTLk(Xr386V3n`wHY%e{VOSoVXETm5A85mTZ) z_iXzOkXtw~`aa0*v9|RQQz8>nR=Y~3hUsUGB}c3=e%bP7$nAD*IbzMmbHbKaLO#zJ zmv%;80lDp$t&bRF=AJE=Gt0$%!;Wuaxz*2R$Zgzgc?0D39Jb{}nN}udTdkONLT>lR zmb)Rh`)|t;n@(%qPB@%QY&z|J+H%C8(;gRFUI{r9gO(iya=ZVwKCUB9yPvikvFv1G z)3OtU+#YvZA2I7>VwUQgG3#Vv*2%=IWfL*zwB~@Yz>?$oV*A3#5t~jXHZA=I$StfG zeZ-(GpD4HV5j!*$REu$3Uo3eDax0b@Ij%cSdv4hJh!MM=jDAI?m6=Pe)*SOgZriuz z7`t3%Owl#HZxxU;V`|AUrn$_RT5^nOE;FW<+y^-`rj{IIn#+u-CC8ZNGGj{R=9uQ1 zW9rY;FuvDV7$P2-`Dx1oklTH;<%nx$ezJ0ho52Lr#KOeQU}DLEiJQU1lEZhm-LAuu z!$&vcBbA#zx=kM|Gs_uYmRmkze%j+AEU<9HJj`Y0p(V%uB-bAIa!ZbRW!sss<-jo4 zo^LglKCoiu2`hKxF<7Chg;gGdl_iJod5rH=Zu*`_eW!a{XGS1?6ku)A?$aor1|2kb z0-n%2bfBW`g(;r~AGGwvtoou+Z0d_y^~J3E&aC>*toqKZ`cAe!`j?wko|{$f&MJ3j zmFH!Z=b7amxT^V#f42c?-_I%9HJstKYXrk<`#gr%znx8O==St?RZ*TEp_Xg3vw%UQ z#{vCB=rbF$T`HoqY{<-KL5AuFIz8)p;@H?T%kKPf_~*gDys5k`xKtqHMmv>g=X{Tb zrODnNWh6Q<81L`9(p&Xsey*`-0@7r*tcX%lFi8}AnPv$iw2KqNfyM{iQrzj1H zp72ntf1sB#VAn@S;$2al0o&C-U@>4fMF;w#JxX7=H+rRa&FYowIvQ85@G3pwz750S z4Ulztm7&cE5bG1eUek(ZIGP-a_N|Yu|HS(6P*_26hi_FccdjKbC5321R1XvKN&IJOrZ4hdz&jLcEAGS^%1p|T_y93ik zp$ZNBZV-(0$Jd`3fk;0ZI%Df-x z9oj#-F{g)i5!WcwI^ER}(tLGmn8BATfDvDjr{}OdaS-aZ*RO$qy3;0;i0Z>$o<}% zectY9czqOFTfA$+8{%CMC%bwg@xE#(w#GN~g@=X*qN}5Q8-{3=m~o)+Q_;=KdiuLI zF;cUXpZ~NFz-+jtFMi{2bY%#$A+k7Hw>Y{e>^BaSw#9p+twZ771d6K`*DYG?ulD;F zqo66O&98O+y{rnIq}S?OI8?Y{7>26FuE9bW7>2 zzaGjRbi0DGH7nM1gs^&OD#L?O+97Qv=%71+Pc74$s-ie)8bjd?kkDmGVu8Hu#P+UVFsP;k5z*CD|d$8k)j-K%5{$UI+1=<{GedJJh>Oik- z>1b)~_|%GZSFKo$#(F!9n+6OU?(#H=eOJKt(-ORef>in+T@{S^ri>O z*?R!*&F2^}8tG?3qiY(jfi9>rQ@^Xfua8F8NPKAXbU25@fC9KlsHCw$#vu}-trFq)w^h!Ft^}zX6uRXu&IyfJ=^K`s=JAU`- z=NSI#vy6WjH(*SRE}^(Fh={@~N{xTaNiO&?fw;lkop|8f1k455V6&g0i6d kumh0Uh# literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h6_s81.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h6_s81.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1cca8f517a7566dac832d59a53343b048ed43232 GIT binary patch literal 2440 zcmbVMK~4iP40Ot>TB=HL;J^V14m^M-AjE-Z?14vcEH{pQQl3!pl0Jd4H@4%j?XDWB zjkAtD<8cy7-MUXiZ$$KSO$2isheR)IZOhuH40BbMt8W;xuYAy{Lp%@5r;ak;{krGA z-giiA$+vC-h%&w`!Tldur2?+`Yuu;0-dNBg+~>C5n1dcly-Dn3M}|3DFL13M z35_`zSNtt59nwlDa(@Sj)V~a478m`MJ=VoR!^asqYmQJaaC_@-)F>lTW6qtcJ|M*$ z1YGksI(xnQkYN!nbdL4L9IUhX8(gpV<04$EN1|g6#ufiWe>;(e`^y#j$S{}a+;NEY zm!qlyoyE_e>Uz=Njo|XB8`x_j!&-v7u?RMXu;TujzsAM=^?HvXCSx^=i~h!XV-D8Y z{0*+x`*jhn)g#d{2jhyr?eA;-UIkd`_H4cH<-O94n&L_geV=de;gRS;zhmx-53##i zi=pNuhrog|EQLCGw?A7>C5LkA&v4onANB@L(8=%pV0_rf_|0;HPO?Wg>UmU7r0?9c zP8u6HK_}<5XDT)_EQLC!lja=*OAh4(oyHs!oS>8VCUo-q!z_Gcn6sRqliUy8sBeyP zf==UmF~JGvNn=}`oYT<>!CJ%#=SlO9!6k=sf=(wnK_~I4PCI0{9kbw3Ow_ECuW?g@ NU)Gf$3I)Hc(;wi1aB=_u literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h6_s81.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h6_s81.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..b8347e8bf6a1c87201d3bab4982880c1e7ad1d79 GIT binary patch literal 92414 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h8_s169.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h8_s169.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..69b8f2c8b461aa2d33f363b63243700ba7ce9888 GIT binary patch literal 3248 zcmb7F%WdQ^45cQRi(b~*@Vee; zymU!B>n}6;$e1qbMSo?F^^LQt0iP8k=mqbs^|!AQh%#21bM3jh z4Ox9y5qK@$`0RR5Ry8MQ9E-f@Z`2zxxW5)}cwO&brn8YTTf=L5Br{?#uf!+%+gX2y z?RwGQj`=JzVzAE==RLJv^!I4}%^bCnF`SmZ^2 zquz+YK3lxub-n+X&PK*;4X^2u%!t9f5})Yr-uio18bMga3!nGA+nkCR++T_Fo?0*Z zduRPUSvGIWIJA&!@9!ONwh=Ly*WxuV`s;e%l}1o9&U#~(7yXTTBL@3y@rKv+zHZkG zUehDhMhxbac-!A|{XddKJ7vrk^}dwHF2HNmIxe=t!Ko+r(1ee#;V zw$}uo6nFHgU}#P7X|^W#B(Vvf{5x|twTz!}=#AOl!6*5S=te3SS`&PdI8FPcxvfuL z)4L(Bt_eOVF6R&x46O-1&DI2;B&I$MNWW(c9x2g)OSMkEMn6Mb)>RxjLR{8W9E>3@ G>+}t|6`3^v literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h8_s169.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h8_s169.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..c68dacd39aa0b12605da8d8520ae4fe224aff8bf GIT binary patch literal 113838 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 W@9jvRfdA!oAKyC5bJmg@1OFfMMQw=y literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h8_s361.insts.bin b/cpp/external/ryzenai_artifacts/ops/attn_h8_s361.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..ce6dab1aa8138666f4f05cdbf03d5c07cdbc0231 GIT binary patch literal 3248 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 K9E<^%_3#a8$Cd2> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/attn_h8_s81.xclbin b/cpp/external/ryzenai_artifacts/ops/attn_h8_s81.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..7aa6343827f96bcd96733569313afb0215ffdfe5 GIT binary patch literal 121518 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 D`CO3& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_1536x1024.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_1536x1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9d6ecb62ea454ba99302244522a1ae4c2854f869 GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_1536x192.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_1536x192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..8f46999144b46227d37560c292f8e31942eab1b5 GIT binary patch literal 3248 zcmb7G%S{6@5S4Xv}!6iggKqFOCmIofm#1Z^U4~ zRZ^U4~w&I=_ehcpd)7h2KI?4;bkvC$nU#ojw_+7}pTpOP@x_IGt zp%Yqn__ey{h2O&aY-uq>!l%ct;qoMk80=T-jO=;g_saafDUBc`eCrQ~p64qWtzQv? z*VpQv7k&%xXEN;)UO9ognv!!G5h?`7OME7apRE7k&*_CPxhREA`s% zTYeAH+EYrqi}yXh2lc^M6njGT{mbX)6VXZs;6COW=5BlzpI%ekmkHC9YVRKVsx@T{ z)wDREX_;#n8#Ey&d4EbyanE*XLQbMv#Z$&mO{DMbc1}7sXhKd!Q{2y8nvj#?B34`( zLp33%Np3?Ea*|pjCwcEmPI0d%Fid#3Z_$x`hP%IzlN>TSkTQm9LQc~m)X;?IN$1u% z6;1IRNZ?kgy_%4d;!aXChH64ido>{^sWozv_qF5{&xkHf$Vm<-6;ByMH6f?z@M`Cz zbL*Unrg(mIX+lnlJLQxyR1^1+;dVm7pTB{s{!scj(L!DNu8xF4UHYyL J#!#33@DG_GoJ{}# literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_1536x192.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_1536x192.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..5ecb97e7c8f437ea318efb703005f68492d96a9d GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_1536x256.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_1536x256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..ab4eed40c1e34a30c344d661ca2d1984675a6dd4 GIT binary patch literal 3248 zcmb7_L6X!k3`Lcut7)dXhFQ#l#ZC0ikl8&@T^ zBkOyIy z-&5$-KyQWN)MwuBNmD{^#!$T$*EJ(AdOPonMxzx*Q(p9D-i)DoBR=w?_iTEv!RLd* zV9JZ$%@^$HwMTEnM_%-H-Zk9Pq{21jMQ`A0l4K0kYjH&$dC~jO^}eyxb}RH#Ui3bU zNg@eD-*3c6Ui5a}H9mQTDqK@u^aidbNybpU7T?i(>3Z!Guyk&PYs!n>%}$XpRByyL zdOPp>);YB=TvJ~32CgPa#!$T$-_iTn^}e&zb}RH#Ui3bWNg@eD^+tT7xAU&)Ro%sl z-oQ2fjG=lhzSaBH&%tZ1npxqR>iyQvL0{-7@m2fz`<}>0k#So&wivnV=*4xcDgT#u z)%0UqQ^W9@&i|A(gijW8pH|YJ6hqsx$VxZNmp*4l UOL3bIaU4osi6sGxuj2s-3gg{r0Nt7X= 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 R`-96n?!L|^tbK=i{tq)1b|3%% literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_1536x384.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_1536x384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..9c300e69b6b22402e1c6d508255b16bd716fd74b GIT binary patch literal 3248 zcmbVOOL7x25bZHjE+?2kQ7l-bfJIiUID!`(f+Y(MGPwaq;RrfHDktJ~ORuFCn#>qg z*(15t@AZ45k7b&Vr%B|8i2ON=pqty%B;U|m{09akp?4^w!y`I6uWvK*wf&o(XMT9D zk&n&1FD>se&n@2x&rRNko;PC1ec@I1mRFvpgX@J4O-tx+@k9T@!*Qb3Y_|K7UZ#g+ie-o*>O zw@k2S#L)Na@lJ2$O}+#aBH=>=R`(I~I<6*3#8AB!ALu>1Ub(T<@|E!1hr- z^~BuXr&?1y2NJkRwOSK=B5p3VV6Z0mv|1B{UyRY+ly8fJjPj(5gc%Cz?2|ndZ zV(b%hd!K4e@%-596LGUo1%oxgr`4L^lf~%M0)%%N1%Lh~>BdtX<3tN_8#i${6yi2+ L;$RGM8&7`$lgpj` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_1536x384.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_1536x384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..acefa67abc35ca64af15084e8e7f5474a86716f3 GIT binary patch literal 40232 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 t-#SbJ~j{vSY^gC76@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x1024.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..895b49b66e564b04da0393696fd81c183bf33b39 GIT binary patch literal 3248 zcmbVOF>)I*48$on8jVNexJco`GgjdTgPDqAvW(9(Q$U1RTMyaU@;% zZMwOU1!Uau4EK9%1RTMyzd2DCew*&^lvA); z)P>)yn>pC8<53sSck6ziFV}_NEoZsk%)x#I=RHvuew*$qqdp3vHGZ>h=3u{$M_u^c ziC_BSf;CvB3%|QQF|Og)@u&;GK^F%~8wKGSzs{?viG%$LKKOpGnqRKSM?tix3%^&M zAwlBc=j(XqH|Rb@ih{+WF5YM7)#Sv%egz-+-8a7)Rq<82@S7Xko#OE8c;`3h{-}~N ztkE0BAlJKKPHt{8Gpu@}#&rt}yK(oE{?UG?%$P0C?4?LMh# zUoq@WHK9*>e@dUYS|0_`Vom6i?6Hk{dQl<@IF~?-=|PhItL0EP3p7v$#}T} z4CM%Y5}XD#p-+Mh`lR=@^eLSY1pru)sq(tR{SSXKO;A1hYP!kbT1xJf?|Gn8JE$Yn*5amvz9=p@hpi;80Astf#-Z C35&%5 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x1024.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..238b69ba7c3c2c2c8aa6f39d738c9ed6b9663878 GIT binary patch literal 40232 zcmeHQ4RBmnb$S=eZf2c2&ZZ;O&V_5}W^qs!jz|ruq z_-z}H+W8FXc+UTA|eFW{U0yqyRhYx46nW40)# z^&INluNfPBU7T$J?tQN!w?)+1(M9z3xT0>zZ_!>m=4kqcv__5m7_h4)Tyy3xjve{l zzkdE9!|)rTuMPMS=T`iP<8Q{lyG9}Pdv8~Fw^eN!_ON-Cysn7&Eem6tF8r}N}aAGh?ZLB9qNG#$%ZTQyuM=Znm9Dc-^AI>5dla4i`r<>cnUi^iJ7k({* zW_Q;e=)o{PV;M&6LsJVi7?9V4g=Y2Wenq+Z>4RPor}777v!ra4ltZj6+7v%Gc@~V% zJHc)o^7=i7d6Us)%&wr7cN-LY<~=^kC^Q<6W@U#!`7PhC${%^ED*s0>Rpm#2T$TU+ z3sw1Bo~+7$`eIf7;a94**BH&ud5o#Q{^f~k7e7Puz~6n+ zGhVYk=oh%+I}*RJ0DS)iV1ICvaR{R}rdIzlKl)e|dd6Yq!?ohv=xsID+4bpp!HBv( zS!Wpe+H3Xz%={^bYx7I4%Xs`$(8zzTts0|^dJXf+W2^I@J5k+bJR;ioZeaDJBQp`t z%2UR;@#xrRJ<*$*FdCn&amqlTN?2s$aVaWAQb9 z=Ni}l68#&yKlJMVAMG1Ib+doKI59R8dB@eYGJY-^hKiu~dgS`KQBl-*+m~-k&+|xX z#MXDpX#BI&flDg~Jd+Q8bj)l%U47aUJ!(`tk@vp37k8YRRVDKggW@w_e&8{=Hp~Yf z4|cu!?}deXyMD8CZsFd1<*sTo_^s-EHDddpzln3GCVvj++x#{8x9t+`$DDf^R$YyM zmHE&sLG#To1C%*idukY+KCVfV9e&j7{ z=SOPaJbyN{ZvL!)?fls;{KVFIv%O#ROozjdj;sh6=W4w5n57lBy?F4{x$gucubvqD zMkp6Mb?%Aa1n{2dQ0z?YQ^Dsv+fRPu<4^Rin)%0Hofzx(_;;PUb0&D-LR;sbTzO?z z$htLfU+}Mb-)>YI-~8k8IBw^b=T|__`1EO@NYQv)=YS_Gaj73_|=f{jf$*c z-8x@+9^*xPyy&U2)Pa<_MU~MZ?)~4SzA+?Z@X3n z?{4n%bvJltDi->D=Qet09$3h?U8>68`FvIW#EVt=+F96O6c`<@ue;V5^Za6yKre5M z?Kp$hVs&B^rv>u7vMIJ>T%gWpo!U+@9##92uDxp4!cx{bzRzEsTnFEqS0T>OE5;G? z1<;#wn6(d92<|=5%sJp$B{&b%I$sd_dVVVViFuye81vorcH7JISEL{F_gAhp&pj9t ze#U%#!X6&P5?915oWH!O4<%?d5=&g(81wvhL+t#|!JTQme1FIn^ZW#Uhh#f3&kN|q zFRnk2nFR}U@v_4uGHq0118>^=iOK&k z{h8W zFOF?}_xiD~iJz|ZV_Un{&!3$@ujUUfNDqQ*5h;k}2Uo^?rx4=@Fw5$|JXMJJkNGN~ z_k^A;td$jrvXy<9hs$Rx{jm#|g+>>yIC@;r8p#=xS|)z3wbXXD>O$XV>}!QiLUHF1 z5em-dEz)jcW&Y+uu+R6-P5!C-ev{unAIuNG8q9xUHkkjHOTqjT&j%|T!(Vy$*RhM& zHpR|g!?m%Ue#~ye#@P9nyohX^UmaP8Rp77}uSyp6bysZ; zSgvky7VBLd`J0~#s{O_sdEl(^He>3uzY_b`7g~)4kGwl!r_JkR(8yPxu2%L&)MM{Y zSRQi67Q66-+OMM`=Qr$nmLER+?J94!@Fm|=a6UiyYOvAkkNU*^j{VMvI`&R`!b5Z0 zw4Jlb(nH_A&i#Ssy~0YAoxIm6J9)2DcJf}QY*@QX^61WzJi54SJY8H4v2u-v^je%x z?{f3$l6=n1r^RcN-{0#2H=n-#t1>sAcJpa*e{l0@H=jn<#?&i~OKJC6g zjl9`?f7*S2+I@f8eSg}0e;UtasQlK+kIj;@lm9yPPX6nZ4XeH+pROy(r;E$R)5YZw zD=(i!YkLO2pdHH<0+0CcjeA>;Y-F({3r`>$o&8PJzM!5O3`}rQ~GgaJt`i=1U z9x9)8@?$(dE%RHa?Bu^r*~x#MGM=9<$*1ddeysB8;xe8eDXPcwBf7kNJ{@-RX*ZvC z^JzDqcJpaBpLX+UH=lMtFVFrwLih9XJn|FuoX@xW{k}h~@>wT8Htqb@DLeVEQ+D!S zQRbgLEk5Z^{@^qB#Ai`EpM2*NpMh66D2oDDGi)&&VK~ZgH^aRQXBi%6c!J?chNl>w zW_X6-S%wQX7Ox4!X9CKxi7~RW&_Io^lZ}tCRUjN;ILdH0!@Ue=86IbNg5gPqrx>1Q zc!uFwh6^@U<7p`wpDNS%n%MXVTLr=qhNBF3Gu+E?mf>-RCm5b&c#7d^hG!U_Ww>Bt zHNN_i@u@P6ua1q6uvH)&VK~ZgH^aRQXBi%6c!J?chNl>wW_X6-S%wQXR^#i@uSt2C z#&=La8LQO=!WP33hNBF3Gu+E?mf>-RCm5b&c#7d^hG!U_Ww>BtHJ;ri<5Oj4Oh%!T zjgPR!_z1&MhPxT=WjM?5IKvYRPcl5k@HE3S49_xLu(29nOUd|Dna0<|#z)vH5RNb$ zWw@K+UWT&_k25^M@Fc@i3{NvW!|*J_1skjJ)t8JJeX+BG*@z;VAAQVq+2ah;DXoi87mRhNIY%$-YzX zNoZeu^@G#C#!>8XWKVlB+SfK{U*jnD46>)a4ejf`;J?Q3U(TEDzi>hNfcCWw+SeHV zGkaQxXkTB8_BDq8%${Ny?Q0vfuQB{*_H~-Kn9dQVvlaEM5=O%R2*VcBIl}IV2D7PV z*kU?I*gXdA<1@Z>`x;wJ=Lp-g(Z04p`x?W4Judh!nv_1H{R#)ee~sZkv+vaQXkXi) zeU0HivnQR=K0cpX`>!$lXZEBs+SfK{UtKsV?Q0vf zudxBm$)4gI{_EIA`x+b2ob2m(``QNWYYhJlvM8pD5PUq?K%LHm-gQQb&)0Dr?8_@CH|fwu+p!%ZVl>4KdM`-UuT*6!M-g0q`e#i|FyJ!(!LD+r2R7bp&p0Q zPhk(rD*n{op!6%QTZ8{?ApNLrv3>{3)DQM$=_l>w82GQH^^^8x=qK%$(GT@Flzs}6 zerhjP`W4r$!T(y5epI(uzdCFZW$l07^7KRdp{N`K|FyJ!(!LD+r2R7bp&p0QPhrwe z-TRb&#dX;Kyrdu1E!GeB*s}D4eOd7*?YVRkFRh=nFGD|Rzl?sU*ZL_;`l(z)=~rBb z{g3HKb&K`uEK@(&m!+SyFGD|RUxt3tei{8xuk}-y^i#Q=(yzD<`ybPf>K5yFuuT16 zUzUE-z6|}OeHr>m`(^Y)z1B}*(of~mO26Vd?0-zZ;=0y?&%oDbj*ENHnmMt`6>bN= z!p0jIUkx5Fj--7%VwU!58 z(_>@tU3}UH#;*sDuWyp}t&F$8Yu^~}FVq_lRoa_#_0&Fid^wEd*E2o_{!KQ&kMSY! z_wZJvX}rYm15fP}zXm+DPdsAG%VJE#upCPlcs;*!KFxQ4 z#}|7_n{LJ zPs=#J>hrSL_OjU4V~iT>ym%om#~AUf(|kL4J=cuKS|F_$-w0mEFyl9X*FH180le0P z@mNz{wx+Z{SW~14v)@pt_p&vm?W5qe|8w=4#~NgFM|=l(tq-&B0R3 zmV4M5>|tw=_%*Pneu_}2 zW6xyz6K{gY7bnX2Y@8$B0#EZu{Ce z9(%Z-;+A;q;eNJg* zezuqDcCe>0pX)W>2%a=29(yCxmiPwnG#A8U4`kXBk3Eq5pCkS#c$y>Pu_rJ;TeP1M z@YFBy*rQm##5aPc7$d$FJjF2a*em>Wza}0r8K8E2BA=F;BlZHM8}W#}0QpILBX}08 zx*e>A0O>&Xi1`4ERc()04Y1hLJYqG#Vp#Kt$pDKb+R zZy`2D&138#Hb%{3>>)Nr%_G+eu`y~MK8Kjkf_HolIX)xa0yK~Hdc4RP0w~BiLVm7! zL z#P$cR6>_$azNdKBX&&o0L~&BDd5nwA9r4g1#Prnm(2d0gxA#@Bm_b)MW-3_BXdbaq z!D2@9h@}b^Gnz-tRIr%QJYu7Q#fIRW*r;$~1NUXNhwRpSNEAHzOg!#u%)Uq4H-d){ z_8bw9*O)YSo^^UoF-HM5N1Df89bkL4=CST7$sZps)f!eZ4K)u9E7^L{JT$3fnh4&} zq|(s@zEz+?js>p~w4Rvv3KS&YFjud6#7_l_2hLa0Jl1O;u$EV`v0y2vHZhN@*jO|V zpI0%T1@HL0%JCVoy^6)Qz7{^SzUn0}-m5SQ$bN)Jm_c2hMmeg=e$+=$#6BtOMR^)H zYL{_6{&<4|UGH@aM0>FJmR#?hhIte}c7Oho>-{Cy`%A9(ms}qxxjs;GeW2v}K*{x? zlIuhKdW^54q`so0zOtmgvZQ`hN&PCPz6R1u4e;C@pm;rDm(_RKQdxZ$7nRj_2~b&m z7Alq1XE{+>{VzI|)&J6nvN*cBkI1tJK_`w2>SRoxRz5j);{3SH&EWick25vZ^FRF2 z?HfL_{lhC?`Rswm3LnOwK+&k^=Z80-{f?bu!$a1I zbaKc_Cx(+d!u$8_JrwWUyC-Z7CDMbVi9vAvVJmks3owu!4LhyKhLdBtWO^Vu@Q#5* zE@7cMt{RJ{26luaW7{H4Ve8mvx<3ck6GNcF*74Ck)mT$_b5UD~kwM#sOctX{hONZF zz)14=@q?p@q13TdaztJ)TShafzl1}PvG%Z)Id<%LGA9ZVw0~FTc@wN+qF3Y_i1nj+DTqpWKHlh!|MtHu1 zVR4Of2!Hq?(h$ej*W2EWYDf6zwVjkVd5N9YMb?D>PQIh(ux%nw+HP92(yr%F=YGuq z9NoQd*WLs1{d*4`y5ms1tMhPYyytM|p~D{xAMd{_Ih=^wx4!W94~B;mcV|Yz+p+sL zhKEyWi6g+-M6UlX@R9I6jp4hJiGd`nJ{aDg7)sY3*I-1hMM0gPEA{o&ozeki-bqS zZ)13GI+q+dmgr9&IU+lEI$i3FOSpnQUe#Gk7vSoJgTUrCq3sj5R04P(<1#i(A@J$|g<@WfEuw>o_?a&)FBta=bq? zn$E#iNH`o9^&+JVZ+|b0<04%_-TpoM<6YQ2q{-;?1aXlG+`db8)g*M17P-VA z7_lwMVqfBTGH&10q-Cp86yq(okN)B=#E$kFUHthy_bexCix{@8Yc?^GOG)*iY8pI~ zwWUP}sby{7vaNmD>0-?mH`LxfP&`4c%Qqytwf!q;DA`oxQt3>mvhktB$;>F`R;cVu zvzj(kE}rGR-SO_8`0aZR9oVxEeGSL$R}7dlyu_0Xy`*5Ie&r!2SG@EP7njU>I+Kgb z$Psno6%UL{6M*nNuQ6L&(ee^vY%Nl?wI7x&?E5q6v{+duQn{1GdWdx;)KT>rtV0Ao zUJ=Ey?2=<}QVXWk)VvIJd$nk?Nyaq4yhXOJCqr9a_i}L;E$+Sb^<6G@nBn;E+`AIz zcfMRqS2?}E#_TsQGyVNV)4xr~#-@L8Br}@Tle{HqI0{NufV=+Q mFzb)yAXs1Q?$~}z-hK4#vGiV~*54mo-f_=$USaJy(Dgq*Pg5t;io4bk_0>9KAc;UD5e!QL+ej{(h zP`_U9{Lbzd@4aaWeQJH{{m#0^{YDJ+YjvH|^1^TB{j61Q3B6Tb_>H^~L;ZTa<;DBm zyWe}~)K0>0l^5^V-l+SH80y#Gc*_gFmG_&{c}wW6^1^TAjTq|J>n$(*9&BH}I3GKk zc;WZJ1*0eYdcEa^-^zQUJww>U3%`zQt0IQ_wfbQH-niehe|ieBi5GrvjF10B41K>| z@BCKYWh_;y!|3$JIp=G1RZs2Y!$4SHh-GKw0I5-)_eS4E5{v&Tr*CeNx42 z37u75_;p-c7%|kZ)dzm>-0%68occ`ot@6U}olf=^G1RZuJHM4Tg~KKRYn2y%9oM)c zhWfR7@Ap*hL3!u?eJuAN1=6=)hrEB)(hrdbPQY_6HLN|iS^Q}=odR;gGX7!lTmRc@ zDj3vsctg{%)G#+_LQZynT267#ZqkIDOgF_#!JsDLy*=I<%&^#q2Dhvzc}w$Jcv8*;Kkl@q0$In;!l@}WD>gzt%K z`<$w#cn&0RlWI{Daw2Y)S}>>yIW1~JPF5S_WcPLco~}PKG?lsN1-yBcV{YaZ?9l IsM~n@4|*)0O#lD@ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x192.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x192.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..4177f8d21788240cd07f562fae24e5ba7c0e7549 GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x256.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..49ffbde2459ffba7c2685aae0012f3585a9f54e9 GIT binary patch literal 3248 zcmb7FTaFYl40I2z(XbjVE3`;_tOOq%fFtn1A^7BjgUsHDBjgAxPDGUxJ9f64G?8ZV za9ri8?sQ~X&zD8yhlu>XieOmV%OYPn@`bi8QZPET+36Vr-PabZTanN9I=$|A{L>>J z!@kdvcddKde?dRx{W9`q40&q2WRJY^vYcG+r7_m7pquhSukLYG8AG7gFcL5Hc3$`& zTEWWh$P2xl_woOEp*Qnp4C?iGeV>+L|*9ayibgJD;Q0Ap*Qnp4C?iGLp8V1=A@n z^bT)u27z9WM_%X+yl-OCAztWp+?t#)s8{0~=l8Db^+!R7L%h&?SNZHeVet8Se9#+s z-&!*Jg5T6<=yhBsi6ji_)%b?qYuB3&eF4an7kX2YNS;EkFARDE?>iQ3tza_Y7)D*w|%nQR1s3!PixRAhBF{~!| zRLk9{2|j6T!>4-h7UHEN$d!tR{uvWJXXs;tPkOJ~M#He0;8VTtH)_KBWVxeHp(ZAJ zD;OEoZcXsXa9d)V;erz`Px!qljV*+ zg__d$<4{fT$#5ZotzuYB@M*Uu_@puO>4xkFLa;51+|Y&j(&zZ1rMS*R91f+p&O;oG IDX#P7FC|cr?EnA( literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x256.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x256.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..7a6f76f86233c3ce151be77315d99df833ecc45d GIT binary patch literal 40232 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 W^jaj=-ydAwarad|VePuD`+op&{&iRY literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x384.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..1bfb1aed2234819a8108706853cb2c630d037de8 GIT binary patch literal 3248 zcmbVOO>Pr06n+y%QCg)1AyieOqFr>wiX*V#5G+}6km-#$f{#%3M11er@6R}yA(qmy z^X%_$V!JfW`@=-^lZgHtiO{X>b)s+RE%t>LsGzrNqumQSJg;vv)^q!Jd7b&`%`5j| z-c#h=*SYO)!E=@Ox#!Io^w4;jJ@V4)v@^fRA+&=2Dlh!X9CMX12!0hK@xrh3ehjR% zEob=6ycvW2TD|i-n_n(?E9k1$bMJTNCFVC{uwSY3oX88m&ijR{)(U#7yzrZOGY0#$ zdgR6X-J9QM-8z|C<-@_cksfN*L_d>YZQbT^=Ju!C*CKykEnW#TkSBO1<~{ zz1@R!;r{*6?m-o(!ry5}@89?M0=6FXdpze>!`dZg@hfV|`?6q}Qk}dre)pOhhH5&T z(R6Gz%uSk*liZ&*r?h7`X+ln-Tg4Mq4An$>Z;x}*wMi3la!q+ZZ_2jYX4kLav$qNJ!e!Ca*{fYbJDeaPOd4R zADc8GC&g_!)pJZWA*Yj?kdxFjrv(TfDhmGjo2VO4KE{cb>M{;>B$Vnh4s|f5x{Rm4 Ds*98j literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x384.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..3f7996b6589934980b0c7a9db6f9fffad622d162 GIT binary patch literal 40232 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 R_j{Lj+;N3>Si5iT{2%3zd}#mx literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x512.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d04182c80cfb985cf52e19df06101af8293bfb92 GIT binary patch literal 3248 zcmbVNJ8s)R5FN^dAQ*yU1Swn?wh9%7tCT5I4I4Cl9@L^=yl z+|_X2kDsMs-0lXV-$eAfC&E<6+d$uWwwcy(YU$t23l?%+)MYlJpNHegDt^AbN98VE zcgVcExE`~H!_=JRJ@&j6gYG9@X3xCzHf-GQEs8N3ri;ArE7!QIib3#e7=;&pgO>%x zXqZ~hCBK!oVz6JYcYa6rdk9j@8jeL?_#L^+{T_G~1Ae8>|72eH4c@1?9UG?>-Efw`@40&GI8!zyzsl_4)Z4({#&6}V80^>UnHPR{ zBJt#kjd&F={C01Swd)yvy`FjDH}QHT+|+Qa@$0zUL{u=?uhiL9=7rzu@QV*wjE3nV zFZ^Cd3(pD$-(Rn1UieMCUo%9*Vv!fmv*T)W!C=2qpYgj7zpThd!)%ckeyc%A(=phu z*E_$7_aPeA-(Sbo=7Pa~r9R{LCj1^h%?rObxrwM?uwSoteiQF=hGeyZWxq6sTb(+zH=gE5eoRX&U9cUmh zs!Pw4;j$nM#V}3C>8vK?B(<5GbibCIjtZ;44W~s-$Vnb*yU@NfrU^OeLqDIB_4YX> zP38NsN)w(Z!&N7w7^Vq1oz;Y#q-HstfN(pZ&@fQ99%79zTB*xA)saxC%R1G;Sn9GK FJ^-uUk2L@Q literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x512.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x512.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..84a2592ce32c9fa700834a0629e75c98156072ac GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_3072x768.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_3072x768.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..e7fc9a78659bbafc6cb6d7c081d02ebaef009bc4 GIT binary patch literal 40232 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 A>;M1& literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x1024.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x1024.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..406d72c54478393e57137b621e7cf9d15014ab40 GIT binary patch literal 3248 zcmb7_L2leI3`OO1kWPa^nnf2~1n4Y!fF5BMJwTUTdeH;)2+oaq1RWvhiTX&36lr*> zi2z%YDgMv@ZA)c3+#jb>ewI@HoJwK1w%4hAlhL8gdsi9Wwdvgp16|i1Sa%>_n&VlZ z^`HLs$mg)`9C@EoQe`&e{krAN80ER~3VY-&uhX6DJrnG$G92=vSJ$|za|e(SdJQA- zqPO#ABP(f^bJb_`X5Ne;dOg0;dvLuMn0l)WhrH<3FT?d-I)IGO>t9afMQ`W*k#Z`t zAuoC}Z^jV49*?}d-+R|PznvGo_mbs$GluBZxU7l1= z?-sp|tNa;5^lE&o_hRSZtXc6^nGAWqw{y@I8i0S*cK&`O@}-n#TR?wkF>;sa#T;wO z|79i3sIHz>zqU0s46Et*pPEiB#@bX9KCS2HOa=L$tvndkgipH078-`tRP5Z|_sMco zP59Jn%K!6CHQ|%tB7xR0tR{R~%iXC7pES1P(|YdC0+{~w%7Yb;{)LJDXY{e*lWuOd z&@ikfd|EfZotpTbEO+ZuuPN^X6>g)tS`$7Q?pkWYu$u7cYEAg0u^pe*^LiG@v`17P z3~RzCHP;pzhSh{mtNHsrS?<=SUQ^ybZmJ2N3>OKshG8|~)76^rNn_^ILi&?nNSmgz b(1rQb=j>=HuJaJbp%mA7h{KrTI-mXlq`8#! literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x1024.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x1024.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..64d102d872494d102ec26c0804007882731a7b7c GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x128.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x128.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..25a7199bf6fccd7ab04db435d1a51b8c6b281856 GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x160.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x160.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..af9eea42eff299054a78536d9f9a5774eeace738 GIT binary patch literal 3248 zcmbVOJ5uB@5N*$TXQ!s72B;#~V5*jYkbnaa5O4^>4L0Bigytp$9DslW_y`my;Rw8L zsaxvCW@TJ8V`*A?KUvmL*RMAn(Jc`@?}*S$*K0?YXg%g`bsN!M<^Jjc4IUS-9`pG! zyfEPOtyF$j9t##-=B#ve~-BTmlu9zjJfg{ z1iy;mc;VN0hhNKi;n(p74EAgF;I}uw+vU9Q+w&~*>oM4`)Ok$J3%|xY;CZXA5pB)r ztMzrf0fYToz2?RGuFdaJ#Y)t~3%_fgWqv&d`;|J6sd?eoc!v|N+BKrp;@9y84EAgF zniqaIvM+;9a5nM6?*?OMFZi{3%?rPU_sUHl(QEN*xH8*guwSW9?BA{VycMZ}eOk_o^)+0f_89C}>e26YJ_qTW`}ZcFgSsGU z`-e94{AK(O*HntgZwi<&ZqYTA6EX_spl>og%JIX@+* z`^rS)^N5^8w~D8Xp_)j~?dhC!uG55^iYC9GTXRy}WGG{(CghalPG~|-Qk%$0&RxmL z@AW24$VtxCL=0IOLp33%bly*B!tn+a literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x160.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x160.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a2d1a197cc97428b5e3a08968e75a02252a72887 GIT binary patch literal 40232 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 Jwg1-6{{#MPh06c{ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x192.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..c831da6147fbe31b7c1f9c57a563b44dd321e7eb GIT binary patch literal 3248 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 iu)fIMvF#YY`>5Mv`MpT2zu&vOO literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x256.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x256.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d0ac495be64d3c6b56dc21ebf09036c75f49785c GIT binary patch literal 3248 zcmb7F!EGBc5ZqG)K`;cz4?prS5Is^rO3))kVBJ$@Xf?;iMlYG~aFSK=$g3+$ccE2&OeQkk{J@U1^Pp>f3$@L1)AUfbiUGKN4eF%mEI zc3$`&TEUn(i#|hd=FJ$Y*W-iUz3Y7ntoOfPbJq1{4Atw-M_%adywBTtp*Qnp4AtxL z$cy)TaJ?Gntzfw7Gv4n(Q(SMxP`wt{J&_lBJMW7|y%mgBd7(G+W(?Kq@yH9kN7Fmh z3C_ECp?5gJ$P5j7Jsx?XxAR^@!kxU(>$sMkF;uU`Xa2truD5LGh2DpESz!TsJwE8| zyk|chnpyC>=lwdaCP~Iny%wL*dvd+E?Yz*NzZ4lm&$Gt|y`A^pc3!++$2GkfL-ksG zM(?BRz0g)eDCoJc_??8_N88OVW2jz_4|+TAD`^a*py$FOFZ4RDWn~Q2Yw=OkAC)%#NmEfufzI$Ny?KG_~_BnE2|-rMs&F*nr&pL$K_?f((@MBFN+VX!9n zRLh;I2|ihD#;1Dks!zA=HNhvlS1WPHU`_C;-uE*#;XE;S^r_dBzXJsfr26PQ5f|Ih z8U|~EPm49dCyUMaRPSr`>B15Wy`bm9VomVrpu4$|7_13CSzP9QV(#cuuj$p1m8Jx$ z#hP%Qh^sjw4TCkor^TA!lf~%M4e3vcp>3MvhDVrBeU3Ah;x-R)=tyy!hd3Bh+~(7N DE!vYg literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x256.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x256.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..fab04700ed17537a5192fc2e7c3e9367f370bfd1 GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x320.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x320.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..0f1f42f353e8ebcaa36da39dcd491e939abe853e GIT binary patch literal 40232 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 O@3{LK@38jV*8RWWoOVF~ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x512.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x512.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..d5f93a97928f8ee62011acc3ee5fb1352edbd3e6 GIT binary patch literal 3248 zcmbVNJ8tAK45cUD!5|nUDN>{euv4Via?35J*h8dDk%M?|lq2W}K~A)fl=u@gV3K5-JvUxvkG%9b?M&|jjNS^mtGv)FKBg*T5cDcW;)P!4<%GNy zbT#Ih-prdZSg+YTy|d{(IVpMt&nhqU&KzZWPdxGly<+D-kr#TM_m}&lSMaRzVtzAk z#$df>kGz=Qz3G*Xac|;<-aSW{-i*QXD|YsYywK~sf7oiRptnVD=FJ$a*X)rOdJmFf zmnS$k@j`F6a}XIC^qM{LLa+0d5U`OK^J};goiSLi*a!Rf*7PnmOANsXt96FnTXwdV zF?fE>-syGTv(gAk!CQY^+rNe@Q5l2vihZE>XnN^JLffn0yUGi_IPGIg7_8UqonGfH zDW(8zl^64CxWb+>Sg+Uzdhbl{Vn+)@6g;cE(0j+u)-nd`HG8MmdCxyA9G!w^l^1#q zSAsJJ>lJ&i_pJBeH}~(~b`NTT!i|^BnBKql`1zCQSsn15n+>r`ti@Z*sf2)ywRrDy zY8aZ+;Yv=&W`l3a33aOXC)X+OSw>g+7xy3PBtGh>7@8C5y*;jz#-^N5C(r3@$Vg|~ znn9fumt%+;hUSDiRnS3BsFTC{nIk|F7RKgbE|Nn`su zc~1Ep*pw6Mq_`r48iwYCI@N<>kQ3@8wn3fheJ$&$hF9=ybBFb`XMd|xJ7+W}tS7P4 zAScvGWBWRJPWk*Of$HMip-zg+sbM|Ub4+tWoi65tI*Co|v>^O}F}O_=E%=1-V!Z literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x512.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x512.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..480f34ce107a07d51bf77b77f9a99bbe4855a38b GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x64.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x64.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..31a4b84959a4545fd85cdc4cd68b1e86aedf979a GIT binary patch literal 3248 zcmbW3J#y4A6vySoEIXN6A^Z#>{JDm}G>?}ld}DTBmdzzHKb7_AiAmbmkD2~746obp z@o%ksYW96;dFz(c9r@ej{o3<-jBr;7Ykp;q(P>9QVBpv8 zw7mGOyl?W}@)@~m&nho|J+H?|ey!f};&(Q`^Ko9jU+FTx9wYg+J1sAMEAQLmy!iFJ z9wYg+ddrL7v-v$A=f$sdnO~2Q{MwzC7r&MF-Em(0dR~u_{93)`#qUL)OH*ask=f?& z3cnZY7)M@dEsSlpt8}lm@Bi_Y}-y7>l6OWO;U#oY1 zEAJ175LxZ~)&R zNzPBnNq!(EYL_N*65T3ZpL^95^xPijq`giPIaN*mdETXooD?^kDHy7WoU+`3CUTP6 zASXF@C8s6Bme0sF<8ggr;bY9Z$Vtvs-58d9Up0|aKJN#b_&sTFpHtQJknzfAGw zn#f6Ub6desP2{wyiJYW1$Vtv?$;rPXc4;Cfd16(3C>W}VobnSr&PjXwoT?`O{@A67 zoD?_bR4`N%Ijw3UC#h*pk05-=DExCjg>F67HE%RmmvvJoAy=1mQ-{&jWj*}^2$qk{ literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x64.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x64.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..174bb6984ab74dcdba5964820c26eedf62b141fb GIT binary patch literal 40232 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x640.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x640.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..3280e0abce19ee4b2fb9c28e5e345920a5d261af GIT binary patch literal 3248 zcmbW3J#y4A6vySo?CfNA0!0dn3{X&{%%o01!Egpj3J$WlL5{!?as(Y=hZArFj==9d z>pkgdZ0tod8(aJI{$F0nNyE553@Lp}DZLz1;&vM6A>DI#+SwO=&D`0yyC){Ht{)@) zG90g4aPzBH-Zkq!w!BxNDKlH;{nYbDjC5Ogg}voX=V9l5Z!YJ>uWEBw5hLN(vCt; z#E|Ff_0DhQJsXYCZsXb`IEVtki~t3UrzgGL=5rk_0DhQ zeeo?WK$*`fFMb_Yno`6NzgnO1d+mOIzSh?ACv#op#qV|7lp==s^?K*G@;>idh)uls zbzE(Z7~)s!z2DE}J(&J;|9&a&K?}x&`!B`bzi+5~Na@xVa2-pH-cy^!_f}Kfmzg%B zTKvuZ=rt7#({%WUremqGHfSOzeSd0BanEkjL{6&P#HWH`nv%V@=X0{&poyHSrnsLs zX(A`XC00hkFiqq%$(_+ePFkDEN#DDgQ{3wrh6#`B6BFHMT-!lTy4h`EDj24ToTkHI zMiaj$>+N%@n<-;Wny8P2^;_lhlG?n#gHU6FF&ZCMSJgYfkZu*rbV^^pG&|cFve4 za+(g2`JAk`vP=f@^Zk<+3ka?+aRbOPb+gu*{VL+a*3opYjvy3U(A P35B}On>vi4uJhq9S{I@T literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x640.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x640.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..a93a7380a8734a4bdd57889e22efe6034ea4898c GIT binary patch literal 40232 zcmeHQe{ft^b$n~tmVu|09Zkl$4=^paeqNnaWInz>tnI!;j_GtJt9b1dnBjjw$8{Thyj z2gPqqvt=oX-|ia;Uq5vJH$VByw)OA$)Wc8rg-`$M4{s`O*>4d(oQG4xhqAfsPFu`)YReTYdD_zZJ4;@-h~DA*WP#nUJr1|auAqQdFtOWu4%sE*tn{W8 zYwGoMM-M2*0*{EZ<$$~1E6MF)dA9u`dV5?_*X6fpuN`wVeO+3kMt%g?*%GQg^%n!T zfA`-$_kgB(HPP1w{D^Zae#G&K@$amaNdDf}+0|tP4b2)hFEZ{+DgKiP0<_~1OOxDWe0Fy{_?m>(cZUTBkO1yjstOOjT(zTG+xA13Hubl!91Chko^*{r{EXkD0e|&}uJK>~9L)p&=eJ$s z)$9FUfh)gZ;^!8C?>P_b^>5a?F=}mU%`1h`$EwgX4!sbn5$8sCt5&PEoqzO#@Qkoc z9(tkAEZ4L`%@u19df|l4wRughQ+vGIuVJ(iw^sOUTTp-gu{DLy9t-N<@vS*FHWU7c zrmZ@mxw`(U_wCvjTD6BF8>t6s*Xq&l4(bc8U}4=?*68cBV4?boZRh!_qte&zWxYm-1y~< znRy;XjoA85XpMh*(wB54U6ZFjGNw1544!mF4r@U>>fTrP!p;-3QqmvNC^mii2Ol%n zg?{>Rf9I?JQCzsI^EbQZ7Vauk?hfkyZw3oN#P#RDj&q>8a2Dr{-s-~5yG8pk`&xz- zSM6P`Kk%|&fAfoeeeUOe{mJM2`u6Yo^)Ei-*H2&Y>mU4)UqASiUvK)pU$1`BuWJpK zZI8jH^9z~=f5}7m3p-n3<===t0xNWj*Mw#cJJhabTzRzmJ@|d>%b$K^SEn}V(IWFB zZ(TP(QuF5dGlAOqGv0OcXFBl{t99pkzv!9{g&rMQ>C?_uyX&=MV=FhlaPY+0Z~Mcq z9vk~wARjw%_6h$4@ZQK!>{QKD{-3&b9RJ$Kp6FdY^H0AzHrD0x?mltHjQ{S1w&))} z|MKpDag*`&%@Ro)y03uskeH?KRZ#W*G$|H^E5ZcJT;qaZ|F5^D)qBL z@DmL&PpiENYS0bnHD^{KQ@QZtO|j@t8U!jf#&#O08@q71A+|FtP;}1b>Rz(BgyNzv zD(*!~4|aKEUDV!bpk4dWYo=FX790P5-F)*Zy--uE>hpANc2B#{K-06vvQ4k4t}L`& zse*Mk^m)1(+%pvmeV((M+%xws6xuFU74CSps&MRuszS{ybTA5x4)yDiGTZj~%agURy?Hg_4839; zF^>%VW_-Z7UxU?ze`tOF=xnF=g)p+TifG6hq3G5D-?ZjNq zp%<^He-1MX7U;qyn@cF}+_Q>%*3v6{{BeID>UyW{f2HumjKA>n@A;+QOlwNUHVz-m zH-A%jWz84XJ@VH#Aqzh2dBIg^$nr3;%M_UwGnKe`RCn;Rk;m zyKrT5?A#U9jqUPcb{jUu&b?%gL*mQ8u?sI@ova4lAW&0e@{vM8^+ zY;nNm>K13Q-sMra;VHk|Z}gFS&uBMmQ=j>jmESD5%&QZ2+JZ_3wL~~tk*0J`LS;0x3+BOzqV}WzqYIy^=0{VU0FU|Dr--d$^j-X zoll3HeA>yUoqXEKr=90Loaa5vzc4$`dx)#B_&b2}yod9=hlm8{c@N=*-|zDtGQSme z$mcyuWjp`1%kBKvmhs%QdX&z3endVqt=c^wisp5Jwz zpB7Olo<;xtJpb)H@8LY};XFT$e9n1(+IfE3d4Ae?e%g6{TKwOjna_&6#Cm?ZM7Hx^ zyWGxyZ5hu`m*vw@l^@IYN@YAhQc{lRN0hvDKE2z?r=9!L&i!fU{9TyfN#(~fpDva0{76YT zo*z;2()o0=lTSPOw3AOe`LvTyJNdMePdoXv^Zg#y_oq1D@8L4P0mS}3j^FR|9x|V` z^J6?eU6xOm%69&1>*M+9vV6Ku<;OCgE|u~8NJ%-KA5rqs`EyUoqXEKr=5J-{C>MP*7xPfeAdp7bt}KMWjp`1Wjp^BGXL&r@lAK;5599xd>6I- z&37L09eBlqrYLZbVT0i?!x4tN817{_$M87A6AVu>JjL)d!!r!eGF-H<_)H+a6VM!+ z7$cK~59IiwYF;i84*`0C5XCuJI69UC8EqewW+ zaD?G5hI<*#F+9%j1jCaIPcb~r@C?JV3>Pgd$Je7ilX98HcThkxR)a;t2E$>7BMf&j z+{g@^sxI1B81^%LiesPIzfgF=I1cG#-M$C$G2)S2}24Vc5^~${SyDHx@ccv*w6H%-2X}k?JErXnSP1?Rb8~NFzjdgb;L6rv~Tj& zvKtexkW->*Gj-ayJ7T>}$t*H|&F=F0uBC54Ut2M4+DqDaughKDnrrFzn)(s0YT{=; z<=uEK{c%%&TpG-3LI17S(vO(>;)}ye57@I>#F!VKQN&?hTP!RZ7iE=@1r}xEvx+$E zvbB(r&6{OGR#xp28sdF7W=O+-P0REj=5$&96Z#RePyTCh{|Wu&_)q9B}vl-m+8OgGW{p?BVq_8$Kw7I`pfa3&|k`bD90iFC$S5% zjK3)JUuoG|Jo`odqq3|0cW{~hJGe~$3H^u|LdmhX|AhW>{3rC6@*m1^NdHMp{*!yL zjK9*dwfNr@@*kC5?Y}zrxO-XqpL==hw+{LdF@%z1asLVZ<@itNFXca!A%u4?0?LERCcxh z4ldJw2bbwTp&t=LC^;7QpU_{9|AhWh{zEwq=|73de=?Vr{wpoR{>S`RTGm?hpi6CB zT!YrmiB&FfJNT6r-oW@EczifA_1hW07Cc@yXYw744}jl`S44{THOWhS*`sZBy{$^{ zVZ3t>8I)PqaN#vQ78dW~Q#LSuJ$Ssn$<%LUya8U>#&~bBUc6t?)Ys?gseSN%i(k+9 z82C3?{C>s73s+;^z`iNC`wQU2_-w$5J594Ft zXd5Gy_&AKUuNxv05#TfDH!BZ>|Z-7_+VeRh+Piuknu_ut9 znLhRenis}D_pmkC!`2}2YoSm55+5tJFn_i%|FF&hKYLg_ z6W;-SibLYV;K@J4W6xy%Cte4S7blwW**HhM0iNcO`1Rn``ephXiapH!9%g?Jvy=ER z^eO&{4}d5C6OXuJ_7IOf+)L}uBkr-7V`%_SejpxuyO-7%@f*NXyb*7Jr*%hs1U%VE zJoa`k#R>7)+r8vx;<1N&DQ=0!9`0p(xER;8wTFAz9`03pl&e;a9ecQ!?cs{=0IzId z`q-1j3wceyb#T5|?`3hcUoD;_xp^BeJqXXa<(u`bv=5|3Ph%_H%Mb05VI@eRcm7C$Y@9>k{) z12gS3=7>j}v$!H2`$K^356V}_*#hdC;;L0V)^C8~q+anD7n?ic;fDb8r_zVtSZr{8 zPX&t^bfsdZg2jyD5gQdOW)zQDs$emrc*INviy6fuHY!+b2;Pp33OhD%U1od89<_%= zz?03y#maQ@t~^mVI}jS z;^D(ewq6tupHwoR2;TNdrR@{gR)GR@EclF|{E2z5fMD_sbM=Zx{8X@b;Cv;`W4*Eg zYk4&r3zmXx6Z5#5jYaXWc{Q_H@V3pXZJQC>t66NTy0Dq`Rd4d?|}%#DWZR?LP|WBF7j znM%GRnaC#$6vt&_@pN)$C_J`3+!QhfMl=0+n4TB{6*7*F_Q}SYLR(7ON{kFzHe_=c zT`FWGlF5Dng1px@4f{v(MIWAma0WEQmmgA^7tlLf8Z z2~Dr%1Za~JTAG(|LSGhbT|Eny3tGs4l38d%2fv*Qj%Cxy#XZoMMMsPFj!v#Q0Zn_Z zSMPA}qP=fjr1$3QHg;1Zo9m80(_ic;x-txM}F2X&L=})nJNNhuFkLcJU zHy3-?=-5IVS;rRI<2ts`_6KZli}wDHyaIc(YvqD<*gM`10np`guLnMBuNU=1A07d$ z!)pVakt3-?)Ugj?4?jd2V%z$9+q+)v2>ZlMB5{}(c@x>Ki>wRZ_H$d$A(OU#DZOdM zntDCm(F2MBIJ{^7?tQn$5A5sizO6gn89fw@_Z*6LANo+}X#bJaa3XG9`a(NC6dF#v zKRXiIf!((;G@Q`@&k|}6?D0Cn(nC=HX)<4vj&NM@@Cq0-+ zqIm(w+(D>Z)r<} ztplZp(!;5qd}26<;-+ow+rlj^?b};X@a~iuU)|YZt|Ef;4w=HC!uv+iQ1d&*sc9?n zxyH}|k?@H4Z4B+p2>x0{{Yoi27pl`bpYyJPpQcc2w8hx>=-Zl1wKcbdw>R~*B)2tfgMMeKZ*&kfL~Sggqevu?vc+jB-IC5E zQP>9ETahRN4yT3>Wpmk~?BMbEa3YNYnRcNlJl32NLlJ40DQ<0tluH~R$|leX)^Tb$ zp0_HSa=bq~n#n^~EYjh)C>JSZXvce@92e;d$`0&35bwn9VXBNCO$md{oggkUfm?Q) zT{Q_mnHu@TAQ-VNnPOk!Xew@9)J)A*=~0Y#xqbAPb|H4O*XZKU?!0p;x3-93TYk+Y zM)GOX`|xT8Jaa3841{uP`_}F4OHLPSwzQ%4_GIYiAm)%ozBIF z634Tnm|Njxdz$66q44Ti-q#iH>WSa7xBJ$;`_b2M-1@|TIm1UhlcA3kj8vaI%*hoW zJw)ZQSra7lipOk8S2(*QDl=D)4Y0%*}j?#rFqTj;woC&yV%%< ztsLNydwMeeNKe)W(&TD+a+Iwr~{{l$ld^!LC literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x768.insts.bin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x768.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..0d12fbd88c00a553fef921ec2a8869573edac93d GIT binary patch literal 3248 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 Yvc?z9)n#4Pk&vs)x~hZG)n(oM0q0_xRR910 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/bnmish_384x96.xclbin b/cpp/external/ryzenai_artifacts/ops/bnmish_384x96.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..d7af94f5ce2075d0b44a43fb350018e06268ef43 GIT binary patch literal 40232 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 U6L1+j94-ScV~3++z-63%0h&K;jQ{`u literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_1024x192.xclbin b/cpp/external/ryzenai_artifacts/ops/softmax_1024x192.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..9012837d2911b0ae096313c76aebe7747b002577 GIT binary patch literal 31224 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 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_1024x96.insts.bin b/cpp/external/ryzenai_artifacts/ops/softmax_1024x96.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..fbd1d34bbf5d2273992c1598a46833e0fc7ef489 GIT binary patch literal 2288 zcmb7D%WcCj45d=T$e}=c=%I%I&7lKy1Rpwx4;{qaB%^4Apc7<-j?gEH6h%RfYXPw( zQG7o~6o&B_h$bTXJrZG>$2HJLn!U=}UJ=uSEDzt9@HyGg*MRHUh~4Q@t!pWZj5+p&uY%_ zt7kHs$4Gv;-tjvWzsr7J_#HB#JUs@%Z>cwajrX>n7k&#aGkc8Wm+KwBWAQt=$Rcob zV>M^^9mQ#Wd5q+@)EmFXdr=yOh zLgRzN=>2`d#v9Q|_wgR229l-DVy-pKRRdAPYE#o!t4T0a)A5d`N2%eg(}bMt{v{PQ zBBq;~kQ1LNIi)TP)kJ#l`#Eth9!?W-GEL`#oM0n*QqjeabPj z-+z8P+lDB0d3&` literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_1024x96.xclbin b/cpp/external/ryzenai_artifacts/ops/softmax_1024x96.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..74d14b8eb1a558775b6a9b7a4e6dabdff7955218 GIT binary patch literal 31224 zcmeHQeQaCTb-(;DC8usg$%@O!cJ@Rmo{^|ADax|s$u(ukg|x_yKJ37SQ;<&-B{7jm zTB1C;nO7!rfwcWcX}f_Pwn4>~)#wULD^SB#u}$fcCD?*N84xrDnm}&XAs^jFIl-U- z&AfB&efQq;Xi>Imp@q@+0Q3FM@1A?^J?DPBBfjUy*~G+fD&5R(ILC$&_|`Z6@JR;8 z+6DY%Ov*ySPxpNqZykF7uZI5mqipyuws-9MyXilF{79+g3XAZ;c``Y9DwEAjWX3MU zCe0KtS#b-6GnSqK=d3xEOXX6TG-{TIiD0l&o*(cBxMx7!=uHR zY*+S^>L89jC73>|V7GNHJx>ah7qx)?O9VmVBbUN*JT1EwQGJyalj360Cmi_eM{@ z_Wf^toiQ)Nwi@9do?GA_9$(G>bFDz)v$wmy-|!pEa+?s+m(lz zO2$%?=9o48klrK9=ouIBpYCtp`{PeACjXU|qYe%_tQj@jROe1{&D9$p;iT#6ehgY* z?1#{oYu{M7Q4J2cU9ixMA=NI*{(3!Qaw{{oEp(VDi45?HTr`vW&z{zBcA znm`@%7plGYS|yj`vfW*>U904#I<>Nn(|;@ee-M9|{Y?wI%=YQg{q@H_V0c*Jc-_uh z&!50$rbb`R#B!s5s~OX@FSIYcMrT?RY-i81rq6hN|Lz)b%|HLe@j&w>|0P$nN6b=e z>52NEA9?l%fq|D`wFS<-YAxID|NDpHjn4-vF8K@J&if1OpZtYChV!l;_zU+jv=9}& z6rX|nKd1<-{%1wt^>-@*?XOh?{`O}Tf#LSEu3K8$kD(ebZoe(idE@7nd?UdG-xzxewv ze+gRr>I04FFRnj+@E*t-Yc-8^!$}|VT zN#tsmjL>@d#xW<~aPkeDcKo1MK9OT>eZJ)68#3CAIr)Z@Z#emelW*L4z9FvvxU-0S z!!FDGK$gq=K+4RBl;j)Xl6=E1v$ySXC6PDIH=3P%!^t;r+VR85H=OS`obNZB?>C(9 zH()!wtG?e5*MHo^MZRH|Wqu&bWqu%KW;B%K8}%jmhFxZF+vQ3kZ=7!goqWT|H*nhV z!^tT|A;8hU_4N+!58l_J z%ltsfGCz1-Z;|JV)?6!3zX05xh+B3c*DSV@&Y>{M!8!vi7f& z_@}W^)Hp1fV4iOwBxS!xS!C8Xy1kVvXPw)c4O9U?yyh3o% z!ot6X690s({i`SbX>1fV4iOwBxS!xS!C8Xy1kVvXPw)c4O9U?yyh3o1;CR%<->HPx zw=BU1TtjeUK|VyTEm5M=Pp|=dvexfZdlJ~^?@P1nD{R0Xr}g!|4EB`{*jLzqJwxm3 zeGcrawxItCL;v}>S^ZaI1oo8<*jE_(PxSRV1pBHk*jE_(PxSR%2K!0}>?;iYC;Ih@ zXC%&k5@&>*?=WPv7AB@%8%S!@2E+@4WEf zdzFPz8Ov(r_hJ0mWTA&;)$pPH4R6w4)Q^G{`%&Is)StI2g9Q3z{6+nZ{1tOR_$#pX zSIiYG^TWMIJZ|>4bCdp}ew5pyALac;{dua&ae04HeU`&;kMZ*Kj9essP5m+=?v z&#$Ln#$VLm$lrRt*9m_G*8YlXp72+f+5HV~(qGiyjK8SA8GliKBY(xUUid4p_E+Qt z!e3ox_qTJC{-XY7{6+oE_>1}*`P)gxS77b0$eDz{y3FqHz$X1g{muA``kV0=^*8c& zfcPu0_E+ST!e4t?OVPvN6~cLb-CFf9I5=(te!GPm3GW9UUb-oC2ww|)mBn`uz7qK3 z@TNJm&jc^$R{BxkRX`<7?&)@6P3brgeOOaEZiM$1hsfF-Qggc&cx_+vJ;ey|3tv1c#uU~d z@k{e_}HE#f~Y=;w5{C;$ctls@M{JSj+gzW4`CWbxP^O^@#LM^RNbqFPc9CJXxE{PGd1b z>_ij~a~NNx%-d~S)jW)akBkw1U&VDG<~}k;iieo{NDLJZG53+NP&~xeM`DY-jIB?` z7GmWiu~K!xcc1Qa1Lt{eTZGw+FGU9Ll)MCTRLEW^4}l2%;pHeV0ghTSD?&nIukV%$ zXb<$=CH37U^}Qway(RU%CH1`}^?fDveI@mMCG~x>KIX67XY0N8AX>6`|E!k9`{A@K z-ru5S@&Bu}EdKwKmc{eQS{Ba_q1@en8b0Cgf0!V6yeLj=&J^DXpbj2*E?C?=obU8# z{oyAbd?VjwUj3K$eP@39VbfBav1Krd?Ofgh`yEGTCnt>a$*F1hy^bTn@FSt1kxVBt zBdPS*k>E^j^pkDDqo2B`BRiFOGMUJI>K?=B$WEBK(ah8&3LuUo&!-YeA%K|3Oeq1x zr;=0YhOi)_khLf|oWO^hy z^2rf1XBto(6UJhxkt4y-Y>-Y_`m)F{=-mEO?g; z8s^BzRC0QHV8)zCji!=Qygs)KW>TMn4uxjhf<|U^bUK+sAq4ivGt;@pG$V*1tt}d# zNu_hGEwNnLKBUsqxvBNK03Kl%;Iw`hphLIUg~YfyWjs{21L?9o04K2r&AJCIGzj5a z1p%~m5F*VR1YtM>wr(B;D+CeU0oy2qp@G{A!TC&Tq7OzX{C<~u~UZ0oJ%THi9?!Hu%5A1c#&29VINwN>&HbnM_jss$Ik-J96 z0lkrR9MF4Q#{s?l0hZe$?#FoGi`U`n!tMAQFnGuv?=S*rk}GZE!^iE33fP8+)Wt+c z9+1zd1MA2G`$G>*0c2nA)ZSLv!Tw>wjRz*x;!uFQ`OE%}(wVNlW4$M1Cwd159~+Ey zcb@8u4V~&7JoR*NIx(J{G-KAKFL?Or;H3FvW-53XcHgGpWGc;Z2yoWSCB}gd1ur%Q z$CKtr611KUo-oH!37}`iPn?0`P--k~=4PgneaZA#4y%k>2NXVyI!|8PD+)T2!8)k!Pn&Gxcs~NHmC_R;$Ob+GD$t)Cy549Z%g~KiFZBX#(B%fb{ znMtaGlk{6X24MMBX|lQgnX_kcmfk1oWD)M-gGWGHEJf3r%&_7WuxWJP^I5W z_Z~lX@^P>N%$dZ*u~gc!kQ_E!4@S)4(UC);NZ5>o+9Qc@>+r~-NPF^NYh(oUyOYB+ zV^9NY!xEZ?L=t};PA{cLQ|S>XYz5tukSGEy`K>u95NQ__g=U+R=nAG?Ts(-8$(k1? zGA3Aob)1}x<*Xm7<8myKnMvnBw;2>CV_1$UW$^G>P>x}`0%a$TpNMtCuds2Indu~U zi0=e3%mf}i#+wRboVZ5L90LZoB`yw|)5(~1QRA8|BBJ2$X4^>Eo4{X&yG0Y9y?Ak> zutv~rE3Wq6<^!IDH4?!+utDL?qukpc>mQ0edVKKY@jhs4GG_h70AmJ!;&Dd*NkK^Umj@qQ z{L=#~myCKklZ)}0gJt*^4=9%=0Ktp57_CEKdHrAvx7ecEk^oII?Gu@F8dui&RPKU3 z9=NVBI-)!S>kuYB{6!RlWtW_VPO5;3Xeyphb!)XKGR)^Rtsdd_)nF*ib*tl5)ZTi_ zomD@0XVpb;e(BERa81T;zxpjkzj=e+kj#P)X>vdi{|c1lAY1I<_X7H@p^!_4gZ>cU)ZOFRbGyyZ;{v@^a+> literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_1408x192.insts.bin b/cpp/external/ryzenai_artifacts/ops/softmax_1408x192.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..2740a1183802d68295a15c2a95d28c7a9cde2241 GIT binary patch literal 2288 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 H&UN?)+`oBU literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_2176x384.xclbin b/cpp/external/ryzenai_artifacts/ops/softmax_2176x384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..34074b0efbfed9366a63ef7c8d3fc30580575077 GIT binary patch literal 28280 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 Ld4+ZOc;Ej6tnBma literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_2944x384.insts.bin b/cpp/external/ryzenai_artifacts/ops/softmax_2944x384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..51769eb19f3b13e64e8328d2a6b153798fc72c8b GIT binary patch literal 2288 zcmb7E+f4&85L}1TDIbvlDM%nizy}4SgnUo{CGbHZp#w^wlq(@h1(c8y81H#sCnx7v zisHRF&(2J;rquPzM6@HK(~=0=aUBwE^KPwA3P1xki&8AUvEld11NrK3{?b|>4S&Ro zQoZ`VADyQdP|WsyoA!+yv?+aaKi`)QX`z095rnM)+u6SGEANaaBL~5+;=V8ZTHn*k zx>8%t@TUVd4bzk@mKMqBX>{s!LU+eqxaCKk!RbDw_*Gs$967RI#;1OFevW+C#{boOnWN0> z*Nqf1zqfesLbQ?R`0fe@b9WdQN<{l9OqQ^W3BfIYmu{Lo^{L#;KwSIWbnr$>uiBdXpyPq;r{L zlKVn5A*XS!E1K|sVyu#rX^QtilP2U8H5Crggq+T5LQafTaA&b7ng OGT>Z0932DBb@~VJ-Ee6D literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_2944x384.xclbin b/cpp/external/ryzenai_artifacts/ops/softmax_2944x384.xclbin new file mode 100644 index 0000000000000000000000000000000000000000..42809c641ceb3e566813a2fda5542e407037d7c9 GIT binary patch literal 28280 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 MtGvQGcyHhT1D%5X2mk;8 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_4352x384.insts.bin b/cpp/external/ryzenai_artifacts/ops/softmax_4352x384.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..b8958fa54853a4dc6a333773c680c2959f04f778 GIT binary patch literal 2288 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 QeV2D!+2#uC)Y-`Y0NveVUH||9 literal 0 HcmV?d00001 diff --git a/cpp/external/ryzenai_artifacts/ops/softmax_704x96.insts.bin b/cpp/external/ryzenai_artifacts/ops/softmax_704x96.insts.bin new file mode 100644 index 0000000000000000000000000000000000000000..f59c6afe1bcc9da51b66dafe8f4d46acb8802d3e GIT binary patch literal 2288 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 literal 0 HcmV?d00001 diff --git a/cpp/neuralnet/ryzenaibackend.cpp b/cpp/neuralnet/ryzenaibackend.cpp new file mode 100644 index 0000000000..c290c30f26 --- /dev/null +++ b/cpp/neuralnet/ryzenaibackend.cpp @@ -0,0 +1,694 @@ +#ifdef USE_RYZENAI_BACKEND + +/** RyzenAI (AMD NPU) backend. + * + * Structured after cpp/neuralnet/eigenbackend.cpp. Currently all evaluation + * runs on the pure C++ CPU reference forward path (neuralnet/ryzenaireference.h); + * NPU kernel dispatch via XRT will be layered on top of it. Inputs and all + * internal activations are NHWC float32. + */ + +#include "../neuralnet/nninterface.h" + +#include "../neuralnet/desc.h" +#include "../neuralnet/modelversion.h" +#include "../neuralnet/nninputs.h" +#include "../neuralnet/nneval.h" + +#include "../core/test.h" + +#include "../neuralnet/ryzenaidevice.h" +#include "../neuralnet/ryzenaikernel.h" +#include "../neuralnet/ryzenaimatmul.h" +#include "../neuralnet/ryzenaireference.h" +#include "../neuralnet/ryzenaishapes.h" + +using namespace std; + +// LoadedModel / ModelDesc --------------------------------------------------------------------------------------------- + +struct LoadedModel { + ModelDesc modelDesc; + + LoadedModel(const string& fileName, const string& expectedSha256) { + ModelDesc::loadFromFileMaybeGZipped(fileName,modelDesc,expectedSha256); + } + + LoadedModel() = delete; + LoadedModel(const LoadedModel&) = delete; + LoadedModel& operator=(const LoadedModel&) = delete; +}; + +LoadedModel* NeuralNet::loadModelFile(const string& file, const string& expectedSha256) { + LoadedModel* loadedModel = new LoadedModel(file,expectedSha256); + return loadedModel; +} + +void NeuralNet::freeLoadedModel(LoadedModel* loadedModel) { + // NOTE: modelDesc weights must still be intact here if any Workspace still + // references them - but all ComputeHandles are always freed before this. + delete loadedModel; +} + +const ModelDesc& NeuralNet::getModelDesc(const LoadedModel* loadedModel) { + return loadedModel->modelDesc; +} + +// -------------------------------------------------------------------------------------------------------------- + +struct ComputeContext { + const int nnXLen; + const int nnYLen; + + const enabled_t useFP16Mode; + + // Backend-specific configuration, read off of cfg in createComputeContext. + // Device indices themselves (ryzenaiDeviceToUse / ryzenaiDeviceToUseThread) + // are parsed uniformly by setup.cpp and arrive via gpuIdxs / gpuIdxForThisThread. + const string artifactDir; + const string dtype; + const bool forceNpuOnly; + const bool verboseDispatch; + const int maxCols; + const int forceK; + const vector gpuIdxs; + const vector xclbins; + + ComputeContext() = delete; + ComputeContext(const ComputeContext&) = delete; + ComputeContext& operator=(const ComputeContext&) = delete; + + ComputeContext( + int nnX, + int nnY, + enabled_t fp16Mode, + const string& aDir, + const string& dt, + bool forceNpu, + bool verbose, + int maxColumns, + int forceReduceDim, + const vector& gIdxs, + const vector& xcl + ) + : nnXLen(nnX), + nnYLen(nnY), + useFP16Mode(fp16Mode), + artifactDir(aDir), + dtype(dt), + forceNpuOnly(forceNpu), + verboseDispatch(verbose), + maxCols(maxColumns), + forceK(forceReduceDim), + gpuIdxs(gIdxs), + xclbins(xcl) + {} + ~ComputeContext() {} +}; + +// -------------------------------------------------------------------------------------------------------------- + +struct ComputeHandle { + ComputeContext* context; + bool inputsUseNHWC; + int gpuIdxForThisThread; + + // NOT owned - owned by the LoadedModel, which always outlives this handle. + // Do not call releaseWeights() on it: the workspace references its weights. + const ModelDesc& modelDesc; + + RyzenAIRef::Workspace* workspace; + + // Dense-layer accelerator. Null when no NPU/artifact is usable, in which case + // the workspace runs entirely on the CPU reference path. + RyzenAIMatMul::Accel* accel; + string accelInitError; + Logger* logger; // not owned; may be null + + // Output buffers for RyzenAIRef::forward(), allocated once per handle. + vector policyBuf; + vector policyPassBuf; + vector valueBuf; + vector scoreValueBuf; + vector ownershipBuf; + + ComputeHandle() = delete; + ComputeHandle(const ComputeHandle&) = delete; + ComputeHandle& operator=(const ComputeHandle&) = delete; + + ComputeHandle( + ComputeContext* ctx, + const LoadedModel& loadedModel, + int maxBatchSize, + bool iNHWC, + int gpuIdx, + Logger* lg + ) + : context(ctx), + inputsUseNHWC(iNHWC), + gpuIdxForThisThread(gpuIdx), + modelDesc(loadedModel.modelDesc), + workspace(NULL), + accel(NULL), + logger(lg) + { + workspace = RyzenAIRef::createWorkspace(modelDesc,maxBatchSize,context->nnXLen,context->nnYLen); + RyzenAIRef::setProfileEnabled(context->verboseDispatch); + + RyzenAIMatMul::Options options; + options.artifactDir = context->artifactDir; + options.deviceIdx = gpuIdx; + options.dtype = context->dtype; + options.maxCols = context->maxCols; + options.forceK = context->forceK; + string accelErr; + accel = RyzenAIMatMul::create(options,accelErr); + if(accel != NULL) + RyzenAIRef::setMatMulAccel(workspace,accel); + else + accelInitError = accelErr; + + const int nnXLen = context->nnXLen; + const int nnYLen = context->nnYLen; + policyBuf = vector((size_t)maxBatchSize * nnXLen * nnYLen * modelDesc.numPolicyChannels); + policyPassBuf = vector((size_t)maxBatchSize * modelDesc.numPolicyChannels); + valueBuf = vector((size_t)maxBatchSize * modelDesc.numValueChannels); + scoreValueBuf = vector((size_t)maxBatchSize * modelDesc.numScoreValueChannels); + ownershipBuf = vector((size_t)maxBatchSize * nnXLen * nnYLen * modelDesc.numOwnershipChannels); + } + + ~ComputeHandle() { + // Report the NPU/CPU split here rather than at startup: how many dense + // layers were actually accelerated is only known after evaluating. + if(logger != NULL && accel != NULL && context->verboseDispatch) + logger->write(RyzenAIMatMul::report(accel)); + if(logger != NULL && context->verboseDispatch) + logger->write(RyzenAIRef::profileReport()); + + // The workspace holds a bare pointer to the accelerator, so it has to stop + // referring to it before the accelerator's device buffers go away. + if(workspace != NULL) + RyzenAIRef::setMatMulAccel(workspace,NULL); + if(accel != NULL) + RyzenAIMatMul::free(accel); + accel = NULL; + if(workspace != NULL) + RyzenAIRef::freeWorkspace(workspace); + workspace = NULL; + } +}; + +//-------------------------------------------------------------- + +struct InputBuffers { + int maxBatchSize; + + size_t singleInputElts; + size_t singleInputGlobalElts; + size_t singleInputMetaElts; + + size_t singlePolicyPassResultElts; + size_t singlePolicyResultElts; + size_t singleValueResultElts; + size_t singleScoreValueResultElts; + size_t singleOwnershipResultElts; + + std::vector spatialInput; + std::vector globalInput; + std::vector metaInput; + + InputBuffers(const LoadedModel* loadedModel, int maxBatchSz, int nnXLen, int nnYLen) { + const ModelDesc& m = loadedModel->modelDesc; + + maxBatchSize = maxBatchSz; + singleInputElts = m.numInputChannels * nnXLen * nnYLen; + singleInputGlobalElts = m.numInputGlobalChannels; + singleInputMetaElts = m.numInputMetaChannels; + + singlePolicyPassResultElts = (size_t)(m.numPolicyChannels); + singlePolicyResultElts = (size_t)(m.numPolicyChannels * nnXLen * nnYLen); + singleValueResultElts = (size_t)m.numValueChannels; + singleScoreValueResultElts = (size_t)m.numScoreValueChannels; + singleOwnershipResultElts = (size_t)m.numOwnershipChannels * nnXLen * nnYLen; + + testAssert(NNModelVersion::getNumSpatialFeatures(m.modelVersion) == m.numInputChannels); + testAssert(NNModelVersion::getNumGlobalFeatures(m.modelVersion) == m.numInputGlobalChannels); + if(m.numInputMetaChannels > 0) { + testAssert(SGFMetadata::METADATA_INPUT_NUM_CHANNELS == m.numInputMetaChannels); + } + + spatialInput = vector(m.numInputChannels * nnXLen * nnYLen * maxBatchSize); + globalInput = vector(m.numInputGlobalChannels * maxBatchSize); + if(m.numInputMetaChannels > 0) + metaInput = vector(m.numInputMetaChannels * maxBatchSize); + else + metaInput = vector(1); + } + + ~InputBuffers() { } + + InputBuffers() = delete; + InputBuffers(const InputBuffers&) = delete; + InputBuffers& operator=(const InputBuffers&) = delete; +}; + +InputBuffers* NeuralNet::createInputBuffers(const LoadedModel* loadedModel, int maxBatchSize, int nnXLen, int nnYLen) { + return new InputBuffers(loadedModel, maxBatchSize, nnXLen, nnYLen); +} +void NeuralNet::freeInputBuffers(InputBuffers* inputBuffers) { + delete inputBuffers; +} + +// NeuralNet ----------------------------------------------------------------------------------------------------------- + +void NeuralNet::globalInitialize() { + // Must happen before the first XRT call of the process. printDevices() also + // runs before any compute context exists, so it calls this too. + RyzenAIDevice::ensureRuntimeLibraryPath(); +} + +void NeuralNet::globalCleanup() { + // no-op +} + +//------------------------------------------------------------------------------ + +ComputeContext* NeuralNet::createComputeContext( + const std::vector& gpuIdxs, + Logger* logger, + int nnXLen, + int nnYLen, + const string& homeDataDirOverride, + enabled_t useFP16Mode, + const LoadedModel* loadedModel, + ConfigParser& cfg +) { + string artifactDirConfig = cfg.contains("ryzenaiArtifactDir") ? cfg.getString("ryzenaiArtifactDir") : ""; + // auto | bf16 | bfp16. Both bf16 and bfp16 hand the NPU bfloat16 operands and + // read float32 back - the difference is entirely inside the kernel - so this + // only selects which artifact directory is loaded. See resolveDtype() for why + // auto currently means bf16 even on hardware that supports bfp16. + string dtypeStr = cfg.contains("ryzenaiDtype") ? cfg.getString("ryzenaiDtype") : "auto"; + RyzenAIKernel::Dtype dtype = RyzenAIKernel::Dtype::Auto; + if(!RyzenAIKernel::parseDtype(dtypeStr, dtype)) + throw StringError( + "RyzenAI backend: unrecognized ryzenaiDtype = '" + dtypeStr + "', expected auto, bf16 or bfp16" + ); + bool forceNpuOnly = cfg.contains("ryzenaiForceNpuOnly") ? cfg.getBool("ryzenaiForceNpuOnly") : false; + bool verboseDispatch = cfg.contains("ryzenaiVerboseDispatch") ? cfg.getBool("ryzenaiVerboseDispatch") : false; + // Wider is not automatically faster: at one board per evaluation the array + // is starved and the fixed dispatch cost dominates, so 4 columns measured + // faster than 8. 0 means "as wide as the device allows". + int maxCols = cfg.contains("ryzenaiMaxColumns") ? cfg.getInt("ryzenaiMaxColumns",0,64) : 4; + // Run every layer from one xclbin, trading zero-padded arithmetic for not + // switching hardware contexts. 0 = pick the closest K per layer. + // -1 (the default) means decide from the model: see RyzenAIShapes::chooseSingleK. + // 0 disables it, a positive value forces that reduction dim. + int forceK = cfg.contains("ryzenaiForceK") ? cfg.getInt("ryzenaiForceK",-1,65536) : -1; + if(forceK < 0) { + // 4x is where the measured trade turns: below it the extra zero-padded + // arithmetic is lost in the noise (NPU compute is ~1% of a forward pass), + // above it the padding is real work on models whose GEMMs are already big. + forceK = loadedModel != NULL ? RyzenAIShapes::chooseSingleK(loadedModel->modelDesc, nnXLen, nnYLen, 4.0) : 0; + } + + string artifactDir = RyzenAIDevice::resolveArtifactDir(artifactDirConfig); + + if(logger != NULL) { + logger->write("RyzenAI backend: " + RyzenAIDevice::ensureRuntimeLibraryPath()); + logger->write("RyzenAI backend: " + RyzenAIDevice::describeRuntime()); + logger->write("RyzenAI backend: artifact dir = " + artifactDir); + logger->write("RyzenAI backend: dtype = " + dtypeStr + " (resolved: " + + RyzenAIKernel::dtypeName(RyzenAIKernel::resolveDtype(dtype, RyzenAIDevice::archOfDevice(-1))) + ")"); + if(useFP16Mode == enabled_t::True) + logger->write("RyzenAI backend: useFP16 = true was requested, but the current reference path always computes in fp32"); + } + + vector xclbins = RyzenAIDevice::listXclbins(artifactDir); + if(xclbins.empty()) { + if(forceNpuOnly) { + throw StringError( + "RyzenAI backend: ryzenaiForceNpuOnly = true but no .xclbin NPU kernel artifacts were found in " + + artifactDir + " - NPU dispatch is not possible" + ); + } + if(logger != NULL) { + logger->write( + "RyzenAI backend: no .xclbin NPU kernel artifacts found in " + artifactDir + + " - running on the CPU reference forward path, NPU acceleration is not enabled yet" + ); + } + } + else if(cfg.contains("ryzenaiSelfTest") && cfg.getBool("ryzenaiSelfTest")) { + // Loads every artifact, dispatches it on the NPU and checks it against a + // plain-C++ GEMM. Opt-in because it costs a few seconds of startup, but it + // is the fastest way to tell whether a machine's NPU/driver/artifact set is + // actually working. + if(logger != NULL) + logger->write(RyzenAIKernel::selfTest(artifactDir, -1)); + } + + // Which GEMM shapes this model actually needs. An xclbin bakes in the + // reduction dim K (and only K -- M and N ride in the instruction stream), so + // this is what decides which artifacts must exist and which layers fall back + // to the CPU reference path. + if(cfg.contains("ryzenaiShapeReport") && cfg.getBool("ryzenaiShapeReport")) { + if(logger != NULL && loadedModel != NULL) + logger->write(RyzenAIShapes::report(loadedModel->modelDesc, nnXLen, nnYLen)); + } + + if(!xclbins.empty()) { + if(logger != NULL) { + // Count only: the shipped grid is a few hundred files, and naming them + // all put tens of thousands of characters on one line of every log. + // Which ones actually got loaded is what matters, and verbose dispatch + // reports that per engine. + logger->write( + "RyzenAI backend: found " + Global::uint64ToString((uint64_t)xclbins.size()) + + " NPU kernel artifacts in " + artifactDir + ); + } + } + + ComputeContext* context = new ComputeContext( + nnXLen,nnYLen,useFP16Mode,artifactDir,dtypeStr,forceNpuOnly,verboseDispatch,maxCols,forceK,gpuIdxs,xclbins + ); + return context; +} + +void NeuralNet::freeComputeContext(ComputeContext* computeContext) { + delete computeContext; +} + +//------------------------------------------------------------------------------ + +ComputeHandle* NeuralNet::createComputeHandle( + ComputeContext* context, + const LoadedModel* loadedModel, + Logger* logger, + int maxBatchSize, + bool requireExactNNLen, + bool inputsUseNHWC, + int gpuIdxForThisThread, + int serverThreadIdx +) { + if(logger != NULL) { + logger->write("RyzenAI (AMD NPU) backend thread " + Global::intToString(serverThreadIdx) + ": Model version " + Global::intToString(loadedModel->modelDesc.modelVersion)); + logger->write("RyzenAI (AMD NPU) backend thread " + Global::intToString(serverThreadIdx) + ": Model name: " + loadedModel->modelDesc.name + " (" + loadedModel->modelDesc.getShortInfoString() + ")"); + } + + (void)requireExactNNLen; //We don't bother with mask optimizations if we know exact sizes right now. + + if(!inputsUseNHWC) + throw StringError("RyzenAI backend: inputsUseNHWC = false unsupported (the reference path requires NHWC input)"); + + ComputeHandle* handle = new ComputeHandle(context, *loadedModel, maxBatchSize, inputsUseNHWC, gpuIdxForThisThread, logger); + if(logger != NULL) { + const string prefix = "RyzenAI (AMD NPU) backend thread " + Global::intToString(serverThreadIdx) + ": "; + if(handle->accel == NULL) + logger->write(prefix + "dense layers stay on the CPU (" + handle->accelInitError + ")"); + else if(context->verboseDispatch) + logger->write(prefix + "device index " + Global::intToString(gpuIdxForThisThread) + + ", dense layers offered to the NPU"); + } + return handle; +} + +void NeuralNet::freeComputeHandle(ComputeHandle* gpuHandle) { + delete gpuHandle; +} + + +bool NeuralNet::isUsingFP16(const ComputeHandle* handle) { + (void)handle; + return false; +} + +bool NeuralNet::setIsWarmup(const ComputeHandle* handle, bool isWarmup) { + (void)handle; + (void)isWarmup; + return false; +} + +//------------------------------------------------------------------------------ + +void NeuralNet::getOutput( + ComputeHandle* computeHandle, + InputBuffers* inputBuffers, + int numBatchEltsFilled, + NNResultBuf** inputBufs, + vector& outputs +) { + assert(numBatchEltsFilled <= inputBuffers->maxBatchSize); + assert(numBatchEltsFilled > 0); + const int batchSize = numBatchEltsFilled; + const int nnXLen = computeHandle->context->nnXLen; + const int nnYLen = computeHandle->context->nnYLen; + const ModelDesc& modelDesc = computeHandle->modelDesc; + const int modelVersion = modelDesc.modelVersion; + + const int numSpatialFeatures = NNModelVersion::getNumSpatialFeatures(modelVersion); + const int numGlobalFeatures = NNModelVersion::getNumGlobalFeatures(modelVersion); + const int numMetaFeatures = inputBuffers->singleInputMetaElts; + assert(numSpatialFeatures == modelDesc.numInputChannels); + assert(numSpatialFeatures * nnXLen * nnYLen == inputBuffers->singleInputElts); + assert(numGlobalFeatures == inputBuffers->singleInputGlobalElts); + const int numPolicyChannels = modelDesc.numPolicyChannels; + + for(int nIdx = 0; nIdxspatialInput.data() + (inputBuffers->singleInputElts * nIdx); + float* rowGlobalInput = inputBuffers->globalInput.data() + (inputBuffers->singleInputGlobalElts * nIdx); + float* rowMetaInput = inputBuffers->metaInput.data() + (inputBuffers->singleInputMetaElts * nIdx); + + const float* rowGlobal = inputBufs[nIdx]->rowGlobalBuf.data(); + const float* rowSpatial = inputBufs[nIdx]->rowSpatialBuf.data(); + const float* rowMeta = inputBufs[nIdx]->rowMetaBuf.data(); + const bool hasRowMeta = inputBufs[nIdx]->hasRowMeta; + std::copy(rowGlobal,rowGlobal+numGlobalFeatures,rowGlobalInput); + if(numMetaFeatures > 0) { + testAssert(rowMeta != NULL); + testAssert(hasRowMeta); + std::copy(rowMeta,rowMeta+numMetaFeatures,rowMetaInput); + } + else { + testAssert(!hasRowMeta); + } + SymmetryHelpers::copyInputsWithSymmetry(rowSpatial, rowSpatialInput, 1, nnYLen, nnXLen, numSpatialFeatures, computeHandle->inputsUseNHWC, inputBufs[nIdx]->symmetry); + } + + RyzenAIRef::forward( + computeHandle->workspace, + batchSize, + inputBuffers->spatialInput.data(), + inputBuffers->globalInput.data(), + (numMetaFeatures > 0 ? inputBuffers->metaInput.data() : NULL), + computeHandle->policyBuf.data(), + computeHandle->policyPassBuf.data(), + computeHandle->valueBuf.data(), + computeHandle->scoreValueBuf.data(), + computeHandle->ownershipBuf.data() + ); + + assert(inputBuffers->singlePolicyPassResultElts == numPolicyChannels); + assert(inputBuffers->singlePolicyResultElts == numPolicyChannels * nnXLen * nnYLen); + + assert(outputs.size() == batchSize); + + float policyProbsTmp[NNPos::MAX_NN_POLICY_SIZE]; + + const float* policyData = computeHandle->policyBuf.data(); + const float* policyPassData = computeHandle->policyPassBuf.data(); + const float* valueData = computeHandle->valueBuf.data(); + const float* scoreValueData = computeHandle->scoreValueBuf.data(); + const float* ownershipData = computeHandle->ownershipBuf.data(); + + for(int row = 0; row < batchSize; row++) { + NNOutput* output = outputs[row]; + assert(output->nnXLen == nnXLen); + assert(output->nnYLen == nnYLen); + float policyOptimism = (float)inputBufs[row]->policyOptimism; + + const float* policyPassSrcBuf = policyPassData + row * numPolicyChannels; + const float* policySrcBuf = policyData + row * numPolicyChannels * nnXLen * nnYLen; + float* policyProbs = output->policyProbs; + + // These are in logits, the client does the postprocessing to turn them into + // policy probabilities and white game outcome probabilities + // Also we don't fill in the nnHash here either + // Handle version >= 12 policy optimism + if(numPolicyChannels == 2 || (numPolicyChannels == 4 && modelVersion >= 16)) { + // NHWC + for(int i = 0; isymmetry); + policyProbs[nnXLen*nnYLen] = policyPassSrcBuf[0] + (policyPassSrcBuf[1] - policyPassSrcBuf[0]) * policyOptimism; + } + else { + assert(numPolicyChannels == 1); + SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf, policyProbs, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + policyProbs[inputBuffers->singlePolicyResultElts] = policyPassSrcBuf[0]; + } + + int numValueChannels = modelDesc.numValueChannels; + assert(numValueChannels == 3); + output->whiteWinProb = valueData[row * numValueChannels]; + output->whiteLossProb = valueData[row * numValueChannels + 1]; + output->whiteNoResultProb = valueData[row * numValueChannels + 2]; + + //As above, these are NOT actually from white's perspective, but rather the player to move. + //As usual the client does the postprocessing. + if(output->whiteOwnerMap != NULL) { + const float* ownershipSrcBuf = ownershipData + row * nnXLen * nnYLen; + assert(modelDesc.numOwnershipChannels == 1); + SymmetryHelpers::copyOutputsWithSymmetry(ownershipSrcBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + } + + if(modelVersion >= 9) { + int numScoreValueChannels = modelDesc.numScoreValueChannels; + assert(numScoreValueChannels == 6); + output->whiteScoreMean = scoreValueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = scoreValueData[row * numScoreValueChannels + 1]; + output->whiteLead = scoreValueData[row * numScoreValueChannels + 2]; + output->varTimeLeft = scoreValueData[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = scoreValueData[row * numScoreValueChannels + 4]; + output->shorttermScoreError = scoreValueData[row * numScoreValueChannels + 5]; + } + else if(modelVersion >= 8) { + int numScoreValueChannels = modelDesc.numScoreValueChannels; + assert(numScoreValueChannels == 4); + output->whiteScoreMean = scoreValueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = scoreValueData[row * numScoreValueChannels + 1]; + output->whiteLead = scoreValueData[row * numScoreValueChannels + 2]; + output->varTimeLeft = scoreValueData[row * numScoreValueChannels + 3]; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(modelVersion >= 4) { + int numScoreValueChannels = modelDesc.numScoreValueChannels; + assert(numScoreValueChannels == 2); + output->whiteScoreMean = scoreValueData[row * numScoreValueChannels]; + output->whiteScoreMeanSq = scoreValueData[row * numScoreValueChannels + 1]; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else if(modelVersion >= 3) { + int numScoreValueChannels = modelDesc.numScoreValueChannels; + assert(numScoreValueChannels == 1); + output->whiteScoreMean = scoreValueData[row * numScoreValueChannels]; + //Version 3 neural nets don't have any second moment output, implicitly already folding it in, so we just use the mean squared + output->whiteScoreMeanSq = output->whiteScoreMean * output->whiteScoreMean; + output->whiteLead = output->whiteScoreMean; + output->varTimeLeft = 0; + output->shorttermWinlossError = 0; + output->shorttermScoreError = 0; + } + else { + ASSERT_UNREACHABLE; + } + } +} + +//------------------------------------------------------------------------------ + +void NeuralNet::printDevices() { + cout << RyzenAIDevice::ensureRuntimeLibraryPath() << endl; + cout << RyzenAIDevice::describeRuntime() << endl; +} + +// FOR TESTING --------------------------------------------------------------------------------------------------------- +bool NeuralNet::testEvaluateConv( + const ConvLayerDesc* desc, + int batchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const std::vector& inputBuffer, + std::vector& outputBuffer +) { + (void)desc; + (void)batchSize; + (void)nnXLen; + (void)nnYLen; + (void)useFP16; + (void)useNHWC; + (void)inputBuffer; + (void)outputBuffer; + return false; +} + +bool NeuralNet::testEvaluateBatchNorm( + const BatchNormLayerDesc* desc, + int batchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const std::vector& inputBuffer, + const std::vector& maskBuffer, + std::vector& outputBuffer +) { + (void)desc; + (void)batchSize; + (void)nnXLen; + (void)nnYLen; + (void)useFP16; + (void)useNHWC; + (void)inputBuffer; + (void)maskBuffer; + (void)outputBuffer; + return false; +} + +bool NeuralNet::testEvaluateResidualBlock( + const ResidualBlockDesc* desc, + int batchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const std::vector& inputBuffer, + const std::vector& maskBuffer, + std::vector& outputBuffer +) { + (void)desc; + (void)batchSize; + (void)nnXLen; + (void)nnYLen; + (void)useFP16; + (void)useNHWC; + (void)inputBuffer; + (void)maskBuffer; + (void)outputBuffer; + return false; +} + +bool NeuralNet::testEvaluateGlobalPoolingResidualBlock( + const GlobalPoolingResidualBlockDesc* desc, + int batchSize, + int nnXLen, + int nnYLen, + bool useFP16, + bool useNHWC, + const std::vector& inputBuffer, + const std::vector& maskBuffer, + std::vector& outputBuffer +) { + (void)desc; + (void)batchSize; + (void)nnXLen; + (void)nnYLen; + (void)useFP16; + (void)useNHWC; + (void)inputBuffer; + (void)maskBuffer; + (void)outputBuffer; + return false; +} + +#endif // USE_RYZENAI_BACKEND diff --git a/cpp/neuralnet/ryzenaidevice.cpp b/cpp/neuralnet/ryzenaidevice.cpp new file mode 100644 index 0000000000..4295d3d85c --- /dev/null +++ b/cpp/neuralnet/ryzenaidevice.cpp @@ -0,0 +1,225 @@ +#include "../neuralnet/ryzenaidevice.h" + +#include +#include + +#include "../core/global.h" +#include "../core/os.h" +#include "../dataio/homedata.h" + +#ifdef OS_IS_WINDOWS +#include +#endif + +// XRT's headers are noisy under MSVC's default warning level and pull in a lot +// of Windows machinery; keep them isolated to this translation unit. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4100 4245 4267 4996) +#endif +#include "xrt/xrt_device.h" +#include "xrt/experimental/xrt_system.h" +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "../external/filesystem-1.5.8/include/ghc/filesystem.hpp" + +namespace gfs = ghc::filesystem; + +using namespace std; + +int RyzenAIDevice::maxColumns(Arch arch) { + switch(arch) { + case Arch::NPU1: return 4; + case Arch::NPU2: return 8; + default: return 0; + } +} + +const char* RyzenAIDevice::archName(Arch arch) { + switch(arch) { + case Arch::NPU1: return "npu1"; + case Arch::NPU2: return "npu2"; + default: return "unknown"; + } +} + +RyzenAIDevice::Arch RyzenAIDevice::archOfDeviceName(const string& name) { + const string lowered = Global::toLower(name); + auto has = [&lowered](const char* needle) { return lowered.find(needle) != string::npos; }; + + // XDNA2 / aie2p + if(has("strix") || has("krackan") || has("halo") || has("npu2")) + return Arch::NPU2; + // XDNA1 / aie2 + if(has("phoenix") || has("hawk") || has("npu1")) + return Arch::NPU1; + return Arch::Unknown; +} + +namespace { + +string repointXrtIfNeeded() { +#ifdef OS_IS_WINDOWS + static const char* const kRuntimeLib = "xrt_core.dll"; +#else + static const char* const kRuntimeLib = "libxrt_core.so"; +#endif + + auto hasRuntime = [](const string& dir) { + if(dir.size() <= 0) + return false; + std::error_code ec; + return gfs::exists(gfs::u8path(dir) / kRuntimeLib, ec); + }; + + string current; + const char* env = std::getenv("XILINX_XRT"); + if(env != NULL) + current = env; + if(hasRuntime(current)) + return "XILINX_XRT = " + current; + + string exeDir; + try { + const vector dirs = HomeData::getDefaultFilesDirs(); + if(dirs.size() > 0) + exeDir = dirs[0]; + } + catch(const std::exception&) { + // Leave exeDir empty; handled below. + } + if(!hasRuntime(exeDir)) { + if(current.size() > 0) + return "XILINX_XRT = " + current + " (no " + kRuntimeLib + + " there, and none next to the executable either)"; + return string("XILINX_XRT is unset and no ") + kRuntimeLib + + " sits next to the executable; relying on the system library path"; + } + + // Both the Win32 environment block and the CRT copy need updating: XRT lives + // in its own DLL with its own CRT, and which one it reads is not contractual. +#ifdef OS_IS_WINDOWS + SetEnvironmentVariableA("XILINX_XRT", exeDir.c_str()); + _putenv_s("XILINX_XRT", exeDir.c_str()); +#else + setenv("XILINX_XRT", exeDir.c_str(), 1); +#endif + + if(current.size() > 0) + return "XILINX_XRT was " + current + ", which has no " + kRuntimeLib + + "; repointed at " + exeDir; + return "XILINX_XRT set to " + exeDir; +} + +} // namespace + +string RyzenAIDevice::ensureRuntimeLibraryPath() { + // Only the first call changes anything. Later callers are logging paths, and + // caching means they report the repair that actually happened rather than the + // already-repaired state, which reads as if nothing had been wrong. + static const string description = repointXrtIfNeeded(); + return description; +} + +RyzenAIDevice::Arch RyzenAIDevice::archOfDevice(int deviceIdx) { + try { + xrt::device device((unsigned int)(deviceIdx < 0 ? 0 : deviceIdx)); + return archOfDeviceName(device.get_info()); + } + catch(const std::exception&) { + return Arch::Unknown; + } +} + +vector RyzenAIDevice::enumerate() { + vector devices; + unsigned int numDevices = 0; + try { + numDevices = xrt::system::enumerate_devices(); + } + catch(const std::exception&) { + // No driver, no device, or an XRT that cannot talk to it. Not an error + // here - the caller reports "none found". + return devices; + } + + for(unsigned int i = 0; i < numDevices; i++) { + Info info; + info.index = (int)i; + info.arch = Arch::Unknown; + try { + xrt::device device(i); + info.name = device.get_info(); + info.bdf = device.get_info(); + info.arch = archOfDeviceName(info.name); + } + catch(const std::exception& e) { + // Report the device as present but undescribable rather than dropping it, + // so that a device that exists-but-is-busy is still visible to the user. + info.name = string("(could not query: ") + e.what() + ")"; + } + devices.push_back(info); + } + return devices; +} + +string RyzenAIDevice::describeRuntime() { + vector devices = enumerate(); + if(devices.size() <= 0) + return string( + "No NPU devices found by XRT. Check that the AMD NPU driver is installed and that the NPU is " + "enabled in the BIOS." + ); + + string ret = "Found " + Global::uint64ToString((uint64_t)devices.size()) + " NPU device(s):"; + for(size_t i = 0; i < devices.size(); i++) { + ret += "\n Device " + Global::intToString(devices[i].index) + ": " + devices[i].name + + (devices[i].bdf.size() > 0 ? (" [" + devices[i].bdf + "]") : string("")); + if(devices[i].arch == Arch::Unknown) + ret += " - unrecognized architecture, NPU acceleration unavailable (will use the CPU reference path)"; + else + ret += " - " + string(archName(devices[i].arch)) + ", up to " + + Global::intToString(maxColumns(devices[i].arch)) + " columns"; + } + return ret; +} + +string RyzenAIDevice::resolveArtifactDir(const string& configuredDir) { + if(configuredDir.size() > 0) + return configuredDir; + + // Kernel artifacts are deployed next to the executable, so that an install is + // just exe + dlls + this directory. + vector dirs = HomeData::getDefaultFilesDirs(); + if(dirs.size() > 0) { + gfs::path p = gfs::u8path(dirs[0]) / "ryzenai"; + return p.u8string(); + } + return string("ryzenai"); +} + +vector RyzenAIDevice::listXclbins(const string& dir) { + vector names; + try { + gfs::path p = gfs::u8path(dir); + if(!gfs::exists(p) || !gfs::is_directory(p)) + return names; + // Artifacts are grouped into per-dtype subdirectories (bf16/, ...), so + // recurse and report paths relative to dir rather than bare filenames. + for(const auto& entry : gfs::recursive_directory_iterator(p)) { + if(!gfs::is_regular_file(entry.path())) + continue; + string filename = entry.path().filename().u8string(); + if(Global::isSuffix(Global::toLower(filename), ".xclbin")) + names.push_back(gfs::relative(entry.path(), p).generic_u8string()); + } + } + catch(const std::exception&) { + // An unreadable directory is equivalent to an empty one for our purposes. + return names; + } + std::sort(names.begin(), names.end()); + return names; +} diff --git a/cpp/neuralnet/ryzenaidevice.h b/cpp/neuralnet/ryzenaidevice.h new file mode 100644 index 0000000000..0bb53872b3 --- /dev/null +++ b/cpp/neuralnet/ryzenaidevice.h @@ -0,0 +1,82 @@ +/* + * XRT device discovery and NPU kernel-artifact (xclbin) location for the + * RyzenAI backend. + * + * This layer is deliberately the ONLY place that includes XRT headers, so that + * the rest of the backend can be built and reasoned about without them. + */ + +#ifndef NEURALNET_RYZENAI_DEVICE_H_ +#define NEURALNET_RYZENAI_DEVICE_H_ + +#include +#include + +namespace RyzenAIDevice { + + // AIE architecture family. Kernel binaries are per-family and NOT + // interchangeable: XDNA2 cores run the aie2p ISA, XDNA1 cores run aie2, so an + // xclbin built for one will not load on the other. The families also differ in + // width - XDNA1 exposes 4 columns (16 compute tiles) to the toolchain, XDNA2 + // exposes 8 (32 tiles) - and only XDNA2 supports the BFP16 path. + enum class Arch { Unknown, NPU1, NPU2 }; + + // Largest column count the toolchain can target for a family, which is also + // the widest artifact variant we ship for it. + int maxColumns(Arch arch); + const char* archName(Arch arch); // "npu1" / "npu2" / "unknown" + + struct Info { + int index; + std::string name; // e.g. "NPU Strix" + std::string bdf; // e.g. "00c2:00:01.1" + Arch arch; + }; + + // Classifies a device by the product name XRT reports. Substring matching is + // all that is available: XRT exposes no architecture field, so new silicon + // will read as Unknown until its name is added here (which degrades to the CPU + // reference path rather than loading a wrong-ISA xclbin). + Arch archOfDeviceName(const std::string& name); + + // Architecture of one device, or Unknown if it cannot be opened/classified. + // deviceIdx < 0 selects the default device. + Arch archOfDevice(int deviceIdx); + + // Makes XRT able to find its own runtime libraries, and must be called before + // any other function here. + // + // XRT resolves xrt_core from $XILINX_XRT. The Windows XRT *SDK* installs only + // headers and import libraries under that path - the runtime DLLs live in the + // driver store and are shipped next to katago.exe - so a machine where + // XILINX_XRT points at the SDK (the natural thing to do when building) has + // every XRT call fail with "No such library ...\\xrt_core.dll", which surfaces + // as "no NPU devices found" rather than as anything pointing at the cause. + // + // If the variable is unset or points somewhere without xrt_core, and the DLL + // is present beside the executable, this repoints it there. Returns a + // description of what it did, for logging; never throws. + std::string ensureRuntimeLibraryPath(); + + // Enumerates NPU devices visible to XRT. Never throws: on any XRT failure it + // returns an empty vector, since callers (notably printDevices) must stay + // usable on machines with no NPU or no driver. + std::vector enumerate(); + + // Human-readable one-line summary of the XRT/driver stack, e.g. for logging. + // Returns an explanatory string rather than throwing if XRT is unavailable. + std::string describeRuntime(); + + // Directory holding the NPU kernel binaries. Resolution order: + // 1. configuredDir, if non-empty (the ryzenaiArtifactDir config key) + // 2. "/ryzenai" + // The directory is not required to exist; callers decide how to react. + std::string resolveArtifactDir(const std::string& configuredDir); + + // Names (not full paths) of the *.xclbin files found directly under dir, or + // an empty vector if dir does not exist. Sorted, for reproducible logging. + std::vector listXclbins(const std::string& dir); + +} // namespace RyzenAIDevice + +#endif // NEURALNET_RYZENAI_DEVICE_H_ diff --git a/cpp/neuralnet/ryzenaikernel.cpp b/cpp/neuralnet/ryzenaikernel.cpp new file mode 100644 index 0000000000..1e4a4d7829 --- /dev/null +++ b/cpp/neuralnet/ryzenaikernel.cpp @@ -0,0 +1,738 @@ +#include "../neuralnet/ryzenaikernel.h" + +#include +#include +#if defined(_M_X64) || defined(__x86_64__) || defined(__SSE2__) +#define RYZENAI_BF16_SSE2 1 +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "../core/fileutils.h" +#include "../core/global.h" +#include "../neuralnet/ryzenaimanifest.h" +#include "../neuralnet/ryzenaisequence.h" + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4100 4245 4267 4996) +#endif +#include "xrt/xrt_bo.h" +#include "xrt/xrt_device.h" +#include "xrt/xrt_hw_context.h" +#include "xrt/xrt_kernel.h" +#include "xrt/experimental/xrt_xclbin.h" +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "../external/filesystem-1.5.8/include/ghc/filesystem.hpp" + +namespace gfs = ghc::filesystem; + +using namespace std; + +namespace { + + string variantDir( + const string& artifactDir, RyzenAIKernel::Dtype dtype, RyzenAIDevice::Arch arch, int cols, + bool swiglu = false) { + return (gfs::u8path(artifactDir) / RyzenAIKernel::dtypeName(dtype) / + (string(RyzenAIDevice::archName(arch)) + "_" + Global::intToString(cols) + "col" + + (swiglu ? "_swiglu" : ""))) + .u8string(); + } + + // Artifact file names carry the shape they were compiled at. Only K matters + // to the binary, so the K is parsed out and the rest ignored -- which also + // means the older gemm_bf16_MKN names and a plain gemm_bf16_K + // both resolve correctly. + bool parseKFromStem(const string& stem, int& kOut) { + const size_t at = stem.rfind('K'); + if(at == string::npos) + return false; + size_t end = at + 1; + while(end < stem.size() && stem[end] >= '0' && stem[end] <= '9') + end++; + if(end == at + 1) + return false; + try { + kOut = Global::stringToInt(stem.substr(at + 1, end - at - 1)); + } + catch(const std::exception&) { + return false; + } + return kOut > 0; + } + + // The grid names artifacts by the only dimension that matters to the binary. + bool isCanonicalStem(const string& stem, int k) { + return stem == "gemm_bf16_K" + Global::intToString(k); + } + + // K -> xclbin path for one variant directory. + map scanVariant(const string& dir) { + map byK; + std::set canonical; + std::error_code ec; + if(!gfs::is_directory(gfs::u8path(dir), ec)) + return byK; + for(auto& entry : gfs::directory_iterator(gfs::u8path(dir), ec)) { + if(!entry.is_regular_file(ec)) + continue; + const gfs::path p = entry.path(); + if(p.extension().u8string() != ".xclbin") + continue; + const string stem = p.stem().u8string(); + int k = 0; + if(!parseKFromStem(stem, k)) + continue; + // Older artifacts are named for the full shape they happened to be + // compiled at, which can collide with a grid entry for the same K. Both + // are correct binaries, but prefer the grid's so the choice does not + // depend on directory order. + const bool canon = isCanonicalStem(stem, k); + if(canon || byK.find(k) == byK.end()) { + if(canon || canonical.find(k) == canonical.end()) + byK[k] = p.u8string(); + if(canon) + canonical.insert(k); + } + } + return byK; + } + + // mlir-aie appends a generated suffix to the kernel name, so match on the + // prefix over what the xclbin actually declares rather than assuming a + // literal name. + string findKernelName(const xrt::xclbin& xclbin, const string& prefix) { + for(const auto& kernel : xclbin.get_kernels()) { + string name = kernel.get_name(); + if(name.rfind(prefix, 0) == 0) + return name; + } + return string(); + } + + int roundUpTo(int v, int q) { + return ((v + q - 1) / q) * q; + } + +} // namespace + +struct RyzenAIKernel::Engine { + RyzenAIKernel::EngineInfo info; + RyzenAISequence::Arch seqArch = RyzenAISequence::Arch::NPU2; + + xrt::device device; + xrt::xclbin xclbin; + xrt::hw_context context; + xrt::kernel kernel; + + // Scratch grown on demand. A and C are per-dispatch; the instruction stream + // changes whenever (M, N) changes, so it is uploaded per dispatch too, but + // only re-generated when the shape actually differs from the last one. + xrt::bo boInstr; + xrt::bo boA; + xrt::bo boC; + size_t capInstrBytes = 0; + size_t capABytes = 0; + size_t capCBytes = 0; + + vector instr; + int lastM = 0; + int lastN = 0; + + // Bumped whenever a scratch BO is reallocated, so cached runs know their + // bound arguments are stale. + uint64_t bufferGeneration = 0; + + RyzenAIKernel::Timings timings; +}; + +struct RyzenAIKernel::Weights { + xrt::bo bo; + int paddedN = 0; + size_t bytes = 0; // K * paddedN * sizeof(uint16_t), for rewriteWeights + + // Building an xrt::run and binding six arguments costs about as much as the + // GEMM itself at these sizes, and the binding only changes when a scratch BO + // moves, so the run is cached per weight set. + xrt::run run; + bool runValid = false; + uint64_t runGeneration = 0; + uint32_t lastNumInstr = 0; +}; + +struct RyzenAIKernel::Op { + xrt::device device; + xrt::xclbin xclbin; + xrt::hw_context context; + xrt::kernel kernel; + xrt::bo boInstr; + std::vector boIns; + xrt::bo boC; + xrt::run run; + std::vector inBytes; + size_t bytesC = 0; +}; + +void RyzenAIKernel::floatToBf16Bulk(const float* src, uint16_t* dst, size_t n) { + size_t i = 0; +#ifdef RYZENAI_BF16_SSE2 + const __m128i expMask = _mm_set1_epi32(0x7F800000); + const __m128i mantMask = _mm_set1_epi32(0x007FFFFF); + const __m128i one = _mm_set1_epi32(1); + const __m128i bias = _mm_set1_epi32(0x7FFF); + const __m128i quiet = _mm_set1_epi32(0x0040); + const __m128i zero = _mm_setzero_si128(); + // Packing 32-bit lanes down to 16 has no unsigned form in SSE2, so shift the + // values into the signed range first and shift them back afterwards. Every + // value is in [0, 0xFFFF] by then, so the bias lands them exactly inside + // int16 and the saturating pack never actually saturates. + const __m128i packBias = _mm_set1_epi32(0x8000); + const __m128i unBias = _mm_set1_epi16((short)0x8000); + + auto round4 = [&](const float* p) { + const __m128i bits = _mm_loadu_si128(reinterpret_cast(p)); + const __m128i isExpAllOnes = _mm_cmpeq_epi32(_mm_and_si128(bits, expMask), expMask); + const __m128i mantIsZero = _mm_cmpeq_epi32(_mm_and_si128(bits, mantMask), zero); + const __m128i isNan = _mm_andnot_si128(mantIsZero, isExpAllOnes); + const __m128i lsb = _mm_and_si128(_mm_srli_epi32(bits, 16), one); + const __m128i rounded = + _mm_srli_epi32(_mm_add_epi32(_mm_add_epi32(bits, bias), lsb), 16); + const __m128i nanVal = _mm_or_si128(_mm_srli_epi32(bits, 16), quiet); + return _mm_or_si128(_mm_and_si128(isNan, nanVal), _mm_andnot_si128(isNan, rounded)); + }; + + for(; i + 8 <= n; i += 8) { + const __m128i lo = _mm_sub_epi32(round4(src + i), packBias); + const __m128i hi = _mm_sub_epi32(round4(src + i + 4), packBias); + _mm_storeu_si128( + reinterpret_cast<__m128i*>(dst + i), _mm_add_epi16(_mm_packs_epi32(lo, hi), unBias)); + } +#endif + for(; i < n; i++) + dst[i] = floatToBf16(src[i]); +} + +const char* RyzenAIKernel::dtypeName(Dtype dtype) { + return dtype == Dtype::Bfp16 ? "bfp16" : "bf16"; +} + +bool RyzenAIKernel::parseDtype(const string& s, Dtype& out) { + const string lowered = Global::toLower(Global::trim(s)); + if(lowered == "auto") { out = Dtype::Auto; return true; } + if(lowered == "bf16") { out = Dtype::Bf16; return true; } + if(lowered == "bfp16") { out = Dtype::Bfp16; return true; } + return false; +} + +RyzenAIKernel::Dtype RyzenAIKernel::resolveDtype(Dtype requested, RyzenAIDevice::Arch arch) { + if(requested != Dtype::Auto) + return requested; + + // Auto means BFP16 where the hardware has it, which is XDNA2 only. + // + // A single BFP16 GEMM carries roughly 3% relative error against a float32 + // reference, against ~2e-5 for bf16, and that gap is what kept the default on + // bf16 until a whole network could be measured. It now has been, and the + // compounding turns out to be mild: over the ~160 chained GEMMs of an + // evaluation, BFP16 lands within about 1.3-2x of bf16's deviation from the + // CPU reference rather than anywhere near 1000x (b10c384h6 policy mean + // 4.1e-4 vs 2.5e-4; b28c512nbt 2.4e-4 vs 1.8e-4), and the policy top-10 set + // is identical for both formats on both models. The per-GEMM error is input + // quantisation, not accumulation - the accumulator is fp32 either way - so it + // does not compound the way a truncated accumulator would. + // + // ryzenaiDtype = bf16 forces the more accurate format for anyone who wants + // it, and is still the only option on XDNA1. + if(arch == RyzenAIDevice::Arch::NPU2) + return Dtype::Bfp16; + return Dtype::Bf16; +} + +int RyzenAIKernel::padM(const EngineInfo& info, int want) { + // One pass over the 4 double-buffered AIE rows consumes tileM*8 rows. + return roundUpTo(std::max(want, 1), info.tileM * 8); +} + +int RyzenAIKernel::padN(const EngineInfo& info, int want) { + return roundUpTo(std::max(want, 1), info.tileN * info.cols); +} + +namespace { + + bool readWholeFile(const string& path, vector& out) { + try { + if(!FileUtils::exists(path)) + return false; + ifstream in; + FileUtils::open(in, path, ios::in | ios::binary | ios::ate); + streamsize size = in.tellg(); + if(size < 0) + return false; + in.seekg(0, ios::beg); + out.resize((size_t)size); + if(size > 0) + in.read(out.data(), size); + return in.good() || in.eof(); + } + catch(const std::exception&) { + return false; + } + } + + // One attempt at one (dtype, arch, cols). Picks the smallest available K that + // is >= the requested one. With swiglu set, scans the SwiGLU-epilogue + // variant's directory instead (same naming, gemm_swiglu_bf16_K stems). + RyzenAIKernel::Engine* tryLoadVariant( + const string& artifactDir, int deviceIdx, RyzenAIKernel::Dtype dtype, + RyzenAIDevice::Arch arch, int cols, int K, bool swiglu, string& err + ) { + err.clear(); + const map byK = scanVariant(variantDir(artifactDir, dtype, arch, cols, swiglu)); + auto it = byK.lower_bound(K); + if(it == byK.end()) { + err = "no artifact with reduction dim >= " + Global::intToString(K) + " at " + + Global::intToString(cols) + " column(s)"; + return nullptr; + } + + try { + unique_ptr engine(new RyzenAIKernel::Engine()); + engine->info.K = it->first; + engine->info.cols = cols; + engine->info.dtype = dtype; + // Every artifact in the set is built from the same whole_array design. + // tileN 48 only appears on shapes whose N is a multiple of 48, and the + // grid is compiled at tileN 32 throughout; manifest.json records the + // actual geometry if that ever stops being true. + engine->info.tileM = RyzenAIManifest::GEMM_TILE_M; + engine->info.tileK = RyzenAIManifest::GEMM_TILE_K; + engine->info.tileN = RyzenAIManifest::GEMM_TILE_N; + engine->seqArch = (arch == RyzenAIDevice::Arch::NPU1) ? RyzenAISequence::Arch::NPU1 + : RyzenAISequence::Arch::NPU2; + + if(!RyzenAISequence::supportsColumns(cols)) { + err = "no instruction-stream layout for " + Global::intToString(cols) + " column(s)"; + return nullptr; + } + + engine->device = xrt::device((unsigned int)(deviceIdx < 0 ? 0 : deviceIdx)); + engine->xclbin = xrt::xclbin(it->second); + + const string kernelName = findKernelName(engine->xclbin, RyzenAIManifest::KERNEL_NAME_PREFIX); + if(kernelName.size() <= 0) { + err = "no kernel named " + string(RyzenAIManifest::KERNEL_NAME_PREFIX) + "* in " + it->second; + return nullptr; + } + + engine->device.register_xclbin(engine->xclbin); + engine->context = xrt::hw_context(engine->device, engine->xclbin.get_uuid()); + engine->kernel = xrt::kernel(engine->context, kernelName); + return engine.release(); + } + catch(const std::exception& e) { + err = string("XRT failed to load ") + it->second + ": " + e.what(); + return nullptr; + } + } + +} // namespace + +namespace { + + RyzenAIKernel::Engine* loadEngineImpl( + const string& artifactDir, int deviceIdx, RyzenAIKernel::Dtype dtype, int K, int maxCols, + bool swiglu, RyzenAIKernel::EngineInfo& infoOut, string& err + ) { + err.clear(); + + const RyzenAIDevice::Arch arch = RyzenAIDevice::archOfDevice(deviceIdx); + if(arch == RyzenAIDevice::Arch::Unknown) { + err = "NPU architecture could not be determined, so no kernel binary can be selected"; + return nullptr; + } + const RyzenAIKernel::Dtype resolved = RyzenAIKernel::resolveDtype(dtype, arch); + + int startCols = RyzenAIDevice::maxColumns(arch); + if(maxCols > 0) + startCols = std::min(startCols, maxCols); + + string lastErr; + for(int cols = startCols; cols >= 1; cols /= 2) { + string variantErr; + RyzenAIKernel::Engine* engine = + tryLoadVariant(artifactDir, deviceIdx, resolved, arch, cols, K, swiglu, variantErr); + if(engine != nullptr) { + infoOut = engine->info; + return engine; + } + if(lastErr.size() <= 0) + lastErr = variantErr; + } + + err = string("no usable ") + RyzenAIKernel::dtypeName(resolved) + + (swiglu ? " swiglu-epilogue" : "") + " kernel for K=" + Global::intToString(K) + + " on " + RyzenAIDevice::archName(arch) + " (" + lastErr + ")"; + return nullptr; + } + +} // namespace + +RyzenAIKernel::Engine* RyzenAIKernel::loadEngine( + const string& artifactDir, int deviceIdx, Dtype dtype, int K, int maxCols, + EngineInfo& infoOut, string& err +) { + return loadEngineImpl(artifactDir, deviceIdx, dtype, K, maxCols, false, infoOut, err); +} + +RyzenAIKernel::Engine* RyzenAIKernel::loadEngineSwiglu( + const string& artifactDir, int deviceIdx, Dtype dtype, int K, int maxCols, + EngineInfo& infoOut, string& err +) { + return loadEngineImpl(artifactDir, deviceIdx, dtype, K, maxCols, true, infoOut, err); +} + +void RyzenAIKernel::freeEngine(Engine* engine) { + delete engine; +} + +const RyzenAIKernel::EngineInfo& RyzenAIKernel::engineInfo(const Engine* engine) { + return engine->info; +} + +const RyzenAIKernel::Timings& RyzenAIKernel::engineTimings(const Engine* engine) { + return engine->timings; +} + +RyzenAIKernel::Weights* RyzenAIKernel::uploadWeights( + Engine* engine, int paddedN, const uint16_t* B, string& err) { + err.clear(); + try { + unique_ptr w(new Weights()); + w->paddedN = paddedN; + w->bytes = (size_t)engine->info.K * (size_t)paddedN * sizeof(uint16_t); + w->bo = xrt::bo( + engine->device, w->bytes, XRT_BO_FLAGS_HOST_ONLY, + engine->kernel.group_id(RyzenAIManifest::ARG_B)); + std::memcpy(w->bo.map(), B, w->bytes); + w->bo.sync(XCL_BO_SYNC_BO_TO_DEVICE); + return w.release(); + } + catch(const std::exception& e) { + err = string("XRT failed to upload weights: ") + e.what(); + return nullptr; + } +} + +void RyzenAIKernel::freeWeights(Weights* weights) { + delete weights; +} + +void RyzenAIKernel::rewriteWeights(Weights* weights, const uint16_t* B) { + std::memcpy(weights->bo.map(), B, weights->bytes); + weights->bo.sync(XCL_BO_SYNC_BO_TO_DEVICE); +} + +RyzenAIKernel::Op* RyzenAIKernel::loadOp( + const string& xclbinPath, const string& instsPath, int deviceIdx, + const size_t* inBytes, int numIns, size_t bytesC, string& err) { + err.clear(); + + vector insts; + if(!readWholeFile(instsPath, insts) || insts.empty()) { + err = "no instruction stream at " + instsPath; + return nullptr; + } + + try { + unique_ptr op(new Op()); + op->bytesC = bytesC; + op->device = xrt::device((unsigned int)(deviceIdx < 0 ? 0 : deviceIdx)); + op->xclbin = xrt::xclbin(xclbinPath); + + const string kernelName = findKernelName(op->xclbin, RyzenAIManifest::KERNEL_NAME_PREFIX); + if(kernelName.empty()) { + err = "no kernel named " + string(RyzenAIManifest::KERNEL_NAME_PREFIX) + "* in " + xclbinPath; + return nullptr; + } + + op->device.register_xclbin(op->xclbin); + op->context = xrt::hw_context(op->device, op->xclbin.get_uuid()); + op->kernel = xrt::kernel(op->context, kernelName); + + op->boInstr = xrt::bo( + op->device, insts.size(), XCL_BO_FLAGS_CACHEABLE, + op->kernel.group_id(RyzenAIManifest::ARG_INSTR)); + op->inBytes.assign(inBytes, inBytes + numIns); + for(int j = 0; j < numIns; j++) + op->boIns.emplace_back( + op->device, inBytes[j], XRT_BO_FLAGS_HOST_ONLY, + op->kernel.group_id(RyzenAIManifest::ARG_A + j)); + op->boC = xrt::bo( + op->device, bytesC, XRT_BO_FLAGS_HOST_ONLY, + op->kernel.group_id(RyzenAIManifest::ARG_A + numIns)); + std::memcpy(op->boInstr.map(), insts.data(), insts.size()); + op->boInstr.sync(XCL_BO_SYNC_BO_TO_DEVICE); + + // Every argument is fixed for the op's lifetime, so the run is built once. + op->run = xrt::run(op->kernel); + op->run.set_arg(RyzenAIManifest::ARG_OPCODE, RyzenAIManifest::OPCODE_START_WITH_INSTRUCTIONS); + op->run.set_arg(RyzenAIManifest::ARG_INSTR, op->boInstr); + op->run.set_arg(RyzenAIManifest::ARG_NINSTR, (uint32_t)(insts.size() / sizeof(uint32_t))); + for(int j = 0; j < numIns; j++) + op->run.set_arg(RyzenAIManifest::ARG_A + j, op->boIns[j]); + op->run.set_arg(RyzenAIManifest::ARG_A + numIns, op->boC); + return op.release(); + } + catch(const std::exception& e) { + err = string("XRT failed to load op ") + xclbinPath + ": " + e.what(); + return nullptr; + } +} + +void RyzenAIKernel::freeOp(Op* op) { + delete op; +} + +void RyzenAIKernel::runOp(Op* op, const void* const* ins, int numIns, void* C) { + try { + for(int j = 0; j < numIns && j < (int)op->boIns.size(); j++) { + std::memcpy(op->boIns[j].map(), ins[j], op->inBytes[j]); + op->boIns[j].sync(XCL_BO_SYNC_BO_TO_DEVICE); + } + op->run.start(); + ert_cmd_state state = op->run.wait(); + if(state != ERT_CMD_STATE_COMPLETED) + throw StringError( + "RyzenAI op dispatch did not complete, ERT state " + Global::intToString((int)state)); + op->boC.sync(XCL_BO_SYNC_BO_FROM_DEVICE); + std::memcpy(C, op->boC.map(), op->bytesC); + } + catch(const StringError&) { + throw; + } + catch(const std::exception& e) { + throw StringError(string("RyzenAI op dispatch failed: ") + e.what()); + } +} + +void RyzenAIKernel::runGemm( + Engine* engine, Weights* weights, int paddedM, int paddedN, const uint16_t* A, float* C) { + try { + const EngineInfo& info = engine->info; + if(paddedN != weights->paddedN) + throw StringError( + "RyzenAI GEMM: N=" + Global::intToString(paddedN) + " does not match the uploaded " + + "weight width " + Global::intToString(weights->paddedN)); + + if(paddedM != engine->lastM || paddedN != engine->lastN) { + engine->instr = RyzenAISequence::generateSequence( + engine->seqArch, info.cols, paddedM, info.K, paddedN, info.tileM, info.tileK, info.tileN); + engine->lastM = paddedM; + engine->lastN = paddedN; + const size_t instrBytes = engine->instr.size() * sizeof(uint32_t); + if(instrBytes > engine->capInstrBytes) { + engine->boInstr = xrt::bo( + engine->device, instrBytes, XCL_BO_FLAGS_CACHEABLE, + engine->kernel.group_id(RyzenAIManifest::ARG_INSTR)); + engine->capInstrBytes = instrBytes; + } + std::memcpy(engine->boInstr.map(), engine->instr.data(), instrBytes); + engine->boInstr.sync(XCL_BO_SYNC_BO_TO_DEVICE); + } + + const size_t bytesA = (size_t)paddedM * (size_t)info.K * sizeof(uint16_t); + const size_t bytesC = (size_t)paddedM * (size_t)paddedN * sizeof(float); + if(bytesA > engine->capABytes) { + engine->boA = xrt::bo( + engine->device, bytesA, XRT_BO_FLAGS_HOST_ONLY, + engine->kernel.group_id(RyzenAIManifest::ARG_A)); + engine->capABytes = bytesA; + engine->bufferGeneration++; + } + if(bytesC > engine->capCBytes) { + engine->boC = xrt::bo( + engine->device, bytesC, XRT_BO_FLAGS_HOST_ONLY, + engine->kernel.group_id(RyzenAIManifest::ARG_C)); + engine->capCBytes = bytesC; + engine->bufferGeneration++; + } + + const auto tUpload = std::chrono::steady_clock::now(); + std::memcpy(engine->boA.map(), A, bytesA); + engine->boA.sync(XCL_BO_SYNC_BO_TO_DEVICE); + const auto tExec = std::chrono::steady_clock::now(); + + if(!weights->runValid || weights->runGeneration != engine->bufferGeneration) { + weights->run = xrt::run(engine->kernel); + weights->run.set_arg( + RyzenAIManifest::ARG_OPCODE, RyzenAIManifest::OPCODE_START_WITH_INSTRUCTIONS); + weights->run.set_arg(RyzenAIManifest::ARG_INSTR, engine->boInstr); + weights->run.set_arg(RyzenAIManifest::ARG_A, engine->boA); + weights->run.set_arg(RyzenAIManifest::ARG_B, weights->bo); + weights->run.set_arg(RyzenAIManifest::ARG_C, engine->boC); + weights->runValid = true; + weights->runGeneration = engine->bufferGeneration; + weights->lastNumInstr = 0; + } + // The instruction count is the one argument that tracks the shape. + if(weights->lastNumInstr != (uint32_t)engine->instr.size()) { + weights->run.set_arg(RyzenAIManifest::ARG_NINSTR, (uint32_t)engine->instr.size()); + weights->lastNumInstr = (uint32_t)engine->instr.size(); + } + + weights->run.start(); + ert_cmd_state state = weights->run.wait(); + const auto tDownload = std::chrono::steady_clock::now(); + if(state != ERT_CMD_STATE_COMPLETED) + throw StringError( + "RyzenAI GEMM dispatch did not complete, ERT state " + Global::intToString((int)state)); + + engine->boC.sync(XCL_BO_SYNC_BO_FROM_DEVICE); + std::memcpy(C, engine->boC.map(), bytesC); + + const auto tEnd = std::chrono::steady_clock::now(); + using Secs = std::chrono::duration; + engine->timings.secsUploadA += Secs(tExec - tUpload).count(); + engine->timings.secsExecute += Secs(tDownload - tExec).count(); + engine->timings.secsDownloadC += Secs(tEnd - tDownload).count(); + engine->timings.numDispatches++; + } + catch(const StringError&) { + throw; + } + catch(const std::exception& e) { + throw StringError(string("RyzenAI GEMM dispatch failed: ") + e.what()); + } +} + +vector RyzenAIKernel::listGemmK(const string& artifactDir) { + std::set ks; + std::error_code ec; + const gfs::path root = gfs::u8path(artifactDir); + if(!gfs::is_directory(root, ec)) + return vector(); + for(auto& entry : gfs::recursive_directory_iterator(root, ec)) { + if(!entry.is_regular_file(ec)) + continue; + const gfs::path p = entry.path(); + if(p.extension().u8string() != ".xclbin") + continue; + const string stem = p.stem().u8string(); + // The swiglu-epilogue variants share the K-suffixed naming but are a + // different operator; they must not advertise a plain-GEMM K. + if(stem.rfind("gemm_swiglu_", 0) == 0) + continue; + int k = 0; + if(parseKFromStem(stem, k)) + ks.insert(k); + } + return vector(ks.begin(), ks.end()); +} + +vector RyzenAIKernel::listSwigluK(const string& artifactDir) { + std::set ks; + std::error_code ec; + const gfs::path root = gfs::u8path(artifactDir); + if(!gfs::is_directory(root, ec)) + return vector(); + for(auto& entry : gfs::recursive_directory_iterator(root, ec)) { + if(!entry.is_regular_file(ec)) + continue; + const gfs::path p = entry.path(); + if(p.extension().u8string() != ".xclbin") + continue; + const string stem = p.stem().u8string(); + if(stem.rfind("gemm_swiglu_", 0) != 0) + continue; + int k = 0; + if(parseKFromStem(stem, k)) + ks.insert(k); + } + return vector(ks.begin(), ks.end()); +} + +string RyzenAIKernel::selfTest(const string& artifactDir, int deviceIdx) { + string out = "RyzenAI NPU self-test:"; + const vector ks = listGemmK(artifactDir); + if(ks.empty()) + return out + " no artifacts found under " + artifactDir; + + std::mt19937 rng(12345); + std::uniform_real_distribution dist(-1.0f, 1.0f); + + for(size_t i = 0; i < ks.size(); i++) { + const int K = ks[i]; + EngineInfo info; + string err; + Engine* engine = loadEngine(artifactDir, deviceIdx, Dtype::Auto, K, 0, info, err); + if(engine == nullptr) { + out += "\n K=" + Global::intToString(K) + ": LOAD FAILED (" + err + ")"; + continue; + } + + try { + // A board's worth of rows and a typical layer width, padded as a real + // dispatch would be. + const int M = padM(info, 361); + const int N = padN(info, 512); + vector A((size_t)M * info.K); + vector B((size_t)info.K * N); + for(size_t j = 0; j < A.size(); j++) A[j] = floatToBf16(dist(rng)); + for(size_t j = 0; j < B.size(); j++) B[j] = floatToBf16(dist(rng)); + vector C((size_t)M * N, 0.0f); + + Weights* w = uploadWeights(engine, N, B.data(), err); + if(w == nullptr) { + out += "\n K=" + Global::intToString(K) + ": " + err; + freeEngine(engine); + continue; + } + + runGemm(engine, w, M, N, A.data(), C.data()); + + // Spot-check a sample of C: a wrong descriptor field produces gross + // garbage, never a subtle drift, so full recomputation buys nothing. + double maxErr = 0.0; + std::mt19937 pick(7); + for(int t = 0; t < 200; t++) { + const int r = (int)(pick() % (unsigned)M); + const int c = (int)(pick() % (unsigned)N); + double acc = 0.0; + for(int k = 0; k < info.K; k++) + acc += (double)bf16ToFloat(A[(size_t)r * info.K + k]) * + bf16ToFloat(B[(size_t)k * N + c]); + maxErr = std::max(maxErr, std::fabs(acc - C[(size_t)r * N + c])); + } + + const int iters = 20; + auto t0 = std::chrono::steady_clock::now(); + for(int t = 0; t < iters; t++) + runGemm(engine, w, M, N, A.data(), C.data()); + auto t1 = std::chrono::steady_clock::now(); + const double ms = std::chrono::duration(t1 - t0).count() / iters; + + char line[256]; + std::snprintf( + line, sizeof(line), "\n K=%-5d %s %dcol M=%d N=%d %.3f ms %.1f GFLOP/s maxAbsErr=%.3g %s", + info.K, dtypeName(info.dtype), info.cols, M, N, ms, + 2.0 * M * info.K * N / (ms * 1e6), maxErr, maxErr < 0.5 ? "OK" : "FAILED"); + out += line; + + freeWeights(w); + } + catch(const std::exception& e) { + out += "\n K=" + Global::intToString(K) + ": THREW (" + e.what() + ")"; + } + freeEngine(engine); + } + return out; +} diff --git a/cpp/neuralnet/ryzenaikernel.h b/cpp/neuralnet/ryzenaikernel.h new file mode 100644 index 0000000000..72e4323d50 --- /dev/null +++ b/cpp/neuralnet/ryzenaikernel.h @@ -0,0 +1,193 @@ +/* + * Loading and dispatch of the NPU kernel binaries (xclbin) produced by + * python/ryzenai_kernels/. + * + * Like device.{h,cpp}, this is one of the only places that includes XRT + * headers; callers deal in plain buffers. + * + * An .xclbin bakes in only the reduction dimension K (measured; see + * python/ryzenai_kernels/INSTS_FORMAT.md), so one binary serves every M and N -- the + * instruction stream that carries those is generated per dispatch by + * sequence.cpp. That is why the unit of loading here is a K, not a shape. + */ + +#ifndef NEURALNET_RYZENAI_KERNEL_H_ +#define NEURALNET_RYZENAI_KERNEL_H_ + +#include +#include +#include +#include + +#include "../neuralnet/ryzenaidevice.h" + +namespace RyzenAIKernel { + + // ---- bfloat16 ------------------------------------------------------------- + // bf16 is just the top 16 bits of an IEEE fp32, so conversion is a shift plus + // round-to-nearest-even. No lookup tables and no library needed. + + // Converts a whole run of floats, eight at a time where the hardware allows. + // Bit-for-bit what the element-wise version below produces, NaN handling + // included - it is the same arithmetic, just widened. Worth having as its own + // function because packing activations is a few percent of every evaluation: + // the branch on NaN keeps compilers from vectorising the obvious loop. + void floatToBf16Bulk(const float* src, uint16_t* dst, size_t n); + + inline uint16_t floatToBf16(float f) { + uint32_t bits; + static_assert(sizeof(bits) == sizeof(f), "float is not 32 bits"); + std::memcpy(&bits, &f, sizeof(bits)); + // NaN must stay NaN: rounding a quiet NaN's payload away could turn it into + // an infinity, so force the quiet bit instead of rounding. + if((bits & 0x7F800000u) == 0x7F800000u && (bits & 0x007FFFFFu) != 0u) + return (uint16_t)((bits >> 16) | 0x0040u); + const uint32_t roundingBias = 0x7FFFu + ((bits >> 16) & 1u); + return (uint16_t)((bits + roundingBias) >> 16); + } + + inline float bf16ToFloat(uint16_t b) { + uint32_t bits = (uint32_t)b << 16; + float f; + std::memcpy(&f, &bits, sizeof(f)); + return f; + } + + // ---- numeric format ------------------------------------------------------- + + // Bf16 runs the native bfloat16 MMUL. Bfp16 compiles the same bfloat16 kernel + // against AIE_API_EMULATE_BFLOAT16_MMUL_WITH_BFP16, which doubles the MMUL + // micro-kernel (measured 1.42x) and is XDNA2-only. The distinction is entirely + // inside the kernel: host buffers are bfloat16 in / float32 out either way, so + // only which artifact directory we load from changes. + enum class Dtype { Auto, Bf16, Bfp16 }; + + const char* dtypeName(Dtype dtype); // "bf16" / "bfp16" + + // Parses a ryzenaiDtype config value. Returns false for anything unrecognized. + bool parseDtype(const std::string& s, Dtype& out); + + // Resolves Auto against the hardware. See the implementation for why Auto is + // currently bf16 even where bfp16 is available. + Dtype resolveDtype(Dtype requested, RyzenAIDevice::Arch arch); + + // ---- engines -------------------------------------------------------------- + + // One loaded xclbin, bound to a device, computing C[M,N] = A[M,K] * B[K,N] + // with bfloat16 inputs and float32 accumulation for any M and N the shape + // rules below allow. K is fixed by the binary. + struct Engine; + + struct EngineInfo { + int K = 0; // the reduction dim this binary was compiled for + int cols = 0; // AIE columns acquired + int tileM = 0; // MMUL tile geometry, needed to pad M and N + int tileK = 0; + int tileN = 0; + Dtype dtype = Dtype::Bf16; + }; + + // Smallest M >= want that an instruction stream can express, and likewise for + // N. Callers zero-pad up to these; the extra rows and columns of C are + // computed and ignored. K is not paddable here -- pick an engine whose K is + // >= the layer's K and zero-pad A's columns and B's rows into it. + int padM(const EngineInfo& info, int want); + int padN(const EngineInfo& info, int want); + + // Loads the artifact for reduction dim K: an exact match if one exists, + // otherwise the smallest available K greater than it (the caller then + // zero-pads). Column counts are tried widest-first down to 1, since a device + // whose columns are partly claimed by another process should still get NPU + // acceleration rather than falling back to the CPU. maxCols caps that search; + // pass 0 for no cap. Wider is not always faster at small M -- see + // references/performance.md. + // + // Returns nullptr and fills err when nothing loads; that is an ordinary + // outcome (callers use the CPU reference path), not a fatal error. + Engine* loadEngine( + const std::string& artifactDir, + int deviceIdx, + Dtype dtype, + int K, + int maxCols, + EngineInfo& infoOut, + std::string& err + ); + void freeEngine(Engine* engine); + const EngineInfo& engineInfo(const Engine* engine); + + // Same as loadEngine, but loads the SwiGLU-epilogue variant of the GEMM + // (gemm_swiglu_bf16_K, in the _swiglu directories). That binary + // computes silu(l)*g on chip for B whose columns interleave two weight + // matrices in groups of 8; see python/ryzenai_kernels/gemm_swiglu_bf16.py. + // It is a separate xclbin and therefore a separate hardware context. + Engine* loadEngineSwiglu( + const std::string& artifactDir, + int deviceIdx, + Dtype dtype, + int K, + int maxCols, + EngineInfo& infoOut, + std::string& err + ); + + // Reduction dims for which a SwiGLU-epilogue artifact exists. Sorted. + std::vector listSwigluK(const std::string& artifactDir); + + // Device-resident B for one layer. Weights do not change between evaluations, + // so they are uploaded once and bound per dispatch. N is the padded width. + struct Weights; + Weights* uploadWeights(Engine* engine, int paddedN, const uint16_t* B, std::string& err); + void freeWeights(Weights* weights); + + // Rewrites the contents of an already-uploaded B in place. This is the path + // for operands that change every dispatch (attention keys/values, as opposed + // to layer weights): the BO itself does not move, so the xrt::run cached + // against it in runGemm stays valid and only a memcpy + sync is paid. + void rewriteWeights(Weights* weights, const uint16_t* B); + + // ---- standalone ops ------------------------------------------------------- + // A non-GEMM kernel (softmax, fused attention, ...) whose instruction stream + // is precompiled next to the xclbin -- unlike the engines nothing is + // generated at run time, so the op computes exactly the one shape it was + // compiled for. Same opcode-3 ABI as the GEMM except that the data args are + // arg3..arg3+numIns-1 = inputs and arg3+numIns = output. Buffer sizes are + // fixed at load. + struct Op; + Op* loadOp( + const std::string& xclbinPath, const std::string& instsPath, int deviceIdx, + const size_t* inBytes, int numIns, size_t bytesC, std::string& err); + void freeOp(Op* op); + // memcpy the inputs in, dispatch, memcpy the output out. ins[j] must point + // at inBytes[j] bytes. Throws StringError on a dispatch failure. + void runOp(Op* op, const void* const* ins, int numIns, void* C); + + // C[M,N] = A[M,K] * B[K,N], all row-major, with M and N already padded per + // padM/padN and A's row stride equal to the engine's K. Blocks until the NPU + // has finished. Throws StringError on a dispatch failure. + void runGemm( + Engine* engine, Weights* weights, int paddedM, int paddedN, const uint16_t* A, float* C); + + // Wall clock accumulated inside runGemm, split so that host<->device transfer + // can be told apart from the NPU's own execution. Deciding whether keeping + // activations resident on the device is worth it needs exactly this split. + struct Timings { + double secsUploadA = 0.0; + double secsExecute = 0.0; + double secsDownloadC = 0.0; + long long numDispatches = 0; + }; + const Timings& engineTimings(const Engine* engine); + + // Reduction dims for which an artifact exists under artifactDir, parsed from + // the filenames. Sorted, for reproducible logging. + std::vector listGemmK(const std::string& artifactDir); + + // Loads every available artifact, runs it against a plain-C++ GEMM on + // pseudorandom data, and times it. Returns a human-readable report; never + // throws, so it is safe to call from a logging path. + std::string selfTest(const std::string& artifactDir, int deviceIdx); + +} // namespace RyzenAIKernel + +#endif // NEURALNET_RYZENAI_KERNEL_H_ diff --git a/cpp/neuralnet/ryzenaimanifest.h b/cpp/neuralnet/ryzenaimanifest.h new file mode 100644 index 0000000000..edb9123724 --- /dev/null +++ b/cpp/neuralnet/ryzenaimanifest.h @@ -0,0 +1,56 @@ +/* + * ABI contract between the NPU kernel binaries under artifacts/ and this C++ + * host code. + * + * The kernel build (python/ryzenai_kernels/build_kernels.py) writes the + * same facts into artifacts/manifest.json. Both must agree: ABI_VERSION here is + * checked against the manifest's "manifest_version" at load time so that a + * mismatched pair fails loudly instead of computing garbage. + * + * None of this is shape information. M/K/N live in the per-shape instruction + * stream, not in the xclbin - see artifacts/README.md. + */ + +#ifndef NEURALNET_RYZENAI_MANIFEST_H_ +#define NEURALNET_RYZENAI_MANIFEST_H_ + +#include + +namespace RyzenAIManifest { + + // Bump together with "manifest_version" in artifacts/manifest.json whenever + // anything below changes. + constexpr int ABI_VERSION = 1; + + // mlir-aie names the xclbin's kernel with this prefix plus a generated + // suffix, so hosts must prefix-match over xclbin.get_kernels() rather than + // compare for equality (this mirrors what mlir-aie's own + // runtime_lib/test_lib/test_utils.cpp does). + constexpr const char* KERNEL_NAME_PREFIX = "MLIR_AIE"; + + // ERT opcode for "start kernel with instruction buffer". + constexpr uint32_t OPCODE_START_WITH_INSTRUCTIONS = 3; + + // xrt::run argument slots. + constexpr int ARG_OPCODE = 0; // scalar, OPCODE_START_WITH_INSTRUCTIONS + constexpr int ARG_INSTR = 1; // xrt::bo, cacheable, holds the .insts.bin bytes + constexpr int ARG_NINSTR = 2; // scalar, instruction length in 32-bit words + constexpr int ARG_A = 3; // xrt::bo, host_only, M*K bfloat16 row-major + constexpr int ARG_B = 4; // xrt::bo, host_only, K*N bfloat16 row-major + constexpr int ARG_C = 5; // xrt::bo, host_only, M*N float32 row-major + + // MMUL tile geometry the GEMM artifacts are compiled with, as recorded in + // artifacts/manifest.json. These drive the padding rules: M must be a + // multiple of GEMM_TILE_M*8 (one pass over 4 double-buffered AIE rows), N a + // multiple of GEMM_TILE_N*cols, and K a multiple of GEMM_TILE_K. + // + // A few early artifacts were compiled at tileN 48 because their N was 384; + // the grid is tileN 32 throughout, which divides every N the padding rules + // produce. + constexpr int GEMM_TILE_M = 32; + constexpr int GEMM_TILE_K = 64; + constexpr int GEMM_TILE_N = 32; + +} // namespace RyzenAIManifest + +#endif // NEURALNET_RYZENAI_MANIFEST_H_ diff --git a/cpp/neuralnet/ryzenaimatmul.cpp b/cpp/neuralnet/ryzenaimatmul.cpp new file mode 100644 index 0000000000..9e7e619828 --- /dev/null +++ b/cpp/neuralnet/ryzenaimatmul.cpp @@ -0,0 +1,1504 @@ +#include "../neuralnet/ryzenaimatmul.h" + +#include +#include +#include +#include + +#include "../core/global.h" +#include "../neuralnet/desc.h" +#include "../neuralnet/ryzenaikernel.h" + +using namespace std; + +namespace RyzenAIMatMul { + +namespace { + + // One dense layer's device-resident weights, plus the engine that serves its + // reduction dim. Engines are shared between every layer with the same K. + struct Layer { + RyzenAIKernel::Engine* engine = nullptr; // not owned + RyzenAIKernel::Weights* weights = nullptr; + int K = 0; // the engine's K, >= inChannels + int paddedN = 0; // >= outChannels + bool usable = false; + string why; // set when !usable, for the report + }; + + // Everything tryAttention needs to route one attention block shape's QK^T + // and P*V GEMMs to the NPU. Unlike a Layer, the B operands (the K and V + // activations) change every evaluation, so the weights BOs are rewritten in + // place per dispatch via RyzenAIKernel::rewriteWeights. The engines are the + // same shared ones the dense layers use. + // + // All heads of one batch element go into ONE GEMM per direction, because a + // dispatch costs ~1 ms regardless of size while the multiply-accumulates are + // nearly free: A carries the per-head data side by side along the reduction + // dim and B is block-diagonal, so C comes out with the per-head results side + // by side along N. Per (batch, block) that is 2 dispatches instead of + // 2*numHeads. + struct AttnState { + // The dims this state was built for; a block with different dims declines. + int S = 0; + int numHeads = 0; + int numKVHeads = 0; + int qHeadDim = 0; + int vHeadDim = 0; + + RyzenAIKernel::Engine* engineQK = nullptr; // not owned (shared) + RyzenAIKernel::Engine* enginePV = nullptr; // not owned (shared) + RyzenAIKernel::Weights* weightsQK = nullptr; // owned + RyzenAIKernel::Weights* weightsPV = nullptr; // owned + int KQK = 0; // engine K serving QK^T (>= numHeads*qHeadDim) + int KPV = 0; // engine K serving P*V (>= numHeads*S) + int paddedMQK = 0; // padM(S) on the QK^T engine + int paddedMPV = 0; // padM(S) on the P*V engine + int paddedNQK = 0; // padN(numHeads*S): head h's scores at columns [h*S, (h+1)*S) + int paddedNPV = 0; // padN(numHeads*vHeadDim) + + // Host scratch, dedicated to attention so that the padding regions can be + // zeroed once at (re)size time; per dispatch only the real regions are + // rewritten. (The dense path's hostA/hostC cannot offer that invariant -- + // every dense layer rewrites them to its own shape.) + vector hostAQK; // paddedMQK x KQK; row qi is qBuf[n][qi][:] outright + vector hostAPV; // paddedMPV x KPV; head h's P rows at columns [h*S, (h+1)*S) + vector hostBQK; // KQK x paddedNQK, block-diagonal transposed K + vector hostBPV; // KPV x paddedNPV, block-diagonal V + vector hostC; // max(paddedMQK*paddedNQK, paddedMPV*paddedNPV) + vector scoreRow; // one softmax working row, S floats + + // The softmax between the two GEMMs, when an op compiled for exactly this + // (rows, width) = (numHeads*S, S) padded to (64, 32) exists. Null keeps the + // CPU softmax below. Rows are head-major: row h*S+qi holds head h's scores + // for query qi, so the scatter into hostAPV is a pure copy. + RyzenAIKernel::Op* softmaxOp = nullptr; // owned + int smRows = 0; // the op's compiled rows (>= numHeads*S) + int smWidth = 0; // the op's compiled width (>= S) + vector hostSmIn; // smRows x smWidth, bfloat16 + vector hostSmOut; // same + + // The fused whole-attention op (QK^T + softmax + P*V in one dispatch), + // when one compiled for exactly (numHeads, S) exists. Buffers are the + // pre-tiled host packing: attnQ [heads][48][256] bf16 (8x32 chunks in + // A-tile order, pre-scaled), attnKV [kvHeads][2][12288] bf16 (B-tile + // order, K then V), attnC [heads][48][256] f32 (C-tile order). + RyzenAIKernel::Op* attnOp = nullptr; // owned + vector attnQ; + vector attnKV; + vector attnC; + + bool usable = false; + string why; // set when !usable, for the report + }; + +} // namespace + +namespace { + + +} // namespace + +struct Accel { + Options options; + RyzenAIKernel::Dtype dtype = RyzenAIKernel::Dtype::Auto; + + // K -> engine. Every dense layer with that reduction dim shares one. + map engines; + map infos; + + // Which K values have artifacts, so a layer can be rejected without paying + // for a load attempt. + vector availableK; + + // Keyed by the desc's address, which is stable for the model's lifetime. + map layers; + + // Fused projections (several layers sharing one input, weights concatenated + // along N into one uploaded B), keyed by the first desc's address. A desc + // used as a fusion key must never also be used standalone -- true for + // q/k/vProj and linear1/linearGate, which only ever appear together. + map fusedLayers; + + // SwiGLU-epilogue engines (a separate xclbin per K, so a separate hardware + // context from the plain GEMM engines) and the FFN layers using them, + // keyed by the linear1 desc's address. + map swigluEngines; + map swigluInfos; + vector availableSwigluK; + map swigluLayers; + long long numSwiglu = 0; + long long numSwigluFallback = 0; + + // Scratch, grown on demand: A in bfloat16 padded to (paddedM x K), C in + // float32 padded to (paddedM x paddedN). + vector hostA; + vector hostC; + + // The convolution input, converted to bfloat16 once per layer. A 3x3 window + // reads every input point from up to nine output positions, so converting + // inside the im2col gather did the same float->bf16 arithmetic nine times + // over; with this the gather is a memcpy per tap. + vector hostConvIn; + + long long numAccelerated = 0; + long long numFallback = 0; + + // Attention (QK^T and P*V) routing state and accounting. + AttnState attn; + long long numAttn = 0; + long long numAttnFallback = 0; + double secsAttnPack = 0.0; // A and B host-side builds + double secsAttnUploadB = 0.0; // rewriteWeights (memcpy + sync) + double secsAttnDispatch = 0.0; // runGemm + double secsAttnUnpack = 0.0; // C -> attnOut + double secsAttnSoftmax = 0.0; // on-CPU softmax between the two GEMMs + double secsAttnSoftmaxNpu = 0.0; // NPU softmax dispatch + double secsAttnSoftmaxHost = 0.0; // gather/scatter around the NPU softmax + + // Where the wall clock goes inside tryMatmul, so that the host-side packing + // can be told apart from the NPU's own time. + double secsPackA = 0.0; + double secsGather = 0.0; // im2col, for convolutions with taps + double secsDispatch = 0.0; + double secsUnpackC = 0.0; + + // BatchNorm+Mish fused op state, keyed by (channels, rows-per-dispatch). + // + // The row count is baked into each artifact, and which one is cheapest + // depends on how many rows the call actually has. Measured on b40c768: a + // dispatch costs ~0.73 ms fixed plus ~0.85 us per row, so a batch of one + // board (361 rows) wants the 384-row op (~1.06 ms) while a batch of seven + // (2635 rows) wants the 3072-row one (~3.3 ms in a single dispatch instead + // of seven 384-row dispatches at ~7.4 ms). Picking per call rather than + // latching one height is the whole point - latching is what silently cost + // b40c768 its BN acceleration under batching in the first place. + // constexpr, so no out-of-class definition is needed (C++17 makes it inline). + static constexpr int kBnMishHeights[3] = {384, 1536, 3072}; + + struct BnMishState { + RyzenAIKernel::Op* op = nullptr; // owned + // Why this width is not accelerated, for the report. A layer that simply + // is not Mish is not recorded: that is routing, not a failure. A missing + // artifact is, because it costs real time and is otherwise invisible - + // the CPU path produces identical numbers, just slowly. + string why; + int rowsPad = 0; + int width = 0; + bool tried = false; + vector hostX; // rowsPad x width bf16 + vector hostSB; // 8 x 2*width bf16 ([scale|bias] per core) + vector hostY; // rowsPad x width bf16 + }; + std::map, BnMishState> bnmByShape; // (channels, rows) + long long numBnMish = 0; + double secsBnMish = 0.0; + + // One-time weight preparation: fp32 -> bfloat16, padded, uploaded. This is + // what a persistent cache would replace, so it is measured separately. + double secsPrepareConvert = 0.0; // conversion + padding on the host + double secsPrepareUpload = 0.0; // memcpy into the BO and sync + long long prepareBytes = 0; +}; + +namespace { + inline double nowSecs() { + return std::chrono::duration( + std::chrono::steady_clock::now().time_since_epoch()).count(); + } +} + +namespace { + + // Smallest artifact K that can hold this layer's reduction dim, or the + // single forced one when the caller has asked for a one-context model. + bool pickK(const Accel* accel, int inChannels, int& kOut) { + // forceK is a preference, not a requirement: it collapses every layer it + // can onto one context, and anything needing a larger reduction dim (the + // block-diagonal P*V, whose K is numHeads*S) still gets its own rather than + // dropping to the CPU. One extra context beats losing the whole operator. + if(accel->options.forceK > 0 && accel->options.forceK >= inChannels) { + kOut = accel->options.forceK; + return true; + } + for(size_t i = 0; i < accel->availableK.size(); i++) { + if(accel->availableK[i] >= inChannels) { + kOut = accel->availableK[i]; + return true; + } + } + return false; + } + + RyzenAIKernel::Engine* engineForK(Accel* accel, int K, RyzenAIKernel::EngineInfo& infoOut) { + auto it = accel->engines.find(K); + if(it != accel->engines.end()) { + infoOut = accel->infos[K]; + return it->second; + } + RyzenAIKernel::EngineInfo info; + string err; + RyzenAIKernel::Engine* engine = RyzenAIKernel::loadEngine( + accel->options.artifactDir, accel->options.deviceIdx, accel->dtype, K, + accel->options.maxCols, info, err); + if(engine == nullptr) + return nullptr; + accel->engines[info.K] = engine; + accel->infos[info.K] = info; + infoOut = info; + return engine; + } + + // How a layer's source weights are laid out, and therefore how they have to + // be shuffled into the K x N row-major B the GEMM wants. + enum class WeightForm { + InByOut, // MatMulLayerDesc: w[ic*outC + oc] + OutByIn, // 1x1 ConvLayerDesc: w[oc*inC + ic] + ConvTaps, // ConvLayerDesc with taps: w[(oc*inC + ic)*ky*kx + dy*kx + dx] + }; + + // First use of a layer: pick an engine, then pad and upload its weights. + // numTaps is convY*convX (1 for a dense layer), so the reduction dim is + // numTaps*inChannels. + Layer& prepareLayer( + Accel* accel, const void* key, const float* w, int inChannels, int outChannels, + WeightForm form, int numTaps = 1) { + Layer& layer = accel->layers[key]; + if(layer.engine != nullptr || layer.why.size() > 0) + return layer; + + const int reduceDim = numTaps * inChannels; + int K = 0; + if(!pickK(accel, reduceDim, K)) { + layer.why = "no artifact with K >= " + Global::intToString(reduceDim); + return layer; + } + + RyzenAIKernel::EngineInfo info; + RyzenAIKernel::Engine* engine = engineForK(accel, K, info); + if(engine == nullptr) { + layer.why = "engine for K=" + Global::intToString(K) + " would not load"; + return layer; + } + + const int paddedN = RyzenAIKernel::padN(info, outChannels); + + // B must end up K x N row-major, zero-padded on both axes. Row k of B pairs + // with column k of A, so for a convolution the tap index has to lead: the + // gather below writes tap t's inChannels values at column t*inChannels. + const double tConvert = nowSecs(); + vector b((size_t)info.K * (size_t)paddedN, RyzenAIKernel::floatToBf16(0.0f)); + for(int t = 0; t < numTaps; t++) { + for(int ic = 0; ic < inChannels; ic++) { + uint16_t* dst = b.data() + ((size_t)t * inChannels + ic) * paddedN; + for(int oc = 0; oc < outChannels; oc++) { + float v; + switch(form) { + case WeightForm::InByOut: v = w[(size_t)ic * outChannels + oc]; break; + case WeightForm::OutByIn: v = w[(size_t)oc * inChannels + ic]; break; + default: v = w[((size_t)oc * inChannels + ic) * numTaps + t]; break; + } + dst[oc] = RyzenAIKernel::floatToBf16(v); + } + } + } + + accel->secsPrepareConvert += nowSecs() - tConvert; + accel->prepareBytes += (long long)b.size() * 2; + + const double tUpload = nowSecs(); + string err; + RyzenAIKernel::Weights* weights = RyzenAIKernel::uploadWeights(engine, paddedN, b.data(), err); + accel->secsPrepareUpload += nowSecs() - tUpload; + if(weights == nullptr) { + layer.why = err; + return layer; + } + + layer.engine = engine; + layer.weights = weights; + layer.K = info.K; + layer.paddedN = paddedN; + layer.usable = true; + return layer; + } + +} // namespace + +Accel* create(const Options& options, string& err) { + err.clear(); + + RyzenAIKernel::Dtype dtype = RyzenAIKernel::Dtype::Auto; + if(!RyzenAIKernel::parseDtype(options.dtype, dtype)) { + err = "unrecognized dtype '" + options.dtype + "'"; + return nullptr; + } + + vector ks = RyzenAIKernel::listGemmK(options.artifactDir); + if(ks.empty()) { + err = "no NPU artifacts under " + options.artifactDir; + return nullptr; + } + + Accel* accel = new Accel(); + accel->options = options; + accel->dtype = dtype; + accel->availableK = ks; // listGemmK returns them sorted + accel->availableSwigluK = RyzenAIKernel::listSwigluK(options.artifactDir); // sorted too + return accel; +} + +void free(Accel* accel) { + if(accel == nullptr) + return; + for(auto& entry : accel->layers) + RyzenAIKernel::freeWeights(entry.second.weights); + for(auto& entry : accel->fusedLayers) + RyzenAIKernel::freeWeights(entry.second.weights); + for(auto& entry : accel->swigluLayers) + RyzenAIKernel::freeWeights(entry.second.weights); + RyzenAIKernel::freeWeights(accel->attn.weightsQK); + RyzenAIKernel::freeWeights(accel->attn.weightsPV); + RyzenAIKernel::freeOp(accel->attn.softmaxOp); + RyzenAIKernel::freeOp(accel->attn.attnOp); + for(auto& e : accel->bnmByShape) + RyzenAIKernel::freeOp(e.second.op); + for(auto& entry : accel->engines) + RyzenAIKernel::freeEngine(entry.second); + for(auto& entry : accel->swigluEngines) + RyzenAIKernel::freeEngine(entry.second); + delete accel; +} + +namespace { + +// `in` may be null, meaning the caller has already written the padded bfloat16 +// A into accel->hostA itself (the im2col path does). +// Packs A (unless in == nullptr, meaning the caller already wrote the padded +// bfloat16 A into accel->hostA, as the im2col path does) and dispatches, +// leaving the padded float32 result in accel->hostC. On a dispatch failure the +// layer is dropped to the CPU permanently and false is returned, already +// accounted; the caller must then run its own implementation. +bool dispatchPacked( + Accel* accel, Layer& layer, const float* in, int inC, int numRows) { + const RyzenAIKernel::EngineInfo& info = RyzenAIKernel::engineInfo(layer.engine); + const int paddedM = RyzenAIKernel::padM(info, numRows); + const int K = layer.K; + const int paddedN = layer.paddedN; + + accel->hostA.resize((size_t)paddedM * (size_t)K); + accel->hostC.resize((size_t)paddedM * (size_t)paddedN); + + // A: convert to bfloat16, zero-filling the columns past inChannels and the + // rows past numRows. Those contribute nothing to the real outputs. + const double tPack = nowSecs(); + if(in != nullptr) { + const uint16_t zero = RyzenAIKernel::floatToBf16(0.0f); + for(int r = 0; r < numRows; r++) { + const float* src = in + (size_t)r * inC; + uint16_t* dst = accel->hostA.data() + (size_t)r * K; + RyzenAIKernel::floatToBf16Bulk(src, dst, (size_t)inC); + for(int c = inC; c < K; c++) + dst[c] = zero; + } + if(paddedM > numRows) + std::fill( + accel->hostA.begin() + (size_t)numRows * K, + accel->hostA.begin() + (size_t)paddedM * K, zero); + } + + const double tDispatch = nowSecs(); + accel->secsPackA += tDispatch - tPack; + try { + RyzenAIKernel::runGemm( + layer.engine, layer.weights, paddedM, paddedN, accel->hostA.data(), accel->hostC.data()); + } + catch(const std::exception&) { + layer.usable = false; + layer.why = "dispatch failed at run time"; + accel->numFallback++; + return false; + } + accel->secsDispatch += nowSecs() - tDispatch; + return true; +} + +bool runLayer( + Accel* accel, Layer& layer, float* out, const float* in, int inC, int outC, int numRows, + bool accumulate) { + const int paddedN = layer.paddedN; + if(!dispatchPacked(accel, layer, in, inC, numRows)) + return false; + + const double tUnpack = nowSecs(); + // C: take the real rows and columns out of the padded result. + for(int r = 0; r < numRows; r++) { + const float* src = accel->hostC.data() + (size_t)r * paddedN; + float* dst = out + (size_t)r * outC; + if(accumulate) { + for(int c = 0; c < outC; c++) + dst[c] += src[c]; + } + else { + std::memcpy(dst, src, (size_t)outC * sizeof(float)); + } + } + + accel->secsUnpackC += nowSecs() - tUnpack; + accel->numAccelerated++; + return true; +} + +} // namespace + +bool tryMatmul( + Accel* accel, float* out, const float* in, const MatMulLayerDesc& desc, int numRows) { + if(accel == nullptr || numRows < accel->options.minRows) { + if(accel != nullptr) + accel->numFallback++; + return false; + } + Layer& layer = prepareLayer( + accel, &desc, desc.weights.data(), desc.inChannels, desc.outChannels, WeightForm::InByOut); + if(!layer.usable) { + accel->numFallback++; + return false; + } + return runLayer(accel, layer, out, in, desc.inChannels, desc.outChannels, numRows, false); +} + +namespace { + + // First use of a fused projection: concatenates the descs' weights along N + // into one uploaded B. All descs must share the same inChannels (checked by + // the caller). Column block j holds descs[j]'s outChannels columns, in + // order, so one dispatch produces every output side by side. + Layer& prepareFusedLayer( + Accel* accel, const MatMulLayerDesc* const* descs, int numDescs) { + Layer& layer = accel->fusedLayers[descs[0]]; + if(layer.engine != nullptr || layer.why.size() > 0) + return layer; + + const int inC = descs[0]->inChannels; + int K = 0; + if(!pickK(accel, inC, K)) { + layer.why = "no artifact with K >= " + Global::intToString(inC); + return layer; + } + + RyzenAIKernel::EngineInfo info; + RyzenAIKernel::Engine* engine = engineForK(accel, K, info); + if(engine == nullptr) { + layer.why = "engine for K=" + Global::intToString(K) + " would not load"; + return layer; + } + + int totalOutC = 0; + for(int j = 0; j < numDescs; j++) + totalOutC += descs[j]->outChannels; + const int paddedN = RyzenAIKernel::padN(info, totalOutC); + + const double tConvert = nowSecs(); + vector b((size_t)info.K * (size_t)paddedN, RyzenAIKernel::floatToBf16(0.0f)); + int off = 0; + for(int j = 0; j < numDescs; j++) { + const MatMulLayerDesc* d = descs[j]; + const float* w = d->weights.data(); + for(int ic = 0; ic < inC; ic++) { + uint16_t* dst = b.data() + (size_t)ic * paddedN + off; + const float* src = w + (size_t)ic * d->outChannels; + for(int oc = 0; oc < d->outChannels; oc++) + dst[oc] = RyzenAIKernel::floatToBf16(src[oc]); + } + off += d->outChannels; + } + accel->secsPrepareConvert += nowSecs() - tConvert; + accel->prepareBytes += (long long)b.size() * 2; + + const double tUpload = nowSecs(); + string err; + RyzenAIKernel::Weights* weights = RyzenAIKernel::uploadWeights(engine, paddedN, b.data(), err); + accel->secsPrepareUpload += nowSecs() - tUpload; + if(weights == nullptr) { + layer.why = err; + return layer; + } + + layer.engine = engine; + layer.weights = weights; + layer.K = info.K; + layer.paddedN = paddedN; + layer.usable = true; + return layer; + } + +} // namespace + +bool tryMatmulMulti( + Accel* accel, float* const* outs, const float* in, + const MatMulLayerDesc* const* descs, int numDescs, int numRows) { + if(accel == nullptr || numDescs < 2 || numRows < accel->options.minRows) { + if(accel != nullptr) + accel->numFallback += numDescs; + return false; + } + const int inC = descs[0]->inChannels; + for(int j = 1; j < numDescs; j++) + if(descs[j]->inChannels != inC) + return false; // not fusible; the caller runs each on its own path + + Layer& layer = prepareFusedLayer(accel, descs, numDescs); + if(!layer.usable) { + accel->numFallback += numDescs; + return false; + } + if(!dispatchPacked(accel, layer, in, inC, numRows)) + return false; + + const double tUnpack = nowSecs(); + const int paddedN = layer.paddedN; + int off = 0; + for(int j = 0; j < numDescs; j++) { + const int outC = descs[j]->outChannels; + float* out = outs[j]; + for(int r = 0; r < numRows; r++) + std::memcpy( + out + (size_t)r * outC, accel->hostC.data() + (size_t)r * paddedN + off, + (size_t)outC * sizeof(float)); + off += outC; + } + + accel->secsUnpackC += nowSecs() - tUnpack; + accel->numAccelerated += numDescs; + return true; +} + +namespace { + + // The swiglu-epilogue engines sit on their own hardware contexts, one per K. + RyzenAIKernel::Engine* swigluEngineForK( + Accel* accel, int K, RyzenAIKernel::EngineInfo& infoOut) { + auto it = accel->swigluEngines.find(K); + if(it != accel->swigluEngines.end()) { + infoOut = accel->swigluInfos[K]; + return it->second; + } + RyzenAIKernel::EngineInfo info; + string err; + RyzenAIKernel::Engine* engine = RyzenAIKernel::loadEngineSwiglu( + accel->options.artifactDir, accel->options.deviceIdx, accel->dtype, K, + accel->options.maxCols, info, err); + if(engine == nullptr) + return nullptr; + accel->swigluEngines[info.K] = engine; + accel->swigluInfos[info.K] = info; + infoOut = info; + return engine; + } + + // Which reduction dim the swiglu path can serve this layer on. forceK wins + // only when a swiglu artifact exists at exactly that K -- substituting a + // different one would add yet another hardware context, which the forced-K + // policy exists to eliminate. Without forceK, take the smallest available + // swiglu K that fits (zero-padding the reduction is nearly free). + bool pickSwigluK(const Accel* accel, int inC, int& kOut) { + const vector& ks = accel->availableSwigluK; + if(accel->options.forceK > 0 && accel->options.forceK >= inC) { + if(std::binary_search(ks.begin(), ks.end(), accel->options.forceK)) { + kOut = accel->options.forceK; + return true; + } + return false; + } + for(size_t i = 0; i < ks.size(); i++) { + if(ks[i] >= inC) { + kOut = ks[i]; + return true; + } + } + return false; + } + + // First use of an FFN's linear1/linearGate pair: pad and upload the two + // weight matrices as one B whose columns interleave in groups of 8 -- + // [linear1 ch 0-7, gate ch 0-7, linear1 ch 8-15, ...] -- so that in every + // core's C tile the even 8-column sub-tiles hold linear1 outputs and the odd + // ones the matching gates, which is the pairing the on-chip epilogue + // assumes (see python/ryzenai_kernels/kernels/mm_swiglu_epilogue.cc). + Layer& prepareSwigluLayer( + Accel* accel, const MatMulLayerDesc& linear1, const MatMulLayerDesc& linearGate) { + Layer& layer = accel->swigluLayers[&linear1]; + if(layer.engine != nullptr || layer.why.size() > 0) + return layer; + + const int inC = linear1.inChannels; + const int ffnC = linear1.outChannels; + int K = 0; + if(!pickSwigluK(accel, inC, K)) { + layer.why = "no swiglu-epilogue artifact serving K >= " + Global::intToString(inC); + return layer; + } + + RyzenAIKernel::EngineInfo info; + RyzenAIKernel::Engine* engine = swigluEngineForK(accel, K, info); + if(engine == nullptr) { + layer.why = "swiglu engine for K=" + Global::intToString(K) + " would not load"; + return layer; + } + + const int paddedN = RyzenAIKernel::padN(info, 2 * ffnC); + + const double tConvert = nowSecs(); + vector b((size_t)info.K * (size_t)paddedN, RyzenAIKernel::floatToBf16(0.0f)); + const float* w1 = linear1.weights.data(); + const float* wg = linearGate.weights.data(); + for(int ic = 0; ic < inC; ic++) { + uint16_t* dst = b.data() + (size_t)ic * paddedN; + const float* s1 = w1 + (size_t)ic * ffnC; + const float* sg = wg + (size_t)ic * ffnC; + for(int c = 0; c < ffnC; c++) { + const int base = (c >> 3) << 4; + dst[base + (c & 7)] = RyzenAIKernel::floatToBf16(s1[c]); + dst[base + 8 + (c & 7)] = RyzenAIKernel::floatToBf16(sg[c]); + } + } + accel->secsPrepareConvert += nowSecs() - tConvert; + accel->prepareBytes += (long long)b.size() * 2; + + const double tUpload = nowSecs(); + string err; + RyzenAIKernel::Weights* weights = RyzenAIKernel::uploadWeights(engine, paddedN, b.data(), err); + accel->secsPrepareUpload += nowSecs() - tUpload; + if(weights == nullptr) { + layer.why = err; + return layer; + } + + layer.engine = engine; + layer.weights = weights; + layer.K = info.K; + layer.paddedN = paddedN; + layer.usable = true; + return layer; + } + +} // namespace + +bool tryMatmulSwiglu( + Accel* accel, float* out, const float* in, + const MatMulLayerDesc& linear1, const MatMulLayerDesc& linearGate, int numRows) { + if(accel == nullptr || numRows < accel->options.minRows) { + if(accel != nullptr) + accel->numSwigluFallback++; + return false; + } + // The epilogue pairs adjacent 8-column groups, so the two projections must + // agree on the shape and the channel count must fill whole groups. + if(linear1.inChannels != linearGate.inChannels || + linear1.outChannels != linearGate.outChannels || + linear1.outChannels % 8 != 0) { + accel->numSwigluFallback++; + return false; + } + + Layer& layer = prepareSwigluLayer(accel, linear1, linearGate); + if(!layer.usable) { + accel->numSwigluFallback++; + return false; + } + if(!dispatchPacked(accel, layer, in, linear1.inChannels, numRows)) + return false; + + // C row r holds silu(l1)*gate for channel c at column (c>>3)*16 + (c&7); + // the interleaved gate columns in between are the raw GEMM outputs and are + // simply never read. + const double tUnpack = nowSecs(); + const int paddedN = layer.paddedN; + const int ffnC = linear1.outChannels; + for(int r = 0; r < numRows; r++) { + const float* src = accel->hostC.data() + (size_t)r * paddedN; + float* dst = out + (size_t)r * ffnC; + for(int c = 0; c < ffnC; c++) + dst[c] = src[((c >> 3) << 4) + (c & 7)]; + } + + accel->secsUnpackC += nowSecs() - tUnpack; + accel->numSwiglu++; + return true; +} + +bool tryConv1x1( + Accel* accel, float* out, const float* in, const ConvLayerDesc& desc, int numRows, + bool accumulate) { + if(accel == nullptr || numRows < accel->options.minRows) { + if(accel != nullptr) + accel->numFallback++; + return false; + } + if(desc.convXSize != 1 || desc.convYSize != 1) + return false; // not a fallback, just not this function's business + Layer& layer = prepareLayer( + accel, &desc, desc.weights.data(), desc.inChannels, desc.outChannels, WeightForm::OutByIn); + if(!layer.usable) { + accel->numFallback++; + return false; + } + return runLayer(accel, layer, out, in, desc.inChannels, desc.outChannels, numRows, accumulate); +} + +bool tryConv( + Accel* accel, float* out, const float* in, const ConvLayerDesc& desc, int batchSize, + int nnXLen, int nnYLen, bool accumulate) { + const int numRows = batchSize * nnXLen * nnYLen; + if(accel == nullptr || numRows < accel->options.minRows) { + if(accel != nullptr) + accel->numFallback++; + return false; + } + const int kx = desc.convXSize; + const int ky = desc.convYSize; + if(kx == 1 && ky == 1) + return tryConv1x1(accel, out, in, desc, numRows, accumulate); + // Even kernel sizes would not centre; KataGo only ever uses odd ones. + if(kx <= 0 || ky <= 0 || (kx % 2) == 0 || (ky % 2) == 0) + return false; + + const int numTaps = ky * kx; + Layer& layer = prepareLayer( + accel, &desc, desc.weights.data(), desc.inChannels, desc.outChannels, WeightForm::ConvTaps, + numTaps); + if(!layer.usable) { + accel->numFallback++; + return false; + } + + const RyzenAIKernel::EngineInfo& info = RyzenAIKernel::engineInfo(layer.engine); + const int paddedM = RyzenAIKernel::padM(info, numRows); + const int K = layer.K; + const int inC = desc.inChannels; + const int padX = kx / 2; + const int padY = ky / 2; + const int dilX = desc.dilationX; + const int dilY = desc.dilationY; + + // im2col straight into the A scratch, in bfloat16. Off-board taps and the + // columns past numTaps*inChannels stay zero, which is exactly what the + // convolution's zero padding means. + const double tGather = nowSecs(); + accel->hostA.assign((size_t)paddedM * (size_t)K, RyzenAIKernel::floatToBf16(0.0f)); + + // One pass over the input converts it; the gather below then only moves + // bytes. Same conversion function on the same values, so the bytes handed to + // the NPU are identical to the element-wise version this replaces. + const size_t inCount = (size_t)numRows * (size_t)inC; + if(accel->hostConvIn.size() < inCount) + accel->hostConvIn.resize(inCount); + RyzenAIKernel::floatToBf16Bulk(in, accel->hostConvIn.data(), inCount); + + const uint16_t* convIn = accel->hostConvIn.data(); + const size_t tapBytes = (size_t)inC * sizeof(uint16_t); + for(int n = 0; n < batchSize; n++) { + for(int y = 0; y < nnYLen; y++) { + for(int x = 0; x < nnXLen; x++) { + uint16_t* dstRow = + accel->hostA.data() + (((size_t)n * nnYLen + y) * nnXLen + x) * K; + for(int dy = 0; dy < ky; dy++) { + const int iy = y + (dy - padY) * dilY; + if(iy < 0 || iy >= nnYLen) + continue; + for(int dx = 0; dx < kx; dx++) { + const int ix = x + (dx - padX) * dilX; + if(ix < 0 || ix >= nnXLen) + continue; + const uint16_t* src = convIn + ((((size_t)n * nnYLen + iy) * nnXLen + ix) * inC); + uint16_t* dst = dstRow + (size_t)(dy * kx + dx) * inC; + std::memcpy(dst, src, tapBytes); + } + } + } + } + } + accel->secsGather += nowSecs() - tGather; + + return runLayer(accel, layer, out, nullptr, inC, desc.outChannels, numRows, accumulate); +} + +namespace { + + // First attention block of a given shape: pick engines for the two reduction + // dims (numHeads*qHeadDim for QK^T, numHeads*S for P*V), then allocate and + // zero-fill the host scratch and the two device-resident B buffers. + // Attention shapes are fixed for a (model, geometry) pair, so this runs once + // per Accel. + void prepareAttention( + Accel* accel, int S, int numHeads, int numKVHeads, int qHeadDim, int vHeadDim) { + AttnState& st = accel->attn; + if(st.usable || st.why.size() > 0) + return; + + st.S = S; + st.numHeads = numHeads; + st.numKVHeads = numKVHeads; + st.qHeadDim = qHeadDim; + st.vHeadDim = vHeadDim; + + const int qTot = numHeads * qHeadDim; + const int headsByS = numHeads * S; + int kQK = 0; + int kPV = 0; + if(!pickK(accel, qTot, kQK)) { + st.why = "no artifact with K >= qTot " + Global::intToString(qTot); + return; + } + if(!pickK(accel, headsByS, kPV)) { + st.why = "no artifact with K >= numHeads*S " + Global::intToString(headsByS); + return; + } + + RyzenAIKernel::EngineInfo infoQK; + RyzenAIKernel::EngineInfo infoPV; + st.engineQK = engineForK(accel, kQK, infoQK); + if(st.engineQK == nullptr) { + st.why = "attention engine for K=" + Global::intToString(kQK) + " would not load"; + return; + } + st.enginePV = engineForK(accel, kPV, infoPV); + if(st.enginePV == nullptr) { + st.why = "attention engine for K=" + Global::intToString(kPV) + " would not load"; + return; + } + + st.KQK = infoQK.K; + st.KPV = infoPV.K; + st.paddedMQK = RyzenAIKernel::padM(infoQK, S); + st.paddedMPV = RyzenAIKernel::padM(infoPV, S); + st.paddedNQK = RyzenAIKernel::padN(infoQK, headsByS); + st.paddedNPV = RyzenAIKernel::padN(infoPV, numHeads * vHeadDim); + + // Zero-filled: the padding regions of every buffer (and the off-diagonal + // blocks of the two B buffers) stay zero for the state's lifetime, and + // only the real regions are rewritten per dispatch. + const uint16_t zero = RyzenAIKernel::floatToBf16(0.0f); + st.hostAQK.assign((size_t)st.paddedMQK * st.KQK, zero); + st.hostAPV.assign((size_t)st.paddedMPV * st.KPV, zero); + st.hostBQK.assign((size_t)st.KQK * st.paddedNQK, zero); + st.hostBPV.assign((size_t)st.KPV * st.paddedNPV, zero); + st.hostC.assign( + std::max((size_t)st.paddedMQK * st.paddedNQK, (size_t)st.paddedMPV * st.paddedNPV), 0.0f); + st.scoreRow.assign(S, 0.0f); + + string err; + st.weightsQK = RyzenAIKernel::uploadWeights(st.engineQK, st.paddedNQK, st.hostBQK.data(), err); + if(st.weightsQK == nullptr) { + st.why = err; + return; + } + st.weightsPV = RyzenAIKernel::uploadWeights(st.enginePV, st.paddedNPV, st.hostBPV.data(), err); + if(st.weightsPV == nullptr) { + st.why = err; + return; + } + + // The softmax between the GEMMs goes to the NPU when an op compiled for + // exactly this shape exists; its absence is ordinary (CPU path stays). + // Rows pad to a multiple of 64 (8 cores x 8-row chunks) and columns to a + // multiple of 32 (the kernel's vector width). + st.smRows = ((numHeads * S + 63) / 64) * 64; + st.smWidth = ((S + 31) / 32) * 32; + { + const string base = accel->options.artifactDir + "/ops/softmax_" + + Global::intToString(st.smRows) + "x" + Global::intToString(st.smWidth); + const size_t smBytes = (size_t)st.smRows * (size_t)st.smWidth * sizeof(uint16_t); + string smErr; + st.softmaxOp = RyzenAIKernel::loadOp( + base + ".xclbin", base + ".insts.bin", accel->options.deviceIdx, &smBytes, 1, smBytes, + smErr); + if(st.softmaxOp != nullptr) { + st.hostSmIn.assign(smBytes / sizeof(uint16_t), RyzenAIKernel::floatToBf16(0.0f)); + st.hostSmOut.assign(smBytes / sizeof(uint16_t), 0); + } + } + + // The fused attention op (QK^T + softmax + P*V in one dispatch) replaces + // the whole staged path when present. Its host buffers carry Q/K/V + // pre-tiled into the mmul tile orders; see + // python/ryzenai_kernels/kernels/attention_head.cc for the layout contract. + { + const string attnBase = accel->options.artifactDir + "/ops/attn_h" + + Global::intToString(numHeads) + "_s" + Global::intToString(S); + const size_t qBytes = (size_t)numHeads * st.smWidth * qHeadDim * sizeof(uint16_t); + // K/V are packed per query head (a GQA group head's data is replicated + // onto each of its query heads' slots -- the compiled op's taps are + // per-head). + const size_t kvBytes = (size_t)numHeads * 2 * st.smWidth * qHeadDim * sizeof(uint16_t); + const size_t cBytes = (size_t)numHeads * st.smWidth * vHeadDim * sizeof(float); + const size_t inBytes[2] = {qBytes, kvBytes}; + string attErr; + st.attnOp = RyzenAIKernel::loadOp( + attnBase + ".xclbin", attnBase + ".insts.bin", accel->options.deviceIdx, + inBytes, 2, cBytes, attErr); + if(st.attnOp != nullptr) { + st.attnQ.assign(qBytes / sizeof(uint16_t), RyzenAIKernel::floatToBf16(0.0f)); + st.attnKV.assign(kvBytes / sizeof(uint16_t), RyzenAIKernel::floatToBf16(0.0f)); + st.attnC.assign(cBytes / sizeof(float), 0.0f); + } + } + + st.usable = true; + } + +} // namespace + +bool tryAttention( + Accel* accel, float* attnOut, + const float* qBuf, const float* kBuf, const float* vBuf, const float* mask, + int batchSize, int S, int numHeads, int numKVHeads, int qHeadDim, int vHeadDim, + double* softmaxSecsOut) { + if(softmaxSecsOut != nullptr) + *softmaxSecsOut = 0.0; + if(accel == nullptr) + return false; + prepareAttention(accel, S, numHeads, numKVHeads, qHeadDim, vHeadDim); + AttnState& st = accel->attn; + if(!st.usable || st.S != S || st.numHeads != numHeads || st.numKVHeads != numKVHeads || + st.qHeadDim != qHeadDim || st.vHeadDim != vHeadDim) { + accel->numAttnFallback++; + return false; + } + + const int qTot = numHeads * qHeadDim; + const int kTot = numKVHeads * qHeadDim; + const int vTot = numKVHeads * vHeadDim; + const int oTot = numHeads * vHeadDim; + const int kvGroupSize = numHeads / numKVHeads; + const float scale = 1.0f / sqrtf((float)qHeadDim); + const uint16_t zero16 = RyzenAIKernel::floatToBf16(0.0f); + double softmaxSecs = 0.0; + + // ---- fused path: the whole attention in one dispatch per batch element --- + // The op computes softmax((q*scale) @ K^T) @ V entirely on-chip. It handles + // full boards only (masked positions would need the -inf treatment the + // staged path's gather does), so anything masked falls through below. + if(st.attnOp != nullptr && qHeadDim == 32 && vHeadDim == 32) { + bool fullBoard = true; + for(int i = 0; i < batchSize * S; i++) { + if(mask[i] == 0.0f) { + fullBoard = false; + break; + } + } + if(fullBoard) { + const int sPad = st.smWidth; // the op's padded S (384 for 361) + for(int n = 0; n < batchSize; n++) { + const float* qN = qBuf + (size_t)n * S * qTot; + const float* kN = kBuf + (size_t)n * S * kTot; + const float* vN = vBuf + (size_t)n * S * vTot; + const double tPack = nowSecs(); + + // Each head-row is 32 contiguous floats going to a strided place, so + // convert the 32 in one call and then move plain uint16s. Doing the + // conversion inside the scatter meant 32 branchy scalar conversions per + // row, which is what made packing rival dispatch in the profile. + float scaled[32]; + uint16_t tmp[32]; + + // Q: per-head contiguous 8x32 chunks in A-tile order, pre-scaled. + for(int h = 0; h < numHeads; h++) { + uint16_t* qH = st.attnQ.data() + (size_t)h * sPad * 32; + const float* src = qN + (size_t)h * 32; + for(int qi = 0; qi < S; qi++, src += qTot) { + // within-chunk offset = (rowgroup*4 + row)*8 lanes: rows 4-7 of + // the chunk live 128 elements in, not at (qi&3)*8. + uint16_t* chunk = qH + (size_t)(qi >> 3) * 256 + + (((qi & 7) >> 2) * 128) + ((qi & 3) * 8); + for(int d = 0; d < 32; d++) + scaled[d] = src[d] * scale; + RyzenAIKernel::floatToBf16Bulk(scaled, tmp, 32); + // d's low three bits stay adjacent, so each group of eight is one + // contiguous run at stride 32. + for(int g = 0; g < 4; g++) + std::memcpy(chunk + (size_t)g * 32, tmp + g * 8, 8 * sizeof(uint16_t)); + } + } + // K/V: per head, K then V back to back, each in its B-tile order. + for(int h = 0; h < numHeads; h++) { + const int kvh = h / kvGroupSize; + uint16_t* kvH = st.attnKV.data() + (size_t)h * 2 * sPad * 32; + const float* kSrc = kN + (size_t)kvh * 32; + const float* vSrc = vN + (size_t)kvh * 32; + for(int ki = 0; ki < S; ki++, kSrc += kTot, vSrc += vTot) { + uint16_t* kDst = kvH + (size_t)(ki >> 3) * 256 + (ki & 7) * 8; + RyzenAIKernel::floatToBf16Bulk(kSrc, tmp, 32); + for(int g = 0; g < 4; g++) + std::memcpy(kDst + (size_t)g * 64, tmp + g * 8, 8 * sizeof(uint16_t)); + // V is transposed relative to K, so this one stays a scatter - but + // now it moves already-converted values. + uint16_t* vDst = kvH + (size_t)sPad * 32 + (ki & 7) + (size_t)(ki >> 3) * 64; + RyzenAIKernel::floatToBf16Bulk(vSrc, tmp, 32); + for(int dv = 0; dv < 32; dv++) + vDst[(dv >> 3) * 3072 + (dv & 7) * 8] = tmp[dv]; + } + } + accel->secsAttnPack += nowSecs() - tPack; + + const double tDispatch = nowSecs(); + try { + const void* ins[2] = {st.attnQ.data(), st.attnKV.data()}; + RyzenAIKernel::runOp(st.attnOp, ins, 2, st.attnC.data()); + } + catch(const std::exception&) { + st.attnOp = nullptr; // permanent: staged path from here on + accel->numAttnFallback++; + return false; + } + accel->secsAttnDispatch += nowSecs() - tDispatch; + + // C: per-head 8x32 chunks in C-tile order -> attnOut rows. + const double tUnpack = nowSecs(); + for(int h = 0; h < numHeads; h++) { + const float* cH = st.attnC.data() + (size_t)h * sPad * 32; + float* dst = attnOut + (size_t)n * S * oTot + (size_t)h * 32; + for(int qi = 0; qi < S; qi++) { + const float* chunk = cH + (size_t)(qi >> 3) * 256 + + (((qi & 7) >> 2) * 128) + ((qi & 3) * 8); + float* out = dst + (size_t)qi * oTot; + for(int dv = 0; dv < 32; dv++) + out[dv] = chunk[(dv >> 3) * 32 + (dv & 7)]; + } + } + accel->secsAttnUnpack += nowSecs() - tUnpack; + } + accel->numAttn++; + return true; + } + } + + for(int n = 0; n < batchSize; n++) { + const float* maskN = mask + (size_t)n * S; + + // ---- QK^T for every head in one GEMM ---------------------------------- + // A[qi][h*qHeadDim + d] = qBuf[n][qi][h*qHeadDim + d] -- i.e. the raw + // qBuf row, which already concatenates the heads exactly along the + // reduction dim. + // B is block-diagonal: B[h*qHeadDim + d][h*S + ki] = kBuf[n][ki][kvh*qHeadDim+d] + // (the K matrix of head h, transposed), zero elsewhere, so + // C[qi][h*S + ki] = falls out per head. + const double tPack = nowSecs(); + for(int qi = 0; qi < S; qi++) { + const float* src = qBuf + ((size_t)n * S + qi) * qTot; + uint16_t* dst = st.hostAQK.data() + (size_t)qi * st.KQK; + for(int c = 0; c < qTot; c++) + dst[c] = RyzenAIKernel::floatToBf16(src[c]); + } + for(int h = 0; h < numHeads; h++) { + const int kvh = h / kvGroupSize; + for(int d = 0; d < qHeadDim; d++) { + uint16_t* dst = st.hostBQK.data() + (size_t)(h * qHeadDim + d) * st.paddedNQK + (size_t)h * S; + const float* src = kBuf + (size_t)n * S * kTot + (size_t)kvh * qHeadDim + d; + for(int ki = 0; ki < S; ki++) + dst[ki] = RyzenAIKernel::floatToBf16(src[(size_t)ki * kTot]); + } + } + const double tUpload = nowSecs(); + accel->secsAttnPack += tUpload - tPack; + RyzenAIKernel::rewriteWeights(st.weightsQK, st.hostBQK.data()); + const double tDispatch = nowSecs(); + accel->secsAttnUploadB += tDispatch - tUpload; + try { + RyzenAIKernel::runGemm( + st.engineQK, st.weightsQK, st.paddedMQK, st.paddedNQK, st.hostAQK.data(), + st.hostC.data()); + } + catch(const std::exception&) { + // A dispatch failure is not fatal: drop attention to the CPU + // permanently and let the evaluation finish with correct numbers. + st.usable = false; + st.why = "dispatch failed at run time"; + accel->numAttnFallback++; + return false; + } + accel->secsAttnDispatch += nowSecs() - tDispatch; + + // ---- softmax ------------------------------------------------------------ + // NPU when an op for this exact shape loaded, CPU otherwise. Either way + // the probabilities land in the P*V GEMM's A (bfloat16) at + // A[qi][h*S + ki], and rows of masked-out queries and columns of + // masked-out keys are exactly 0, matching the reference semantics. + if(st.softmaxOp != nullptr) { + const double tGather = nowSecs(); + const uint16_t negInf = RyzenAIKernel::floatToBf16(-1e30f); + for(int h = 0; h < numHeads; h++) { + for(int qi = 0; qi < S; qi++) { + if(maskN[qi] == 0.0f) + continue; // the scatter writes exact zeros for this row + const float* cRow = st.hostC.data() + (size_t)qi * st.paddedNQK + (size_t)h * S; + uint16_t* dst = st.hostSmIn.data() + ((size_t)h * S + qi) * st.smWidth; + for(int ki = 0; ki < S; ki++) + dst[ki] = maskN[ki] == 0.0f ? negInf : RyzenAIKernel::floatToBf16(cRow[ki] * scale); + for(int ki = S; ki < st.smWidth; ki++) + dst[ki] = negInf; + } + } + const double tSmDispatch = nowSecs(); + accel->secsAttnSoftmaxHost += tSmDispatch - tGather; + try { + const void* smIns[1] = {st.hostSmIn.data()}; + RyzenAIKernel::runOp(st.softmaxOp, smIns, 1, st.hostSmOut.data()); + } + catch(const std::exception&) { + st.usable = false; + st.why = "softmax dispatch failed at run time"; + accel->numAttnFallback++; + return false; + } + const double tScatter = nowSecs(); + accel->secsAttnSoftmaxNpu += tScatter - tSmDispatch; + + for(int h = 0; h < numHeads; h++) { + for(int qi = 0; qi < S; qi++) { + uint16_t* dst = st.hostAPV.data() + (size_t)qi * st.KPV + (size_t)h * S; + if(maskN[qi] == 0.0f) { + std::fill(dst, dst + S, zero16); + continue; + } + const uint16_t* src = st.hostSmOut.data() + ((size_t)h * S + qi) * st.smWidth; + for(int ki = 0; ki < S; ki++) + dst[ki] = maskN[ki] == 0.0f ? zero16 : src[ki]; + } + } + accel->secsAttnSoftmaxHost += nowSecs() - tScatter; + } + else { + // ---- softmax on the CPU, byte-for-byte the reference semantics -------- + // Reads the raw scores out of C and writes the probabilities straight + // into the P*V GEMM's A (bfloat16), at A[qi][h*S + ki]. Rows of + // masked-out queries and columns of masked-out keys are exactly 0. + const double tSoftmax = nowSecs(); + for(int h = 0; h < numHeads; h++) { + for(int qi = 0; qi < S; qi++) { + uint16_t* dst = st.hostAPV.data() + (size_t)qi * st.KPV + (size_t)h * S; + if(maskN[qi] == 0.0f) { + std::fill(dst, dst + S, zero16); + continue; + } + const float* cRow = st.hostC.data() + (size_t)qi * st.paddedNQK + (size_t)h * S; + float maxVal = -1e30f; + for(int ki = 0; ki < S; ki++) { + if(maskN[ki] == 0.0f) + continue; + const float acc = cRow[ki] * scale; + st.scoreRow[ki] = acc; + if(acc > maxVal) + maxVal = acc; + } + float sumExp = 0.0f; + for(int ki = 0; ki < S; ki++) { + if(maskN[ki] == 0.0f) + continue; + float e = expf(st.scoreRow[ki] - maxVal); + st.scoreRow[ki] = e; + sumExp += e; + } + float invSum = 1.0f / sumExp; + for(int ki = 0; ki < S; ki++) + dst[ki] = maskN[ki] == 0.0f ? zero16 : RyzenAIKernel::floatToBf16(st.scoreRow[ki] * invSum); + } + } + softmaxSecs += nowSecs() - tSoftmax; + } + + // ---- P*V for every head in one GEMM ----------------------------------- + // A is the softmax output written above. B is block-diagonal: + // B[h*S + ki][h*vHeadDim + dv] = vBuf[n][ki][kvh*vHeadDim + dv], zero + // elsewhere, so C[qi][h*vHeadDim + dv] = sum_ki P_h[qi][ki] * V_h[ki][dv] + // -- i.e. one C row is exactly one attnOut row. + const double tPack2 = nowSecs(); + for(int h = 0; h < numHeads; h++) { + const int kvh = h / kvGroupSize; + for(int ki = 0; ki < S; ki++) { + const float* src = vBuf + ((size_t)n * S + ki) * vTot + (size_t)kvh * vHeadDim; + uint16_t* dst = + st.hostBPV.data() + (size_t)(h * S + ki) * st.paddedNPV + (size_t)h * vHeadDim; + for(int dv = 0; dv < vHeadDim; dv++) + dst[dv] = RyzenAIKernel::floatToBf16(src[dv]); + } + } + const double tUpload2 = nowSecs(); + accel->secsAttnPack += tUpload2 - tPack2; + RyzenAIKernel::rewriteWeights(st.weightsPV, st.hostBPV.data()); + const double tDispatch2 = nowSecs(); + accel->secsAttnUploadB += tDispatch2 - tUpload2; + try { + RyzenAIKernel::runGemm( + st.enginePV, st.weightsPV, st.paddedMPV, st.paddedNPV, st.hostAPV.data(), + st.hostC.data()); + } + catch(const std::exception&) { + st.usable = false; + st.why = "dispatch failed at run time"; + accel->numAttnFallback++; + return false; + } + const double tUnpack = nowSecs(); + accel->secsAttnDispatch += tUnpack - tDispatch2; + + for(int qi = 0; qi < S; qi++) { + float* dst = attnOut + ((size_t)n * S + qi) * oTot; + const float* src = st.hostC.data() + (size_t)qi * st.paddedNPV; + std::memcpy(dst, src, (size_t)oTot * sizeof(float)); + } + accel->secsAttnUnpack += nowSecs() - tUnpack; + } + + accel->numAttn++; + accel->secsAttnSoftmax += softmaxSecs; + if(softmaxSecsOut != nullptr) + *softmaxSecsOut = softmaxSecs; + return true; +} + + + + + +bool tryBnMish( + Accel* accel, float* out, const float* in, const BatchNormLayerDesc& bn, + int activation, int numRows) { + if(accel == nullptr) + return false; + if(activation != ACTIVATION_MISH) + return false; + + const int C = bn.numChannels; + // Smallest shipped height that covers this call in one dispatch, or the + // tallest if none does (which then chunks). Both ends cost: too short pays + // the fixed dispatch cost repeatedly, too tall pays the per-row cost on rows + // that are only padding. Choosing per call is the point - latching a height + // on the first call is what silently cost b40c768 its BN acceleration under + // batching (CPU norms 0.38 s -> 21.55 s). + int rows = Accel::kBnMishHeights[2]; + for(int i = 0; i < 3; i++) { + if(Accel::kBnMishHeights[i] >= numRows) { + rows = Accel::kBnMishHeights[i]; + break; + } + } + Accel::BnMishState& st = accel->bnmByShape[std::make_pair(C, rows)]; + if(!st.tried) { + st.tried = true; + st.width = C; + st.rowsPad = rows; + const string base = accel->options.artifactDir + "/ops/bnmish_" + + Global::intToString(st.rowsPad) + "x" + Global::intToString(st.width); + const size_t xBytes = (size_t)st.rowsPad * st.width * sizeof(uint16_t); + const size_t sbBytes = (size_t)8 * 2 * st.width * sizeof(uint16_t); + const size_t inBytes[2] = {xBytes, sbBytes}; + string err; + st.op = RyzenAIKernel::loadOp( + base + ".xclbin", base + ".insts.bin", accel->options.deviceIdx, + inBytes, 2, xBytes, err); + if(st.op != nullptr) { + st.hostX.assign(xBytes / sizeof(uint16_t), RyzenAIKernel::floatToBf16(0.0f)); + st.hostSB.assign(sbBytes / sizeof(uint16_t), 0); + st.hostY.assign(xBytes / sizeof(uint16_t), 0); + } + else { + st.why = "no " + Global::intToString(st.rowsPad) + "x" + + Global::intToString(st.width) + " artifact (" + err + ")"; + } + } + if(st.op == nullptr) + return false; + + const int W = st.width; + // Row blocks are independent: feeding the op 64 rows at a time instead of + // 384 reproduced the whole raw-nn output byte for byte, partial final block + // included, so this stride is purely a performance knob. + const int rowsPerRun = st.rowsPad; + const double t0 = nowSecs(); + + // scale/bias, replicated per core, [scale | bias] per core. Per layer, not + // per row block, so it is packed once for the whole call. + for(int core = 0; core < 8; core++) { + uint16_t* sb = st.hostSB.data() + (size_t)core * 2 * W; + for(int c = 0; c < W; c++) { + sb[c] = RyzenAIKernel::floatToBf16(bn.mergedScale[c]); + sb[W + c] = RyzenAIKernel::floatToBf16(bn.mergedBias[c]); + } + } + + for(int base = 0; base < numRows; base += rowsPerRun) { + const int rows = std::min(rowsPerRun, numRows - base); + + // X: rows of board points in bf16. A short final block leaves whatever the + // previous block wrote in the tail; those outputs are simply not read back, + // and Mish is elementwise so they cannot disturb the rows that are. + for(int r = 0; r < rows; r++) { + const float* src = in + (size_t)(base + r) * W; + uint16_t* dst = st.hostX.data() + (size_t)r * W; + for(int c = 0; c < W; c++) + dst[c] = RyzenAIKernel::floatToBf16(src[c]); + } + + try { + const void* ins[2] = {st.hostX.data(), st.hostSB.data()}; + RyzenAIKernel::runOp(st.op, ins, 2, st.hostY.data()); + } + catch(const std::exception&) { + RyzenAIKernel::freeOp(st.op); + st.op = nullptr; + // Rows before this block are already written; the caller's contract is + // that a false return means it must redo the whole layer, which + // overwrites them. + return false; + } + + for(int r = 0; r < rows; r++) { + float* dst = out + (size_t)(base + r) * W; + const uint16_t* src = st.hostY.data() + (size_t)r * W; + for(int c = 0; c < W; c++) + dst[c] = RyzenAIKernel::bf16ToFloat(src[c]); + } + accel->numBnMish++; // counts dispatches, so batching shows up here + } + + accel->secsBnMish += nowSecs() - t0; + return true; +} + +string report(const Accel* accel) { if(accel == nullptr) + return "RyzenAI dense layers: accelerator not created"; + + std::ostringstream out; + out << "RyzenAI dense layers: " << accel->numAccelerated << " on NPU, " << accel->numFallback + << " on CPU"; + if(accel->numBnMish > 0) { + char b[128]; + std::snprintf( + b, sizeof(b), "\n bn+mish on NPU: %lld dispatches (%.2f s)", accel->numBnMish, + accel->secsBnMish); + out << b; + } + // A width with no artifact runs on the CPU at full numerical fidelity, so + // nothing looks wrong - it is just slow. Name it, or the next model with an + // unshipped channel count silently loses this acceleration the way batched + // b40c768 did. + for(const auto& e : accel->bnmByShape) { + if(e.second.why.size() > 0) + out << "\n bn+mish NOT on NPU for " << e.first.first << " channels x " + << e.first.second << " rows: " << e.second.why; + } + if(accel->numAccelerated > 0) { + const double total = + accel->secsPackA + accel->secsGather + accel->secsDispatch + accel->secsUnpackC; + char buf[320]; + std::snprintf( + buf, sizeof(buf), + "\n %.2f s total: pack A %.2f s (%.0f%%), im2col %.2f s (%.0f%%), " + "dispatch %.2f s (%.0f%%), unpack C %.2f s (%.0f%%)" + "\n %.3f ms per accelerated layer", + total, accel->secsPackA, 100 * accel->secsPackA / total, + accel->secsGather, 100 * accel->secsGather / total, + accel->secsDispatch, 100 * accel->secsDispatch / total, + accel->secsUnpackC, 100 * accel->secsUnpackC / total, + 1000.0 * total / (double)accel->numAccelerated); + out << buf; + std::snprintf( + buf, sizeof(buf), + "\n one-time weight prep: convert+pad %.3f s, upload %.3f s, %.1f MB", + accel->secsPrepareConvert, accel->secsPrepareUpload, + (double)accel->prepareBytes / (1024.0 * 1024.0)); + out << buf; + } + + if(!accel->engines.empty() || !accel->swigluEngines.empty()) { + out << "\n engines:"; + for(const auto& entry : accel->infos) + out << " K=" << entry.first << "(" << entry.second.cols << "col)"; + for(const auto& entry : accel->swigluInfos) + out << " K=" << entry.first << "(" << entry.second.cols << "col,swiglu)"; + + // Split the dispatch cost, which is what decides whether keeping + // activations resident on the device would pay. + RyzenAIKernel::Timings t; + for(const auto& entry : accel->engines) { + const RyzenAIKernel::Timings& e = RyzenAIKernel::engineTimings(entry.second); + t.secsUploadA += e.secsUploadA; + t.secsExecute += e.secsExecute; + t.secsDownloadC += e.secsDownloadC; + t.numDispatches += e.numDispatches; + } + for(const auto& entry : accel->swigluEngines) { + const RyzenAIKernel::Timings& e = RyzenAIKernel::engineTimings(entry.second); + t.secsUploadA += e.secsUploadA; + t.secsExecute += e.secsExecute; + t.secsDownloadC += e.secsDownloadC; + t.numDispatches += e.numDispatches; + } + if(t.numDispatches > 0) { + char buf[256]; + std::snprintf( + buf, sizeof(buf), + "\n inside dispatch: upload A %.2f s, execute %.2f s, download C %.2f s" + " (%.3f / %.3f / %.3f ms each, %lld dispatches)", + t.secsUploadA, t.secsExecute, t.secsDownloadC, + 1000.0 * t.secsUploadA / (double)t.numDispatches, + 1000.0 * t.secsExecute / (double)t.numDispatches, + 1000.0 * t.secsDownloadC / (double)t.numDispatches, + t.numDispatches); + out << buf; + } + } + + // Attention (QK^T / P*V) routing, reported separately from the dense layers + // because its per-call cost profile is entirely different. + if(accel->numAttn > 0 || accel->numAttnFallback > 0) { + out << "\n attention blocks: " << accel->numAttn << " on NPU, " << accel->numAttnFallback + << " on CPU"; + if(accel->numAttn > 0) { + const double total = + accel->secsAttnPack + accel->secsAttnUploadB + accel->secsAttnDispatch + + accel->secsAttnUnpack; + char buf[448]; + std::snprintf( + buf, sizeof(buf), + "\n %.2f s around the GEMMs: pack %.2f s, upload B %.2f s, dispatch %.2f s, " + "unpack %.2f s (%.3f ms per block)", + total, accel->secsAttnPack, accel->secsAttnUploadB, accel->secsAttnDispatch, + accel->secsAttnUnpack, 1000.0 * total / (double)accel->numAttn); + out << buf; + if(accel->attn.softmaxOp != nullptr) + std::snprintf( + buf, sizeof(buf), + "\n softmax on NPU: dispatch %.2f s, gather/scatter %.2f s", + accel->secsAttnSoftmaxNpu, accel->secsAttnSoftmaxHost); + else + std::snprintf( + buf, sizeof(buf), "\n softmax still on CPU: %.2f s", accel->secsAttnSoftmax); + out << buf; + } + if(!accel->attn.usable && accel->attn.why.size() > 0) + out << "\n attention on CPU: " << accel->attn.why; + } + + // Only the reasons matter, not which layer hit them: a model has at most a + // handful of distinct failure modes and dozens of layers sharing each. + if(accel->numSwiglu > 0 || accel->numSwigluFallback > 0) + out << "\n swiglu epilogue: " << accel->numSwiglu << " FFN blocks on NPU, " + << accel->numSwigluFallback << " on CPU"; + std::map reasons; + for(const auto& entry : accel->layers) { + if(!entry.second.usable && entry.second.why.size() > 0) + reasons[entry.second.why]++; + } + for(const auto& entry : accel->swigluLayers) { + if(!entry.second.usable && entry.second.why.size() > 0) + reasons[entry.second.why]++; + } + for(const auto& entry : reasons) + out << "\n " << entry.second << " layer(s) on CPU: " << entry.first; + + return out.str(); +} + +} // namespace RyzenAIMatMul diff --git a/cpp/neuralnet/ryzenaimatmul.h b/cpp/neuralnet/ryzenaimatmul.h new file mode 100644 index 0000000000..5c8d31ccb9 --- /dev/null +++ b/cpp/neuralnet/ryzenaimatmul.h @@ -0,0 +1,153 @@ +#ifndef NEURALNET_RYZENAI_MATMUL_H_ +#define NEURALNET_RYZENAI_MATMUL_H_ + +// Routes KataGo's dense layers to the NPU, falling back to the caller's CPU +// implementation whenever it cannot help. Also routes the two attention +// matmuls (QK^T and P*V), whose B operands are per-evaluation activations +// rather than resident weights -- see tryAttention below. +// +// KataGo already stores MatMulLayerDesc weights as inChannels x outChannels +// row-major, which is exactly the B operand the GEMM kernel wants, so weights +// need converting to bfloat16 but never transposing. Each layer's B is uploaded +// once and stays resident; only A and C cross the bus per evaluation. +// +// Padding: an xclbin fixes K, and the instruction stream requires M to be a +// multiple of tileM*8 and N a multiple of tileN*cols. Rows and columns beyond +// the real shape are zero-filled and their outputs discarded, so any layer +// shape runs -- at the cost of the wasted multiply-accumulates. + +#include +#include + +struct MatMulLayerDesc; +struct ConvLayerDesc; +struct BatchNormLayerDesc; +struct TransformerAttentionDesc; +struct TransformerFFNDesc; + +namespace RyzenAIMatMul { + + struct Accel; + + struct Options { + std::string artifactDir; + int deviceIdx = -1; // <0 selects the default device + std::string dtype = "auto"; // auto | bf16 | bfp16 + int maxCols = 0; // 0 = as wide as the device allows + // Dense layers whose row count is below this stay on the CPU. A dispatch + // costs on the order of 0.2 ms no matter how small the work is, which + // swamps the batch-row matmuls in the heads (a few dozen rows at most). + int minRows = 128; + // Force every layer onto one reduction dim, so the whole model runs from a + // single xclbin and therefore a single hardware context. Switching contexts + // measured ~0.46 ms per dispatch, which dwarfs the arithmetic these kernels + // do, so paying extra zero-padded multiply-accumulates to avoid it can win + // by a wide margin -- on models whose GEMMs are small. 0 disables it. + int forceK = 0; + bool verbose = false; + }; + + // Returns nullptr (and fills err) when the NPU cannot be used at all, which + // is an ordinary outcome: callers then run entirely on the CPU path. + Accel* create(const Options& options, std::string& err); + void free(Accel* accel); + + // out[numRows][outChannels] = in[numRows][inChannels] * weights, matching + // reference.cpp's matmulRows exactly. Returns false without touching `out` + // if this layer is not eligible or no artifact covers it, in which case the + // caller must run its own implementation. + bool tryMatmul( + Accel* accel, float* out, const float* in, const MatMulLayerDesc& desc, int numRows); + + // Several projections that read the same input (attention's q/k/vProj, the + // FFN's linear1/linearGate) fused into one GEMM: the weights are + // concatenated along N once at upload, so one dispatch replaces numDescs. + // out[j] receives descs[j]'s columns. Returns false without touching any + // output if the group is not eligible; the caller runs each layer itself. + bool tryMatmulMulti( + Accel* accel, float* const* outs, const float* in, + const MatMulLayerDesc* const* descs, int numDescs, int numRows); + + // The transformer FFN's SwiGLU: out = silu(in @ linear1) * (in @ + // linearGate), with both projections fused into ONE GEMM dispatch whose + // epilogue applies the silu and the multiply on chip. Requires a + // gemm_swiglu_bf16 artifact for the layer's reduction dim (a separate + // xclbin, hence a separate hardware context) and outChannels % 8 == 0 -- + // the uploaded B interleaves the two weight matrices in groups of 8 columns + // so each core's C tile holds (linear1, gate) sub-tile pairs. Returns false + // without touching `out` when unavailable; the caller then runs the two + // projections and the elementwise SwiGLU itself. + bool tryMatmulSwiglu( + Accel* accel, float* out, const float* in, + const MatMulLayerDesc& linear1, const MatMulLayerDesc& linearGate, int numRows); + + // A 1x1 convolution is a dense layer over board points, so it takes the same + // path. Declines anything with a larger kernel. ConvLayerDesc stores weights + // as outChannels x inChannels, the transpose of what the GEMM wants, so those + // are transposed once at upload rather than per evaluation. + // + // accumulate adds into `out` instead of overwriting it, matching + // reference.cpp's convNHWC. + bool tryConv1x1( + Accel* accel, float* out, const float* in, const ConvLayerDesc& desc, int numRows, + bool accumulate); + + // BatchNorm + Mish fused op (out = mish(scale*x + bias) per channel), for + // the convolutional model's trunk norms. Only handles Mish and full boards + // (masked positions would need zeroing the staged path does); anything else + // returns false and the caller runs its CPU loop. rows = batchSize*S. + bool tryBnMish( + Accel* accel, float* out, const float* in, const BatchNormLayerDesc& bn, + int activation, int numRows); + + // A convolution with a larger kernel becomes the same GEMM once its input + // patches are gathered into rows: K = convY*convX*inChannels, one row per + // board point ("implicit GEMM"). The gather costs one pass over the input per + // tap, which is far cheaper than the direct convolution it replaces. + // + // Declines when no artifact reaches K, which for a 3x3 means 9*inChannels. + bool tryConv( + Accel* accel, float* out, const float* in, const ConvLayerDesc& desc, int batchSize, + int nnXLen, int nnYLen, bool accumulate); + + // Routes the two attention matmuls (QK^T and P*V) of one transformer + // attention block to the NPU: one GEMM per batch element each way, with all + // heads laid out side by side along A's reduction dim and a block-diagonal + // B built from the K / V activations, so a block costs 2 dispatches per + // batch element instead of 2 per head (a dispatch costs ~1 ms regardless of + // size; the multiply-accumulates are nearly free). The softmax in between + // goes to the NPU too when an op compiled for exactly this (numHeads*S, S) + // shape is present under artifactDir/ops; otherwise it runs on the CPU. + // Either way the semantics are exactly the reference path's (scale on the + // scores, masked-out query rows produce exact zeros, masked-out key columns + // excluded -- as -1e30 through the NPU softmax, whose exp underflows to 0). + // + // Unlike layer weights, the B operands here (the K and V activations) + // change every evaluation, so they are re-uploaded per dispatch through + // RyzenAIKernel::rewriteWeights into BOs that stay resident. + // + // qBuf/kBuf/vBuf are [batchSize][S][qTot/kTot/vTot] with the per-head slices + // at h*qHeadDim and kvh*qHeadDim / kvh*vHeadDim (kvh = h / (numHeads/ + // numKVHeads)); attnOut is [batchSize][S][numHeads*vHeadDim]; mask is + // [batchSize][S] with 1.0f on-board. All exactly as reference.cpp's + // applyTransformerAttentionBlock already lays them out. + // + // softmaxSecsOut, when non-null, accumulates the wall clock spent in the + // on-CPU softmax so the caller's profile can keep attributing it. + // + // Returns false if any piece is not eligible or a dispatch failed. attnOut + // may then be partially written, so the caller must run its own + // implementation for the whole block, which overwrites it fully. + bool tryAttention( + Accel* accel, float* attnOut, + const float* qBuf, const float* kBuf, const float* vBuf, const float* mask, + int batchSize, int S, int numHeads, int numKVHeads, int qHeadDim, int vHeadDim, + double* softmaxSecsOut); + + // Per-layer accounting, for logging: how many dense layers were routed to the + // NPU, how many fell back, and why. + std::string report(const Accel* accel); + +} // namespace RyzenAIMatMul + +#endif // NEURALNET_RYZENAI_MATMUL_H_ diff --git a/cpp/neuralnet/ryzenaireference.cpp b/cpp/neuralnet/ryzenaireference.cpp new file mode 100644 index 0000000000..b74a5ac4cd --- /dev/null +++ b/cpp/neuralnet/ryzenaireference.cpp @@ -0,0 +1,1361 @@ +/* + * Pure C++ (C++17, standard library only) CPU reference implementation of the + * KataGo neural network forward pass, for the RyzenAI (AMD NPU) backend. + * See reference.h for the API and the exact input/output buffer contracts. + * + * The math here is a direct, loop-level port of cpp/neuralnet/eigenbackend.cpp + * (Winograd convolutions there are replaced by plain direct convolutions, + * which are mathematically identical). Internal layout is NHWC throughout. + * + * No heap allocation happens inside forward(): all scratch is bump-allocated + * from an arena whose exact worst-case size is computed in createWorkspace(). + */ + +#include "../neuralnet/ryzenaireference.h" + +#include +#include +#include +#include +#include + +#include "../neuralnet/activations.h" +#include "../neuralnet/ryzenaimatmul.h" + +#include +#include + +namespace RyzenAIRef { + +namespace { + +// --------------------------------------------------------------------------- +// Precomputed per-attention-block RoPE cos/sin tables (created once per +// Workspace via TransformerAttentionDesc::computeRopeCosSin). +// --------------------------------------------------------------------------- +struct RopeTables { + std::vector cosTable; + std::vector sinTable; +}; + +// --------------------------------------------------------------------------- +// Bump allocator over a preallocated float arena. No heap traffic at forward +// time; alloc() throws if the compile-time-computed capacity is exceeded +// (which would indicate a bug in the size accounting below). +// --------------------------------------------------------------------------- +struct Arena { + float* base; + size_t capacity; + size_t offset; + + float* alloc(size_t numElts) { + if(numElts > capacity - offset) + throw StringError("RyzenAIRef: internal scratch arena overflow"); + float* p = base + offset; + offset += numElts; + return p; + } + size_t mark() const { return offset; } + void rewind(size_t m) { offset = m; } +}; + +// Coarse profile of the parts that are still on the CPU, so that the next +// thing to move onto the NPU is chosen from measurement rather than from +// multiply-accumulate counts (which have already misled once: see +// references/performance.md). Off unless RyzenAIRef::profileEnabled() is set. +struct CpuProfile { + double attnScores = 0.0; // CPU-path attention only (QK^T, softmax, P*V loops) + double softmax = 0.0; // softmax anywhere: nested in the CPU attention path, + // or reported by the NPU attention path + double norms = 0.0; // RMSNorm / BatchNorm / activations + double rope = 0.0; + double swiglu = 0.0; // silu(linear1) * gate elementwise + double residual = 0.0; // masked residual adds + double gpool = 0.0; + double headSmall = 0.0; // heads' batch-row matmuls and pooling + bool enabled = false; +}; +CpuProfile g_profile; + +inline double nowSecs() { + return std::chrono::duration( + std::chrono::steady_clock::now().time_since_epoch()).count(); +} + +// Adds its lifetime to one bucket. +struct ProfileScope { + double* bucket; + double start; + explicit ProfileScope(double* b) + : bucket(g_profile.enabled ? b : nullptr), start(bucket ? nowSecs() : 0.0) {} + ~ProfileScope() { if(bucket) *bucket += nowSecs() - start; } +}; + +// --------------------------------------------------------------------------- +// Per-forward-pass context handed to every block. +// mask is [batchSize][nnYLen*nnXLen] (1.0f on-board, 0.0f padding). +// --------------------------------------------------------------------------- +struct ForwardCtx { + int batchSize; + int nnXLen; + int nnYLen; + const float* mask; + const float* maskSum; + Arena* arena; + const std::map* ropeTables; + RyzenAIMatMul::Accel* accel; // may be null: then everything stays on the CPU +}; + +// --------------------------------------------------------------------------- +// Scalar activation. Mirrors eigenbackend.cpp exactly, including the +// numerically-stable softplus formulation log1p(exp(min(x,20)))+(max(x,20)-20). +// --------------------------------------------------------------------------- +inline float softplusForMish(float x) { + float lo = x < 20.0f ? x : 20.0f; + float hi = x > 20.0f ? x : 20.0f; + return log1pf(expf(lo)) + (hi - 20.0f); +} + +inline float applyActivation(int activation, float x) { + switch(activation) { + case ACTIVATION_IDENTITY: return x; + case ACTIVATION_RELU: return x > 0.0f ? x : 0.0f; + case ACTIVATION_MISH: return x * tanhf(softplusForMish(x)); + case ACTIVATION_SILU: return x / (1.0f + expf(-x)); + // x * tanh(softplus(8x)); not used by the Eigen backend (fp32 only there), + // but supported here so scale8-transformed descs can also be referenced. + case ACTIVATION_MISH_SCALE8: return x * tanhf(softplusForMish(8.0f * x)); + default: throw StringError("RyzenAIRef: unsupported activation " + std::to_string(activation)); + } +} + +void applyActivationInplace(float* data, size_t numElts, int activation) { + if(activation == ACTIVATION_IDENTITY) + return; + for(size_t i = 0; i < numElts; i++) + data[i] = applyActivation(activation, data[i]); +} + +// --------------------------------------------------------------------------- +// Direct zero-padded cross-correlation, NHWC in and out. +// Weight layout (from ConvLayerDesc): w[((oc*inC + ic)*ky + dy)*kx + dx]. +// out[n][y][x][oc] = sum_{ic,dy,dx} in[n][y+(dy-ky/2)*dilY][x+(dx-kx/2)*dilX][ic] * w[...] +// --------------------------------------------------------------------------- +void convNHWC( + float* out, + const float* in, + const ConvLayerDesc& desc, + int batchSize, + int nnXLen, + int nnYLen, + bool accumulate +) { + const int inC = desc.inChannels; + const int outC = desc.outChannels; + const int kx = desc.convXSize; + const int ky = desc.convYSize; + const int padX = kx / 2; + const int padY = ky / 2; + const int dilX = desc.dilationX; + const int dilY = desc.dilationY; + const float* w = desc.weights.data(); + const size_t kernelPosStride = (size_t)ky * kx; // stride of ic within one oc + + for(int n = 0; n < batchSize; n++) { + for(int y = 0; y < nnYLen; y++) { + for(int x = 0; x < nnXLen; x++) { + size_t outBase = (((size_t)n * nnYLen + y) * nnXLen + x) * outC; + for(int oc = 0; oc < outC; oc++) { + const float* wo = w + (size_t)oc * inC * kernelPosStride; + float acc = 0.0f; + for(int dy = 0; dy < ky; dy++) { + int iy = y + (dy - padY) * dilY; + if(iy < 0 || iy >= nnYLen) + continue; + for(int dx = 0; dx < kx; dx++) { + int ix = x + (dx - padX) * dilX; + if(ix < 0 || ix >= nnXLen) + continue; + size_t inBase = (((size_t)n * nnYLen + iy) * nnXLen + ix) * inC; + const float* wi = wo + (size_t)dy * kx + dx; + for(int ic = 0; ic < inC; ic++) + acc += in[inBase + ic] * wi[(size_t)ic * kernelPosStride]; + } + } + if(accumulate) + out[outBase + oc] += acc; + else + out[outBase + oc] = acc; + } + } + } + } +} + +// --------------------------------------------------------------------------- +// BatchNorm (using precomputed mergedScale/mergedBias) + activation, NHWC. +// Positions where mask != 1.0f are zeroed (exactly as eigenbackend's select). +// --------------------------------------------------------------------------- +void batchNormActNHWC( + float* out, + const float* in, + const BatchNormLayerDesc& bn, + int activation, + const float* mask, + int batchSize, + int nnXLen, + int nnYLen +) { + ProfileScope profileScope(&g_profile.norms); + const int C = bn.numChannels; + const size_t S = (size_t)nnXLen * nnYLen; + for(int n = 0; n < batchSize; n++) { + for(size_t s = 0; s < S; s++) { + size_t base = ((size_t)n * S + s) * C; + if(mask[(size_t)n * S + s] == 1.0f) { + for(int c = 0; c < C; c++) + out[base + c] = applyActivation(activation, in[base + c] * bn.mergedScale[c] + bn.mergedBias[c]); + } + else { + for(int c = 0; c < C; c++) + out[base + c] = 0.0f; + } + } + } +} + +// --------------------------------------------------------------------------- +// Lightweight per-position RMSNorm used inside transformer blocks +// (weight only, no bias, no activation). Masked positions are zeroed. +// --------------------------------------------------------------------------- +void transformerRMSNormNHWC( + float* out, + const float* in, + const TransformerRMSNormDesc& desc, + const float* mask, + int batchSize, + int nnXLen, + int nnYLen +) { + ProfileScope profileScope(&g_profile.norms); + const int C = desc.numChannels; + const size_t S = (size_t)nnXLen * nnYLen; + for(int n = 0; n < batchSize; n++) { + for(size_t s = 0; s < S; s++) { + size_t base = ((size_t)n * S + s) * C; + if(mask[(size_t)n * S + s] == 0.0f) { + for(int c = 0; c < C; c++) + out[base + c] = 0.0f; + continue; + } + float sumSq = 0.0f; + for(int c = 0; c < C; c++) { + float v = in[base + c]; + sumSq += v * v; + } + float rms = 1.0f / sqrtf(sumSq / (float)C + desc.epsilon); + for(int c = 0; c < C; c++) + out[base + c] = in[base + c] * rms * desc.weight[c]; + } + } +} + +// --------------------------------------------------------------------------- +// Full RMSNorm for the trunk tip (gamma+beta+activation, spatial or +// non-spatial). Direct port of RMSNormLayer in eigenbackend.cpp. +// Non-spatial: normalize across channels per position. +// Spatial: normalize across channels AND all valid (masked-in) positions. +// --------------------------------------------------------------------------- +void trunkTipRMSNormNHWC( + float* out, + const float* in, + const RMSNormLayerDesc& desc, + int activation, + const float* mask, + int batchSize, + int nnXLen, + int nnYLen +) { + const int C = desc.numChannels; + const size_t S = (size_t)nnXLen * nnYLen; + if(!desc.spatial) { + for(int n = 0; n < batchSize; n++) { + for(size_t s = 0; s < S; s++) { + size_t base = ((size_t)n * S + s) * C; + if(mask[(size_t)n * S + s] == 0.0f) { + for(int c = 0; c < C; c++) + out[base + c] = 0.0f; + continue; + } + float sumSq = 0.0f; + for(int c = 0; c < C; c++) { + float v = in[base + c]; + sumSq += v * v; + } + float rms = 1.0f / sqrtf(sumSq / (float)C + desc.epsilon); + for(int c = 0; c < C; c++) + out[base + c] = applyActivation(activation, in[base + c] * rms * desc.gamma[c] + desc.beta[c]); + } + } + } + else { + for(int n = 0; n < batchSize; n++) { + float sumSq = 0.0f; + size_t count = 0; + for(size_t s = 0; s < S; s++) { + if(mask[(size_t)n * S + s] == 0.0f) + continue; + size_t base = ((size_t)n * S + s) * C; + for(int c = 0; c < C; c++) { + float v = in[base + c]; + sumSq += v * v; + } + count++; + } + float totalElts = (float)count * (float)C; + float rms = 1.0f / sqrtf(sumSq / totalElts + desc.epsilon); + for(size_t s = 0; s < S; s++) { + size_t base = ((size_t)n * S + s) * C; + if(mask[(size_t)n * S + s] == 0.0f) { + for(int c = 0; c < C; c++) + out[base + c] = 0.0f; + continue; + } + for(int c = 0; c < C; c++) + out[base + c] = applyActivation(activation, in[base + c] * rms * desc.gamma[c] + desc.beta[c]); + } + } + } +} + +// --------------------------------------------------------------------------- +// Dense layer over rows: out[r][oc] = sum_ic in[r][ic] * W[ic*outC + oc]. +// Used for all MatMulLayerDesc applications. The "rows" are either batch +// rows ([N][C]) or flattened batch*spatial rows ([N*H*W][C]). +// --------------------------------------------------------------------------- +void matmulRows(float* out, const float* in, const MatMulLayerDesc& desc, int numRows) { + const int inC = desc.inChannels; + const int outC = desc.outChannels; + const float* w = desc.weights.data(); + for(int r = 0; r < numRows; r++) { + const float* inRow = in + (size_t)r * inC; + float* outRow = out + (size_t)r * outC; + for(int oc = 0; oc < outC; oc++) + outRow[oc] = 0.0f; + for(int ic = 0; ic < inC; ic++) { + float iv = inRow[ic]; + const float* wRow = w + (size_t)ic * outC; + for(int oc = 0; oc < outC; oc++) + outRow[oc] += iv * wRow[oc]; + } + } +} + +// Every convolution is offered to the NPU: 1x1 directly as a dense layer, +// larger kernels via implicit GEMM (the accelerator gathers the input patches +// itself). Anything it declines falls through to the direct convolution. +void convNHWCMaybeNpu( + ForwardCtx& ctx, + float* out, + const float* in, + const ConvLayerDesc& desc, + int batchSize, + int nnXLen, + int nnYLen, + bool accumulate +) { + if(RyzenAIMatMul::tryConv(ctx.accel, out, in, desc, batchSize, nnXLen, nnYLen, accumulate)) + return; + convNHWC(out, in, desc, batchSize, nnXLen, nnYLen, accumulate); +} + +// Same, but offers the layer to the NPU first. Used only for the trunk's +// board-sized dense layers; the heads' batch-row matmuls are far too small to +// repay a dispatch and call matmulRows directly. +void matmulRowsMaybeNpu( + ForwardCtx& ctx, float* out, const float* in, const MatMulLayerDesc& desc, int numRows) { + if(RyzenAIMatMul::tryMatmul(ctx.accel, out, in, desc, numRows)) + return; + matmulRows(out, in, desc, numRows); +} + +// Projections that share an input go to the NPU as one fused GEMM; if the +// accelerator declines, each runs the ordinary maybe-NPU path on its own. +void matmulRowsMultiMaybeNpu( + ForwardCtx& ctx, + float* const* outs, + const float* in, + const MatMulLayerDesc* const* descs, + int numDescs, + int numRows +) { + if(RyzenAIMatMul::tryMatmulMulti(ctx.accel, outs, in, descs, numDescs, numRows)) + return; + for(int j = 0; j < numDescs; j++) + matmulRowsMaybeNpu(ctx, outs[j], in, *descs[j], numRows); +} + +// BatchNorm+activation, offered to the NPU first when it's Mish on a full +// board (the fused op handles exactly that; anything else falls through). +void bnActMaybeNpu( + ForwardCtx& ctx, + float* out, + const float* in, + const BatchNormLayerDesc& bn, + int activation, + int batchSize, + int nnXLen, + int nnYLen +) { + const size_t S = (size_t)nnXLen * nnYLen; + bool fullBoard = true; + for(int n = 0; n < batchSize; n++) + if(ctx.maskSum[n] != (float)S) { + fullBoard = false; + break; + } + if(fullBoard && + RyzenAIMatMul::tryBnMish(ctx.accel, out, in, bn, activation, batchSize * (int)S)) + return; + batchNormActNHWC(out, in, bn, activation, ctx.mask, batchSize, nnXLen, nnYLen); +} + +// io[r][c] += bias[c] +void matBiasAddRows(float* io, const MatBiasLayerDesc& desc, int numRows) { + const int C = desc.numChannels; + for(int r = 0; r < numRows; r++) { + float* row = io + (size_t)r * C; + for(int c = 0; c < C; c++) + row[c] += desc.weights[c]; + } +} + +// io[n][y][x][c] += bias[n][c] (addNCBiasInplace in eigenbackend.cpp) +void addPerBatchChannelBiasNHWC( + float* io, + const float* bias, + int C, + int batchSize, + int nnXLen, + int nnYLen +) { + const size_t S = (size_t)nnXLen * nnYLen; + for(int n = 0; n < batchSize; n++) { + const float* biasN = bias + (size_t)n * C; + for(size_t s = 0; s < S; s++) { + float* row = io + ((size_t)n * S + s) * C; + for(int c = 0; c < C; c++) + row[c] += biasN[c]; + } + } +} + +// --------------------------------------------------------------------------- +// Global pooling for gpool residual blocks / policy head. +// in: [N][H][W][C] (must be zero at masked-out positions, which holds because +// this only ever follows a masked BN+activation), out: [N][3*C] with +// [c] = mean over valid positions (denominator = maskSum) +// [C+c] = mean * (sqrt(maskSum) - 14) * 0.1 +// [2*C+c] = max over valid positions +// Direct port of poolRowsGPool in eigenbackend.cpp. +// --------------------------------------------------------------------------- +void poolRowsGPoolNHWC( + float* out, + const float* in, + const float* mask, + const float* maskSum, + int C, + int batchSize, + int nnXLen, + int nnYLen +) { + const size_t S = (size_t)nnXLen * nnYLen; + for(int n = 0; n < batchSize; n++) { + const float* inN = in + (size_t)n * S * C; + const float* maskN = mask + (size_t)n * S; + float* outN = out + (size_t)n * 3 * C; + for(int c = 0; c < C; c++) { + float s = 0.0f; + float m = -1.0f; + for(size_t xy = 0; xy < S; xy++) { + float x = inN[xy * C + c]; + s += x; + // Init to -1.0 and +(mask-1.0) makes padded space effectively -1.0, + // below anything current activations produce (padded inputs are 0). + float xm = x + (maskN[xy] - 1.0f); + if(xm > m) + m = xm; + } + float div = maskSum[n]; + float sqrtdiv = sqrtf(div); + float mean = s / div; + outN[c] = mean; + outN[C + c] = mean * (sqrtdiv - 14.0f) * 0.1f; + outN[2 * C + c] = m; + } + } +} + +// --------------------------------------------------------------------------- +// Global pooling for the value head. out: [N][3*C] with +// [c] = mean +// [C+c] = mean * (sqrt(maskSum) - 14) * 0.1 +// [2*C+c] = mean * ((sqrt(maskSum) - 14)^2 * 0.01 - 0.1) +// Direct port of poolRowsValueHead in eigenbackend.cpp. +// --------------------------------------------------------------------------- +void poolRowsValueHeadNHWC( + float* out, + const float* in, + const float* maskSum, + int C, + int batchSize, + int nnXLen, + int nnYLen +) { + const size_t S = (size_t)nnXLen * nnYLen; + for(int n = 0; n < batchSize; n++) { + const float* inN = in + (size_t)n * S * C; + float* outN = out + (size_t)n * 3 * C; + for(int c = 0; c < C; c++) { + float s = 0.0f; + for(size_t xy = 0; xy < S; xy++) + s += inN[xy * C + c]; + float div = maskSum[n]; + float sqrtdiv = sqrtf(div); + float mean = s / div; + outN[c] = mean; + outN[C + c] = mean * (sqrtdiv - 14.0f) * 0.1f; + outN[2 * C + c] = mean * ((sqrtdiv - 14.0f) * (sqrtdiv - 14.0f) * 0.01f - 0.1f); + } + } +} + +// --------------------------------------------------------------------------- +// Blocks. `trunk` is the [N][H][W][C] residual stream, updated in place. +// `trunkScratch` is a caller-provided buffer of the same shape used for +// norm outputs / projection results. All other intermediates come from the +// arena and are released (rewound) before the block returns. +// --------------------------------------------------------------------------- +void applyBlockStack( + const std::vector>& blocks, + int numBlocks, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +); + +// ORDINARY_BLOCK_KIND +void applyResidualBlock( + const ResidualBlockDesc& desc, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const size_t BXY = (size_t)N * W * H; + const int midC = desc.regularConv.outChannels; + + size_t mark = ctx.arena->mark(); + float* midIn = ctx.arena->alloc(BXY * midC); + float* midScratch = ctx.arena->alloc(BXY * midC); + + bnActMaybeNpu(ctx, trunkScratch, trunk, desc.preBN, desc.preActivation.activation, N, W, H); + convNHWCMaybeNpu(ctx, midIn, trunkScratch, desc.regularConv, N, W, H, false); + bnActMaybeNpu(ctx, midScratch, midIn, desc.midBN, desc.midActivation.activation, N, W, H); + convNHWCMaybeNpu(ctx, trunk, midScratch, desc.finalConv, N, W, H, true); + + ctx.arena->rewind(mark); +} + +// GLOBAL_POOLING_BLOCK_KIND +void applyGlobalPoolingResidualBlock( + const GlobalPoolingResidualBlockDesc& desc, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const size_t BXY = (size_t)N * W * H; + const int regC = desc.regularConv.outChannels; + const int gpoolC = desc.gpoolConv.outChannels; + + size_t mark = ctx.arena->mark(); + float* regularOut = ctx.arena->alloc(BXY * regC); + float* regularScratch = ctx.arena->alloc(BXY * regC); + float* gpoolOut = ctx.arena->alloc(BXY * gpoolC); + float* gpoolOut2 = ctx.arena->alloc(BXY * gpoolC); + float* gpoolConcat = ctx.arena->alloc((size_t)N * 3 * gpoolC); + float* gpoolBias = ctx.arena->alloc((size_t)N * regC); + + bnActMaybeNpu(ctx, trunkScratch, trunk, desc.preBN, desc.preActivation.activation, N, W, H); + convNHWCMaybeNpu(ctx, regularOut, trunkScratch, desc.regularConv, N, W, H, false); + convNHWCMaybeNpu(ctx, gpoolOut, trunkScratch, desc.gpoolConv, N, W, H, false); + bnActMaybeNpu(ctx, gpoolOut2, gpoolOut, desc.gpoolBN, desc.gpoolActivation.activation, N, W, H); + poolRowsGPoolNHWC(gpoolConcat, gpoolOut2, ctx.mask, ctx.maskSum, gpoolC, N, W, H); + matmulRows(gpoolBias, gpoolConcat, desc.gpoolToBiasMul, N); + addPerBatchChannelBiasNHWC(regularOut, gpoolBias, regC, N, W, H); + bnActMaybeNpu(ctx, regularScratch, regularOut, desc.midBN, desc.midActivation.activation, N, W, H); + convNHWCMaybeNpu(ctx, trunk, regularScratch, desc.finalConv, N, W, H, true); + + ctx.arena->rewind(mark); +} + +// NESTED_BOTTLENECK_BLOCK_KIND (inner stack may contain any block kind) +void applyNestedBottleneckResidualBlock( + const NestedBottleneckResidualBlockDesc& desc, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const size_t BXY = (size_t)N * W * H; + const int bottleC = desc.preConv.outChannels; + size_t mark = ctx.arena->mark(); + float* midIn = ctx.arena->alloc(BXY * bottleC); + float* midScratch = ctx.arena->alloc(BXY * bottleC); + + bnActMaybeNpu(ctx, trunkScratch, trunk, desc.preBN, desc.preActivation.activation, N, W, H); + convNHWCMaybeNpu(ctx, midIn, trunkScratch, desc.preConv, N, W, H, false); + // The inner block stack treats midIn as its residual stream and midScratch + // as its scratch. + applyBlockStack(desc.blocks, desc.numBlocks, ctx, midIn, midScratch); + bnActMaybeNpu(ctx, midScratch, midIn, desc.postBN, desc.postActivation.activation, N, W, H); + convNHWCMaybeNpu(ctx, trunk, midScratch, desc.postConv, N, W, H, true); + + ctx.arena->rewind(mark); +} + +// TRANSFORMER_ATTENTION_BLOCK_KIND +// Multi-head attention with grouped-query KV heads, optional RoPE (learnable +// or fixed), masked softmax. Direct port of TransformerAttentionBlock in +// eigenbackend.cpp. +void applyTransformerAttentionBlock( + const TransformerAttentionDesc& desc, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const int S = W * H; + const size_t BXY = (size_t)N * S; + const int inC = desc.qProj.inChannels; + const int numHeads = desc.numHeads; + const int numKVHeads = desc.numKVHeads; + const int qHeadDim = desc.qHeadDim; + const int vHeadDim = desc.vHeadDim; + const int qTot = numHeads * qHeadDim; + const int kTot = numKVHeads * qHeadDim; + const int vTot = numKVHeads * vHeadDim; + const int oTot = numHeads * vHeadDim; + + const RopeTables* rope = nullptr; + if(desc.useRope) { + std::map::const_iterator it = ctx.ropeTables->find((const void*)&desc); + if(it == ctx.ropeTables->end()) + throw StringError("RyzenAIRef: missing RoPE tables for attention block " + desc.name); + rope = &it->second; + } + + size_t mark = ctx.arena->mark(); + float* qBuf = ctx.arena->alloc(BXY * qTot); + float* kBuf = ctx.arena->alloc(BXY * kTot); + float* vBuf = ctx.arena->alloc(BXY * vTot); + float* attnOut = ctx.arena->alloc(BXY * oTot); + float* scores = ctx.arena->alloc((size_t)S * S); + + // Step 1: pre-norm (per-position RMSNorm), masked. + transformerRMSNormNHWC(trunkScratch, trunk, desc.preLN, ctx.mask, N, W, H); + + // Step 2: Q/K/V projections; the [N][H][W][C] tensors are treated as + // [N*S][C] row matrices (C innermost, so rows are contiguous). + { + float* qkvOuts[3] = {qBuf, kBuf, vBuf}; + const MatMulLayerDesc* qkvDescs[3] = {&desc.qProj, &desc.kProj, &desc.vProj}; + matmulRowsMultiMaybeNpu(ctx, qkvOuts, trunkScratch, qkvDescs, 3, N * S); + } + + // Step 3: RoPE on Q and K, rotating channel pairs (2p, 2p+1). + { + ProfileScope ropeScope(&g_profile.rope); + if(desc.useRope) { + const int ropeNumPairs = qHeadDim / 2; + for(int which = 0; which < 2; which++) { + float* data = which == 0 ? qBuf : kBuf; + const int numBufHeads = which == 0 ? numHeads : numKVHeads; + const int totalDim = which == 0 ? qTot : kTot; + for(int n = 0; n < N; n++) { + for(int h = 0; h < numBufHeads; h++) { + // For Q heads, map to the corresponding KV head; for K heads, identity. + const int kvh = h * numKVHeads / numBufHeads; + for(int xy = 0; xy < S; xy++) { + size_t rowBase = ((size_t)n * S + xy) * totalDim + (size_t)h * qHeadDim; + for(int p = 0; p < ropeNumPairs; p++) { + size_t tableIdx; + if(desc.learnableRope) + tableIdx = ((size_t)kvh * ropeNumPairs + p) * S + xy; + else + tableIdx = (size_t)p * S + xy; + float cosVal = rope->cosTable[tableIdx]; + float sinVal = rope->sinTable[tableIdx]; + size_t i0 = rowBase + 2 * p; + float x0 = data[i0]; + float x1 = data[i0 + 1]; + data[i0] = x0 * cosVal - x1 * sinVal; + data[i0 + 1] = x0 * sinVal + x1 * cosVal; + } + } + } + } + } + } + + } // ropeScope + + // Step 4: masked scaled dot-product attention, per (batch, head). + { + // Offer the two matmuls (QK^T and P*V) to the NPU first. The softmax + // between them stays on the CPU either way; whatever the accelerator + // declines runs the original CPU loops below, byte-for-byte unchanged + // (and deliberately left at their original indentation). + // + // Profiling note: the NPU path's time is accounted inside matmul.cpp + // (pack/uploadB/dispatch/unpack/softmax), so the attnScores bucket must + // only wrap the CPU loops -- wrapping the dispatch too would double-count + // it against engineTimings' execute window. + double npuSoftmaxSecs = 0.0; + const bool attnOnNpu = RyzenAIMatMul::tryAttention( + ctx.accel, attnOut, qBuf, kBuf, vBuf, ctx.mask, N, S, + numHeads, numKVHeads, qHeadDim, vHeadDim, + g_profile.enabled ? &npuSoftmaxSecs : nullptr); + g_profile.softmax += npuSoftmaxSecs; + if(!attnOnNpu) { + ProfileScope profileScope(&g_profile.attnScores); + const float scale = 1.0f / sqrtf((float)qHeadDim); + const int kvGroupSize = numHeads / numKVHeads; + for(int n = 0; n < N; n++) { + const float* maskN = ctx.mask + (size_t)n * S; + for(int h = 0; h < numHeads; h++) { + const int kvh = h / kvGroupSize; + const float* qHead = qBuf + (size_t)n * S * qTot + (size_t)h * qHeadDim; + const float* kHead = kBuf + (size_t)n * S * kTot + (size_t)kvh * qHeadDim; + const float* vHead = vBuf + (size_t)n * S * vTot + (size_t)kvh * vHeadDim; + float* outHead = attnOut + (size_t)n * S * oTot + (size_t)h * vHeadDim; + + // scores[qi*S + ki] = softmax over valid ki of (scale * ). + // Rows of masked-out queries are exactly 0 (as in eigenbackend). + for(int qi = 0; qi < S; qi++) { + float* scoreRow = scores + (size_t)qi * S; + if(maskN[qi] == 0.0f) { + for(int ki = 0; ki < S; ki++) + scoreRow[ki] = 0.0f; + continue; + } + const float* qRow = qHead + (size_t)qi * qTot; + float maxVal = -1e30f; + for(int ki = 0; ki < S; ki++) { + if(maskN[ki] == 0.0f) { + scoreRow[ki] = 0.0f; + continue; + } + const float* kRow = kHead + (size_t)ki * kTot; + float acc = 0.0f; + for(int d = 0; d < qHeadDim; d++) + acc += qRow[d] * kRow[d]; + acc *= scale; + scoreRow[ki] = acc; + if(acc > maxVal) + maxVal = acc; + } + { + ProfileScope softmaxScope(&g_profile.softmax); + float sumExp = 0.0f; + for(int ki = 0; ki < S; ki++) { + if(maskN[ki] == 0.0f) + continue; + float e = expf(scoreRow[ki] - maxVal); + scoreRow[ki] = e; + sumExp += e; + } + float invSum = 1.0f / sumExp; + for(int ki = 0; ki < S; ki++) { + if(maskN[ki] != 0.0f) + scoreRow[ki] *= invSum; + } + } + } + + // attnOut[qi, h*vHeadDim + dv] = sum_ki scores[qi,ki] * V[ki, kvh*vHeadDim + dv] + for(int qi = 0; qi < S; qi++) { + const float* scoreRow = scores + (size_t)qi * S; + float* outRow = outHead + (size_t)qi * oTot; + for(int dv = 0; dv < vHeadDim; dv++) + outRow[dv] = 0.0f; + for(int ki = 0; ki < S; ki++) { + float wgt = scoreRow[ki]; + if(wgt == 0.0f) + continue; // exact: 0-weight terms contribute nothing + const float* vRow = vHead + (size_t)ki * vTot; + for(int dv = 0; dv < vHeadDim; dv++) + outRow[dv] += wgt * vRow[dv]; + } + } + } + } + } // !attnOnNpu + } + + // Step 5: output projection back to trunk channels. + matmulRowsMaybeNpu(ctx, trunkScratch, attnOut, desc.outProj, N * S); + + // Step 6: residual add, masked (padded positions stay untouched). + ProfileScope residualScope(&g_profile.residual); + for(int n = 0; n < N; n++) { + const float* maskN = ctx.mask + (size_t)n * S; + for(int xy = 0; xy < S; xy++) { + float maskVal = maskN[xy]; + size_t base = ((size_t)n * S + xy) * inC; + for(int c = 0; c < inC; c++) + trunk[base + c] += trunkScratch[base + c] * maskVal; + } + } + + ctx.arena->rewind(mark); +} + +// TRANSFORMER_FFN_BLOCK_KIND (SwiGLU form; useSwiGLU is validated at +// workspace creation time, matching the Eigen backend's restriction). +void applyTransformerFFNBlock( + const TransformerFFNDesc& desc, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const int S = W * H; + const size_t BXY = (size_t)N * S; + const int C = desc.numChannels; + const int ffnC = desc.ffnChannels; + return; + + size_t mark = ctx.arena->mark(); + float* ffnBuf = ctx.arena->alloc(BXY * ffnC); + float* gateBuf = ctx.arena->alloc(BXY * ffnC); + + // Step 1: pre-norm, masked. + transformerRMSNormNHWC(trunkScratch, trunk, desc.preLN, ctx.mask, N, W, H); + + // Step 2/3: SwiGLU = silu(linear1(x)) * linearGate(x), applied to all rows. + // The NPU path fuses both projections into one GEMM whose epilogue applies + // the silu and the multiply on chip, so ffnBuf comes back holding the + // finished SwiGLU output and the elementwise loop below is skipped. + const bool swigluOnNpu = RyzenAIMatMul::tryMatmulSwiglu( + ctx.accel, ffnBuf, trunkScratch, desc.linear1, desc.linearGate, N * S); + if(!swigluOnNpu) { + { + float* ffnOuts[2] = {ffnBuf, gateBuf}; + const MatMulLayerDesc* ffnDescs[2] = {&desc.linear1, &desc.linearGate}; + matmulRowsMultiMaybeNpu(ctx, ffnOuts, trunkScratch, ffnDescs, 2, N * S); + } + ProfileScope swigluScope(&g_profile.swiglu); + const size_t total = BXY * ffnC; + for(size_t i = 0; i < total; i++) { + float a = ffnBuf[i]; + float siluA = a / (1.0f + expf(-a)); + ffnBuf[i] = siluA * gateBuf[i]; + } + } + + // Step 4: down projection back to trunk channels. + matmulRowsMaybeNpu(ctx, trunkScratch, ffnBuf, desc.linear2, N * S); + + // Step 5: residual add, masked. + ProfileScope residualScope(&g_profile.residual); + for(int n = 0; n < N; n++) { + const float* maskN = ctx.mask + (size_t)n * S; + for(int xy = 0; xy < S; xy++) { + float maskVal = maskN[xy]; + size_t base = ((size_t)n * S + xy) * C; + for(int c = 0; c < C; c++) + trunk[base + c] += trunkScratch[base + c] * maskVal; + } + } + + ctx.arena->rewind(mark); +} + +void applySingleBlock( + int kind, + const void* descPtr, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + switch(kind) { + case ORDINARY_BLOCK_KIND: + applyResidualBlock(*(const ResidualBlockDesc*)descPtr, ctx, trunk, trunkScratch); + break; + case GLOBAL_POOLING_BLOCK_KIND: + applyGlobalPoolingResidualBlock(*(const GlobalPoolingResidualBlockDesc*)descPtr, ctx, trunk, trunkScratch); + break; + case NESTED_BOTTLENECK_BLOCK_KIND: + applyNestedBottleneckResidualBlock(*(const NestedBottleneckResidualBlockDesc*)descPtr, ctx, trunk, trunkScratch); + break; + case TRANSFORMER_ATTENTION_BLOCK_KIND: + applyTransformerAttentionBlock(*(const TransformerAttentionDesc*)descPtr, ctx, trunk, trunkScratch); + break; + case TRANSFORMER_FFN_BLOCK_KIND: + applyTransformerFFNBlock(*(const TransformerFFNDesc*)descPtr, ctx, trunk, trunkScratch); + break; + default: + throw StringError("RyzenAIRef: unknown block kind " + std::to_string(kind)); + } +} + +void applyBlockStack( + const std::vector>& blocks, + int numBlocks, + ForwardCtx& ctx, + float* trunk, + float* trunkScratch +) { + for(int i = 0; i < numBlocks; i++) + applySingleBlock(blocks[i].first, blocks[i].second.get(), ctx, trunk, trunkScratch); +} + +// --------------------------------------------------------------------------- +// SGF metadata encoder: mul1+bias1+act1, mul2+bias2+act2, mul3. +// input: [N][numInputMetaChannels], output: [N][trunkNumChannels]. +// --------------------------------------------------------------------------- +void applySGFMetadataEncoder( + const SGFMetadataEncoderDesc& desc, + ForwardCtx& ctx, + const float* input, + float* output +) { + const int N = ctx.batchSize; + size_t mark = ctx.arena->mark(); + float* internal1 = ctx.arena->alloc((size_t)N * desc.mul1.outChannels); + float* internal2 = ctx.arena->alloc((size_t)N * desc.mul2.outChannels); + + matmulRows(internal1, input, desc.mul1, N); + matBiasAddRows(internal1, desc.bias1, N); + applyActivationInplace(internal1, (size_t)N * desc.mul1.outChannels, desc.act1.activation); + matmulRows(internal2, internal1, desc.mul2, N); + matBiasAddRows(internal2, desc.bias2, N); + applyActivationInplace(internal2, (size_t)N * desc.mul2.outChannels, desc.act2.activation); + matmulRows(output, internal2, desc.mul3, N); + + ctx.arena->rewind(mark); +} + +// --------------------------------------------------------------------------- +// Policy head. trunk: [N][H][W][trunkC] (post tip-norm). +// policy: [N][H][W][numPolicyChannels] logits, policyPass: [N][numPolicyChannels]. +// --------------------------------------------------------------------------- +void applyPolicyHead( + const PolicyHeadDesc& desc, + ForwardCtx& ctx, + const float* trunk, + float* policyPass, + float* policy +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const size_t BXY = (size_t)N * W * H; + const int p1C = desc.p1Conv.outChannels; + const int g1C = desc.g1Conv.outChannels; + + size_t mark = ctx.arena->mark(); + float* p1Out = ctx.arena->alloc(BXY * p1C); + float* p1Out2 = ctx.arena->alloc(BXY * p1C); + float* g1Out = ctx.arena->alloc(BXY * g1C); + float* g1Out2 = ctx.arena->alloc(BXY * g1C); + float* g1Concat = ctx.arena->alloc((size_t)N * 3 * g1C); + float* g1Bias = ctx.arena->alloc((size_t)N * p1C); + float* p1Pass = ctx.arena->alloc((size_t)N * p1C); + + convNHWCMaybeNpu(ctx, p1Out, trunk, desc.p1Conv, N, W, H, false); + convNHWCMaybeNpu(ctx, g1Out, trunk, desc.g1Conv, N, W, H, false); + batchNormActNHWC(g1Out2, g1Out, desc.g1BN, desc.g1Activation.activation, ctx.mask, N, W, H); + poolRowsGPoolNHWC(g1Concat, g1Out2, ctx.mask, ctx.maskSum, g1C, N, W, H); + matmulRows(g1Bias, g1Concat, desc.gpoolToBiasMul, N); + addPerBatchChannelBiasNHWC(p1Out, g1Bias, p1C, N, W, H); + batchNormActNHWC(p1Out2, p1Out, desc.p1BN, desc.p1Activation.activation, ctx.mask, N, W, H); + // Raw logits; intentionally NOT masked after the final conv (as eigenbackend). + convNHWCMaybeNpu(ctx, policy, p1Out2, desc.p2Conv, N, W, H, false); + + if(desc.modelVersion >= 15) { + matmulRows(p1Pass, g1Concat, desc.gpoolToPassMul, N); + matBiasAddRows(p1Pass, desc.gpoolToPassBias, N); + applyActivationInplace(p1Pass, (size_t)N * p1C, desc.passActivation.activation); + matmulRows(policyPass, p1Pass, desc.gpoolToPassMul2, N); + } + else { + matmulRows(policyPass, g1Concat, desc.gpoolToPassMul, N); + } + + ctx.arena->rewind(mark); +} + +// --------------------------------------------------------------------------- +// Value head. trunk: [N][H][W][trunkC] (post tip-norm). +// value: [N][numValueChannels] logits, scoreValue: [N][numScoreValueChannels] +// raw, ownership: [N][H][W][numOwnershipChannels] pre-tanh, unmasked. +// --------------------------------------------------------------------------- +void applyValueHead( + const ValueHeadDesc& desc, + ForwardCtx& ctx, + const float* trunk, + float* value, + float* scoreValue, + float* ownership +) { + const int N = ctx.batchSize; + const int W = ctx.nnXLen; + const int H = ctx.nnYLen; + const size_t BXY = (size_t)N * W * H; + const int v1C = desc.v1Conv.outChannels; + const int v2C = desc.v2Mul.outChannels; + + size_t mark = ctx.arena->mark(); + float* v1Out = ctx.arena->alloc(BXY * v1C); + float* v1Out2 = ctx.arena->alloc(BXY * v1C); + float* v1Mean = ctx.arena->alloc((size_t)N * 3 * v1C); + float* v2Out = ctx.arena->alloc((size_t)N * v2C); + + convNHWCMaybeNpu(ctx, v1Out, trunk, desc.v1Conv, N, W, H, false); + batchNormActNHWC(v1Out2, v1Out, desc.v1BN, desc.v1Activation.activation, ctx.mask, N, W, H); + poolRowsValueHeadNHWC(v1Mean, v1Out2, ctx.maskSum, v1C, N, W, H); + matmulRows(v2Out, v1Mean, desc.v2Mul, N); + matBiasAddRows(v2Out, desc.v2Bias, N); + applyActivationInplace(v2Out, (size_t)N * v2C, desc.v2Activation.activation); + matmulRows(value, v2Out, desc.v3Mul, N); + matBiasAddRows(value, desc.v3Bias, N); + matmulRows(scoreValue, v2Out, desc.sv3Mul, N); + matBiasAddRows(scoreValue, desc.sv3Bias, N); + // Raw conv output; intentionally NOT masked or tanh'd (as eigenbackend). + convNHWCMaybeNpu(ctx, ownership, v1Out2, desc.vOwnershipConv, N, W, H, false); + + ctx.arena->rewind(mark); +} + +// --------------------------------------------------------------------------- +// Worst-case arena sizing (in floats), mirroring exactly the buffers each +// code path above holds simultaneously. batchXY = maxBatchSize*nnXLen*nnYLen. +// --------------------------------------------------------------------------- +size_t arenaEltsForBlockStack( + const std::vector>& blocks, + size_t batchXY, + size_t batch, + size_t seqLen +); + +size_t arenaEltsForBlock( + int kind, + const void* descPtr, + size_t batchXY, + size_t batch, + size_t seqLen +) { + switch(kind) { + case ORDINARY_BLOCK_KIND: { + const ResidualBlockDesc* d = (const ResidualBlockDesc*)descPtr; + return 2 * (size_t)d->regularConv.outChannels * batchXY; + } + case GLOBAL_POOLING_BLOCK_KIND: { + const GlobalPoolingResidualBlockDesc* d = (const GlobalPoolingResidualBlockDesc*)descPtr; + size_t regC = (size_t)d->regularConv.outChannels; + size_t gpoolC = (size_t)d->gpoolConv.outChannels; + return (2 * regC + 2 * gpoolC) * batchXY + (3 * gpoolC + regC) * batch; + } + case NESTED_BOTTLENECK_BLOCK_KIND: { + const NestedBottleneckResidualBlockDesc* d = (const NestedBottleneckResidualBlockDesc*)descPtr; + // Outer midIn/midScratch stay live while the inner stack runs. + return 2 * (size_t)d->preConv.outChannels * batchXY + + arenaEltsForBlockStack(d->blocks, batchXY, batch, seqLen); + } + case TRANSFORMER_ATTENTION_BLOCK_KIND: { + const TransformerAttentionDesc* d = (const TransformerAttentionDesc*)descPtr; + size_t qTot = (size_t)d->numHeads * d->qHeadDim; + size_t kTot = (size_t)d->numKVHeads * d->qHeadDim; + size_t vTot = (size_t)d->numKVHeads * d->vHeadDim; + size_t oTot = (size_t)d->numHeads * d->vHeadDim; + return (qTot + kTot + vTot + oTot) * batchXY + seqLen * seqLen; + } + case TRANSFORMER_FFN_BLOCK_KIND: { + const TransformerFFNDesc* d = (const TransformerFFNDesc*)descPtr; + return 2 * (size_t)d->ffnChannels * batchXY; + } + default: + throw StringError("RyzenAIRef: unknown block kind " + std::to_string(kind)); + } +} + +size_t arenaEltsForBlockStack( + const std::vector>& blocks, + size_t batchXY, + size_t batch, + size_t seqLen +) { + size_t maxElts = 0; + for(size_t i = 0; i < blocks.size(); i++) + maxElts = std::max(maxElts, arenaEltsForBlock(blocks[i].first, blocks[i].second.get(), batchXY, batch, seqLen)); + return maxElts; +} + +// --------------------------------------------------------------------------- +// Model validation + RoPE table precomputation (recurses into nested +// bottleneck blocks). Throws on unsupported features. +// --------------------------------------------------------------------------- +void validateAndCollectBlocks( + const std::vector>& blocks, + int nnXLen, + int nnYLen, + std::map& ropeTables +) { + for(size_t i = 0; i < blocks.size(); i++) { + int kind = blocks[i].first; + const void* ptr = blocks[i].second.get(); + if(kind == ORDINARY_BLOCK_KIND || kind == GLOBAL_POOLING_BLOCK_KIND) { + // nothing special + } + else if(kind == NESTED_BOTTLENECK_BLOCK_KIND) { + const NestedBottleneckResidualBlockDesc* d = (const NestedBottleneckResidualBlockDesc*)ptr; + validateAndCollectBlocks(d->blocks, nnXLen, nnYLen, ropeTables); + } + else if(kind == TRANSFORMER_ATTENTION_BLOCK_KIND) { + const TransformerAttentionDesc* d = (const TransformerAttentionDesc*)ptr; + if(d->useRope) { + RopeTables tables; + // paddedNNXYLen == nnXLen*nnYLen (no extra padding), as eigenbackend. + d->computeRopeCosSin(nnXLen, nnYLen, nnXLen * nnYLen, tables.cosTable, tables.sinTable); + ropeTables[ptr] = std::move(tables); + } + } + else if(kind == TRANSFORMER_FFN_BLOCK_KIND) { + const TransformerFFNDesc* d = (const TransformerFFNDesc*)ptr; + if(!d->useSwiGLU) + throw StringError("RyzenAIRef: non-SwiGLU transformer FFN block '" + d->name + "' is not supported"); + } + else { + throw StringError("RyzenAIRef: unknown block kind " + std::to_string(kind)); + } + } +} + +} // namespace + +// --------------------------------------------------------------------------- +// Workspace +// --------------------------------------------------------------------------- +struct Workspace { + const ModelDesc* model; // not owned; must outlive this Workspace + int maxBatchSize; + int nnXLen; + int nnYLen; + + std::vector mask; // [maxBatchSize][nnYLen*nnXLen] + std::vector maskSum; // [maxBatchSize] + std::vector trunkA; // [maxBatchSize][nnYLen*nnXLen][trunkC] + std::vector trunkB; // same; scratch / heads' input + std::vector arenaStorage; + std::map ropeTables; + RyzenAIMatMul::Accel* accel = nullptr; // not owned +}; + +Workspace* createWorkspace( + const ModelDesc& model, + int maxBatchSize, + int nnXLen, + int nnYLen +) { + if(maxBatchSize < 1) + throw StringError("RyzenAIRef: maxBatchSize must be positive"); + if(nnXLen < 1 || nnYLen < 1) + throw StringError("RyzenAIRef: nnXLen/nnYLen must be positive"); + + std::unique_ptr ws(new Workspace()); + ws->model = &model; + ws->maxBatchSize = maxBatchSize; + ws->nnXLen = nnXLen; + ws->nnYLen = nnYLen; + + const TrunkDesc& trunk = model.trunk; + const size_t S = (size_t)nnXLen * nnYLen; + const size_t B = (size_t)maxBatchSize; + const size_t BXY = B * S; + const size_t trunkC = (size_t)trunk.trunkNumChannels; + + // Validates all blocks (recursively) and precomputes RoPE tables. + validateAndCollectBlocks(trunk.blocks, nnXLen, nnYLen, ws->ropeTables); + + // Arena sizing, mirroring the live buffers of each top-level phase. + // Trunk preamble: initial matmul output (+ SGF metadata encoder internals). + size_t preambleElts = (size_t)trunk.initialMatMul.outChannels * B; + if(trunk.metaEncoderVersion > 0) { + const SGFMetadataEncoderDesc& enc = trunk.sgfMetadataEncoder; + size_t encInternal = (size_t)std::max(enc.mul1.outChannels, enc.mul2.outChannels); + preambleElts += 2 * encInternal * B; + } + size_t trunkElts = std::max(preambleElts, arenaEltsForBlockStack(trunk.blocks, BXY, B, S)); + + const PolicyHeadDesc& ph = model.policyHead; + size_t p1C = (size_t)ph.p1Conv.outChannels; + size_t g1C = (size_t)ph.g1Conv.outChannels; + size_t policyElts = (2 * p1C + 2 * g1C) * BXY + (3 * g1C + 2 * p1C) * B; + + const ValueHeadDesc& vh = model.valueHead; + size_t v1C = (size_t)vh.v1Conv.outChannels; + size_t v2C = (size_t)vh.v2Mul.outChannels; + size_t valueElts = 2 * v1C * BXY + (3 * v1C + v2C) * B; + + size_t arenaElts = std::max(trunkElts, std::max(policyElts, valueElts)); + + ws->mask.resize(B * S); + ws->maskSum.resize(B); + ws->trunkA.resize(BXY * trunkC); + ws->trunkB.resize(BXY * trunkC); + ws->arenaStorage.resize(arenaElts); + return ws.release(); +} + +void setProfileEnabled(bool enabled) { + g_profile = CpuProfile(); + g_profile.enabled = enabled; +} + +std::string profileReport() { + if(!g_profile.enabled) + return "RyzenAI CPU profile: not enabled"; + // attnScores covers only the CPU attention path and includes that path's + // softmax, so subtract -- but only what the CPU path itself contributed, + // which is exactly the softmax bucket when attention ran on the CPU and + // zero when it ran on the NPU (the NPU path's softmax is reported there). + char buf[320]; + std::snprintf( + buf, sizeof(buf), + "RyzenAI CPU profile: attention(CPU) %.2f s, softmax %.2f s, norms %.2f s, " + "rope %.2f s, swiglu %.2f s, residual %.2f s", + g_profile.attnScores, g_profile.softmax, g_profile.norms, + g_profile.rope, g_profile.swiglu, g_profile.residual); + return std::string(buf); +} + +void setMatMulAccel(Workspace* workspace, RyzenAIMatMul::Accel* accel) { + workspace->accel = accel; +} + +void freeWorkspace(Workspace* workspace) { + delete workspace; +} + +void forward( + Workspace* workspace, + int batchSize, + const float* spatialInput, + const float* globalInput, + const float* metaInput, + float* policy, + float* policyPass, + float* value, + float* scoreValue, + float* ownership +) { + if(workspace == nullptr) + throw StringError("RyzenAIRef: forward called with null workspace"); + const ModelDesc& model = *workspace->model; + if(batchSize < 1 || batchSize > workspace->maxBatchSize) + throw StringError("RyzenAIRef: batchSize out of range for workspace"); + if(spatialInput == nullptr || globalInput == nullptr) + throw StringError("RyzenAIRef: spatialInput and globalInput must be non-null"); + const bool hasMeta = model.trunk.metaEncoderVersion > 0; + if(hasMeta && metaInput == nullptr) + throw StringError("RyzenAIRef: model has an SGF metadata encoder but metaInput is null"); + if(!hasMeta && metaInput != nullptr) + throw StringError("RyzenAIRef: model has no SGF metadata encoder but metaInput is non-null"); + if(policy == nullptr || policyPass == nullptr || value == nullptr || scoreValue == nullptr || ownership == nullptr) + throw StringError("RyzenAIRef: output buffers must be non-null"); + + const int N = batchSize; + const int W = workspace->nnXLen; + const int H = workspace->nnYLen; + const int S = W * H; + const int inC = model.numInputChannels; + + // Mask = channel 0 of the spatial input (1.0f on-board, 0.0f padding), + // matching eigenbackend's `*mask = input->chip(0,0)` + computeMaskSum. + float* mask = workspace->mask.data(); + float* maskSum = workspace->maskSum.data(); + for(int n = 0; n < N; n++) { + float s = 0.0f; + for(int xy = 0; xy < S; xy++) { + float mv = spatialInput[((size_t)n * S + xy) * inC]; + mask[(size_t)n * S + xy] = mv; + s += mv; + } + maskSum[n] = s; + } + + Arena arena; + arena.base = workspace->arenaStorage.data(); + arena.capacity = workspace->arenaStorage.size(); + arena.offset = 0; + + ForwardCtx ctx; + ctx.batchSize = N; + ctx.nnXLen = W; + ctx.nnYLen = H; + ctx.mask = mask; + ctx.maskSum = maskSum; + ctx.arena = &arena; + ctx.ropeTables = &workspace->ropeTables; + ctx.accel = workspace->accel; + + float* trunkA = workspace->trunkA.data(); // residual stream + float* trunkB = workspace->trunkB.data(); // trunk scratch / heads' input + + const TrunkDesc& trunk = model.trunk; + + // ---- Trunk preamble: initial conv + global projection (+ SGF metadata) ---- + { + size_t mark = arena.mark(); + const int immC = trunk.initialMatMul.outChannels; + float* immOut = arena.alloc((size_t)N * immC); + convNHWCMaybeNpu(ctx, trunkA, spatialInput, trunk.initialConv, N, W, H, false); + matmulRows(immOut, globalInput, trunk.initialMatMul, N); + addPerBatchChannelBiasNHWC(trunkA, immOut, immC, N, W, H); + if(hasMeta) { + applySGFMetadataEncoder(trunk.sgfMetadataEncoder, ctx, metaInput, immOut); + addPerBatchChannelBiasNHWC(trunkA, immOut, immC, N, W, H); + } + arena.rewind(mark); + } + + // ---- Trunk blocks (residual stream in trunkA, trunkB as block scratch) ---- + applyBlockStack(trunk.blocks, trunk.numBlocks, ctx, trunkA, trunkB); + + // ---- Trunk tip norm + activation: trunkA -> trunkB ---- + if(trunk.trunkNormKind == TRUNK_NORM_KIND_STANDARD) { + batchNormActNHWC(trunkB, trunkA, trunk.trunkTipBN, trunk.trunkTipActivation.activation, mask, N, W, H); + } + else { + trunkTipRMSNormNHWC(trunkB, trunkA, trunk.trunkTipRMSNorm, trunk.trunkTipActivation.activation, mask, N, W, H); + } + + // ---- Heads, reading the normalized trunk output in trunkB ---- + applyPolicyHead(model.policyHead, ctx, trunkB, policyPass, policy); + applyValueHead(model.valueHead, ctx, trunkB, value, scoreValue, ownership); +} + +} // namespace RyzenAIRef diff --git a/cpp/neuralnet/ryzenaireference.h b/cpp/neuralnet/ryzenaireference.h new file mode 100644 index 0000000000..5a00a6e8ff --- /dev/null +++ b/cpp/neuralnet/ryzenaireference.h @@ -0,0 +1,191 @@ +/* + * Pure C++ (C++17, standard library only) CPU reference implementation of the + * KataGo neural network forward pass, for the RyzenAI (AMD NPU) backend. + * + * Purpose: + * - Numerical ground truth for elementwise A/B checking of the accelerated + * NPU/GPU paths, and a per-operator fallback when an operator is not (yet) + * available on device. + * + * Layout contract: + * - ALL internal activations and ALL input/output buffers below are NHWC: + * spatial tensors are [N][nnYLen][nnXLen][C] row-major (C innermost), so a + * per-batch-element slab is [H*W][C] and can be fed directly to a GEMM as + * the A matrix. This is identical to the runtime layout of + * cpp/neuralnet/eigenbackend.cpp (whose Eigen tensors are (C,W,H,N) + * column-major, i.e. the same memory order). + * + * Semantics: + * - Ported 1:1 from cpp/neuralnet/eigenbackend.cpp: mask handling, global + * pooling normalization, RoPE/attention, SwiGLU FFN, and the exact + * boundary between backend outputs and client post-processing. + * - KataGo convention: ALL outputs are raw logits / pre-activation values. + * No softmax, no tanh, no policy-optimism interpolation and no symmetry + * handling is applied by this code. That post-processing is the caller's + * job, exactly as in eigenbackend.cpp's getOutput() (which reads buffers + * with precisely the layouts documented below). + * + * Supported model structure (all block kinds from desc.h): + * - ORDINARY_BLOCK_KIND (0) plain residual block + * - GLOBAL_POOLING_BLOCK_KIND (2) residual block with global-pooling bias + * - NESTED_BOTTLENECK_BLOCK_KIND (3) bottleneck block containing a nested + * stack of any of the block kinds here + * (recursion supported to any depth) + * - TRANSFORMER_ATTENTION_BLOCK_KIND (4) multi-head attention with GQA, + * optional RoPE (learnable rope_freqs or + * fixed rope_theta), TransformerRMSNorm + * - TRANSFORMER_FFN_BLOCK_KIND (5) SwiGLU FFN (linear1/linearGate/linear2) + * - initial conv + initial matmul (global feature projection) + * - SGF metadata encoder (when ModelDesc::metaEncoderVersion > 0) + * - trunk tip norm+activation, both TRUNK_NORM_KIND_STANDARD (BatchNorm) + * and TRUNK_NORM_KIND_RMSNORM (RMSNormLayerDesc, spatial and non-spatial) + * - policy head (both modelVersion >= 15 and older pass branches) + * - value head (value, scoreValue, ownership) + * + * Threading/reentrancy: + * - No global mutable state. A Workspace may only be used by one thread at a + * time (same rule as a ComputeHandle in the other backends). Different + * threads must use different Workspaces; each Workspace is independently + * reentrant across calls. + * - All scratch memory is allocated once in createWorkspace(); forward() + * performs no heap allocation. + */ + +#ifndef NEURALNET_RYZENAI_REFERENCE_H_ +#define NEURALNET_RYZENAI_REFERENCE_H_ + +#include + +#include "../neuralnet/desc.h" + +namespace RyzenAIMatMul { struct Accel; } + +namespace RyzenAIRef { + + // Opaque handle holding all scratch buffers and precomputed tables + // (e.g. RoPE cos/sin) for one (model, maxBatchSize, nnXLen, nnYLen) + // configuration. + struct Workspace; + + // Allocates all scratch space needed by forward() for the given model and + // geometry. Throws StringError on unsupported model features (currently the + // only unsupported feature is a non-SwiGLU transformer FFN). + // + // The ModelDesc is NOT copied: `model` must remain alive and unmodified + // (in particular, do not call releaseWeights() on it) until freeWorkspace(). + // + // nnXLen/nnYLen are the (possibly padded) board dimensions the net is + // evaluated at; boards smaller than this are handled via the mask channel + // of spatialInput (see forward()). + Workspace* createWorkspace( + const ModelDesc& model, + int maxBatchSize, + int nnXLen, + int nnYLen + ); + + void freeWorkspace(Workspace* workspace); + + // Attaches an NPU accelerator for the trunk's dense layers (attention + // projections and FFN linears -- the layers whose row count is the whole + // board, which is where nearly all the arithmetic is). Not owned; it must + // outlive the workspace. nullptr, the default, keeps everything on the CPU. + // + // Anything the accelerator declines runs on the CPU path, so attaching one + // never changes which models work, only how fast they are. + void setMatMulAccel(Workspace* workspace, RyzenAIMatMul::Accel* accel); + + // Coarse timing of the work still done on the CPU, for deciding what to move + // onto the NPU next. Enabling it costs a clock read per region, which is + // negligible next to the regions themselves. Not thread-safe: the counters + // are process-wide, so enable it only on single-threaded runs. + void setProfileEnabled(bool enabled); + std::string profileReport(); + + // Runs one batched forward pass. batchSize must satisfy + // 1 <= batchSize <= workspace's maxBatchSize. + // + // ============================ INPUT BUFFERS ============================ + // + // spatialInput: + // [batchSize][nnYLen][nnXLen][ModelDesc::numInputChannels] row-major. + // Element (n,y,x,c) at spatialInput[((n*nnYLen + y)*nnXLen + x)*C + c]. + // Channel 0 MUST be the on-board mask: exactly 1.0f at positions inside + // the actual board and 0.0f at padding positions (when the board is + // smaller than nnXLen x nnYLen). All global-pooling denominators and all + // masked reductions are computed from this channel, matching + // eigenbackend.cpp (`*mask = input->chip(0,0)`). + // + // globalInput: + // [batchSize][ModelDesc::numInputGlobalChannels] row-major. + // Element (n,c) at globalInput[n*Cg + c]. + // + // metaInput: + // [batchSize][ModelDesc::numInputMetaChannels] row-major. + // Must be non-null iff the model has an SGF metadata encoder + // (ModelDesc::metaEncoderVersion > 0); pass nullptr otherwise. + // + // ============================ OUTPUT BUFFERS =========================== + // All are written fully (for all batchSize rows) by forward(). + // All values are raw network outputs (logits / pre-activation); no final + // softmax/tanh is applied anywhere. Below, PC = ModelDesc::numPolicyChannels, + // VC = ModelDesc::numValueChannels, SVC = ModelDesc::numScoreValueChannels, + // OC = ModelDesc::numOwnershipChannels. + // + // policy: + // [batchSize][nnYLen][nnXLen][PC] row-major (NHWC). + // Element (n,y,x,c) at policy[((n*nnYLen + y)*nnXLen + x)*PC + c]. + // Raw output of the policy head's final conv (p2Conv). Per KataGo + // convention this buffer is NOT masked after the final conv (padded + // positions contain whatever the conv produces; the caller must ignore + // or legalize them, as eigenbackend's getOutput does via the client). + // Channel meaning: + // c=0: policy logit for playing at (y,x). + // c=1: (only if PC == 2 or PC == 4) optimistic-policy logit. + // c=2,3: (only if PC == 4, modelVersion >= 16) auxiliary q-value + // prediction channels. + // The optimism interpolation between channels 0/1 is NOT done here; it is + // part of getOutput()-side post-processing. + // + // policyPass: + // [batchSize][PC] row-major. Element (n,c) at policyPass[n*PC + c]. + // Raw pass-move logits, same channel semantics as `policy`. + // + // value: + // [batchSize][VC] row-major (VC == 3). Element (n,c) at value[n*VC + c]. + // c=0: win logit, c=1: loss logit, c=2: no-result logit, from the + // perspective of the player to move. No softmax applied. + // + // scoreValue: + // [batchSize][SVC] row-major. Element (n,c) at scoreValue[n*SVC + c]. + // Raw linear outputs (no activation). Channel order: + // modelVersion >= 9 (SVC == 6): [scoreMean, scoreMeanSq, lead, + // varTimeLeft, shorttermWinlossError, shorttermScoreError] + // modelVersion == 8 (SVC == 4): first 4 of the above + // 4 <= modelVersion <= 7 (SVC == 2): first 2 of the above + // modelVersion == 3 (SVC == 1): scoreMean only + // + // ownership: + // [batchSize][nnYLen][nnXLen][OC] row-major (OC == 1). + // Element (n,y,x,c) at ownership[((n*nnYLen + y)*nnXLen + x)*OC + c]. + // Raw output of vOwnershipConv: pre-tanh ownership prediction from the + // perspective of the player to move. NOT masked (raw conv output). + // + // The caller-provided output buffers may not alias each other or the input + // buffers. + void forward( + Workspace* workspace, + int batchSize, + const float* spatialInput, + const float* globalInput, + const float* metaInput, + float* policy, + float* policyPass, + float* value, + float* scoreValue, + float* ownership + ); + +} // namespace RyzenAIRef + +#endif // NEURALNET_RYZENAI_REFERENCE_H_ diff --git a/cpp/neuralnet/ryzenaisequence.cpp b/cpp/neuralnet/ryzenaisequence.cpp new file mode 100644 index 0000000000..3cef9dc046 --- /dev/null +++ b/cpp/neuralnet/ryzenaisequence.cpp @@ -0,0 +1,329 @@ +// sequence.cpp -- see sequence.h for the module overview. +// +// A stream is a run of independent M-chunks of chunkRows = tileM * 4 * 2 rows +// (4 AIE rows, doubled for ping-pong). Within a chunk each buffer descriptor is +// emitted as +// +// BLOCKWRITE + DDR_PATCH [+ ISSUE_TOKEN] + QUEUE_PUSH +// +// and after the chunks come the WAIT_TCTs. Two things vary between chunks and +// nothing else: the DDR offsets, and which of two buffer-descriptor sets is +// used (chunk 1 double-buffers against chunk 0; chunk 2 onward reuse set A, +// having waited). +// +// The one thing not derivable from (M, K, N, tiles, cols) is which physical +// shim column each descriptor lands on and in what order -- that is IRON's +// placer output. It depends only on the column count, so it is tabulated in +// sequence_layout.h (generated by python/ryzenai_kernels/extract_layout.py) and everything +// numeric is computed here. +// +// Field formulas, with cr = chunkRows and nA = number of A descriptors: +// C: len = cr*N/2/cols, D0=(tileN,1), D1=(cr/2,N), D2.stride=tileN*cols, +// iter=(2, cr*N/2), bufoff = chunk*cr*N*4 + slot*tileN*4 +// A: len = cr*K/2/nA, D0=(tileM,1), D1=(cr/nA,K/2), D2.stride=tileM, +// iter=(1,1), bufoff = chunk*cr*K*2 + slot*cr*K/cols +// B: len = K*tileN/2, D0=(tileN/2,1), D1=(tileK,N/2), D2.stride=tileK*N/2, +// iter=(N/tileN/cols, tileN/2*cols), bufoff = slot*tileN*2 (no chunk term: +// the same B panel feeds every chunk) +// QUEUE_PUSH.repeat = N/(tileN*cols) - 1 on MM2S; S2MM uses 1 with a token +// +// Two bugs were found here by widening the golden set, both of the same shape: +// a formula that aliased with the right answer at the single point where it had +// been checked. B's D1.stride was written K/2 and only a non-square golden +// showed it must be N/2; C's and A's fields were written as functions of M and +// only a golden with M != 2*chunkRows showed they are chunk constants. Any new +// field formula must be checked against goldens that vary that dimension. + +#include "../neuralnet/ryzenaisequence.h" + +#include "../neuralnet/ryzenaisequence_layout.h" + +#include +#include + +namespace RyzenAISequence { + +namespace { + +// Command opcodes (see INSTS_FORMAT.md / FastFlowLM op_headers). +constexpr uint32_t OP_WRITE32 = 0x00; +constexpr uint32_t OP_BLOCKWRITE = 0x01; +constexpr uint32_t OP_MASKWRITE = 0x03; +constexpr uint32_t OP_WAIT_TCT = 0x80; +constexpr uint32_t OP_DDR_PATCH = 0x81; + +// Register addresses within a shim tile. The full location word additionally +// carries the column in bits 31:25 and the row (always 0 here) in bits 24:20. +constexpr uint32_t ADDR_BD_BASE = 0x1D000; // descriptor i at +0x20*i +constexpr uint32_t ADDR_BD_PATCH = 0x1D004; // its address word, for patching +constexpr uint32_t ADDR_QUEUE_S2MM_CH0 = 0x1D204; +constexpr uint32_t ADDR_TOKEN_S2MM_CH0 = 0x1D200; + +constexpr uint32_t BD_OPSIZE_BYTES = 12 * 4; +constexpr uint32_t QUEUE_OPSIZE_BYTES = 6 * 4; +constexpr uint32_t TOKEN_OPSIZE_BYTES = 7 * 4; +constexpr uint32_t WAIT_OPSIZE_BYTES = 4 * 4; + +// Every design in the artifact set uses the 4 compute rows of a column, and +// each row's tile is double-buffered, so one pass over the array consumes +// tileM*4*2 rows of A. IRON rejects any M that is not a whole number of these. +constexpr uint32_t AIE_ROWS = 4; + +void check(bool ok, const char* what) { + if(!ok) + throw std::invalid_argument(std::string("RyzenAISequence: invalid shape: ") + what); +} + +uint32_t loc(uint32_t col, uint32_t addr) { + return (col << 25) | addr; // row is 0: these are all shim-tile registers +} + +void pushBlockWrite( + std::vector& out, + uint32_t burstConst, + uint32_t col, + uint32_t bdId, + uint32_t lenBlocks, + uint32_t bufOffBytes, + uint32_t d0Size, + uint32_t d0Stride, + uint32_t d1Size, + uint32_t d1Stride, + uint32_t d2Stride, + uint32_t iterSize, + uint32_t iterStride) { + out.push_back(OP_BLOCKWRITE); + out.push_back(0); + out.push_back(loc(col, ADDR_BD_BASE + 0x20 * bdId)); + out.push_back(BD_OPSIZE_BYTES); + out.push_back(lenBlocks); + out.push_back(bufOffBytes); + out.push_back(0); // packet disabled + out.push_back((d0Size << 20) | (d0Stride - 1)); + out.push_back(burstConst | (d1Size << 20) | (d1Stride - 1)); + out.push_back((2u << 24) | (d2Stride - 1)); // AxCache=2; D2's size is implied by len + out.push_back(((iterSize - 1) << 20) | (iterStride - 1)); + // valid_bd=1, lock rel_val=128; everything else zero (as in golden streams). + out.push_back((1u << 25) | (128u << 18)); +} + +void pushDdrPatch( + std::vector& out, uint32_t col, uint32_t bdId, uint32_t argIdx, uint32_t argOffBytes) { + out.push_back(OP_DDR_PATCH); + out.push_back(BD_OPSIZE_BYTES); + out.push_back(0); + out.push_back(0); + out.push_back(0); + out.push_back(0); + out.push_back(loc(col, ADDR_BD_PATCH + 0x20 * bdId)); + out.push_back(0); + out.push_back(argIdx); + out.push_back(0); + out.push_back(argOffBytes); + out.push_back(0); +} + +void pushIssueToken(std::vector& out, uint32_t col, uint32_t channel) { + // MASKWRITE on the S2MM queue: controller packet id 15. + out.push_back(OP_MASKWRITE); + out.push_back(0); + out.push_back(loc(col, ADDR_TOKEN_S2MM_CH0 + (channel ? 0x8 : 0))); + out.push_back(0); + out.push_back(15u << 8); + out.push_back(0x00001F00u); + out.push_back(TOKEN_OPSIZE_BYTES); +} + +void pushQueuePush( + std::vector& out, + uint32_t col, + bool mm2s, + uint32_t channel, + uint32_t bdId, + uint32_t repeat, + bool issueToken) { + const uint32_t addr = ADDR_QUEUE_S2MM_CH0 + (mm2s ? 0x10 : 0) + (channel ? 0x8 : 0); + const uint32_t value = (bdId & 0xF) | ((repeat & 0xFF) << 16) | (issueToken ? (1u << 31) : 0); + out.push_back(OP_WRITE32); + out.push_back(0); + out.push_back(loc(col, addr)); + out.push_back(0); + out.push_back(value); + out.push_back(QUEUE_OPSIZE_BYTES); +} + +void pushWaitTct(std::vector& out, uint32_t col, uint32_t channel) { + out.push_back(OP_WAIT_TCT); + out.push_back(WAIT_OPSIZE_BYTES); + out.push_back(col << 16); // row 0, S2MM + out.push_back((channel << 24) | 0x00010100u); +} + +const Layout* findLayout(int cols) { + for(int i = 0; i < NUM_LAYOUTS; i++) { + if(LAYOUTS[i].cols == cols) + return &LAYOUTS[i]; + } + return nullptr; +} + +} // namespace + +bool supportsColumns(int cols) { + return findLayout(cols) != nullptr; +} + +std::vector generateSequence( + Arch arch, int cols, int M, int K, int N, int tileM, int tileK, int tileN) { + GemmShape shape{M, K, N, tileM, tileK, tileN}; + return generateSequence(arch, cols, shape); +} + +std::vector generateSingleColSequence(Arch arch, const GemmShape& shape) { + return generateSequence(arch, 1, shape); +} + +std::vector generateSingleColSequence( + Arch arch, int M, int K, int N, int tileM, int tileK, int tileN) { + return generateSequence(arch, 1, M, K, N, tileM, tileK, tileN); +} + +std::vector generateSequence(Arch arch, int cols, const GemmShape& s) { + const Layout* layout = findLayout(cols); + if(layout == nullptr) + throw std::invalid_argument( + "RyzenAISequence: no descriptor layout for " + std::to_string(cols) + " column(s)"); + + check(s.M > 0 && s.K > 0 && s.N > 0, "M/K/N must be positive"); + check(s.tileM > 0 && s.tileK > 0 && s.tileN > 0, "tiles must be positive"); + check(s.K % s.tileK == 0, "K % tileK != 0"); + check(s.tileN % 2 == 0, "tileN must be even"); + check(s.N % (s.tileN * cols) == 0, "N % (tileN*cols) != 0"); + check((s.N / (s.tileN * cols) - 1) <= 0xFF, "N/(tileN*cols)-1 overflows QUEUE_PUSH.repeat"); + + const uint32_t M = static_cast(s.M); + const uint32_t K = static_cast(s.K); + const uint32_t N = static_cast(s.N); + const uint32_t tm = static_cast(s.tileM); + const uint32_t tk = static_cast(s.tileK); + const uint32_t tn = static_cast(s.tileN); + const uint32_t nCols = static_cast(cols); + + const uint32_t chunkRows = tm * AIE_ROWS * 2; + check(s.M % (int)chunkRows == 0, + "M must be a multiple of tileM*8 (one pass over the 4 double-buffered AIE rows)"); + const uint32_t chunks = M / chunkRows; + + uint32_t numA = 0; + for(int i = 0; i < layout->numSteps; i++) + numA += (layout->steps[i].role == Role::A) ? 1u : 0u; + + // Per-descriptor transfer sizes, in the 4-word blocks the length field counts. + const uint32_t lenC = chunkRows * N / 2 / nCols; + const uint32_t lenA = chunkRows * K / 2 / numA; + const uint32_t lenB = K * tn / 2; + // Units the DDR offsets step by, matching the slot indices in the layout. + const uint32_t unitC = tn * 4; // one tile of float32 output + const uint32_t unitA = chunkRows * K / nCols; + const uint32_t unitB = tn * 2; // one tile of bfloat16 + const uint32_t stripsPerCol = N / (tn * nCols); + const uint32_t repeatMm2s = stripsPerCol - 1; + + // Normally a C descriptor covers one output tile and is re-issued once per + // half-chunk (queue repeat 1, iter walking the two halves). When a column + // owns exactly one tile there is no strip loop left to run, so IRON folds the + // two halves into the descriptor instead: double the length, walk the halves + // with D2, and issue it once. Both encodings move the same bytes. + const bool foldC = stripsPerCol < 2; + const uint32_t lenCEff = foldC ? (chunkRows * N / nCols) : lenC; + const uint32_t d2C = foldC ? (chunkRows * N / 2) : (tn * nCols); + const uint32_t iterSizeC = foldC ? 1u : 2u; + const uint32_t iterStrideC = foldC ? 1u : (chunkRows * N / 2); + const uint32_t repeatS2mm = foldC ? 0u : 1u; + // A one-iteration loop carries no stride. + const uint32_t iterStrideB = (stripsPerCol == 1) ? 1u : (tn / 2 * nCols); + + std::vector out; + out.reserve(4 + chunks * (layout->numSteps * 31 + nCols * 4)); + + // Header: n_rows=6, gen from arch, minor=1, major=0; mem_tile_rows=1. + // The num_cols byte is the device's physical width, not the design's: npu2 + // streams carry 8 even for a 1-column design. npu1 1-column streams carry 1. + const uint32_t gen = static_cast(arch); + const uint32_t physCols = (arch == Arch::NPU1 && cols == 1) ? 1u : (arch == Arch::NPU1 ? 4u : 8u); + out.push_back((6u << 24) | (gen << 16) | (1u << 8)); + out.push_back((1u << 8) | physCols); + out.push_back(0); // command count, patched at the end + out.push_back(0); // total bytes, patched at the end + + // BLOCKWRITE D1 word burst-size constant differs between generations: + // 0xC0000000 on npu2 (aie2p), 0x80000000 on npu1 (aie2). + const uint32_t burstConst = (arch == Arch::NPU1) ? 0x80000000u : 0xC0000000u; + + uint32_t numCommands = 0; + for(uint32_t chunk = 0; chunk < chunks; ++chunk) { + // Chunk 1 is the only one that needs its own descriptor set: it is issued + // before chunk 0's tokens are collected. From chunk 2 on there is always an + // intervening wait, so set A is free again. + const bool setB = (chunk == 1); + + for(int i = 0; i < layout->numSteps; i++) { + const Step& step = layout->steps[i]; + const uint32_t col = step.col; + const uint32_t bd = setB ? step.bdB : step.bdA; + const uint32_t slot = step.slot; + + uint32_t argIdx, off; + switch(step.role) { + case Role::C: + off = chunk * chunkRows * N * 4 + slot * unitC; + argIdx = 2; + pushBlockWrite( + out, burstConst, col, bd, lenCEff, off, tn, 1, chunkRows / 2, N, d2C, iterSizeC, + iterStrideC); + break; + case Role::A: + off = chunk * chunkRows * K * 2 + slot * unitA; + argIdx = 0; + pushBlockWrite( + out, burstConst, col, bd, lenA, off, tm, 1, chunkRows / numA, K / 2, tm, 1, 1); + break; + default: // Role::B -- the same panel is re-read by every chunk + off = slot * unitB; + argIdx = 1; + pushBlockWrite( + out, burstConst, col, bd, lenB, off, tn / 2, 1, tk, N / 2, tk * N / 2, stripsPerCol, + iterStrideB); + break; + } + pushDdrPatch(out, col, bd, argIdx, off); + numCommands += 2; + + if(step.token) { + pushIssueToken(out, col, step.chan); + numCommands++; + } + pushQueuePush( + out, col, step.mm2s, step.chan, bd, step.mm2s ? repeatMm2s : repeatS2mm, step.token); + numCommands++; + } + + // One token per C descriptor per chunk. Chunk 0's are collected together + // with chunk 1's, which is what lets those two chunks overlap. + const uint32_t pending = (chunk == 0 && chunks > 1) ? 0 : (chunk == 1 ? 2 : 1); + for(uint32_t rep = 0; rep < pending; rep++) { + for(int i = 0; i < layout->numSteps; i++) { + if(layout->steps[i].role != Role::C) + continue; + pushWaitTct(out, layout->steps[i].col, layout->steps[i].chan); + numCommands++; + } + } + } + + out[2] = numCommands; + out[3] = static_cast(out.size() * 4); + return out; +} + +} // namespace RyzenAISequence diff --git a/cpp/neuralnet/ryzenaisequence.h b/cpp/neuralnet/ryzenaisequence.h new file mode 100644 index 0000000000..7e4753bff5 --- /dev/null +++ b/cpp/neuralnet/ryzenaisequence.h @@ -0,0 +1,53 @@ +#ifndef NEURALNET_RYZENAI_SEQUENCE_H_ +#define NEURALNET_RYZENAI_SEQUENCE_H_ + +// Builds the NPU instruction stream (the TXN control code that an .insts.bin +// file holds) for a GEMM, in plain C++ with no toolchain of any kind. This is +// what lets an arbitrary model run without Python: the .xclbin bakes in only K, +// so M and N -- which vary per layer, per board size and per batch -- are +// resolved here at run time instead of needing a precompiled artifact each. +// +// Pure C++17, standard library only. No XRT headers, no IRON, no file I/O: +// callers hand the result straight to an xrt::bo. +// +// Verified by byte-for-byte comparison against IRON-compiled goldens; see +// python/ryzenai_kernels/INSTS_FORMAT.md for the decoded format and the field formulas. + +#include +#include + +namespace RyzenAISequence { + +// Header field: which AIE generation the stream targets. npu1 = Phoenix / +// Hawk Point (aie2), npu2 = Strix / Krackan (aie2p). +enum class Arch { NPU1 = 3, NPU2 = 4 }; + +struct GemmShape { + int M; // rows of A and C + int K; // reduction dim -- must match the .xclbin, which bakes K in + int N; // columns of B and C + int tileM; // MMUL micro-kernel tile, from the artifact manifest + int tileK; + int tileN; +}; + +// True if instruction streams can be generated for this column count. The +// per-column descriptor layout comes from IRON's placer and is tabulated in +// sequence_layout.h, so only the tabulated widths are supported. +bool supportsColumns(int cols); + +// Builds the stream for `cols` AIE columns. Throws std::invalid_argument if the +// shape is not realizable (see the checks at the top of the implementation) or +// if the column count has no layout. +std::vector generateSequence(Arch arch, int cols, const GemmShape& shape); +std::vector generateSequence( + Arch arch, int cols, int M, int K, int N, int tileM, int tileK, int tileN); + +// Convenience wrappers for the single-column case. +std::vector generateSingleColSequence(Arch arch, const GemmShape& shape); +std::vector generateSingleColSequence( + Arch arch, int M, int K, int N, int tileM, int tileK, int tileN); + +} // namespace RyzenAISequence + +#endif // NEURALNET_RYZENAI_SEQUENCE_H_ diff --git a/cpp/neuralnet/ryzenaisequence_layout.h b/cpp/neuralnet/ryzenaisequence_layout.h new file mode 100644 index 0000000000..a9b08bb9d5 --- /dev/null +++ b/cpp/neuralnet/ryzenaisequence_layout.h @@ -0,0 +1,123 @@ +// Generated by python/ryzenai_kernels/extract_layout.py -- do not edit by hand. +// +// IRON's placer decides which shim column each buffer descriptor lands on +// and in what order. That decision depends only on the column count, not on +// M/K/N, so it is captured here once per column count and every numeric field +// is computed from the shape at run time. See python/ryzenai_kernels/INSTS_FORMAT.md. + +#ifndef NEURALNET_RYZENAI_SEQUENCE_LAYOUT_H_ +#define NEURALNET_RYZENAI_SEQUENCE_LAYOUT_H_ + +#include + +namespace RyzenAISequence { + +enum class Role : uint8_t { C = 0, A = 1, B = 2 }; + +struct Step { + uint8_t col; // physical shim column + Role role; // which kernel argument this descriptor feeds + uint8_t slot; // index into that role's DDR partition + uint8_t bdA; // buffer descriptor id on even-numbered chunk sets + uint8_t bdB; // ... and on chunk 1, which double-buffers against set A + uint8_t chan; // DMA channel the queue push targets + bool mm2s; // true = host->array, false = array->host + bool token; // emit an ISSUE_TOKEN before the queue push +}; + +// 1 column(s): 5 descriptors per chunk +static const Step LAYOUT_1COL[] = { + {0, Role::C, 0, 0, 5, 0, false, true }, + {0, Role::A, 0, 1, 6, 0, true , false}, + {0, Role::B, 0, 2, 7, 1, true , false}, + {0, Role::A, 1, 3, 8, 0, true , false}, + {0, Role::B, 0, 4, 9, 1, true , false}, +}; + +// 2 column(s): 10 descriptors per chunk +static const Step LAYOUT_2COL[] = { + {0, Role::C, 0, 0, 6, 0, false, true }, + {0, Role::A, 0, 1, 7, 0, true , false}, + {0, Role::B, 0, 2, 8, 1, true , false}, + {0, Role::A, 2, 3, 9, 0, true , false}, + {0, Role::B, 0, 4, 10, 1, true , false}, + {0, Role::C, 1, 5, 11, 1, false, true }, + {1, Role::A, 1, 0, 4, 0, true , false}, + {1, Role::B, 1, 1, 5, 1, true , false}, + {1, Role::A, 3, 2, 6, 0, true , false}, + {1, Role::B, 1, 3, 7, 1, true , false}, +}; + +// 4 column(s): 20 descriptors per chunk +static const Step LAYOUT_4COL[] = { + {1, Role::C, 0, 0, 6, 0, false, true }, + {0, Role::A, 0, 0, 5, 0, true , false}, + {1, Role::B, 0, 1, 7, 1, true , false}, + {0, Role::A, 4, 1, 6, 0, true , false}, + {1, Role::B, 0, 2, 8, 1, true , false}, + {1, Role::C, 1, 3, 9, 1, false, true }, + {1, Role::A, 1, 4, 10, 0, true , false}, + {0, Role::B, 1, 2, 7, 1, true , false}, + {1, Role::A, 5, 5, 11, 0, true , false}, + {0, Role::B, 1, 3, 8, 1, true , false}, + {0, Role::C, 2, 4, 9, 0, false, true }, + {2, Role::A, 2, 0, 5, 0, true , false}, + {2, Role::B, 2, 1, 6, 1, true , false}, + {2, Role::A, 6, 2, 7, 0, true , false}, + {2, Role::B, 2, 3, 8, 1, true , false}, + {2, Role::C, 3, 4, 9, 0, false, true }, + {3, Role::A, 3, 0, 4, 0, true , false}, + {3, Role::B, 3, 1, 5, 1, true , false}, + {3, Role::A, 7, 2, 6, 0, true , false}, + {3, Role::B, 3, 3, 7, 1, true , false}, +}; + +// 8 column(s): 32 descriptors per chunk +static const Step LAYOUT_8COL[] = { + {3, Role::C, 0, 0, 6, 0, false, true }, + {0, Role::A, 0, 0, 2, 0, true , false}, + {3, Role::B, 0, 1, 7, 0, true , false}, + {0, Role::A, 8, 1, 3, 0, true , false}, + {3, Role::B, 0, 2, 8, 0, true , false}, + {3, Role::C, 1, 3, 9, 1, false, true }, + {2, Role::A, 2, 0, 5, 0, true , false}, + {3, Role::B, 1, 4, 10, 1, true , false}, + {2, Role::A, 10, 1, 6, 0, true , false}, + {3, Role::B, 1, 5, 11, 1, true , false}, + {2, Role::C, 2, 2, 7, 0, false, true }, + {4, Role::A, 4, 0, 6, 0, true , false}, + {2, Role::B, 2, 3, 8, 1, true , false}, + {4, Role::A, 12, 1, 7, 0, true , false}, + {2, Role::B, 2, 4, 9, 1, true , false}, + {4, Role::C, 3, 2, 8, 0, false, true }, + {6, Role::A, 6, 0, 5, 0, true , false}, + {4, Role::B, 3, 3, 9, 1, true , false}, + {6, Role::A, 14, 1, 6, 0, true , false}, + {4, Role::B, 3, 4, 10, 1, true , false}, + {4, Role::C, 4, 5, 11, 1, false, true }, + {5, Role::B, 4, 0, 6, 0, true , false}, + {5, Role::B, 4, 1, 7, 0, true , false}, + {5, Role::C, 5, 2, 8, 0, false, true }, + {5, Role::B, 5, 3, 9, 1, true , false}, + {5, Role::B, 5, 4, 10, 1, true , false}, + {5, Role::C, 6, 5, 11, 1, false, true }, + {6, Role::B, 6, 2, 7, 1, true , false}, + {6, Role::B, 6, 3, 8, 1, true , false}, + {6, Role::C, 7, 4, 9, 0, false, true }, + {1, Role::B, 7, 0, 2, 0, true , false}, + {1, Role::B, 7, 1, 3, 0, true , false}, +}; + +struct Layout { int cols; const Step* steps; int numSteps; }; + +static const Layout LAYOUTS[] = { + {1, LAYOUT_1COL, 5}, + {2, LAYOUT_2COL, 10}, + {4, LAYOUT_4COL, 20}, + {8, LAYOUT_8COL, 32}, +}; +static const int NUM_LAYOUTS = 4; + +} // namespace RyzenAISequence + +#endif // NEURALNET_RYZENAI_SEQUENCE_LAYOUT_H_ diff --git a/cpp/neuralnet/ryzenaishapes.cpp b/cpp/neuralnet/ryzenaishapes.cpp new file mode 100644 index 0000000000..0619fb8081 --- /dev/null +++ b/cpp/neuralnet/ryzenaishapes.cpp @@ -0,0 +1,308 @@ +#include "../neuralnet/ryzenaishapes.h" + +#include "../neuralnet/desc.h" + +#include +#include +#include +#include + +using std::string; +using std::vector; + +namespace RyzenAIShapes { + +const char* rowKindName(RowKind kind) { + switch(kind) { + case RowKind::Spatial: return "spatial"; + case RowKind::Batch: return "batch"; + case RowKind::AttnScore: return "attn"; + } + return "?"; +} + +namespace { + +string blockLabel(const string& prefix, size_t idx) { + std::ostringstream out; + out << prefix << ".b" << idx; + return out.str(); +} + +void addMatMul(vector& uses, const string& path, const MatMulLayerDesc& d, RowKind rows) { + // A zero-channel matmul means the layer is absent (e.g. linearGate without SwiGLU). + if(d.inChannels <= 0 || d.outChannels <= 0) + return; + GemmUse u; + u.path = path; + u.op = "matmul"; + u.convY = 1; + u.convX = 1; + u.inChannels = d.inChannels; + u.outChannels = d.outChannels; + u.K = d.inChannels; + u.N = d.outChannels; + u.rows = rows; + uses.push_back(u); +} + +void addConv(vector& uses, const string& path, const ConvLayerDesc& d) { + if(d.inChannels <= 0 || d.outChannels <= 0) + return; + GemmUse u; + u.path = path; + std::ostringstream op; + op << "conv" << d.convYSize << "x" << d.convXSize; + u.op = op.str(); + u.convY = d.convYSize; + u.convX = d.convXSize; + u.inChannels = d.inChannels; + u.outChannels = d.outChannels; + // Implicit GEMM: one reduction over every tap of every input channel. + u.K = d.convYSize * d.convXSize * d.inChannels; + u.N = d.outChannels; + u.rows = RowKind::Spatial; + uses.push_back(u); +} + +void addAttnScore(vector& uses, const string& path, const string& op, int K, int N) { + GemmUse u; + u.path = path; + u.op = op; + u.convY = 1; + u.convX = 1; + u.inChannels = K; + u.outChannels = N; + u.K = K; + u.N = N; + u.rows = RowKind::AttnScore; + uses.push_back(u); +} + +void walkBlocks( + vector& uses, + const std::vector>& blocks, + const string& prefix, + int nnXY +) { + for(size_t i = 0; i < blocks.size(); i++) { + const int kind = blocks[i].first; + const void* ptr = blocks[i].second.get(); + const string path = blockLabel(prefix, i); + + if(kind == ORDINARY_BLOCK_KIND) { + const ResidualBlockDesc* d = (const ResidualBlockDesc*)ptr; + addConv(uses, path + ".regularConv", d->regularConv); + addConv(uses, path + ".finalConv", d->finalConv); + } + else if(kind == GLOBAL_POOLING_BLOCK_KIND) { + const GlobalPoolingResidualBlockDesc* d = (const GlobalPoolingResidualBlockDesc*)ptr; + addConv(uses, path + ".regularConv", d->regularConv); + addConv(uses, path + ".gpoolConv", d->gpoolConv); + addMatMul(uses, path + ".gpoolToBiasMul", d->gpoolToBiasMul, RowKind::Batch); + addConv(uses, path + ".finalConv", d->finalConv); + } + else if(kind == NESTED_BOTTLENECK_BLOCK_KIND) { + const NestedBottleneckResidualBlockDesc* d = (const NestedBottleneckResidualBlockDesc*)ptr; + addConv(uses, path + ".preConv", d->preConv); + walkBlocks(uses, d->blocks, path, nnXY); + addConv(uses, path + ".postConv", d->postConv); + } + else if(kind == TRANSFORMER_ATTENTION_BLOCK_KIND) { + const TransformerAttentionDesc* d = (const TransformerAttentionDesc*)ptr; + addMatMul(uses, path + ".attn.qProj", d->qProj, RowKind::Spatial); + addMatMul(uses, path + ".attn.kProj", d->kProj, RowKind::Spatial); + addMatMul(uses, path + ".attn.vProj", d->vProj, RowKind::Spatial); + if(nnXY > 0) { + // Per head: scores = Q[nnXY x qHeadDim] * K^T[qHeadDim x nnXY], + // ctx = P[nnXY x nnXY] * V[nnXY x vHeadDim]. + addAttnScore(uses, path + ".attn.qk", "attn.qk", d->qHeadDim, nnXY); + addAttnScore(uses, path + ".attn.pv", "attn.pv", nnXY, d->vHeadDim); + } + addMatMul(uses, path + ".attn.outProj", d->outProj, RowKind::Spatial); + } + else if(kind == TRANSFORMER_FFN_BLOCK_KIND) { + const TransformerFFNDesc* d = (const TransformerFFNDesc*)ptr; + addMatMul(uses, path + ".ffn.linear1", d->linear1, RowKind::Spatial); + if(d->useSwiGLU) + addMatMul(uses, path + ".ffn.linearGate", d->linearGate, RowKind::Spatial); + addMatMul(uses, path + ".ffn.linear2", d->linear2, RowKind::Spatial); + } + // Unknown kinds are skipped rather than fatal: this is a diagnostic, and the + // real forward path in reference.cpp is what must reject them. + } +} + +int roundUpTo(int v, int q) { + return ((v + q - 1) / q) * q; +} + +// Right/left aligned fixed-width cells, so the tables line up without pulling in +// iostream manipulator state. +string padLeft(const string& s, size_t width) { + return s.size() >= width ? s : string(width - s.size(), ' ') + s; +} +string padLeft(int v, size_t width) { + return padLeft(std::to_string(v), width); +} +string padRight(const string& s, size_t width) { + return s.size() >= width ? s : s + string(width - s.size(), ' '); +} + +} // namespace + +vector enumerate(const ModelDesc& desc, int nnXY) { + vector uses; + + addConv(uses, "trunk.initialConv", desc.trunk.initialConv); + addMatMul(uses, "trunk.initialMatMul", desc.trunk.initialMatMul, RowKind::Batch); + if(desc.metaEncoderVersion != 0) { + const SGFMetadataEncoderDesc& m = desc.trunk.sgfMetadataEncoder; + addMatMul(uses, "trunk.meta.mul1", m.mul1, RowKind::Batch); + addMatMul(uses, "trunk.meta.mul2", m.mul2, RowKind::Batch); + addMatMul(uses, "trunk.meta.mul3", m.mul3, RowKind::Batch); + } + walkBlocks(uses, desc.trunk.blocks, "trunk", nnXY); + + const PolicyHeadDesc& p = desc.policyHead; + addConv(uses, "policy.p1Conv", p.p1Conv); + addConv(uses, "policy.g1Conv", p.g1Conv); + addMatMul(uses, "policy.gpoolToBiasMul", p.gpoolToBiasMul, RowKind::Batch); + addConv(uses, "policy.p2Conv", p.p2Conv); + addMatMul(uses, "policy.gpoolToPassMul", p.gpoolToPassMul, RowKind::Batch); + addMatMul(uses, "policy.gpoolToPassMul2", p.gpoolToPassMul2, RowKind::Batch); + + const ValueHeadDesc& v = desc.valueHead; + addConv(uses, "value.v1Conv", v.v1Conv); + addMatMul(uses, "value.v2Mul", v.v2Mul, RowKind::Batch); + addMatMul(uses, "value.v3Mul", v.v3Mul, RowKind::Batch); + addMatMul(uses, "value.sv3Mul", v.sv3Mul, RowKind::Batch); + addConv(uses, "value.vOwnershipConv", v.vOwnershipConv); + + return uses; +} + +int chooseSingleK(const ModelDesc& desc, int nnXLen, int nnYLen, double maxSpread) { + const vector uses = enumerate(desc, nnXLen * nnYLen); + + // Only the spatial layers matter: the head's batch-row matmuls never reach + // the NPU at all (too few rows to repay a dispatch). And among those, only + // the ones carrying real arithmetic -- a policy head's 48-channel 1x1 would + // otherwise drag the spread out by itself while contributing nothing. + // Weight by arithmetic and aggregate per reduction dim before thresholding: + // a single instance of even the busiest layer is a fraction of a percent, so + // the test has to be on the K as a whole, not on one layer. + std::map weightByK; + double total = 0.0; + for(size_t i = 0; i < uses.size(); i++) { + if(uses[i].rows != RowKind::Spatial) + continue; + const double macs = (double)uses[i].K * uses[i].N; + weightByK[uses[i].K] += macs; + total += macs; + } + if(total <= 0.0) + return 0; + + int minK = 0; + int maxK = 0; + for(std::map::const_iterator it = weightByK.begin(); it != weightByK.end(); ++it) { + if(it->second / total < 0.01) + continue; + if(minK == 0) + minK = it->first; + maxK = it->first; + } + if(minK <= 0 || maxK <= 0) + return 0; + if((double)maxK / (double)minK > maxSpread) + return 0; + return maxK; +} + +string report(const ModelDesc& desc, int nnXLen, int nnYLen) { + const int nnXY = nnXLen * nnYLen; + const vector uses = enumerate(desc, nnXY); + + std::ostringstream out; + out << "RyzenAI shape report for model '" << desc.name << "'" + << " (version " << desc.modelVersion << ", board " << nnXLen << "x" << nnYLen << ")\n"; + out << " trunk: " << desc.trunk.numBlocks << " blocks, " + << desc.trunk.trunkNumChannels << " trunk channels, " + << desc.trunk.midNumChannels << " mid channels\n"; + + // ---- distinct (K,N,rows), with occurrence counts and one example ------------- + struct Agg { + int count = 0; + string example; + string op; + }; + std::map, int>, Agg> distinct; + for(size_t i = 0; i < uses.size(); i++) { + const GemmUse& u = uses[i]; + auto key = std::make_pair(std::make_pair(u.K, u.N), (int)u.rows); + Agg& a = distinct[key]; + a.count++; + if(a.example.empty()) { + a.example = u.path; + a.op = u.op; + } + } + + out << "\n distinct (K,N) shapes: " << distinct.size() + << " (total GEMM sites: " << uses.size() << ")\n"; + out << " K N rows uses op example\n"; + for(auto it = distinct.begin(); it != distinct.end(); ++it) { + const int K = it->first.first.first; + const int N = it->first.first.second; + const RowKind rows = (RowKind)it->first.second; + out << " " << padLeft(K, 8) << padLeft(N, 8) << padLeft(rowKindName(rows), 9) + << padLeft(it->second.count, 7) << " " << padRight(it->second.op, 10) + << " " << it->second.example << "\n"; + } + + // ---- how big M actually gets ------------------------------------------------ + out << "\n M per dispatch (rows are independent, so M is tiled, not baked into artifacts):\n"; + out << " spatial: batch * " << nnXY << "\n"; + out << " batch: batch\n"; + out << " attn: batch * numHeads * " << nnXY << "\n"; + + // ---- what a quantized artifact grid would cost ------------------------------ + // K, N and M can all be zero-padded up without changing the result (pad B's + // rows and A's columns for K, drop the extra output columns for N, drop the + // extra output rows for M), so a coarse grid covers every model at the price + // of wasted multiply-accumulates. + out << "\n artifact grid if (K,N) are rounded up to a quantum:\n"; + out << " " << padLeft("quantum", 9) << padLeft("distinct(K,N)", 16) + << padLeft("padded/useful MACs", 22) << "\n"; + const int quanta[] = {16, 32, 64, 128, 256}; + for(size_t qi = 0; qi < sizeof(quanta) / sizeof(quanta[0]); qi++) { + const int q = quanta[qi]; + std::set> padded; + double useful = 0.0; + double actual = 0.0; + for(size_t i = 0; i < uses.size(); i++) { + const GemmUse& u = uses[i]; + if(u.rows != RowKind::Spatial) + continue; // batch/attn rows are a different dispatch story; count the bulk only + const int Kp = roundUpTo(u.K, q); + const int Np = roundUpTo(u.N, q); + padded.insert(std::make_pair(Kp, Np)); + useful += (double)u.K * u.N; + actual += (double)Kp * Np; + } + string waste = "n/a"; + if(useful > 0.0) { + std::ostringstream w; + w.precision(3); + w << (actual / useful) << "x"; + waste = w.str(); + } + out << " " << padLeft(q, 9) << padLeft((int)padded.size(), 16) << padLeft(waste, 22) << "\n"; + } + out << " (grid counts and waste cover spatial GEMMs only - the bulk of the work)\n"; + + return out.str(); +} + +} // namespace RyzenAIShapes diff --git a/cpp/neuralnet/ryzenaishapes.h b/cpp/neuralnet/ryzenaishapes.h new file mode 100644 index 0000000000..7b748f095c --- /dev/null +++ b/cpp/neuralnet/ryzenaishapes.h @@ -0,0 +1,68 @@ +#ifndef NEURALNET_RYZENAI_SHAPES_H_ +#define NEURALNET_RYZENAI_SHAPES_H_ + +// Enumerates every matrix multiply a RyzenAI forward pass would want to run, +// straight out of KataGo's own ModelDesc. This exists because the NPU artifacts +// are shape-specific: an .xclbin bakes K into the AIE core program, so the set +// of shapes a model actually needs decides the set of artifacts that must ship. +// See ../../.claude/skills/ryzenai-npu-backend/SKILL.md section 2.1. +// +// Only the reduction dim K and the output dim N are enumerated. M is not a grid +// dimension: rows of a GEMM are independent, so any M is handled by dispatching +// a fixed-M kernel ceil(M/Mkernel) times over row slices, padding only the tail. +// +// Reads shapes only, never weights, so it is cheap and safe to run at startup. + +#include +#include + +struct ModelDesc; + +namespace RyzenAIShapes { + +// Where a GEMM's row count comes from, which decides how big M gets at runtime. +enum class RowKind { + Spatial, // M = batch * nnXLen * nnYLen (one row per board point) + Batch, // M = batch (one row per position, e.g. gpool -> bias) + AttnScore // M = batch * numHeads * nnXY (attention's own QK^T / PV products) +}; + +struct GemmUse { + std::string path; // "trunk.block07.ffn.linear1" + std::string op; // "matmul" | "conv1x1" | "conv3x3" | "attn.qk" | "attn.pv" + int convY; // 1 for a matmul + int convX; + int inChannels; + int outChannels; + int K; // convY * convX * inChannels -- the implicit-GEMM reduction dim + int N; // outChannels + RowKind rows; +}; + +const char* rowKindName(RowKind kind); + +// Every GEMM in model order, recursing into nested-bottleneck stacks. +// nnXY = nnXLen*nnYLen. Attention's own QK^T / PV products have a board-dependent +// K or N, so they are only emitted when nnXY > 0. +std::vector enumerate(const ModelDesc& desc, int nnXY = 0); + +// Human-readable dump: per-layer table, deduplicated (K,N) set, and how many +// artifacts a quantized grid would need at several quantum choices together +// with the compute wasted on padding. This is the input to the M3.5 grid decision. +std::string report(const ModelDesc& desc, int nnXLen, int nnYLen); + +// Picks a single reduction dim to run every spatial layer at, or 0 to keep +// per-layer choices. +// +// Every distinct K is a separate xclbin and therefore a separate hardware +// context, and alternating contexts measured ~0.46 ms per dispatch -- far more +// than these kernels spend on arithmetic. Collapsing onto one K trades +// zero-padded multiply-accumulates for one context, which wins whenever the +// padding stays modest. It does not win on convolution-heavy models, where the +// largest K (9*inChannels) dwarfs the smallest and the arithmetic is real, so +// the spread is bounded before accepting. +int chooseSingleK(const ModelDesc& desc, int nnXLen, int nnYLen, double maxSpread); + +} // namespace RyzenAIShapes + +#endif // NEURALNET_RYZENAI_SHAPES_H_ diff --git a/python/ryzenai_kernels/INSTS_FORMAT.md b/python/ryzenai_kernels/INSTS_FORMAT.md new file mode 100644 index 0000000000..b2eda2747b --- /dev/null +++ b/python/ryzenai_kernels/INSTS_FORMAT.md @@ -0,0 +1,255 @@ +# `.insts.bin` 指令流格式 + +IRON/aiecc 产出的 `.insts.bin` 是 NPU 的 **TXN 控制码**:一串 32 位命令,配置 shim DMA 的 buffer descriptor 并把它们压进 DMA 队列。`.xclbin` 提供阵列配置(与 shape 无关),这份指令流则编码了具体的 M/K/N。 + +M3 的目标是在 C++ 里按 (arch, cols, M, K, N, tile) 现场生成同样的字节流,从而摆脱对每-shape 预编译产物的依赖。 + +工具:`parse_insts.py`(遍历 `artifacts/manifest.json` 里的全部 golden 并 dump 成可读命令列表)。 +参考实现:`tmp/FastFlowLM/src/include/npu_utils/npu_instr_utils.hpp`(735 行,MIT,可商用)。 + +## 头部(4 个 uint32) + +| 字 | 位域 | 含义 | +|---|---|---| +| w0 | `[31:24]` n_rows | 6 | +| | `[23:16]` gen | **3 = npu1/aie2,4 = npu2/aie2p** | +| | `[15:8]` minor | 1 | +| | `[7:0]` major | 0 | +| w1 | `[15:8]` mem_tile_rows | 1 | +| | `[7:0]` num_cols | **物理列数**(npu1=4、npu2=8),不是设计实际用的列数 | +| w2 | — | 命令条数 | +| w3 | — | 总字节数(与文件大小一致,可用于自检) | + +移位常量与 FastFlowLM `npu_sequence` 的 `dev_n_row_shift=24 / dev_gen_shift=16 / dev_minor_shift=8 / dev_major_shift=0`、`dev_mem_tile_rows_shift=8 / dev_num_cols_shift=0` 完全一致。 + +## 命令类型 + +| op | 名称 | 作用 | +|---|---|---| +| 0 | WRITE32 | 单字写寄存器 | +| 1 | BLOCKWRITE | **写一个 DMA buffer descriptor**(本格式的主体) | +| 3 | MASKWRITE | 带掩码写 | +| 6 | PREEMPT | 抢占级别 | +| 0x80 | WAIT_TCT | 等待 task completion token | +| 0x81 | DDR_PATCH | **把 BD 的地址字段绑定到某个 kernel 参数槽** | +| — | ISSUE_TOKEN / QUEUE_PUSH | 配置 token、把 BD 压进 DMA 通道队列 | + +## 主体结构 + +高度规整,反复出现同一四元组: + +``` +BLOCKWRITE col row bd addr len bufoff D0=(size,stride) D1=(size,stride) D2=(size,stride) iter cache lock +DDR_PATCH col row bd addr arg_idx arg_off <- arg_idx: 0=A, 1=B, 2=C +[ISSUE_TOKEN col row S2MM/MM2S ch pkt_id mask] +QUEUE_PUSH col row MM2S/S2MM ch bd repeat issue_token +``` + +`arg_idx` 与 XRT 的参数槽对应(见 `../manifest.h`:ARG_A=3、ARG_B=4、ARG_C=5,减 3 即为此处的 0/1/2)。 + +**命令条数只取决于 (arch, cols),与 M/K/N 无关**——npu2_1col 恒为 35 条,npu1_4col 恒为 136 条。换 shape 只改字段值,不改结构。这对生成器是极有利的性质。 + +## 字段与 (M, K, N, tile) 的关系式 + +以 **npu2_1col、M=512、bf16→fp32** 为例,横向对比 K=N∈{384,512,768} 得出(三个 shape 全部吻合): + +| 字段 | 公式 | K=384 | K=512 | K=768 | +|---|---|---|---|---| +| BD0 (C, arg_idx=2) `len` | **M·N/4** | 49152 | 65536 | 98304 | +| BD0 `D1.stride` | **N** | 384 | 512 | 768 | +| BD0 `D0.size` | **tile_n** | 48 | 32 | 32 | +| BD1 (A, arg_idx=0) `len` | **M·K/8** | 24576 | 32768 | 49152 | +| BD1 `D1.stride` | **K/2**(bf16 每字打包 2 个) | 192 | 256 | 384 | +| BD3 `bufoff` | **M·K/4** | 98304 | 131072 | 196608 | +| QUEUE_PUSH `repeat` | **N/tile_n − 1** | 7 | 15 | 23 | + +`len` 的单位不是字节也不是字,而是 4 字的块(C 是 fp32:`M·N·4 字节 = M·N 字 = M·N/4 块`;A 是 bf16:`M·K·2 字节 = M·K/2 字 = M·K/8 块`)。 + +**结论:没有任何字段需要 IRON 的内部布局决策,全部可从 (M, K, N, tile) 推导。** 这是 M3 可行性的关键判据。 + +## 多列与两代架构 + +对 K=N=512 横向对比: + +| 列数 | 命令数 | C 的 BD `len` | 用到的 col | +|---|---|---|---| +| 1 | 35 | 65536 | 0 | +| 4 | 137 | 16384 = 65536/4 | 0, 1 | +| 8 | 225 | 8192 = 65536/8 | 0, 3 | + +**`len` 精确按列数等分**:`len = M·N/4/cols`,即每列负责 N/cols 的输出列块。A 的 BD 同理。 + +### ★ 命令体与架构无关 + +npu1 与 npu2 在**相同 (cols, M, K, N, tile)** 下命令体完全相同: + +- npu1_1col 与 npu2_1col:均 35 条,BD0 `len`=65536、BD1 `len`=32768,逐字段一致 +- npu1_4col 与 npu2_4col:均 137 条,首个 BD `len`=16384,一致 + +**两代架构的差异只在头部 w0 的 `gen` 字段(npu1=3、npu2=4)。** 生成器因此不需要为两代写两套逻辑,只需在头部填不同的 gen。 + +## ✅ 多列已解决(2026-08-13,本节推翻下面「关键障碍」一节) + +下面那节的统计是在**没有 chunk 结构认知**的前提下做的,把整条流按列计数、混进了 chunk 的重复,因而得出「每列命令数不对称、不可推导」的错误结论。重新分解后: + +| 列数 | 每 chunk 描述符数 | 构成 | +|---|---|---| +| 1 | 5 | 1×C + 2×A + 2×B | +| 4 | 20 | 4×C + 8×A + 8×B | +| 8 | 32 | 8×C + 8×A + 16×B | + +**唯一不可推导的东西只有「哪个描述符落在哪个物理 shim 列、按什么顺序」**——这是 placer 的输出。而它: + +- **只取决于列数**,与 M/K/N/tile 全部无关 +- **与架构无关**(npu1 与 npu2 的表逐字段相同) +- **与 dtype 无关**(bf16 与 bfp16 的表相同) + +所以把它按列数各存一张表就够了。`kernels/extract_layout.py` 从 golden 里提取并生成 `../sequence_layout.h`(1col 5 条、4col 20 条、8col 32 条,共 108 行),其余全部由 `(M,K,N,tile,cols)` 现场算出。 + +**每个角色的字段公式**(`cr = chunkRows`、`nA` = 表里 A 描述符个数、`sPerCol = N/(tileN·cols)`): + +``` +C: len=cr*N/2/cols D0=(tileN,1) D1=(cr/2,N) D2.stride=tileN*cols + iter=(2, cr*N/2) bufoff=chunk*cr*N*4 + slot*tileN*4 S2MM repeat=1 +A: len=cr*K/2/nA D0=(tileM,1) D1=(cr/nA,K/2) D2.stride=tileM + iter=(1,1) bufoff=chunk*cr*K*2 + slot*cr*K/cols +B: len=K*tileN/2 D0=(tileN/2,1) D1=(tileK,N/2) D2.stride=tileK*N/2 + iter=(sPerCol, tileN/2*cols) bufoff=slot*tileN*2(不随 chunk 前进) +MM2S repeat = sPerCol - 1 +``` + +**边界情形 `sPerCol == 1`**(每列正好一个输出 tile,如 8col + N=384/tileN=48):没有 strip 循环可跑了,IRON 把 chunk 的两个半程折进描述符本身—— +`C.len` 翻倍为 `cr*N/cols`、`D2.stride` 变成 `cr*N/2`、`iter=(1,1)`、S2MM `repeat=0`;同时 `B.iter` 的 stride 也归 1(一次迭代的循环没有步长)。两种编码搬运的字节数完全相同。 + +**WAIT_TCT 不需要单独的表**:它就是 C 描述符的 `(col, ch)` 按表内顺序、每 chunk 重复一遍,`w3 = (ch<<24) | 0x00010100`。发放节奏:chunk0 后 0 条、chunk1 后 2×cols 条、chunk≥2 后各 cols 条。 + +**BD 号**:chunk0 用集 A、chunk1 用集 B(两者重叠执行),chunk≥2 因为前面必有 wait,一律复用集 A。 + +### 验收 + +| 测试 | 结果 | +|---|---| +| 逐字节 vs golden | **35/35**(1/4/8 列 × npu1/npu2 × bf16/bfp16 × M∈{256,512,768,1024} × K∈{384,512,768} × N∈{256,384,512,768} × tileN∈{32,48}) | +| 硬件对拍(生成流,无 golden 的 shape) | **34/34 PASS**,maxAbsErr ≤ 1.2e-05;M 到 5888、N 到 2048 | + +约束:`N % (tileN*cols) == 0`。例如 N=1152 在 8col 下不合法(1152/256=4.5),生成器会明确拒绝,运行时降到 4col 或 1col 即可。 + +--- + +## ⛔ 关键障碍:多列指令流不可纯推导(**已被上一节推翻,保留作教训**) + +按 (列号, 命令类型) 统计 K=N=512: + +| 列数 | BLOCKWRITE | DDR_PATCH | QUEUE_PUSH | ISSUE_TOKEN | WAIT_TCT | 列号分布 | +|---|---|---|---|---|---|---| +| 1 | 10 | 10 | 10 | 2 | 2 | `{0:34}` | +| 4 | 40 | 40 | 40 | 8 | 8 | `{0:34, 1:44, 2:34, 3:24}` | +| 8 | 64 | 64 | 64 | 16 | 16 | `{0:12, 1:12, 2:34, 3:44, 4:44, 5:44, 6:34}` | + +`ISSUE_TOKEN = WAIT_TCT = 2 × cols`,这条干净。但另外两点不干净: + +1. **8 列的设计只用了 7 个列(0–6)**,不是 8 个;每列命令数完全不对称(12/12/34/44/44/44/34)。4 列同样不对称(34/44/34/24)。 +2. **BLOCKWRITE 每列数量不是常数**:1col=10、4col=10/列、8col=8/列。 + +这种不对称说明指令流**不是「按列重复同一段」**,而是 IRON 的 placer 给每列分配了不同角色(某列做广播源、某列只做搬运等)。要逐字节复现就得复现 placer 的启发式决策——**这就是「掺了 IRON 内部布局决策」的风险在多列上的兑现**。 + +**当时的结论(错误)**: +- 1 列:可纯推导 ✓ +- 多列:不可纯推导 ✗ 列角色分配不是 (M,K,N,tile,cols) 的函数 + +⚠️ **错在哪**:结论的后半句其实是对的——列角色分配确实不是 shape 的函数。错的是从这里跳到「所以多列不可生成」。它**是 cols 的函数**,一张 5/20/32 条的表就能钉死,其余全部可算。 + +**教训:区分「不可推导」和「不是所求参数的函数」。** 一个量只要维度足够低、取值足够少,列表化就等于解决。当时先按列做直方图、看到不对称就收手了,如果先按 chunk 分解再看,结构立刻是清楚的。 + +## ★★ M、N、K 的归属已实测分离(2026-08-13) + +| 维度 | 在 xclbin 里? | 判据 | +|---|---|---| +| **K** | **是** | K=512 的 xclbin 驱动 K=768 的 golden 流 → ERT=4 completed 但 maxAbsErr=56.1(静默错误)。xclbin 字节数只随 K 变:K=512→26056、K=768→28872,改 M 或 N 都不变 | +| **M** | 否 | 同一 xclbin 驱动 M=256 / M=768 的 golden 流 → PASS | +| **N** | 否 | 同一 xclbin 驱动 N=256 / N=768 的 golden 流 → PASS;反向用 K=768 的 xclbin 驱动 N=512 与 N=768 也都 PASS | + +**结论:xclbin 由 (器件, 列数, dtype, tile, K) 参数化。M 和 N 完全由指令流决定。** + +## ★ 指令流的 chunk 结构(M 自由的原因) + +以 `chunkRows = tileM × 4 × 2` 行 M 为一个 **chunk**(4 个 AIE 行,×2 是乒乓双缓冲),每 chunk 恒 **17 条命令 / 161 字**: + +``` +BLOCKWRITE BD(C) + DDR_PATCH(arg=C) + ISSUE_TOKEN + QUEUE_PUSH(S2MM) +2× [ BLOCKWRITE BD(A) + DDR_PATCH(arg=A) + QUEUE_PUSH(MM2S ch0) + BLOCKWRITE BD(B) + DDR_PATCH(arg=B) + QUEUE_PUSH(MM2S ch1) ] +WAIT_TCT ×1(但 golden 是每两个 chunk 攒着一起发两条) +``` + +- chunk 之间**除 DDR 偏移外逐字节相同**:实测 M=768 的 chunk0/chunk1 与 M=512 的完全一致 +- BD 号在偶/奇 chunk 间交替 `5*(c%2) + {0..4}`,所以 M 再大也不超过 shim tile 的 16 个 BD +- 命令总数 = 17 × M/chunkRows;字数 = 4 + 161 × M/chunkRows(实测 M=256/512/768 → 165/326/487 字) +- IRON 要求 `M % chunkRows == 0`(报错原文:`M/m/n_aie_rows must be even`) + +**每 chunk 的字段值(都不含总 M)**: +``` +C BD: len=chunkRows*N/2, D1=(chunkRows/2, N), iter=(2, len), bufoff=chunk*chunkRows*N*4 +A BD: len=chunkRows*K/4, D1=(chunkRows/2, K/2), iter=(1,1), bufoff=(2*chunk+half)*chunkRows*K +B BD: len=K*tileN/2, D1=(tileK, N/2), D2.stride=tileK*N/2, iter=(N/tileN, tileN/2), bufoff=0 +``` + +## ⛔ 被这个结构咬到的第二个 bug + +`sequence.cpp` 最初把 C/A 的字段写成 M 的函数(`lenC = M*N/4`、`D1.size = M/4`)。正确形式是上面的 chunk 常量。当时全部 golden 的 M 都是 512 = 2×chunkRows,两种写法**数值恰好相等**,9 个 golden 全过。 + +连同 B 的 `D1.stride` 被 K=N 掩盖那次,**同一类错误已经发生两次**。 + +⚠️ **规则:任何字段公式,必须用「该维度取至少两个不同值」的 golden 验证。** 单点验证等于没验证。 + +## ✅ 采纳方案(2026-08-13 实测后修订) + +**预编译只按 K 一维铺网格(quantum 64);M、N、列数全部由 `sequence.cpp` 现场生成。** + +K 可以零填充抬高(A 补零列、B 补零行),所以一维 K 网格能覆盖**任意**模型,硬约束 C3 完整达成,不需要任何降级。 + +被否决的:逆向 IRON 的 placer 的**启发式**(工作量大、脆弱、上游一改就崩)。实际做法是不逆向启发式,只把它对每个列数的**输出**列成表——上游若改了 placer,重跑 `extract_layout.py` 即可。 + +## 实现后的订正(`../sequence.cpp` 已按 golden 逐字节对齐,9/9 PASS) + +写生成器时发现上面几处推导有误,**以下为准**: + +1. **w1 的 num_cols 不是物理列数**。npu1_1col 的 w1 = `0x00000101`(num_cols=1),npu2_1col 才是 8。对 1 列生成按 golden 直接填:npu1→1、npu2→8。 +2. **A 的 BD `bufoff` = `M·K/2 × 序号`**(字节:0、M·K/2、M·K、3M·K/2),上表写的 `M·K/4` 漏算了 bf16 的 2 字节宽度。 +3. **「命令体与架构无关」有一个例外**:BLOCKWRITE 的 D1 字里有个 burst 常量,npu1 = `0x80000000`、npu2 = `0xC0000000`(D1 的 size/stride 本身仍然一致)。连同头部 gen,两代共 **2 处**差异。 + +## ✅ K≠N 歧义已用非方阵 golden 判定(2026-08-13) + +最初 9 个 golden 全部是 K=N 方阵,三个字段存在等价歧义。用 `M=512, K=384, N=768` 重新编一个 golden 后全部判定: + +| 字段 | 判定 | 被排除的候选 | +|---|---|---| +| B 的 `D1.stride` | **N/2**(=384) | K/2(=192) | +| B 的 `D2.stride` | **tileK·N/2**(=24576) | tileK·K/2 | +| C/A 的 `D1.size` | **M/4**(=128) | — | + +**这次验证抓到了一个真实 bug**:`sequence.cpp` 当时把 B 的 `D1.stride` 写成了 `K/2`,而 9 个方阵 golden 因为 K=N 全部通过,掩盖了错误。非方阵一测立刻在 4 个 B 的 BD 上暴露(4/326 个字不同)。 + +⚠️ **教训:只用方阵验证是不够的。** KataGo 的 attention 投影里 K≠N 是常态(如 QKV 合并投影 K=384、N=1152),这个 bug 若留到 M4 会让 NPU 静默算出错误的 policy 而不报错。今后新增任何字段公式,**必须同时用方阵和非方阵验证**。 + +## 当前验证状态 + +| 测试集 | 结果 | +|---|---| +| 9 个方阵 golden(bf16/npu1_1col、bf16/npu2_1col、bfp16/npu2_1col × 3 shape) | **9/9 逐字节一致** | +| 非方阵 M=512 K=384 N=768(npu2_1col bf16) | **逐字节一致** | + +测试程序:`C:\Temp\seqtest.cpp`(方阵集)、`C:\Temp\nsqtest.cpp`(非方阵)。非方阵 golden 由 +`gemm_bf16.compile_aot('npu2',1,'bf16',512,384,768,32,64,32,...)` 生成,冷编译 30.7 秒。 + +## 尚未验证的部分 + +- `iter`、`cache`、`lock` 在已对比样本里未变化,是否与 shape 相关未知。 +- 关系式表只用 bf16 推导,bfp16 变体未对比(预期只有 tile 几何不同,因为 BFP16 的微内核是 8×8×8 而非 4×8×8)。 +- 1 列情况下 BLOCKWRITE 恒为 10 条,与 M/K/N 无关——需确认更极端的 shape 是否仍然成立(BD 硬件上限是每 shim tile 16 个)。 + +## 下一步 + +1. 把上面的对比扩展到 4col / 8col 和 npu1,补全关系式 +2. 写 `../sequence.{h,cpp}`(命名空间 `RyzenAISequence`),C++17,只用标准库 +3. 对 `artifacts/` 下全部 24 个 golden 逐字节 `memcmp`——**这是唯一的验收标准** diff --git a/python/ryzenai_kernels/aiecc_cleanup.py b/python/ryzenai_kernels/aiecc_cleanup.py new file mode 100644 index 0000000000..f3654ef95b --- /dev/null +++ b/python/ryzenai_kernels/aiecc_cleanup.py @@ -0,0 +1,24 @@ +"""Remove the work directory aiecc leaves beside a compiled artifact. + +aiecc writes a .prj tree next to whatever --xclbin points at: MLIR at +several lowering stages, one ELF and one linker script per core, .ll files, a +.pdi. For a 32-core design that is a few thousand files and tens of megabytes, +and none of it is an input to anything afterwards - only the .xclbin and the +.insts.bin are. Left behind under cpp/external/ryzenai_artifacts it also gets +copied next to katago.exe by the build, which is how a deployed tree once ended +up carrying several hundred stray files. + +Keep it when a compile fails: the logs in there are the only record of why. +""" + +import shutil +from pathlib import Path + + +def clean(xclbin_path, keep=False): + """Delete the .prj beside xclbin_path. Returns what it removed, or None.""" + prj = Path(xclbin_path).with_suffix(".prj") + if keep or not prj.is_dir(): + return None + shutil.rmtree(prj, ignore_errors=True) + return prj if not prj.exists() else None diff --git a/python/ryzenai_kernels/build_attention.py b/python/ryzenai_kernels/build_attention.py new file mode 100644 index 0000000000..85ca188a34 --- /dev/null +++ b/python/ryzenai_kernels/build_attention.py @@ -0,0 +1,183 @@ +# build_attention.py - AOT-compile the fused single-head-per-core attention op. +# +# One attention block instance in one dispatch: each AIE core owns one head, +# keeps K/V resident (host pre-packs each head's K and V back to back, S -> 384 +# rows zero-padded), streams Q in 8-row blocks, and computes +# QK^T -> softmax -> P*V on-chip (f32 out). This replaces 3 dispatches +# (QK^T GEMM, softmax op, P*V GEMM) plus all the host marshaling between them +# with a single dispatch. +# +# A core tile has only two input DMA channels, so K and V travel as one +# packed buffer per head. +# +# Host ABI (opcode-3, like the GEMM/ops): +# arg3: Q [heads][384 x d] bf16, per-head contiguous, host-pre-tiled +# (mmul A-tile order per 8x32 chunk, pad rows zero), PRE-SCALED by +# 1/sqrt(d) -- the kernel applies no attention scale +# arg4: KV [heads][2 x 384 x d] bf16, per head: K then V, host-pre-tiled +# (mmul B-tile order), pad rows zero +# arg5: C [heads][384 x dv] f32, per-head contiguous, C-tile order +# (host un-tiles on readback) +# +# (heads == kv_heads for the models this was built for; GQA would need each +# core's KV tap aimed at its group head -- not implemented here.) +# +# No masking support: masked (smaller-than-geometry) boards must fall back to +# the staged path. RoPE is applied by the caller before packing. +# +# Usage (inside the iron env): +# python build_attention.py --heads 6 --s 361 --xclbin out.xclbin --insts out.insts.bin + +import argparse +import aiecc_cleanup +import time +from pathlib import Path + +import aie.iron as iron +import numpy as np +from aie.helpers.taplib import TensorTiler2D +from aie.iron import CompileTime, In, ObjectFifo, Out, Program, Runtime, Worker +from aie.iron.controlflow import range_ +from aie.iron.device import from_name +from aie.iron.kernel import ExternalFunction +from aie.utils import config +from ml_dtypes import bfloat16 + +KERNEL_CC = str(Path(__file__).parent / "kernels" / "attention_head.cc") + +Q_BLOCK = 8 # query rows per tile (L1 budget: KV resident + 8x384 scores) + + +@iron.jit(aiecc_flags=["--alloc-scheme=basic-sequential"]) +def attention( + q_in: In, + kv_in: In, + c_out: Out, + *, + s_pad: CompileTime[int], + heads: CompileTime[int], + d: CompileTime[int], + dv: CompileTime[int], + s_real: CompileTime[int], + heads_per_core: CompileTime[int], +): + n_cores = heads // heads_per_core # one core's heads are processed serially + q_blocks = s_pad // Q_BLOCK + + q_chunk_ty = np.ndarray[(Q_BLOCK, d), np.dtype[bfloat16]] + kv_head_ty = np.ndarray[(2 * s_pad, d), np.dtype[bfloat16]] # K then V + c_chunk_ty = np.ndarray[(Q_BLOCK, dv), np.dtype[np.float32]] + + q_ty = np.ndarray[(heads * s_pad, d), np.dtype[bfloat16]] + kv_ty = np.ndarray[(heads * 2 * s_pad, d), np.dtype[bfloat16]] + c_ty = np.ndarray[(heads * s_pad, dv), np.dtype[np.float32]] + + # Q's fifo elements are 8-row chunks; the runtime splits each head's + # (s_pad, d) strip tap into the 48 chunk transfers automatically. + of_q = [ObjectFifo(q_chunk_ty, name=f"q_{i}", depth=1) for i in range(n_cores)] + of_kv = [ObjectFifo(kv_head_ty, name=f"kv_{i}", depth=1) for i in range(n_cores)] + of_c = [ObjectFifo(c_chunk_ty, name=f"c_{i}", depth=1) for i in range(n_cores)] + + kern = ExternalFunction( + "attn_block_bf16", + source_file=KERNEL_CC, + arg_types=[ + np.ndarray[(Q_BLOCK, d), np.dtype[bfloat16]], + kv_head_ty, + c_chunk_ty, + ], + compile_flags=[f"-DATTN_S_REAL={s_real}"], + include_dirs=[config.cxx_header_path()], + ) + + # One head's K+V is resident at a time (two heads' would not fit in L1); + # with several heads per core they run one after another, the KV buffer + # released and refilled between them. + def core_fn(ofq, ofkv, ofc, k): + for _ in range_(heads_per_core): + ekv = ofkv.acquire(1) + for _ in range_(q_blocks): + eq = ofq.acquire(1) + eo = ofc.acquire(1) + k(eq, ekv, eo) + ofq.release(1) + ofc.release(1) + ofkv.release(1) + + workers = [ + Worker(core_fn, [of_q[i].cons(), of_kv[i].cons(), of_c[i].prod(), kern]) + for i in range(n_cores) + ] + + # Q/KV/C are all per-head contiguous flat taps. Q/K/V are pre-tiled by the + # host into the mmul tile order the stock template reads (see + # attention_head.cc's layout note); C comes back in C-tile order and the + # host un-tiles it. Core i handles heads [i*heads_per_core, +heads_per_core). + q_taps = TensorTiler2D.simple_tiler((heads * s_pad, d), (s_pad, d)) + kv_taps = TensorTiler2D.simple_tiler((heads * 2 * s_pad, d), (2 * s_pad, d)) + c_taps = TensorTiler2D.simple_tiler((heads * s_pad, dv), (s_pad, dv)) + + def sequence(q, kv, c, q_prods, kv_prods, c_conses): + for i in range(n_cores): + for j in range(heads_per_core): + kv_prods[i].fill(kv, kv_taps[i * heads_per_core + j]) + q_prods[i].fill(q, q_taps[i * heads_per_core + j]) + for i in range(n_cores): + for j in range(heads_per_core): + c_conses[i].drain(c, c_taps[i * heads_per_core + j], wait=True) + + rt = Runtime( + sequence, + [ + q_ty, + kv_ty, + c_ty, + [f.prod() for f in of_q], + [f.prod() for f in of_kv], + [f.cons() for f in of_c], + ], + ) + return Program(iron.get_current_device(), rt, workers=workers).resolve_program() + + +def main(): + p = argparse.ArgumentParser(prog="build_attention") + p.add_argument("--heads", type=int, required=True) + p.add_argument("--d", type=int, default=32, help="qHeadDim = vHeadDim") + p.add_argument("--s", type=int, default=361, help="real sequence length (board points)") + p.add_argument("--heads-per-core", type=int, default=1, + help="heads processed serially per core; >1 needed when heads " + "exceed the shim's DMA channel count (e.g. 12 heads -> 2 per core)") + p.add_argument("--xclbin", type=str, required=True) + p.add_argument("--insts", type=str, required=True) + p.add_argument("--keep-work", action="store_true", + help="keep the aiecc .prj work tree (only useful when debugging a compile)") + args = p.parse_args() + + s_pad = ((args.s + 31) // 32) * 32 # softmax vector width multiple + if s_pad % Q_BLOCK != 0: + p.error(f"padded S {s_pad} must be a multiple of Q_BLOCK {Q_BLOCK}") + if args.d != 32: + p.error("prototype hardcodes head dim 32 (score buffer sizing)") + if args.heads % args.heads_per_core != 0: + p.error("heads must be a multiple of heads-per-core") + + iron.set_current_device(from_name("npu2", n_cols=None)) + start = time.perf_counter() + spec = attention.specialize( + s_pad=s_pad, heads=args.heads, d=args.d, dv=args.d, s_real=args.s, + heads_per_core=args.heads_per_core, + ) + spec.compile(xclbin_path=args.xclbin, inst_path=args.insts) + # Only the .xclbin and .insts.bin are inputs to anything after this; the + # rest of what aiecc wrote is scratch. See aiecc_cleanup. + aiecc_cleanup.clean(args.xclbin, keep=args.keep_work) + secs = time.perf_counter() - start + print(f"attention h{args.heads} d{args.d} S{args.s}->{s_pad} " + f"({args.heads_per_core}/core) compiled in {secs:.1f}s") + print(f" -> {args.xclbin}") + print(f" -> {args.insts}") + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/build_bn_mish.py b/python/ryzenai_kernels/build_bn_mish.py new file mode 100644 index 0000000000..c470aed4f8 --- /dev/null +++ b/python/ryzenai_kernels/build_bn_mish.py @@ -0,0 +1,144 @@ +# build_bn_mish.py - AOT-compile the fused BatchNorm+Mish row op. +# +# out[r][c] = mish(scale[c] * x[r][c] + bias[c]), bf16 in/out, f32 internal. +# 8 columns x 1 core; rows are split across cores, the scale/bias vectors are +# replicated per core on the host (each core DMAs its own copy once per +# dispatch and holds it for all its rows). +# +# Host ABI (opcode-3): +# arg3: X [rows_pad x width] bf16 (pad rows zero) +# arg4: scale [8 x width] bf16 (replicated per core) +# arg5: bias [8 x width] bf16 (replicated per core) +# arg6: Y [rows_pad x width] bf16 +# +# Usage: +# python build_bn_mish.py --rows 384 --width 768 --xclbin out.xclbin --insts out.insts.bin + +import argparse +import aiecc_cleanup +import time +from pathlib import Path + +import aie.iron as iron +import numpy as np +from aie.helpers.taplib import TensorTiler2D +from aie.iron import CompileTime, In, ObjectFifo, Out, Program, Runtime, Worker +from aie.iron.controlflow import range_ +from aie.iron.device import from_name +from aie.iron.kernel import ExternalFunction +from aie.utils import config +from ml_dtypes import bfloat16 + +KERNEL_CC = str(Path(__file__).parent / "kernels" / "bn_mish.cc") + +N_CORES = 8 +CHUNK_ROWS = 4 # rows per fifo element + + +@iron.jit(aiecc_flags=["--alloc-scheme=basic-sequential"]) +def bn_mish( + x_in: In, + s_in: In, + b_in: In, + y_out: Out, + *, + rows: CompileTime[int], + width: CompileTime[int], + dumpmode: CompileTime[int] = 0, + n_cores: CompileTime[int], + chunk_rows: CompileTime[int], +): + rows_per_core = rows // n_cores + chunk_ty = np.ndarray[(chunk_rows, width), np.dtype[bfloat16]] + row_ty = np.ndarray[(width,), np.dtype[bfloat16]] # one param row + tensor_ty = np.ndarray[(rows, width), np.dtype[bfloat16]] + param_ty = np.ndarray[(n_cores, 2 * width), np.dtype[bfloat16]] + + sb_row_ty = np.ndarray[(2 * width,), np.dtype[bfloat16]] # [scale | bias] + + of_x = [ObjectFifo(chunk_ty, name=f"x_{i}", depth=2) for i in range(n_cores)] + of_sb = [ObjectFifo(sb_row_ty, name=f"sb_{i}", depth=1) for i in range(n_cores)] + of_y = [ObjectFifo(chunk_ty, name=f"y_{i}", depth=2) for i in range(n_cores)] + + kern = ExternalFunction( + "bn_mish_bf16", + source_file=KERNEL_CC, + arg_types=[chunk_ty, sb_row_ty, chunk_ty, np.int32, np.int32], + compile_flags=[f"-DBNM_DUMPMODE={dumpmode}"] + (["-DBNM_NOCLAMP"] if dumpmode == 3 else []), + include_dirs=[config.cxx_header_path()], + ) + + def core_fn(ofx, ofsb, ofy, k): + esb = ofsb.acquire(1) + for _ in range_(rows_per_core // chunk_rows): + ex = ofx.acquire(1) + ey = ofy.acquire(1) + k(ex, esb, ey, chunk_rows, width) + ofx.release(1) + ofy.release(1) + ofsb.release(1) + + workers = [ + Worker(core_fn, [of_x[i].cons(), of_sb[i].cons(), of_y[i].prod(), kern]) + for i in range(n_cores) + ] + + x_taps = TensorTiler2D.simple_tiler((rows, width), (rows_per_core, width)) + y_taps = TensorTiler2D.simple_tiler((rows, width), (rows_per_core, width)) + p_taps = TensorTiler2D.simple_tiler((n_cores, 2 * width), (1, 2 * width)) + + def sequence(x, sb, y, x_p, sb_p, y_c): + for i in range(n_cores): + sb_p[i].fill(sb, p_taps[i]) + for i in range(n_cores): + x_p[i].fill(x, x_taps[i]) + for i in range(n_cores): + y_c[i].drain(y, y_taps[i], wait=True) + + rt = Runtime( + sequence, + [ + tensor_ty, + param_ty, + tensor_ty, + [f.prod() for f in of_x], + [f.prod() for f in of_sb], + [f.cons() for f in of_y], + ], + ) + return Program(iron.get_current_device(), rt, workers=workers).resolve_program() + + +def main(): + p = argparse.ArgumentParser(prog="build_bn_mish") + p.add_argument("--rows", type=int, required=True, help="padded rows (multiple of 32)") + p.add_argument("--width", type=int, required=True, help="channels (multiple of 16)") + p.add_argument("--xclbin", type=str, required=True) + p.add_argument("--insts", type=str, required=True) + p.add_argument("--keep-work", action="store_true", + help="keep the aiecc .prj work tree (only useful when debugging a compile)") + p.add_argument("--dumpmode", type=int, default=0) + args = p.parse_args() + + if args.rows % (N_CORES * CHUNK_ROWS) != 0: + p.error(f"rows {args.rows} must be a multiple of {N_CORES * CHUNK_ROWS}") + if args.width % 16 != 0: + p.error("width must be a multiple of 16") + + iron.set_current_device(from_name("npu2", n_cols=None)) + start = time.perf_counter() + spec = bn_mish.specialize( + rows=args.rows, width=args.width, n_cores=N_CORES, chunk_rows=CHUNK_ROWS, + dumpmode=args.dumpmode, + ) + spec.compile(xclbin_path=args.xclbin, inst_path=args.insts) + # Only the .xclbin and .insts.bin are inputs to anything after this; the + # rest of what aiecc wrote is scratch. See aiecc_cleanup. + aiecc_cleanup.clean(args.xclbin, keep=args.keep_work) + print(f"bn_mish [{args.rows}x{args.width}] compiled in {time.perf_counter()-start:.1f}s") + print(f" -> {args.xclbin}") + print(f" -> {args.insts}") + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/build_grid.py b/python/ryzenai_kernels/build_grid.py new file mode 100644 index 0000000000..50fa6c209f --- /dev/null +++ b/python/ryzenai_kernels/build_grid.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python3 +"""Compile the artifact grid. + +An .xclbin bakes in the reduction dim K and nothing else -- M and N ride in the +instruction stream, which sequence.cpp generates at run time (see +INSTS_FORMAT.md for the measurements). So the grid is one dimensional: one +binary per (dtype, arch, columns, K), named for the K alone. + +Each entry is compiled at a canonical (M, N); which one is irrelevant to the +resulting binary, it only has to be legal for the design. + +Must be run inside the activated mlir-aie iron environment, with XRT on PATH so +that aiecc can find xclbinutil: + + set PATH=%LOCALAPPDATA%\\..\\mlir_aie\\bin;C:\\Xilinx\\XRT;%PATH% + python build_grid.py --dtype bf16 --arch npu2 + +Run with --list to see what would be built without building it. +""" + +import argparse +import hashlib +import json +import shutil +import sys +import tempfile +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent)) + +ARTIFACTS = Path(__file__).parent.parent.parent / "cpp" / "external" / "ryzenai_artifacts" + +# K values the four shipped models need, from RyzenAIShapes::report. K is a +# multiple of 64 for every one of them except the initial 3x3 convolution +# (9*22 = 198), which pads up into 256. +# +# b10c384h6 192 384 512 +# b10c512h8 256 512 768 +# b11c768h12 384 768 1152 +# b40c768 384 768 2304 3456 (2304 = 9*256, 3456 = 9*384) +# +# Anything not listed still runs: the loader picks the smallest K above it and +# the caller zero-pads. That is what makes an arbitrary model work without a +# toolchain, at the price of some wasted multiply-accumulates. +MODEL_K = [192, 256, 384, 512, 768, 1152, 2304, 3456] + +# A denser sweep for coverage of models we have never seen. 64 is the tile size, +# so it is the finest grid the design can express. +def sweep_k(lo, hi, step=64): + return list(range(lo, hi + 1, step)) + +ARCH_COLS = {"npu1": [1, 2, 4], "npu2": [1, 2, 4, 8]} + +TILE_M, TILE_K, TILE_N = 32, 64, 32 + + +def canonical_shape(cols): + """A legal (M, N) to compile at. The binary does not depend on either.""" + m = TILE_M * 8 # one chunk + n = TILE_N * cols * 2 # two output strips per column + return m, n + + +def sha256(path): + return hashlib.sha256(Path(path).read_bytes()).hexdigest() + + +def scan_artifacts(): + """Every gemm grid xclbin on disk, as index entries. + + Recovers (dtype, arch, cols, K) from the path, which is the only thing the + loader keys on. compiled_at cannot be recovered and is reported as null -- + it is provenance, and the note in the index already says it constrains + nothing. + """ + entries = [] + for xclbin in sorted(ARTIFACTS.glob("*/*col/gemm_bf16_K*.xclbin")): + variant = xclbin.parent.name # "npu2_4col" + arch, _, cols = variant.rpartition("_") + insts = xclbin.with_suffix("").with_suffix(".insts.bin") + entries.append({ + "dtype": xclbin.parent.parent.name, + "arch": arch, + "n_aie_cols": int(cols[:-3]), + "K": int(xclbin.stem.split("_K")[1]), + "compiled_at": None, + "tile": {"m": TILE_M, "k": TILE_K, "n": TILE_N}, + "xclbin": str(xclbin.relative_to(ARTIFACTS)).replace("\\", "/"), + "xclbin_bytes": xclbin.stat().st_size, + "xclbin_sha256": sha256(xclbin), + "insts_golden": str(insts.relative_to(ARTIFACTS)).replace("\\", "/"), + }) + if not insts.exists(): + print("warning: %s has no .insts.bin beside it" % xclbin.name) + return entries + + +def build(dtypes, arches, ks, dry_run): + # Imported here, not at module scope, so that --reindex (which only reads + # the files already on disk) works outside the mlir-aie iron environment. + import gemm_bf16 + + jobs = [] + for dtype in dtypes: + for arch in arches: + if dtype == "bfp16" and arch != "npu2": + continue # BFP16 is an XDNA2-only micro-kernel + for cols in ARCH_COLS[arch]: + for k in ks: + jobs.append((dtype, arch, cols, k)) + + print("%d artifact(s) to build" % len(jobs)) + if dry_run: + for dtype, arch, cols, k in jobs: + print(" %-5s %-4s %dcol K=%d" % (dtype, arch, cols, k)) + return + + entries = [] + total = 0.0 + for i, (dtype, arch, cols, k) in enumerate(jobs): + subdir = ARTIFACTS / dtype / ("%s_%dcol" % (arch, cols)) + subdir.mkdir(parents=True, exist_ok=True) + xclbin = subdir / ("gemm_bf16_K%d.xclbin" % k) + insts = subdir / ("gemm_bf16_K%d.insts.bin" % k) + m, n = canonical_shape(cols) + + if xclbin.exists(): + print("[%3d/%3d] %-5s %-4s %dcol K=%-5d already present" % + (i + 1, len(jobs), dtype, arch, cols, k)) + else: + # aiecc drops a .prj work directory beside its output, so compile + # into a scratch dir and move only the two files worth keeping. + try: + with tempfile.TemporaryDirectory(prefix="ryzenai_grid_") as work: + tmp_x = Path(work) / xclbin.name + tmp_i = Path(work) / insts.name + secs = gemm_bf16.compile_aot( + arch, cols, dtype, m, k, n, TILE_M, TILE_K, TILE_N, str(tmp_x), str(tmp_i)) + shutil.move(str(tmp_x), str(xclbin)) + shutil.move(str(tmp_i), str(insts)) + except Exception as e: + print("[%3d/%3d] %-5s %-4s %dcol K=%-5d FAILED: %s" % + (i + 1, len(jobs), dtype, arch, cols, k, e)) + continue + total += secs + print("[%3d/%3d] %-5s %-4s %dcol K=%-5d %5.1fs %7d B" % + (i + 1, len(jobs), dtype, arch, cols, k, secs, xclbin.stat().st_size)) + + entries.append({ + "dtype": dtype, + "arch": arch, + "n_aie_cols": cols, + "K": k, + "compiled_at": {"M": m, "N": n}, + "tile": {"m": TILE_M, "k": TILE_K, "n": TILE_N}, + "xclbin": str(xclbin.relative_to(ARTIFACTS)).replace("\\", "/"), + "xclbin_bytes": xclbin.stat().st_size, + "xclbin_sha256": sha256(xclbin), + "insts_golden": str(insts.relative_to(ARTIFACTS)).replace("\\", "/"), + }) + + write_index(entries) + print("(%.1f s of compiling)" % total) + + +def write_index(entries, replace=False): + """Update grid.json. + + Merges into whatever is already on disk rather than replacing it: the grid + is normally filled in over several invocations (one per dtype or K range), + and a plain overwrite left grid.json describing only the last batch while + the earlier xclbins sat there unlisted. Pass replace=True (--reindex) to + make the index exactly the set of entries handed in. + """ + grid_path = ARTIFACTS / "grid.json" + key = lambda e: (e["dtype"], e["arch"], e["n_aie_cols"], e["K"]) + merged = {} + if grid_path.exists() and not replace: + try: + for e in json.loads(grid_path.read_text()).get("artifacts", []): + merged[key(e)] = e + except (ValueError, KeyError) as e: + print("warning: ignoring unreadable %s (%s)" % (grid_path, e)) + from_disk = len(merged) + for e in entries: + merged[key(e)] = e # the caller wins on collision + out = [merged[k] for k in sorted(merged)] + + grid_path.write_text(json.dumps({ + "grid_version": 1, + "generated_by": "python/ryzenai_kernels/build_grid.py", + "note": ("An xclbin depends only on (dtype, arch, n_aie_cols, K, tile). " + "M and N are carried by the instruction stream, which " + "sequence.cpp generates at run time, so compiled_at is " + "provenance only and imposes no constraint on dispatch."), + "artifacts": out, + }, indent=1)) + print("wrote %s: %d entries (%d supplied, %d carried over)" + % (grid_path, len(out), len(entries), from_disk)) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--dtype", action="append", choices=["bf16", "bfp16"]) + ap.add_argument("--arch", action="append", choices=["npu1", "npu2"]) + ap.add_argument("--k", action="append", type=int, help="explicit K (repeatable)") + ap.add_argument("--sweep", nargs=2, type=int, metavar=("LO", "HI"), + help="dense 64-step K sweep instead of the model list") + ap.add_argument("--list", action="store_true") + ap.add_argument("--reindex", action="store_true", + help="rebuild grid.json from the xclbins on disk, compiling nothing") + args = ap.parse_args() + + if args.reindex: + write_index(scan_artifacts(), replace=True) + return + + ks = args.k if args.k else (sweep_k(*args.sweep) if args.sweep else MODEL_K) + build(args.dtype or ["bf16"], args.arch or ["npu2"], sorted(set(ks)), args.list) + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/build_softmax.py b/python/ryzenai_kernels/build_softmax.py new file mode 100644 index 0000000000..13a7005b48 --- /dev/null +++ b/python/ryzenai_kernels/build_softmax.py @@ -0,0 +1,128 @@ +# build_softmax.py - AOT-compile the row-wise bf16 softmax op for one shape. +# +# The op computes softmax over each row of a [rows x width] bf16 matrix on +# npu2, 8 columns x 1 core. Width must be a multiple of 32; rows must be a +# multiple of n_cores*chunk_rows (64). The host pads: +# - pad columns with -1e30 (exp underflows to 0: no effect on the row sum) +# - pad rows with 0 (uniform softmax output, discarded) +# Masked-out columns (KataGo's board mask) are likewise written as -1e30 by +# the host, so the kernel needs no mask input. +# +# Origin: adapted from the softmax_bench.py left by the kernel prototyping +# session; that script's JIT path is dead on this mlir-aie version +# (iron.tensor(device="npu") is unsupported), only its AOT path is kept here. +# +# Usage (inside the iron env, see ../README or environment.md): +# python build_softmax.py --rows 2176 --width 384 \ +# --xclbin out.xclbin --insts out.insts.bin + +import argparse +import aiecc_cleanup +import time +from pathlib import Path + +import aie.iron as iron +import numpy as np +from aie.helpers.taplib import TensorTiler2D +from aie.iron import CompileTime, In, ObjectFifo, Out, Program, Runtime, Worker +from aie.iron.controlflow import range_ +from aie.iron.device import from_name +from aie.iron.kernel import ExternalFunction +from aie.utils import config +from ml_dtypes import bfloat16 + +KERNEL_CC = str(Path(__file__).parent / "kernels" / "softmax_rows.cc") + +N_CORES = 8 # 8 columns, one core each +CHUNK_ROWS = 8 # rows per fifo element (8*384*2 B = 6 KiB) + + +@iron.jit(aiecc_flags=["--alloc-scheme=basic-sequential"]) +def softmax_rows( + a_in: In, + b_out: Out, + *, + rows: CompileTime[int], + width: CompileTime[int], + chunk_rows: CompileTime[int], + n_cores: CompileTime[int], +): + rows_per_core = rows // n_cores + chunk_ty = np.ndarray[(chunk_rows, width), np.dtype[bfloat16]] + tensor_ty = np.ndarray[(rows, width), np.dtype[bfloat16]] + + of_ins = [ObjectFifo(chunk_ty, name=f"in_{i}", depth=2) for i in range(n_cores)] + of_outs = [ObjectFifo(chunk_ty, name=f"out_{i}", depth=2) for i in range(n_cores)] + + kern = ExternalFunction( + "softmax_rows_bf16", + source_file=KERNEL_CC, + arg_types=[chunk_ty, chunk_ty, np.int32, np.int32], + include_dirs=[config.cxx_header_path()], + ) + + def core_fn(of_in, of_out, k): + for _ in range_(rows_per_core // chunk_rows): + ei = of_in.acquire(1) + eo = of_out.acquire(1) + k(ei, eo, chunk_rows, width) + of_in.release(1) + of_out.release(1) + + workers = [ + Worker(core_fn, [of_ins[i].cons(), of_outs[i].prod(), kern]) + for i in range(n_cores) + ] + + taps = TensorTiler2D.simple_tiler((rows, width), (rows_per_core, width)) + + def sequence(a, b, in_prods, out_conses): + for i in range(n_cores): + in_prods[i].fill(a, taps[i]) + for i in range(n_cores): + out_conses[i].drain(b, taps[i], wait=True) + + rt = Runtime( + sequence, + [ + tensor_ty, + tensor_ty, + [of_ins[i].prod() for i in range(n_cores)], + [of_outs[i].cons() for i in range(n_cores)], + ], + ) + return Program(iron.get_current_device(), rt, workers=workers).resolve_program() + + +def main(): + p = argparse.ArgumentParser(prog="build_softmax") + p.add_argument("--rows", type=int, required=True, help="padded row count (multiple of 64)") + p.add_argument("--width", type=int, required=True, help="padded width (multiple of 32)") + p.add_argument("--xclbin", type=str, required=True) + p.add_argument("--insts", type=str, required=True) + p.add_argument("--keep-work", action="store_true", + help="keep the aiecc .prj work tree (only useful when debugging a compile)") + args = p.parse_args() + + if args.rows % (N_CORES * CHUNK_ROWS) != 0: + p.error(f"rows {args.rows} must be a multiple of {N_CORES * CHUNK_ROWS}") + if args.width % 32 != 0: + p.error(f"width {args.width} must be a multiple of 32") + + iron.set_current_device(from_name("npu2", n_cols=None)) + start = time.perf_counter() + spec = softmax_rows.specialize( + rows=args.rows, width=args.width, chunk_rows=CHUNK_ROWS, n_cores=N_CORES + ) + spec.compile(xclbin_path=args.xclbin, inst_path=args.insts) + # Only the .xclbin and .insts.bin are inputs to anything after this; the + # rest of what aiecc wrote is scratch. See aiecc_cleanup. + aiecc_cleanup.clean(args.xclbin, keep=args.keep_work) + secs = time.perf_counter() - start + print(f"softmax [{args.rows}x{args.width}] npu2 {N_CORES}col compiled in {secs:.1f}s") + print(f" -> {args.xclbin}") + print(f" -> {args.insts}") + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/build_swiglu_grid.py b/python/ryzenai_kernels/build_swiglu_grid.py new file mode 100644 index 0000000000..c83d1f1f44 --- /dev/null +++ b/python/ryzenai_kernels/build_swiglu_grid.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""Compile the SwiGLU-epilogue GEMM artifacts. + +Companion to build_grid.py: one gemm_swiglu_bf16_K binary per (arch, cols, +K), into bf16/_col_swiglu/. The binary bakes in only K, exactly +like the plain GEMM; M/N ride in the runtime-generated instruction stream. + +Only the Ks the shipped transformer models' FFN blocks actually use (after the +forceK collapse, see RyzenAIShapes::chooseSingleK) get artifacts; any other +model falls back to the plain fused GEMM + CPU SwiGLU, which is always +correct. SwiGLU is a no-op win, never a requirement. + +Must be run inside the activated mlir-aie iron environment with XRT on PATH. +""" + +import argparse +import shutil +import sys +import tempfile +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent)) +import gemm_swiglu_bf16 + +ARTIFACTS = Path(__file__).parent.parent.parent / "cpp" / "external" / "ryzenai_artifacts" + +# forceK-collapsed FFN reduction dims: b10c384h6 -> 512 (inC 192), +# b10c512h8 -> 768 (inC 256), b11c768h12 -> 1152 (inC 384). b40c768 has no FFN. +MODEL_K = [512, 768, 1152] + +TILE_M, TILE_K, TILE_N = 32, 64, 32 + + +def main(): + ap = argparse.ArgumentParser(prog="build_swiglu_grid") + ap.add_argument("--arch", choices=["npu2"], default="npu2") + ap.add_argument("--cols", type=int, nargs="*", default=[1, 2, 4]) + ap.add_argument("--k", type=int, nargs="*", default=MODEL_K) + args = ap.parse_args() + + jobs = [(c, k) for c in sorted(args.cols) for k in sorted(args.k)] + print("%d swiglu artifact(s) to build" % len(jobs)) + total = 0.0 + for i, (cols, k) in enumerate(jobs): + subdir = ARTIFACTS / "bf16" / ("%s_%dcol_swiglu" % (args.arch, cols)) + subdir.mkdir(parents=True, exist_ok=True) + xclbin = subdir / ("gemm_swiglu_bf16_K%d.xclbin" % k) + insts = subdir / ("gemm_swiglu_bf16_K%d.insts.bin" % k) + if xclbin.exists(): + print("[%d/%d] %dcol K=%d already present" % (i + 1, len(jobs), cols, k)) + continue + m = TILE_M * 8 + n = TILE_N * cols * 2 + try: + with tempfile.TemporaryDirectory(prefix="ryzenai_swg_") as work: + tmp_x = Path(work) / xclbin.name + tmp_i = Path(work) / insts.name + secs = gemm_swiglu_bf16.compile_aot( + args.arch, cols, m, k, n, TILE_M, TILE_K, TILE_N, + str(tmp_x), str(tmp_i)) + shutil.move(str(tmp_x), str(xclbin)) + shutil.move(str(tmp_i), str(insts)) + except Exception as e: + print("[%d/%d] %dcol K=%d FAILED: %s" % (i + 1, len(jobs), cols, k, e)) + continue + total += secs + print("[%d/%d] %dcol K=%d %.1fs %d B" % + (i + 1, len(jobs), cols, k, secs, xclbin.stat().st_size)) + print("done (%.1f s of compiling)" % total) + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/extract_layout.py b/python/ryzenai_kernels/extract_layout.py new file mode 100644 index 0000000000..7f015795d3 --- /dev/null +++ b/python/ryzenai_kernels/extract_layout.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +"""Extract the per-column-count command layout from golden instruction streams. + +Everything in a stream except one thing is a closed-form function of +(M, K, N, tiles, cols) -- see INSTS_FORMAT.md. The exception is which physical +shim column each buffer descriptor lands on and in what order, which is IRON's +placer output. That layout turns out to depend only on `cols`, so it can be +extracted once and compiled into sequence.cpp as a small table. + +This script decodes chunk 0 of a golden, resolves every DDR offset into an +integer slot index against the shape-derived unit, and emits sequence_layout.h. + +The goldens it reads must have at least two M-chunks (M >= 2*tileM*8), since +that is what exposes the alternating buffer-descriptor sets. The shipped grid is +compiled at one chunk, so compile dedicated ones first: + + gemm_bf16.compile_aot("npu2", cols, "bf16", 512, 512, 64*cols, 32, 64, 32, ...) + +Run only when adding a new column count: + python extract_layout.py --dir > ../sequence_layout.h +""" + +import argparse +import re +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent)) +import parse_insts as P + +ART = Path(__file__).parent.parent.parent / "cpp" / "external" / "ryzenai_artifacts" + +# One golden per column count is enough: the layout was verified identical +# between npu1 and npu2 and between bf16 and bfp16, and every numeric field is +# recomputed from the shape, so only the placer's ordering is captured here. +COLUMN_COUNTS = [1, 2, 4, 8] +GOLDEN_M, GOLDEN_K = 512, 512 +TILE_M, TILE_K, TILE_N = 32, 64, 32 + +AIE_ROWS = 4 + + +def decode_cmds(path): + return P.decode(P.u32s(Path(path).read_bytes()))[1][1:] + + +def chunk_starts(cmds, chunkCBytes): + starts = [] + for i, l in enumerate(cmds): + m = re.search(r"arg_idx=2 arg_off=(\d+)", l) + if m and int(m.group(1)) % chunkCBytes == 0 and int(m.group(1)) // chunkCBytes == len(starts): + starts.append(i - 1) # the BLOCKWRITE precedes its DDR_PATCH + starts.append(len(cmds)) + return starts + + +def field(line, pat, cast=int): + m = re.search(pat, line) + return cast(m.group(1)) if m else None + + +def extract(name, cols, path, M, K, N, tm, tk, tn): + cmds = decode_cmds(path) + chunkRows = tm * AIE_ROWS * 2 + chunkCBytes = chunkRows * N * 4 + starts = chunk_starts(cmds, chunkCBytes) + if len(starts) < 3: + raise SystemExit("%s: need a golden with at least 2 chunks" % name) + + # Units the DDR offsets are multiples of, derived from the shape. + unitC = tn * 4 # C strips advance one tile of float32 + unitA = chunkRows * K * 2 // (2 * cols) # A slices split the chunk's rows + unitB = tn * 4 // 2 # B panels advance one tile of bfloat16 + + steps = [] + i = starts[0] + while i < starts[1]: + line = cmds[i] + assert "BLOCKWRITE" in line, line + col = field(line, r"col=(\d+)") + bdA = field(line, r"bd=(\d+)") + patch = cmds[i + 1] + assert "DDR_PATCH" in patch, patch + arg = field(patch, r"arg_idx=(\d+)") + off = field(patch, r"arg_off=(\d+)") + role = "C" if arg == 2 else ("A" if arg == 0 else "B") + unit = {"C": unitC, "A": unitA, "B": unitB}[role] + assert off % unit == 0, (name, role, off, unit) + j = i + 2 + token = "ISSUE_TOKEN" in cmds[j] + if token: + j += 1 + push = cmds[j] + assert "QUEUE_PUSH" in push, push + chan = field(push, r"ch=(\d+)") + mm2s = "MM2S" in push + steps.append(dict(col=col, role=role, slot=off // unit, bdA=bdA, + chan=chan, mm2s=mm2s, token=token)) + i = j + 1 + + # Second chunk uses a disjoint BD set; chunks 2+ go back to set A. + bdB = [] + i = starts[1] + while i < starts[2] and len(bdB) < len(steps): + if "BLOCKWRITE" in cmds[i]: + bdB.append(field(cmds[i], r"bd=(\d+)")) + i += 1 + assert len(bdB) == len(steps), (name, len(bdB), len(steps)) + for s, b in zip(steps, bdB): + s["bdB"] = b + + waits = [(field(l, r"col=(\d+)"), field(l, r"ch=(\d+)"), "MM2S" in l, field(l, r"w3=0x([0-9a-f]+)", lambda s: int(s, 16))) + for l in cmds if "WAIT_TCT" in l] + return steps, waits + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--dir", required=True, help="directory of npu2_col.insts.bin goldens") + args = ap.parse_args() + global golden_dir + golden_dir = Path(args.dir) + + out = [] + out.append("// Generated by kernels/extract_layout.py -- do not edit by hand.") + out.append("//") + out.append("// IRON's placer decides which shim column each buffer descriptor lands on") + out.append("// and in what order. That decision depends only on the column count, not on") + out.append("// M/K/N, so it is captured here once per column count and every numeric field") + out.append("// is computed from the shape at run time. See kernels/INSTS_FORMAT.md.") + out.append("") + out.append("#ifndef NEURALNET_RYZENAI_SEQUENCE_LAYOUT_H_") + out.append("#define NEURALNET_RYZENAI_SEQUENCE_LAYOUT_H_") + out.append("") + out.append("#include ") + out.append("") + out.append("namespace RyzenAISequence {") + out.append("") + out.append("enum class Role : uint8_t { C = 0, A = 1, B = 2 };") + out.append("") + out.append("struct Step {") + out.append(" uint8_t col; // physical shim column") + out.append(" Role role; // which kernel argument this descriptor feeds") + out.append(" uint8_t slot; // index into that role's DDR partition") + out.append(" uint8_t bdA; // buffer descriptor id on even-numbered chunk sets") + out.append(" uint8_t bdB; // ... and on chunk 1, which double-buffers against set A") + out.append(" uint8_t chan; // DMA channel the queue push targets") + out.append(" bool mm2s; // true = host->array, false = array->host") + out.append(" bool token; // emit an ISSUE_TOKEN before the queue push") + out.append("};") + out.append("") + + names = [] + for cols in COLUMN_COUNTS: + name = "%dCOL" % cols + path = golden_dir / ("npu2_%dcol.insts.bin" % cols) + if not path.exists(): + raise SystemExit("missing golden %s" % path) + steps, waits = extract( + name, cols, path, GOLDEN_M, GOLDEN_K, TILE_N * 2 * cols, TILE_M, TILE_K, TILE_N) + # The WAIT_TCT list is exactly the C descriptors' (col, channel) repeated + # once per chunk, so it needs no table of its own -- assert that here + # rather than emitting redundant data. + cwait = [(s["col"], s["chan"], False) for s in steps if s["role"] == "C"] + for c in range(len(waits) // len(cwait)): + got = [(w[0], w[1], w[2]) for w in waits[c * len(cwait):(c + 1) * len(cwait)]] + assert got == cwait, (name, c, got, cwait) + names.append((name, cols, len(steps))) + out.append("// %d column(s): %d descriptors per chunk" % (cols, len(steps))) + out.append("static const Step LAYOUT_%s[] = {" % name) + for s in steps: + out.append(" {%d, Role::%s, %2d, %2d, %2d, %d, %-5s, %-5s}," + % (s["col"], s["role"], s["slot"], s["bdA"], s["bdB"], s["chan"], + "true" if s["mm2s"] else "false", + "true" if s["token"] else "false")) + out.append("};") + out.append("") + + out.append("struct Layout { int cols; const Step* steps; int numSteps; };") + out.append("") + out.append("static const Layout LAYOUTS[] = {") + for name, cols, n in names: + out.append(" {%d, LAYOUT_%s, %d}," % (cols, name, n)) + out.append("};") + out.append("static const int NUM_LAYOUTS = %d;" % len(names)) + out.append("") + out.append("} // namespace RyzenAISequence") + out.append("") + out.append("#endif // NEURALNET_RYZENAI_SEQUENCE_LAYOUT_H_") + print("\n".join(out)) + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/gemm_bf16.py b/python/ryzenai_kernels/gemm_bf16.py new file mode 100644 index 0000000000..fd9af81dca --- /dev/null +++ b/python/ryzenai_kernels/gemm_bf16.py @@ -0,0 +1,672 @@ +# gemm_bf16.py +# +# Multi-core (whole-array) bf16 x bf16 -> fp32 GEMM, AOT-compiled for AMD +# Ryzen AI NPUs: XDNA1 / AIE2 / mlir-aie `npu` (Phoenix/Hawk Point, 4 cols) +# and XDNA2 / AIE2P / mlir-aie `npu2` (Strix/Krackan, 8 cols). +# +# Derived from mlir-aie's +# programming_examples/basic/matrix_multiplication/whole_array/whole_array.py +# (see that file for the design's own documentation). KataGo-specific +# changes: +# * dtypes are fixed to bfloat16 inputs / float32 output (bf16 multiply, +# fp32 accumulate) — the host ABI is unchanged from the previous +# single-core design (plain row-major A/B/C host buffers, same XRT +# dispatch), only the on-chip tiling is parameterized; +# * `--dtype bfp16` selects AIE2P's BFP16-emulated bf16 MMUL +# (`emulate_bf16_mmul_with_bfp16`, mac_dims (8,8,8) instead of (4,8,8)); +# ignored on AIE2, where the flag is not supported; +# * the shape/tile geometry is fully parameterized (arch, n_aie_cols, +# M/K/N, m/k/n) so build_kernels.py can emit the whole artifact matrix. +# +# Tile/DMA constraints (enforced by validate_shape, mirroring the template): +# * M % (m * n_aie_rows) == 0 (n_aie_rows = 4) +# * M / (m * n_aie_rows) must be EVEN (transfer-block ping-pong pairing; +# odd counts fail in TensorTiler2D) +# * K % k == 0 +# * N % (n * n_aie_cols) == 0 +# * (m, k, n) % (r, s, t) == 0 (mac_dims of the MMUL kernel: +# (4,8,8) aie2p bf16, (8,8,8) aie2p +# bfp16-emulated, (4,8,4) aie2) +# * core-local memory 64 KiB: depth-2 A/B tiles + depth-2 C tile + stack +# (0xD00) must fit — rules out e.g. m=k=n=64 with fp32 C. +# +# Host ABI for the pure C++ + XRT loader (see artifacts/manifest.json): +# xrt::kernel(hw_context, "MLIR_AIE") +# arg 0 : uint32 opcode = 3 +# arg 1 : xrt::bo instruction buffer, XCL_BO_FLAGS_CACHEABLE, kernel.group_id(1) +# arg 2 : uint32 n_instr (instruction words, insts_bytes / 4) +# arg 3 : A — M*K bfloat16, row-major, contiguous (XRT_BO_FLAGS_HOST_ONLY, group_id(3)) +# arg 4 : B — K*N bfloat16, row-major, contiguous (XRT_BO_FLAGS_HOST_ONLY, group_id(4)) +# arg 5 : C — M*N float32, row-major, contiguous (XRT_BO_FLAGS_HOST_ONLY, group_id(5)) +# +# Usage (inside the activated mlir-aie iron environment): +# python gemm_bf16.py -M 512 -K 512 -N 512 -m 32 -k 64 -n 32 \ +# --arch npu2 --n-aie-cols 8 --dtype bf16 # compile + run + verify +# python gemm_bf16.py ... --xclbin-path out.xclbin --insts-path out.insts.bin +# # AOT compile only + +import argparse +import time + +import aie.iron as iron +import numpy as np +from aie.helpers.taplib import TensorTiler2D +from aie.iron import ( + CompileTime, + In, + ObjectFifo, + Out, + Program, + Runtime, + StreamDims, + TaskGroup, + Worker, + kernels, + str_to_dtype, +) +from aie.iron.controlflow import range_ +from aie.iron.device import NPU2, from_name +from aie.utils.benchmark import run_iters +from ml_dtypes import bfloat16 + +# --------------------------------------------------------------------------- +# Target configuration +# --------------------------------------------------------------------------- + +# arch name -> (iron device name, aiecc arch, human description, max columns) +ARCHES = { + "npu1": ("npu", "aie2", "XDNA1 (Ryzen AI Phoenix/Hawk Point)", 4), + "npu2": ("npu2", "aie2p", "XDNA2 (Ryzen AI Strix/Krackan)", 8), +} + +N_AIE_ROWS = 4 # compute rows on both generations (mem/shim rows not counted) + +# Host ABI dtypes (fixed): bf16 in, fp32 out/accumulate. +INPUT_DTYPE = bfloat16 +OUTPUT_DTYPE = np.float32 +DTYPE_IN_STR = "bf16" +DTYPE_OUT_STR = "f32" + +# Default tile geometry measured on Strix (see artifacts/manifest.json +# "tile_selection" notes written by build_kernels.py). +DEFAULT_TILE = {"m": 32, "k": 64, "n": 32} + + +def _device_for(arch: str, n_aie_cols: int): + """Iron device for (arch, cols). + + On npu1 pick the matching ColN variant (or the full NPU1 when cols == 4). + On npu2 use the unrestricted device regardless of cols so the placer has + the full 8-column array. + """ + dev_str = ARCHES[arch][0] + return from_name(dev_str, n_cols=n_aie_cols if dev_str == "npu" else None) + + +def set_target_device(arch: str, n_aie_cols: int): + """Explicitly bind the target device for codegen and kernel selection.""" + iron.set_current_device(_device_for(arch, n_aie_cols)) + + +def validate_shape( + arch: str, n_aie_cols: int, M: int, K: int, N: int, m: int, k: int, n: int +) -> None: + """Raise ValueError on any geometry the design cannot express.""" + max_cols = ARCHES[arch][3] + if not 1 <= n_aie_cols <= max_cols: + raise ValueError(f"{arch} supports 1..{max_cols} AIE columns, got {n_aie_cols}") + if M % (m * N_AIE_ROWS) != 0: + raise ValueError( + f"M={M} must be a multiple of m*n_aie_rows ({m}*{N_AIE_ROWS})" + ) + n_row_blocks = M // m // N_AIE_ROWS + if n_row_blocks % 2 != 0: + raise ValueError( + f"M/m/n_aie_rows = {n_row_blocks} must be even (transfer-block " + f"ping-pong pairing); try a different m or M" + ) + if K % k != 0: + raise ValueError(f"K={K} must be a multiple of k={k}") + if N % (n * n_aie_cols) != 0: + raise ValueError( + f"N={N} must be a multiple of n*n_aie_cols ({n}*{n_aie_cols})" + ) + + +# --------------------------------------------------------------------------- +# Design (verbatim copy of whole_array.py's _build_design minus the +# generate_taps visualization mode; b_col_maj/c_col_maj are always 0 for the +# KataGo ABI but the branches are kept faithful to the template) +# --------------------------------------------------------------------------- + + +def _build_design( + dev, + M, + K, + N, + m, + k, + n, + n_aie_cols, + dtype_in_str, + dtype_out_str, + b_col_maj, + c_col_maj, + emulate_bf16_mmul_with_bfp16, + use_chess, + scalar, +): + """Build the whole-array matmul IRON design and resolve to MLIR.""" + dev_str = "npu2" if isinstance(dev, NPU2) else "npu" + + n_aie_rows = N_AIE_ROWS + n_aie_cores = n_aie_rows * n_aie_cols + + dtype_in = str_to_dtype(dtype_in_str) + dtype_out = str_to_dtype(dtype_out_str) + + assert np.issubdtype(dtype_in, np.integer) == np.issubdtype( + dtype_out, np.integer + ), f"Input dtype ({dtype_in}) and output dtype ({dtype_out}) must either both be integral or both be float" + assert ( + np.dtype(dtype_out).itemsize >= np.dtype(dtype_in).itemsize + ), f"Output dtype ({dtype_out}) must be equal or larger to input dtype ({dtype_in})" + + matmul_kernel = kernels.mm( + dim_m=m, + dim_k=k, + dim_n=n, + input_dtype=dtype_in, + output_dtype=dtype_out, + b_col_maj=bool(b_col_maj), + c_col_maj=bool(c_col_maj), + use_chess=use_chess, + emulate_bf16_mmul_with_bfp16=emulate_bf16_mmul_with_bfp16, + vectorized=not scalar, + ) + zero_kernel = matmul_kernel.zero + r, s, t = matmul_kernel.mac_dims + + if dev_str == "npu" and n_aie_cols > 4: + raise AssertionError("Invalid configuration: NPU (Phoenix/Hawk) has 4 columns") + if dev_str == "npu2" and n_aie_cols > 8: + raise AssertionError( + "Invalid configuration: NPU2 (Strix/Strix Halo/Krackan) has 8 columns" + ) + + assert ( + M % (m * n_aie_rows) == 0 + ), "A must be tileable into (m * n_aie_rows, k)-sized blocks" + assert K % k == 0 + assert ( + N % (n * n_aie_cols) == 0 + ), "B must be tileable into (k, n * n_aie_cols)-sized blocks" + assert m % r == 0 + assert k % s == 0 + assert n % t == 0 + + fifo_depth = 2 + n_tiles_per_core = (M // m) * (N // n) // n_aie_cores + + if n_aie_cols > n_aie_rows: + n_shim_mem_A = n_aie_rows + else: + n_shim_mem_A = n_aie_cols + + n_A_tiles_per_shim = n_aie_rows // n_aie_cols if n_aie_cols < 4 else 1 + + A_taps = [] + B_taps = [] + C_taps = [] + + A_ty = np.ndarray[(M * K,), np.dtype[dtype_in]] + B_ty = np.ndarray[(K * N,), np.dtype[dtype_in]] + C_ty = np.ndarray[(M * N,), np.dtype[dtype_out]] + A_l2_ty = np.ndarray[(m * k * n_A_tiles_per_shim,), np.dtype[dtype_in]] + B_l2_ty = np.ndarray[(k * n,), np.dtype[dtype_in]] + C_l2_ty = np.ndarray[(m * n * n_aie_rows,), np.dtype[dtype_out]] + A_l1_ty = np.ndarray[(m, k), np.dtype[dtype_in]] + B_l1_ty = np.ndarray[(k, n), np.dtype[dtype_in]] + C_l1_ty = np.ndarray[(m, n), np.dtype[dtype_out]] + + A_l3l2_fifos: list[ObjectFifo] = [] + A_l2l1_fifos: list[ObjectFifo] = [] + B_l3l2_fifos: list[ObjectFifo] = [] + B_l2l1_fifos: list[ObjectFifo] = [] + C_l1l2_fifos: list[list[ObjectFifo]] = [[] for _ in range(n_aie_rows)] + C_l2l3_fifos: list[ObjectFifo] = [] + + for i in range(n_shim_mem_A): + a_l3l2 = ObjectFifo(A_l2_ty, name=f"A_L3L2_{i}", depth=fifo_depth) + A_l3l2_fifos.append(a_l3l2) + start_row = i * n_A_tiles_per_shim + stop_row = start_row + n_A_tiles_per_shim + of_offsets = [m * k * j for j in range(stop_row - start_row)] + a_dims: list[StreamDims] = [ + [ + (m // r, r * k), + (k // s, s), + (r, k), + (s, 1), + ] + ] * (stop_row - start_row) + a_tmp_fifos = a_l3l2.cons().split( + of_offsets, + obj_types=[A_l1_ty] * (stop_row - start_row), + names=[f"A_L2L1_{row}" for row in range(start_row, stop_row)], + dims_to_stream=a_dims, + ) + A_l2l1_fifos.extend(a_tmp_fifos) + + for col in range(n_aie_cols): + b_l3l2 = ObjectFifo(B_l2_ty, name=f"B_L3L2_{col}", depth=fifo_depth) + B_l3l2_fifos.append(b_l3l2) + b_dims: StreamDims = ( + [(n // t, t * k), (k // s, s), (t, k), (s, 1)] + if b_col_maj + else [(k // s, s * n), (n // t, t), (s, n), (t, 1)] + ) + B_l2l1_fifos.append( + b_l3l2.cons().forward( + obj_type=B_l1_ty, + name=f"B_L2L1_{col}", + dims_to_stream=b_dims, + ) + ) + + c_dims: StreamDims = ( + [(m // r, r * n), (r, t), (n // t, r * t), (t, 1)] + if not c_col_maj + else [(n // t, t * m), (t, r), (m // r, r * t), (r, 1)] + ) + c_l2l3 = ObjectFifo( + C_l2_ty, + name=f"C_L2L3_{col}", + depth=fifo_depth, + dims_to_stream=c_dims, + ) + C_l2l3_fifos.append(c_l2l3) + of_offsets = [m * n * i for i in range(n_aie_rows)] + + c_tmp_fifos = c_l2l3.prod().join( + of_offsets, + obj_types=[C_l1_ty] * n_aie_rows, + names=[f"C_L1L2_{col}_{row}" for row in range(n_aie_rows)], + depths=[fifo_depth] * n_aie_rows, + ) + for j in range(n_aie_rows): + C_l1l2_fifos[j].append(c_tmp_fifos[j]) + + def core_fn(in_a, in_b, out_c, zero, matmul): + loop = range(1) # Workaround for issue #1547 + if n_tiles_per_core > 1: + loop = range_(n_tiles_per_core) + for _ in loop: + elem_out = out_c.acquire(1) + zero(elem_out) + + for _ in range_(K // k): + elem_in_a = in_a.acquire(1) + elem_in_b = in_b.acquire(1) + matmul(elem_in_a, elem_in_b, elem_out) + in_a.release(1) + in_b.release(1) + out_c.release(1) + + workers = Worker.grid( + n_aie_rows, + n_aie_cols, + lambda row, col: Worker( + core_fn, + [ + A_l2l1_fifos[row].cons(), + B_l2l1_fifos[col].cons(), + C_l1l2_fifos[row][col].prod(), + zero_kernel, + matmul_kernel, + ], + stack_size=0xD00, + ), + ) + + tb_max_n_rows = 4 if not c_col_maj else 2 + tb_n_rows = tb_max_n_rows // 2 + + A_tiles = TensorTiler2D.group_tiler( + (M, K), + (m * n_A_tiles_per_shim, k), + (1, K // k), + pattern_repeat=N // n // n_aie_cols, + prune_step=False, + ) + if b_col_maj: + B_tiles = TensorTiler2D.step_tiler( + (N, K), + (n, k), + tile_group_repeats=(N // n // n_aie_cols, K // k), + tile_group_steps=(n_aie_cols, 1), + prune_step=False, + ) + else: + B_tiles = TensorTiler2D.step_tiler( + (K, N), + (k, n), + tile_group_repeats=(K // k, N // n // n_aie_cols), + tile_group_steps=(1, n_aie_cols), + tile_group_col_major=True, + prune_step=False, + ) + if c_col_maj: + # Splitting n_aie_rows out of the tile dim is what lets TensorTiler emit + # the (col-fast, row_block-slow) DMA pattern; iter_col_major matches it. + C_tiles = TensorTiler2D.step_tiler( + (N, M), + (n, m), + tile_group_repeats=(N // n // n_aie_cols, n_aie_rows), + tile_group_steps=(n_aie_cols, 1), + iter_col_major=True, + prune_step=False, + ) + else: + C_tiles = TensorTiler2D.step_tiler( + (M, N), + (m * n_aie_rows, n), + tile_group_repeats=(tb_n_rows, N // n // n_aie_cols), + tile_group_steps=(1, n_aie_cols), + prune_step=False, + ) + flat_workers = [w for row in workers for w in row] + + A_prods = [f.prod() for f in A_l3l2_fifos] + B_prods = [f.prod() for f in B_l3l2_fifos] + C_conses = [f.cons() for f in C_l2l3_fifos] + + def sequence(A, B, C, A_hs, B_hs, C_hs): + c_index = 0 + tg = TaskGroup() + for tb in range(iron.ceildiv(M // m // n_aie_rows, tb_max_n_rows)): + for pingpong in [0, 1]: + if c_index >= len(C_tiles): + break + + row_base = tb * tb_max_n_rows + pingpong * tb_max_n_rows // 2 + current_tb_n_rows = min( + [tb_max_n_rows // 2, M // m // n_aie_rows - row_base] + ) + + for col in range(n_aie_cols): + C_taps.append(C_tiles[c_index]) + C_hs[col].drain( + C, + tap=C_tiles[c_index], + wait=True, + group=tg, + ) + c_index += 1 + + for tile_row in range(current_tb_n_rows): + tile_offset = ( + (row_base + tile_row) * n_shim_mem_A + col + ) % len(A_tiles) + if col < n_aie_rows: + A_hs[col].fill( + A, + tap=A_tiles[tile_offset], + group=tg, + ) + B_hs[col].fill( + B, + tap=B_tiles[col], + group=tg, + ) + A_taps.append(A_tiles[tile_offset]) + B_taps.append(B_tiles[col]) + + if tb > 0 or (tb == 0 and pingpong > 0): + tg.finish() + tg = TaskGroup() + tg.finish() + + rt = Runtime( + sequence, + [A_ty, B_ty, C_ty, A_prods, B_prods, C_conses], + ) + + program = Program(dev, rt, workers=flat_workers) + module = program.resolve_program() + + return module + + +@iron.jit(aiecc_flags=["--alloc-scheme=basic-sequential"]) +def gemm_bf16( + A: In, + B: In, + C: Out, + *, + M: CompileTime[int], + K: CompileTime[int], + N: CompileTime[int], + m: CompileTime[int], + k: CompileTime[int], + n: CompileTime[int], + n_aie_cols: CompileTime[int], + emulate_bf16_mmul_with_bfp16: CompileTime[bool] = False, +): + return _build_design( + iron.get_current_device(), + M, + K, + N, + m, + k, + n, + n_aie_cols, + DTYPE_IN_STR, + DTYPE_OUT_STR, + 0, # b_col_maj + 0, # c_col_maj + emulate_bf16_mmul_with_bfp16, + False, # use_chess + False, # scalar + ) + + +# --------------------------------------------------------------------------- +# Host-side helpers (compile / metadata / verify) +# --------------------------------------------------------------------------- + + +def compile_aot( + arch: str, + n_aie_cols: int, + dtype: str, + M: int, + K: int, + N: int, + m: int, + k: int, + n: int, + xclbin_path: str, + insts_path: str, +) -> float: + """AOT-compile one variant to explicit paths; returns wall-clock seconds. + + Explicit output paths bypass the JIT cache, so this is always a true + cold compile. + """ + validate_shape(arch, n_aie_cols, M, K, N, m, k, n) + set_target_device(arch, n_aie_cols) + start = time.perf_counter() + spec = gemm_bf16.specialize( + M=M, + K=K, + N=N, + m=m, + k=k, + n=n, + n_aie_cols=n_aie_cols, + emulate_bf16_mmul_with_bfp16=(dtype == "bfp16"), + ) + spec.compile(xclbin_path=xclbin_path, inst_path=insts_path) + return time.perf_counter() - start + + +def kernel_info(arch: str, n_aie_cols: int, dtype: str, m: int, k: int, n: int) -> dict: + """Static kernel metadata for the manifest (no design compilation).""" + set_target_device(arch, n_aie_cols) + matmul_kernel = kernels.mm( + dim_m=m, + dim_k=k, + dim_n=n, + input_dtype=INPUT_DTYPE, + output_dtype=OUTPUT_DTYPE, + emulate_bf16_mmul_with_bfp16=(dtype == "bfp16"), + vectorized=True, + ) + return { + "tile": {"m": m, "k": k, "n": n}, + "mac_dims": list(matmul_kernel.mac_dims), + "core_kernel": getattr(matmul_kernel, "_name", "matmul_bf16_f32"), + "zero_kernel": getattr(matmul_kernel.zero, "_name", "zero_f32"), + "input_dtype": "bfloat16", + "output_dtype": "float32", + "iron_device": ARCHES[arch][0], + "aie_arch": ARCHES[arch][1], + } + + +def run_and_verify( + arch: str, + n_aie_cols: int, + dtype: str, + M: int, + K: int, + N: int, + m: int, + k: int, + n: int, + warmup: int = 3, + iters: int = 10, + seed: int = 0, +) -> bool: + """Run one variant on the NPU and compare against a float64 reference.""" + validate_shape(arch, n_aie_cols, M, K, N, m, k, n) + set_target_device(arch, n_aie_cols) + emulate = dtype == "bfp16" + print(f"\n=== Running gemm_bf16 {M}x{K}x{N} {dtype} {arch} cols={n_aie_cols} " + f"tile={m}x{k}x{n} ===") + rng = np.random.default_rng(seed) + a_np = rng.uniform(-1.0, 1.0, size=(M, K)).astype(bfloat16) + b_np = rng.uniform(-1.0, 1.0, size=(K, N)).astype(bfloat16) + + input0 = iron.tensor(a_np, dtype=bfloat16, device="npu") + input1 = iron.tensor(b_np, dtype=bfloat16, device="npu") + output = iron.zeros(M * N, dtype=OUTPUT_DTYPE, device="npu") + + # bf16 x bf16 products are exact in fp32, so a float64 reference from the + # already-rounded bf16 inputs agrees with the NPU up to fp32 accumulation + # ordering (~1e-3 absolute at K=768). + ref = a_np.astype(np.float64) @ b_np.astype(np.float64) + + bench = run_iters( + gemm_bf16, + input0, + input1, + output, + M=M, + K=K, + N=N, + m=m, + k=k, + n=n, + n_aie_cols=n_aie_cols, + emulate_bf16_mmul_with_bfp16=emulate, + warmup=warmup, + iters=iters, + ) + + got = output.numpy().reshape(M, N).astype(np.float64) + abs_err = np.abs(got - ref) + rel_err = abs_err / np.maximum(np.abs(ref), 1e-6) + print( + f" max abs err: {abs_err.max():.6g} " + f"max rel err: {rel_err.max():.6g} " + f"|C| max: {np.abs(ref).max():.6g}" + ) + rtol, atol = 0.02, 0.1 + ok = bool(np.all(abs_err <= atol + rtol * np.abs(ref))) + if bench.npu is not None: + avg_us = bench.npu.avg_us + gflops = 2.0 * M * K * N / (1000.0 * avg_us) + print(f" NPU time avg: {avg_us:.1f} us {gflops:.2f} GFLOPS") + if not ok: + n_bad = int(np.sum(abs_err > atol + rtol * np.abs(ref))) + print(f" FAIL: {n_bad}/{ref.size} elements outside rtol={rtol} atol={atol}") + return False + print(f" PASS (rtol={rtol}, atol={atol})") + return True + + +def main(): + parser = argparse.ArgumentParser(prog="gemm_bf16") + parser.add_argument("--arch", choices=list(ARCHES), default="npu2") + parser.add_argument("--n-aie-cols", type=int, choices=[1, 2, 4, 8], default=8) + parser.add_argument( + "--dtype", + choices=["bf16", "bfp16"], + default="bf16", + help="bf16 = native bf16 MMUL; bfp16 = BFP16-emulated bf16 MMUL " + "(AIE2P only, ~1.4x on Strix)", + ) + parser.add_argument("-M", type=int, required=True) + parser.add_argument("-K", type=int, required=True) + parser.add_argument("-N", type=int, required=True) + parser.add_argument("-m", type=int, default=DEFAULT_TILE["m"]) + parser.add_argument("-k", type=int, default=DEFAULT_TILE["k"]) + parser.add_argument("-n", type=int, default=DEFAULT_TILE["n"]) + parser.add_argument("--xclbin-path", type=str, default=None, + help="compile-only mode: write the xclbin here") + parser.add_argument("--insts-path", type=str, default=None, + help="compile-only mode: write the instruction binary here") + parser.add_argument("--warmup", type=int, default=3) + parser.add_argument("--iters", type=int, default=10) + args = parser.parse_args() + + if (args.xclbin_path is None) != (args.insts_path is None): + parser.error("--xclbin-path and --insts-path must be given together") + if args.dtype == "bfp16" and args.arch != "npu2": + parser.error("--dtype bfp16 (BFP16 emulation) is only supported on npu2") + + try: + validate_shape(args.arch, args.n_aie_cols, args.M, args.K, args.N, + args.m, args.k, args.n) + except ValueError as e: + parser.error(str(e)) + + if args.xclbin_path is not None: + secs = compile_aot( + args.arch, args.n_aie_cols, args.dtype, + args.M, args.K, args.N, args.m, args.k, args.n, + args.xclbin_path, args.insts_path, + ) + print(f"AOT compiled {args.M}x{args.K}x{args.N} {args.dtype} " + f"{args.arch} cols={args.n_aie_cols} tile={args.m}x{args.k}x{args.n} " + f"in {secs:.1f}s -> {args.xclbin_path}, {args.insts_path}") + return + + if args.arch != "npu2": + parser.error("on-hardware verification requires an attached npu2 device; " + "use --xclbin-path/--insts-path for compile-only npu1 builds") + if not run_and_verify( + args.arch, args.n_aie_cols, args.dtype, + args.M, args.K, args.N, args.m, args.k, args.n, + warmup=args.warmup, iters=args.iters, + ): + raise SystemExit(1) + print("PASS!") + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/gemm_swiglu_bf16.py b/python/ryzenai_kernels/gemm_swiglu_bf16.py new file mode 100644 index 0000000000..d434b0ccee --- /dev/null +++ b/python/ryzenai_kernels/gemm_swiglu_bf16.py @@ -0,0 +1,457 @@ +# gemm_swiglu_bf16.py +# +# Variant of gemm_bf16.py whose cores apply a SwiGLU epilogue to the +# accumulated C tile before it leaves the core. Everything else -- the +# whole_array design, the DMA layout, the host ABI (row-major bf16 A/B in, +# row-major f32 C out, same opcode-3 dispatch) -- is identical to the plain +# GEMM, so the same runtime-generated instruction streams drive it. +# +# The epilogue expects B's columns pre-interleaved by the host in groups of 8: +# [linear1 ch 0-7, linearGate ch 0-7, linear1 ch 8-15, ...] and writes +# silu(l1) * gate back over the linear1 positions. The host reads C column +# (c>>3)*16 + (c&7) for out channel c and ignores the gate columns. See +# kernels/mm_swiglu_epilogue.cc. +# +# Compile-only: the on-hardware check goes through the C++ probe in the +# scratchpad (this mlir-aie build's Python side cannot allocate NPU tensors). +# +# Usage (inside the activated mlir-aie iron environment): +# python gemm_swiglu_bf16.py -K 512 --n-aie-cols 4 \ +# --xclbin-path out.xclbin --insts-path out.insts.bin + +import argparse +import time +from pathlib import Path + +import aie.iron as iron +import numpy as np +from aie.helpers.taplib import TensorTiler2D +from aie.iron import ( + CompileTime, + In, + ObjectFifo, + Out, + Program, + Runtime, + StreamDims, + TaskGroup, + Worker, + kernels, + str_to_dtype, +) +from aie.iron.controlflow import range_ +from aie.iron.device import NPU2, from_name +from aie.iron.kernel import ExternalFunction +from aie.utils import config +from ml_dtypes import bfloat16 + +KERNEL_CC = str(Path(__file__).parent / "kernels" / "mm_swiglu_epilogue.cc") + +# --------------------------------------------------------------------------- +# Target configuration (identical to gemm_bf16.py) +# --------------------------------------------------------------------------- + +ARCHES = { + "npu1": ("npu", "aie2", "XDNA1 (Ryzen AI Phoenix/Hawk Point)", 4), + "npu2": ("npu2", "aie2p", "XDNA2 (Ryzen AI Strix/Krackan)", 8), +} + +N_AIE_ROWS = 4 + +INPUT_DTYPE = bfloat16 +OUTPUT_DTYPE = np.float32 +DTYPE_IN_STR = "bf16" +DTYPE_OUT_STR = "f32" + +DEFAULT_TILE = {"m": 32, "k": 64, "n": 32} + + +def _device_for(arch: str, n_aie_cols: int): + dev_str = ARCHES[arch][0] + return from_name(dev_str, n_cols=n_aie_cols if dev_str == "npu" else None) + + +def set_target_device(arch: str, n_aie_cols: int): + iron.set_current_device(_device_for(arch, n_aie_cols)) + + +def validate_shape( + arch: str, n_aie_cols: int, M: int, K: int, N: int, m: int, k: int, n: int +) -> None: + max_cols = ARCHES[arch][3] + if not 1 <= n_aie_cols <= max_cols: + raise ValueError(f"{arch} supports 1..{max_cols} AIE columns, got {n_aie_cols}") + if M % (m * N_AIE_ROWS) != 0: + raise ValueError(f"M={M} must be a multiple of m*n_aie_rows ({m}*{N_AIE_ROWS})") + n_row_blocks = M // m // N_AIE_ROWS + if n_row_blocks % 2 != 0: + raise ValueError( + f"M/m/n_aie_rows = {n_row_blocks} must be even (transfer-block " + f"ping-pong pairing); try a different m or M" + ) + if K % k != 0: + raise ValueError(f"K={K} must be a multiple of k={k}") + if N % (n * n_aie_cols) != 0: + raise ValueError(f"N={N} must be a multiple of n*n_aie_cols ({n}*{n_aie_cols})") + # The epilogue pairs adjacent 8-column sub-tiles, so each core's n-column + # slice must hold whole (l, g) pairs. + if n % 16 != 0: + raise ValueError(f"n={n} must be a multiple of 16 for the swiglu pairing") + + +# --------------------------------------------------------------------------- +# Design: gemm_bf16.py's whole-array build plus the epilogue call in core_fn +# --------------------------------------------------------------------------- + + +def _build_design( + dev, + M, + K, + N, + m, + k, + n, + n_aie_cols, + dtype_in_str, + dtype_out_str, +): + dev_str = "npu2" if isinstance(dev, NPU2) else "npu" + + n_aie_rows = N_AIE_ROWS + n_aie_cores = n_aie_rows * n_aie_cols + + dtype_in = str_to_dtype(dtype_in_str) + dtype_out = str_to_dtype(dtype_out_str) + + matmul_kernel = kernels.mm( + dim_m=m, + dim_k=k, + dim_n=n, + input_dtype=dtype_in, + output_dtype=dtype_out, + b_col_maj=False, + c_col_maj=False, + use_chess=False, + emulate_bf16_mmul_with_bfp16=False, + vectorized=True, + ) + zero_kernel = matmul_kernel.zero + r, s, t = matmul_kernel.mac_dims + + assert M % (m * n_aie_rows) == 0 + assert K % k == 0 + assert N % (n * n_aie_cols) == 0 + assert m % r == 0 + assert k % s == 0 + assert n % t == 0 + + fifo_depth = 2 + n_tiles_per_core = (M // m) * (N // n) // n_aie_cores + + if n_aie_cols > n_aie_rows: + n_shim_mem_A = n_aie_rows + else: + n_shim_mem_A = n_aie_cols + + n_A_tiles_per_shim = n_aie_rows // n_aie_cols if n_aie_cols < 4 else 1 + + A_taps = [] + B_taps = [] + C_taps = [] + + A_ty = np.ndarray[(M * K,), np.dtype[dtype_in]] + B_ty = np.ndarray[(K * N,), np.dtype[dtype_in]] + C_ty = np.ndarray[(M * N,), np.dtype[dtype_out]] + A_l2_ty = np.ndarray[(m * k * n_A_tiles_per_shim,), np.dtype[dtype_in]] + B_l2_ty = np.ndarray[(k * n,), np.dtype[dtype_in]] + C_l2_ty = np.ndarray[(m * n * n_aie_rows,), np.dtype[dtype_out]] + A_l1_ty = np.ndarray[(m, k), np.dtype[dtype_in]] + B_l1_ty = np.ndarray[(k, n), np.dtype[dtype_in]] + C_l1_ty = np.ndarray[(m, n), np.dtype[dtype_out]] + + swiglu_kernel = ExternalFunction( + "mm_swiglu_epilogue_f32", + source_file=KERNEL_CC, + arg_types=[C_l1_ty], + compile_flags=[f"-DDIM_M={m}", f"-DDIM_N={n}"], + include_dirs=[config.cxx_header_path()], + ) + + A_l3l2_fifos: list[ObjectFifo] = [] + A_l2l1_fifos: list[ObjectFifo] = [] + B_l3l2_fifos: list[ObjectFifo] = [] + B_l2l1_fifos: list[ObjectFifo] = [] + C_l1l2_fifos: list[list[ObjectFifo]] = [[] for _ in range(n_aie_rows)] + C_l2l3_fifos: list[ObjectFifo] = [] + + for i in range(n_shim_mem_A): + a_l3l2 = ObjectFifo(A_l2_ty, name=f"A_L3L2_{i}", depth=fifo_depth) + A_l3l2_fifos.append(a_l3l2) + start_row = i * n_A_tiles_per_shim + stop_row = start_row + n_A_tiles_per_shim + of_offsets = [m * k * j for j in range(stop_row - start_row)] + a_dims: list[StreamDims] = [ + [ + (m // r, r * k), + (k // s, s), + (r, k), + (s, 1), + ] + ] * (stop_row - start_row) + a_tmp_fifos = a_l3l2.cons().split( + of_offsets, + obj_types=[A_l1_ty] * (stop_row - start_row), + names=[f"A_L2L1_{row}" for row in range(start_row, stop_row)], + dims_to_stream=a_dims, + ) + A_l2l1_fifos.extend(a_tmp_fifos) + + for col in range(n_aie_cols): + b_l3l2 = ObjectFifo(B_l2_ty, name=f"B_L3L2_{col}", depth=fifo_depth) + B_l3l2_fifos.append(b_l3l2) + b_dims: StreamDims = [(k // s, s * n), (n // t, t), (s, n), (t, 1)] + B_l2l1_fifos.append( + b_l3l2.cons().forward( + obj_type=B_l1_ty, + name=f"B_L2L1_{col}", + dims_to_stream=b_dims, + ) + ) + + c_dims: StreamDims = [(m // r, r * n), (r, t), (n // t, r * t), (t, 1)] + c_l2l3 = ObjectFifo( + C_l2_ty, + name=f"C_L2L3_{col}", + depth=fifo_depth, + dims_to_stream=c_dims, + ) + C_l2l3_fifos.append(c_l2l3) + of_offsets = [m * n * i for i in range(n_aie_rows)] + + c_tmp_fifos = c_l2l3.prod().join( + of_offsets, + obj_types=[C_l1_ty] * n_aie_rows, + names=[f"C_L1L2_{col}_{row}" for row in range(n_aie_rows)], + depths=[fifo_depth] * n_aie_rows, + ) + for j in range(n_aie_rows): + C_l1l2_fifos[j].append(c_tmp_fifos[j]) + + def core_fn(in_a, in_b, out_c, zero, matmul, swiglu): + loop = range(1) + if n_tiles_per_core > 1: + loop = range_(n_tiles_per_core) + for _ in loop: + elem_out = out_c.acquire(1) + zero(elem_out) + + for _ in range_(K // k): + elem_in_a = in_a.acquire(1) + elem_in_b = in_b.acquire(1) + matmul(elem_in_a, elem_in_b, elem_out) + in_a.release(1) + in_b.release(1) + # K reduction done: C tile holds the raw GEMM. Apply silu(l)*g over + # the (l, g) sub-tile pairs in place, then hand the tile off. + swiglu(elem_out) + out_c.release(1) + + workers = Worker.grid( + n_aie_rows, + n_aie_cols, + lambda row, col: Worker( + core_fn, + [ + A_l2l1_fifos[row].cons(), + B_l2l1_fifos[col].cons(), + C_l1l2_fifos[row][col].prod(), + zero_kernel, + matmul_kernel, + swiglu_kernel, + ], + stack_size=0xD00, + ), + ) + + tb_max_n_rows = 4 + tb_n_rows = tb_max_n_rows // 2 + + A_tiles = TensorTiler2D.group_tiler( + (M, K), + (m * n_A_tiles_per_shim, k), + (1, K // k), + pattern_repeat=N // n // n_aie_cols, + prune_step=False, + ) + B_tiles = TensorTiler2D.step_tiler( + (K, N), + (k, n), + tile_group_repeats=(K // k, N // n // n_aie_cols), + tile_group_steps=(1, n_aie_cols), + tile_group_col_major=True, + prune_step=False, + ) + C_tiles = TensorTiler2D.step_tiler( + (M, N), + (m * n_aie_rows, n), + tile_group_repeats=(tb_n_rows, N // n // n_aie_cols), + tile_group_steps=(1, n_aie_cols), + prune_step=False, + ) + flat_workers = [w for row in workers for w in row] + + A_prods = [f.prod() for f in A_l3l2_fifos] + B_prods = [f.prod() for f in B_l3l2_fifos] + C_conses = [f.cons() for f in C_l2l3_fifos] + + def sequence(A, B, C, A_hs, B_hs, C_hs): + c_index = 0 + tg = TaskGroup() + for tb in range(iron.ceildiv(M // m // n_aie_rows, tb_max_n_rows)): + for pingpong in [0, 1]: + if c_index >= len(C_tiles): + break + + row_base = tb * tb_max_n_rows + pingpong * tb_max_n_rows // 2 + current_tb_n_rows = min( + [tb_max_n_rows // 2, M // m // n_aie_rows - row_base] + ) + + for col in range(n_aie_cols): + C_taps.append(C_tiles[c_index]) + C_hs[col].drain( + C, + tap=C_tiles[c_index], + wait=True, + group=tg, + ) + c_index += 1 + + for tile_row in range(current_tb_n_rows): + tile_offset = ( + (row_base + tile_row) * n_shim_mem_A + col + ) % len(A_tiles) + if col < n_aie_rows: + A_hs[col].fill( + A, + tap=A_tiles[tile_offset], + group=tg, + ) + B_hs[col].fill( + B, + tap=B_tiles[col], + group=tg, + ) + A_taps.append(A_tiles[tile_offset]) + B_taps.append(B_tiles[col]) + + if tb > 0 or (tb == 0 and pingpong > 0): + tg.finish() + tg = TaskGroup() + tg.finish() + + rt = Runtime( + sequence, + [A_ty, B_ty, C_ty, A_prods, B_prods, C_conses], + ) + + program = Program(dev, rt, workers=flat_workers) + module = program.resolve_program() + + return module + + +@iron.jit(aiecc_flags=["--alloc-scheme=basic-sequential"]) +def gemm_swiglu_bf16( + A: In, + B: In, + C: Out, + *, + M: CompileTime[int], + K: CompileTime[int], + N: CompileTime[int], + m: CompileTime[int], + k: CompileTime[int], + n: CompileTime[int], + n_aie_cols: CompileTime[int], +): + return _build_design( + iron.get_current_device(), + M, + K, + N, + m, + k, + n, + n_aie_cols, + DTYPE_IN_STR, + DTYPE_OUT_STR, + ) + + +# --------------------------------------------------------------------------- + + +def compile_aot( + arch: str, + n_aie_cols: int, + M: int, + K: int, + N: int, + m: int, + k: int, + n: int, + xclbin_path: str, + insts_path: str, +) -> float: + """AOT-compile one variant to explicit paths; returns wall-clock seconds.""" + validate_shape(arch, n_aie_cols, M, K, N, m, k, n) + set_target_device(arch, n_aie_cols) + start = time.perf_counter() + spec = gemm_swiglu_bf16.specialize( + M=M, + K=K, + N=N, + m=m, + k=k, + n=n, + n_aie_cols=n_aie_cols, + ) + spec.compile(xclbin_path=xclbin_path, inst_path=insts_path) + return time.perf_counter() - start + + +def main(): + parser = argparse.ArgumentParser(prog="gemm_swiglu_bf16") + parser.add_argument("--arch", choices=list(ARCHES), default="npu2") + parser.add_argument("--n-aie-cols", type=int, choices=[1, 2, 4, 8], default=4) + parser.add_argument("-M", type=int, default=256) + parser.add_argument("-K", type=int, required=True) + parser.add_argument("-N", type=int, default=0, help="0 picks n*cols*2") + parser.add_argument("-m", type=int, default=DEFAULT_TILE["m"]) + parser.add_argument("-k", type=int, default=DEFAULT_TILE["k"]) + parser.add_argument("-n", type=int, default=DEFAULT_TILE["n"]) + parser.add_argument("--xclbin-path", type=str, required=True) + parser.add_argument("--insts-path", type=str, required=True) + args = parser.parse_args() + + N = args.N if args.N > 0 else args.n * args.n_aie_cols * 2 + try: + validate_shape(args.arch, args.n_aie_cols, args.M, args.K, N, + args.m, args.k, args.n) + except ValueError as e: + parser.error(str(e)) + + secs = compile_aot( + args.arch, args.n_aie_cols, + args.M, args.K, N, args.m, args.k, args.n, + args.xclbin_path, args.insts_path, + ) + print(f"AOT compiled swiglu-epilogue GEMM {args.M}x{args.K}x{N} " + f"{args.arch} cols={args.n_aie_cols} tile={args.m}x{args.k}x{args.n} " + f"in {secs:.1f}s -> {args.xclbin_path}, {args.insts_path}") + + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/kernels/attention_head.cc b/python/ryzenai_kernels/kernels/attention_head.cc new file mode 100644 index 0000000000..cc014dbb51 --- /dev/null +++ b/python/ryzenai_kernels/kernels/attention_head.cc @@ -0,0 +1,132 @@ +// attention_head.cc - fused single-head attention tile kernel for AIE2P +// (Strix/npu2), bf16 in with f32 accumulation. +// +// One AIE core owns one attention head for a whole dispatch. K and V arrive +// as one packed per-head buffer (a core tile has only two input DMA +// channels), pre-tiled by the host into the mmul tile order the stock +// 2x2_mmul template reads; Q streams through in 8-row blocks, likewise +// pre-tiled. Per 8-row query block: +// +// scores[8 x 384] = Q[8 x 32] @ K^T[32 x 384] (K col-major B) +// scores = softmax(scores) (pad columns forced -1e30) +// out[8 x 32] = P[8 x 384] @ V[384 x 32] (V row-major B, f32 out) +// +// LAYOUT NOTE (the subtle part of this kernel): the stock matmul template +// reads A and B and writes C in mmul tile order -- (4x8) tiles of A, (8x8) +// tiles of B, (4x8) tiles of C, NOT plain row-major. The host pre-tiles Q/K/V +// and un-tiles the output; the score buffer never leaves the core, so the +// softmax here gathers it out of QK^T's C-tile order and scatters the +// probabilities into P*V's A-tile order. The three index mappings below are +// derived from matmul_vectorized_2x2_mmul's pointer arithmetic in mm.cc and +// verified on hardware by attnbench. +// +// Numerics match the staged path: scores are bf16 before the exp (as they +// are when the standalone softmax op reads them), P*V accumulates in f32. +// Pad key columns are set to (row max - 20) before the softmax -- NOT -inf, +// because this kernel's f32 exp2 wraps huge negative inputs to huge positive +// ones -- and then written as exact 0 into P, so they contribute nothing. +// Pad query rows produce finite garbage the host discards. + +#define DIM_M 8 +#define DIM_K 32 +#define DIM_N 384 +#define bf16_bf16_ONLY +#define B_COL_MAJ + +#include "aie_kernels/aie2p/mm.cc" +#include "aie_kernels/aie2p/softmax.cc" + +#ifndef ATTN_S_REAL +#define ATTN_S_REAL 361 +#endif + +namespace { + +// Per-core scratch in L1: QK^T's scores and P*V's probabilities (same +// elements, different tile order), plus one plain row for the softmax. +// Static storage is private to each core (each core links its own ELF). +alignas(64) bfloat16 g_scores[8 * 384]; +bfloat16 g_row[384]; + +// The C-tile order of QK^T and the A-tile order of P*V are the SAME formula +// for these shapes (verified on hardware), so the softmax reads and writes +// g_scores in place through idx_tile -- no separate probability buffer. +int idx_tile(int qi, int ki) { + return (qi >> 2) * 1536 + (ki >> 3) * 32 + (qi & 3) * 8 + (ki & 7); +} + +} // namespace + +extern "C" { + +// One 8-row query block of one head: q = 256 bf16 in A-tile order, kv = the +// head's K then V, each 384x32 bf16 in B-tile order (back to back), out = +// 8x32 f32 in C-tile order (host un-tiles on readback). +void attn_block_bf16(bfloat16 *restrict q, bfloat16 *restrict kv, + float *restrict out) { + const bfloat16 *k = kv; + const bfloat16 *v = kv + (size_t)384 * 32; + + // The 2x2_mmul template accumulates onto C in place (the GEMM design zeroes + // between calls), so both output buffers must be zeroed first. + for (int i = 0; i < 8 * 384; i++) + g_scores[i] = (bfloat16)0.0f; + for (int i = 0; i < 8 * 32; i++) + out[i] = 0.0f; + + // scores = Q @ K^T (K's tile order is the col-major-B one). + matmul_vectorized_2x2_mmul( + q, k, g_scores); + + // Per-row softmax. The tiled score layout keeps one row's 8 columns + // contiguous within each 32-element group, so gather/scatter run as + // 8-wide vector ops. Pad columns get (row max - 20), NOT -inf: this + // softmax kernel computes exp2 in f32 and huge negative inputs wrap the + // exponent field to huge POSITIVE values (measured: -1e30 pads come out as + // ~+7.7e30). max-20 gives exp2(-28.9) ~ 3e-9, negligible and safe. Pad + // columns are stored as exact 0 afterwards. + for (int r = 0; r < 8; r++) { + const int rbase = (r >> 2) * 1536 + (r & 3) * 8; + // Full 8-column chunks are gathered as vectors; the ragged tail (S is not + // a multiple of 8) is gathered element-wise so stale values never leak in. + aie::vector vmax8 = aie::broadcast(-1e30f); + constexpr int fullG = ATTN_S_REAL / 8; + for (int g = 0; g < fullG; g++) { + aie::vector el = aie::load_v<8>(g_scores + rbase + g * 32); + aie::store_v(g_row + g * 8, el); + aie::vector f = aie::accum(el).to_vector(); + vmax8 = aie::max(vmax8, f); + } + float maxVal = aie::reduce_max(vmax8); + for (int ki = fullG * 8; ki < ATTN_S_REAL; ki++) { + const bfloat16 el = g_scores[rbase + (ki >> 3) * 32 + (ki & 7)]; + g_row[ki] = el; + if((float)el > maxVal) + maxVal = (float)el; + } + // Pad columns: row max - 20, NOT -inf (see above about the exp2 wrap). + // Their softmax output is stored as exact 0 below, and V's pad rows are + // host-zeroed, so the pads contribute nothing either way. + for (int ki = ATTN_S_REAL; ki < 384; ki++) + g_row[ki] = (bfloat16)(maxVal - 20.0f); + softmax_simple_bf16(g_row, g_row, 384); + for (int g = 0; g < fullG; g++) + aie::store_v(g_scores + rbase + g * 32, aie::load_v<8>(g_row + g * 8)); + for (int ki = fullG * 8; ki < ATTN_S_REAL; ki++) + g_scores[rbase + (ki >> 3) * 32 + (ki & 7)] = g_row[ki]; + for (int g = (ATTN_S_REAL + 7) / 8; g < 48; g++) + aie::store_v(g_scores + rbase + g * 32, aie::broadcast(0.0f)); + } + + // out = P @ V, f32. V arrives col-major (its host tiling matches the + // col-major B read verified by the PV probe; the row-major read was never + // verified for this shape). + matmul_vectorized_2x2_mmul( + g_scores, v, out); +} + +} // extern "C" diff --git a/python/ryzenai_kernels/kernels/bn_mish.cc b/python/ryzenai_kernels/kernels/bn_mish.cc new file mode 100644 index 0000000000..2d5c324f13 --- /dev/null +++ b/python/ryzenai_kernels/kernels/bn_mish.cc @@ -0,0 +1,100 @@ +// bn_mish.cc - fused per-channel BatchNorm scale/bias + Mish activation, +// row-streamed, bf16 in/out, f32 internal, for AIE2P (Strix/npu2). +// +// out[r][c] = mish(scale[c] * x[r][c] + bias[c]) +// +// mish(t) = t * (s^2 + 2s) / (s^2 + 2s + 2) with s = e^t. The division uses +// aie::inv (vector reciprocal). For t > 16 the formula saturates to t +// (mish(16) == 16 to bf16 precision), so the exp argument is clamped at 16 +// and the result selected from the identity branch above the clamp. For +// t < -16 the result is ~t*e^t, already below bf16 resolution. +// +// scale/bias are resident per core (the host replicates the vectors across +// the 8 columns). width must be a multiple of 16. + +#include +#include + +namespace { + +constexpr float kLog2e = 1.44269504089f; + +} // namespace + +extern "C" { + +void bn_mish_bf16(bfloat16 *restrict input, bfloat16 *restrict sb, + bfloat16 *restrict output, const int32_t rows, + const int32_t width) { + // A core tile has only two input DMA channels, so scale and bias arrive as + // one buffer: [scale (width) | bias (width)]. + const bfloat16 *scale = sb; + const bfloat16 *bias = sb + width; + constexpr int V = 16; + const int chunks = width / V; + for (int r = 0; r < rows; r++) { + const bfloat16 *in = input + (size_t)r * width; + bfloat16 *out = output + (size_t)r * width; + for (int i = 0; i < chunks; i++) { + aie::vector xb = aie::load_v(in + i * V); +#ifdef BNM_DUMPMODE + // 1: copy x; 2: output t=x*s+b; else full mish + if(BNM_DUMPMODE == 1) { aie::store_v(out + i * V, xb); continue; } +#endif + aie::vector sb = aie::load_v(scale + i * V); + aie::vector bb = aie::load_v(bias + i * V); + + aie::vector x = aie::accum(xb).to_vector(); + aie::vector sc = aie::accum(sb).to_vector(); + aie::vector bi = aie::accum(bb).to_vector(); + + // t = x*scale + bias. The exp path clamps at +16 (bf16 resolution makes + // mish(16) == 16); anything above the clamp is the identity branch and + // is added back as the excess, so no select/mask is needed: + // out = mish(min(t,16)) + max(t-16, 0) + aie::vector t = aie::add(aie::mul(x, sc), bi); + // Clamp for the exp overflow point. aie::min/max on f32 vectors are + // broken on XDNA2 (they returned garbage -- measured), so the clamp runs + // in bf16 through the proven from_vector/to_vector conversions. The + // excess above the clamp is kept exactly: out = mish(min(t,16)) + (t-tc). + aie::accum tacc; + tacc.from_vector(t); + aie::vector tcb = + aie::min(tacc.to_vector(), aie::broadcast(16.0f)); + aie::accum tcacc; + tcacc.from_vector(tcb); + aie::vector tc = tcacc.to_vector(); + aie::vector over = aie::sub(t, tc); + + // s = e^tc = exp2(tc * log2e). XDNA2's exp2 returns bf16 (f32 return is + // AIE_MLv2-only), which is plenty since the output is bf16 anyway. + aie::vector arg = + aie::mul(tc, aie::broadcast(kLog2e)); + aie::vector sigb = aie::exp2(arg); + aie::vector sig = aie::accum(sigb).to_vector(); + // mish = tc * (s^2+2s)/(s^2+2s+2) = tc * num/(num+2). XDNA2's vector + // reciprocal only takes bf16, so the divide narrows through bf16 -- + // harmless at bf16 output precision. + aie::vector two = aie::broadcast(2.0f); + aie::vector num = aie::add(aie::mul(sig, sig), aie::mul(two, sig)); + aie::vector den = aie::add(num, two); + aie::accum den_acc; + den_acc.from_vector(den); + aie::vector rinv_b = aie::inv(den_acc.to_vector()); + aie::accum rinv_acc; + rinv_acc.from_vector(rinv_b); + aie::vector frac = aie::mul(num, rinv_acc.to_vector()); + aie::vector mish = aie::mul(tc, frac); + aie::vector res = aie::add(mish, over); +#ifdef BNM_DUMPMODE + if(BNM_DUMPMODE == 2) + res = t; // output the pre-activation +#endif + aie::accum rac; + rac.from_vector(res); + aie::store_v(out + i * V, rac.to_vector()); + } + } +} + +} // extern "C" diff --git a/python/ryzenai_kernels/kernels/mm_swiglu_epilogue.cc b/python/ryzenai_kernels/kernels/mm_swiglu_epilogue.cc new file mode 100644 index 0000000000..259239f509 --- /dev/null +++ b/python/ryzenai_kernels/kernels/mm_swiglu_epilogue.cc @@ -0,0 +1,79 @@ +// mm_swiglu_epilogue.cc -- SwiGLU epilogue for the whole_array bf16 GEMM core. +// +// Runs on the fully accumulated C tile (DIM_M x DIM_N f32) after the K loop, +// before the tile is released to the output fifo. The host uploaded B with the +// linear1 / linearGate columns interleaved in groups of 8: +// +// B column (c>>3)*16 + (c&7) = linear1 weight for out channel c +// B column (c>>3)*16 + 8 + (c&7) = linearGate weight for out channel c +// +// so inside a core's C tile every even 8-column sub-tile holds linear1 outputs +// and the following odd sub-tile the matching gates. The epilogue computes +// silu(l) * g for each pair and writes it back over the l positions; the gate +// positions keep their raw values and the host simply never reads them. +// +// The C tile's in-memory order is the stock 2x2_mmul template's (r=4, t=8 +// sub-tiles): logical element (i, j) of the tile sits at +// +// offset(i, j) = (i >> 2) * (4 * DIM_N) + (j >> 3) * 32 + (i & 3) * 8 + (j & 7) +// +// (hardware-verified for this template family, see the attention op's probes). +// An (l, g) sub-tile pair is therefore always 32 contiguous f32 apart, and each +// 16-lane chunk within a sub-tile holds whole rows of one pair half. +// +// SiLU follows mm_activation_epilogue.cc: sigmoid built from the tanh SFU as +// 0.5 * (1 + tanh(x/2)), narrowing to bf16 only inside the sigmoid where the +// [0, 1] range is harmless; x, the gate and both multiplies stay f32. + +#include +#include + +#ifndef DIM_M +#define DIM_M 32 +#endif +#ifndef DIM_N +#define DIM_N 32 +#endif + +using namespace aie; + +static inline aie::vector swiglu16(aie::vector l, + aie::vector g) { + const aie::vector halff = aie::broadcast(0.5f); + const aie::vector onef = aie::broadcast(1.0f); + aie::vector half_l = aie::mul(l, halff); + // Only the tanh itself narrows to bf16 (the SFU's output format); the + // 1 + t and the 0.5x stay f32 so they add no further rounding, and x, the + // gate and both multiplies stay f32 as in mm_activation_epilogue.cc. + aie::vector tanh_half = aie::tanh(half_l); + aie::accum tacc; + tacc.from_vector(tanh_half); + aie::vector t = tacc.to_vector(); + aie::vector sig = aie::mul(aie::add(t, onef), halff); + // aie::mul on f32 vectors yields an accumulator, so chain via explicit + // vector temporaries (as mm_activation_epilogue.cc does). + aie::vector ls = aie::mul(l, sig); + return aie::vector(aie::mul(ls, g)); +} + +extern "C" { + +void mm_swiglu_epilogue_f32(float *__restrict c) { + event0(); + static_assert(DIM_M % 4 == 0 && DIM_N % 16 == 0, + "sub-tiles are 4x8 and (l, g) pairs span two of them"); + for (int rb = 0; rb < DIM_M / 4; rb++) { + for (int cg = 0; cg < DIM_N / 8; cg += 2) { + float *__restrict pl = c + rb * (4 * DIM_N) + cg * 32; + float *__restrict pg = pl + 32; + for (int h = 0; h < 2; h++) { // 32 elements per sub-tile = 2 x 16 lanes + aie::vector l = aie::load_v<16>(pl + h * 16); + aie::vector g = aie::load_v<16>(pg + h * 16); + aie::store_v(pl + h * 16, swiglu16(l, g)); + } + } + } + event1(); +} + +} // extern "C" diff --git a/python/ryzenai_kernels/kernels/softmax_rows.cc b/python/ryzenai_kernels/kernels/softmax_rows.cc new file mode 100644 index 0000000000..d52446c627 --- /dev/null +++ b/python/ryzenai_kernels/kernels/softmax_rows.cc @@ -0,0 +1,24 @@ +// softmax_rows.cc - multi-row bf16 softmax wrapper for AIE2P (Strix/npu2). +// +// Reuses the stock mlir-aie aie2p kernel (per-row softmax, vector width 32, +// aie::exp2 native exp) and loops it over the rows of one fifo element. +// Width must be a multiple of 32 (the design pads 361 -> 384 on the host; +// pad columns are -1e30 so exp() underflows to exactly 0 and the row sum is +// unaffected). +// +// Origin: written for the KataGo RyzenAI backend's attention softmax +// (rows = numHeads * S). Compiled per shape by build_softmax.py. + +#include "aie_kernels/aie2p/softmax.cc" + +extern "C" { + +void softmax_rows_bf16(bfloat16 *restrict input, bfloat16 *restrict output, + const int32_t n_rows, const int32_t width) { + for (int r = 0; r < n_rows; r++) { + softmax_simple_bf16(input + (size_t)r * width, + output + (size_t)r * width, width); + } +} + +} // extern "C" diff --git a/python/ryzenai_kernels/make_artifacts.py b/python/ryzenai_kernels/make_artifacts.py new file mode 100644 index 0000000000..d104cde04a --- /dev/null +++ b/python/ryzenai_kernels/make_artifacts.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python3 +"""Generate the NPU artifacts a model needs, into cpp/external/ryzenai_artifacts. + +Everything the runtime loads is named by its shape, and the loader finds it by +that name alone, so generating for a new model is a matter of naming the shapes +it uses. This wraps the individual builders so that is one command. + + python make_artifacts.py --for-model 512 8 # trunk 512, 8 heads + python make_artifacts.py --for-model 768 0 # a convnet: no heads + python make_artifacts.py --gemm-grid # the K grid (slow) + python make_artifacts.py --list --for-model 512 8 # show, build nothing + +What a model needs: + + gemm one per K it reduces over, shared by every model - the shipped grid + already covers K up to 6912, so a new model normally needs none + bnmish convnets with Mish: one per (rows, channel count) + attn transformers: one per (heads, board points) + softmax transformers: one per (heads * points, points), both padded + swiglu transformers: one per FFN hidden width (--ffn-hidden) + +Run inside the mlir-aie iron environment with XRT on PATH: + + set PATH=C:\\Envs\\mlir-aie\\ironenv\\Lib\\site-packages\\mlir_aie\\bin;C:\\Xilinx\\XRT;%PATH% +""" + +import argparse +import shutil +import subprocess +import sys +import tempfile +from pathlib import Path + +HERE = Path(__file__).parent +ARTIFACTS = HERE.parent.parent / "cpp" / "external" / "ryzenai_artifacts" +OPS = ARTIFACTS / "ops" + +# Rows per dispatch that the C++ side knows about. bnmish picks per call among +# these (matmul.cpp Accel::kBnMishHeights), so all three want to exist for any +# channel count that carries real work. +BNMISH_ROWS = [384, 1536, 3072] + + +def pad(n, to): + return ((n + to - 1) // to) * to + + +def plan(trunk_c, heads, points): + """Artifacts for one model geometry, as (builder, args, output stem).""" + jobs = [] + # nbt convnets normalise on several widths, not just the trunk: the + # bottleneck is trunk/2 and the heads run narrower still. Covering the + # usual set costs a few minutes and saves a silent fallback later. + widths = sorted({trunk_c, trunk_c // 2, trunk_c // 4, 256, 384}) + for w in widths: + for rows in BNMISH_ROWS: + # Only the trunk-sized widths ever see batched rows worth the tall + # variants; the narrow head layers stay small. + if rows > 384 and w < trunk_c // 2: + continue + jobs.append(("build_bn_mish.py", + ["--rows", str(rows), "--width", str(w)], + f"bnmish_{rows}x{w}")) + if heads > 0: + s_pad = pad(points, 32) + # 12 heads exceed the shim's DMA channel budget one head per core, so + # those run two heads per core (see SKILL.md pit #18). + per_core = 2 if heads > 8 else 1 + jobs.append(("build_attention.py", + ["--heads", str(heads), "--s", str(points), + "--heads-per-core", str(per_core)], + f"attn_h{heads}_s{points}")) + jobs.append(("build_softmax.py", + ["--rows", str(pad(heads * points, 64)), "--width", str(s_pad)], + f"softmax_{pad(heads * points, 64)}x{s_pad}")) + return jobs + + +def run(jobs, list_only, force): + OPS.mkdir(parents=True, exist_ok=True) + todo = [j for j in jobs if force or not (OPS / (j[2] + ".xclbin")).exists()] + have = len(jobs) - len(todo) + print("%d artifact(s): %d already present, %d to build" % (len(jobs), have, len(todo))) + for _, _, stem in todo: + print(" " + stem) + if list_only or not todo: + return 0 + + failed = [] + for i, (script, args, stem) in enumerate(todo): + # Builders drop an aiecc .prj work directory beside their output, so + # build into scratch and move only the two files worth keeping. + with tempfile.TemporaryDirectory(prefix="ryzenai_op_") as work: + x, b = Path(work) / (stem + ".xclbin"), Path(work) / (stem + ".insts.bin") + cmd = [sys.executable, str(HERE / script)] + args + \ + ["--xclbin", str(x), "--insts", str(b)] + print("[%d/%d] %s" % (i + 1, len(todo), stem), flush=True) + if subprocess.call(cmd, cwd=str(HERE)) != 0 or not x.exists(): + print(" FAILED") + failed.append(stem) + continue + shutil.move(str(x), str(OPS / x.name)) + shutil.move(str(b), str(OPS / b.name)) + + print("\ndone: %d built, %d failed" % (len(todo) - len(failed), len(failed))) + for f in failed: + print(" failed: " + f) + return 1 if failed else 0 + + +def snapshot(): + return {p.relative_to(ARTIFACTS).as_posix() + for p in ARTIFACTS.rglob("*") + if p.suffix in (".xclbin", ".bin")} + + +def audit(before): + """Report where this run's artifacts landed, and that nothing else did. + + The builders write to three different places - ops/ for the fused ops, and + bf16|bfp16/_col[_swiglu]/ for the GEMM grids - so a per-directory + count is the only way to see that a run produced what was asked for. It also + catches an aiecc .prj work directory left inside the artifact tree, which + happened once and quietly added a few hundred files to the deployed build. + """ + after = snapshot() + added = sorted(after - before) + print("\nartifact tree: %d files (%d new this run)" % (len(after), len(added))) + by_dir = {} + for a in added: + by_dir.setdefault(a.rsplit("/", 1)[0] if "/" in a else ".", []).append(a) + for d in sorted(by_dir): + print(" %-44s %d" % (d + "/", len(by_dir[d]))) + strays = [p for p in ARTIFACTS.rglob("*.prj") if p.is_dir()] + if strays: + print("WARNING: aiecc work directories left in the artifact tree - delete these:") + for p in strays: + print(" " + p.relative_to(ARTIFACTS).as_posix()) + return 1 + return 0 + + +def main(): + ap = argparse.ArgumentParser( + description="Build NPU artifacts into cpp/external/ryzenai_artifacts/ops") + ap.add_argument("--for-model", nargs="+", metavar="N", type=int, + help="trunk channels, heads (0 for a convnet), " + "and optionally board points (default 361)") + ap.add_argument("--ffn-hidden", type=int, metavar="K", + help="FFN hidden width, for the SwiGLU epilogue GEMM. There is no reliable " + "formula for it (384->512 but 512->768 and 768->1152), so read it off " + "the model: run katago with ryzenaiShapeReport=true and take the N of " + "the ffn.linear1 row. Omitted means skip the SwiGLU artifacts.") + ap.add_argument("--gemm-grid", action="store_true", + help="rebuild the shared K grid instead (slow; see build_grid.py)") + ap.add_argument("--list", action="store_true", help="show the plan, build nothing") + ap.add_argument("--force", action="store_true", help="rebuild artifacts that exist") + args = ap.parse_args() + + before = snapshot() + + if args.gemm_grid: + rc = subprocess.call( + [sys.executable, str(HERE / "build_grid.py"), "--arch", "npu2", + "--dtype", "bf16", "--dtype", "bfp16"], cwd=str(HERE)) + return audit(before) or rc + + if not args.for_model: + ap.error("give --for-model TRUNK HEADS [POINTS], or --gemm-grid") + trunk = args.for_model[0] + heads = args.for_model[1] if len(args.for_model) > 1 else 0 + points = args.for_model[2] if len(args.for_model) > 2 else 361 + print("model: trunk %d, %d head(s), %d board points" % (trunk, heads, points)) + rc = run(plan(trunk, heads, points), args.list, args.force) + + # The SwiGLU epilogue variants live under bf16/_col_swiglu/ rather than ops/, and + # build_swiglu_grid.py already puts them there and skips what exists, so hand off to it. + if heads > 0 and args.ffn_hidden: + print("\nSwiGLU epilogue GEMM for FFN hidden %d" % args.ffn_hidden) + cmd = [sys.executable, str(HERE / "build_swiglu_grid.py"), "--k", str(args.ffn_hidden)] + if args.list: + print(" would run: " + " ".join(cmd[1:])) + else: + rc = subprocess.call(cmd, cwd=str(HERE)) or rc + elif heads > 0: + print("\nNote: --ffn-hidden not given, so no SwiGLU epilogue artifact was considered.\n" + " Without one the FFN still runs, just without the fused activation.") + + if not args.list: + rc = audit(before) or rc + return rc + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/python/ryzenai_kernels/parse_insts.py b/python/ryzenai_kernels/parse_insts.py new file mode 100644 index 0000000000..b152746cf8 --- /dev/null +++ b/python/ryzenai_kernels/parse_insts.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +# parse_insts.py -- decode KataGo ryzenai golden .insts.bin (TXN control code) +# Field layouts follow FastFlowLM npu_utils/instr_utils/*.hpp (MIT). +import json, struct, sys, os +from pathlib import Path + +ROOT = Path(r"c:\Users\lizel\OneDrive\Desktop\Codes\Github\KataGo-Multi-backends") +ART = ROOT / "cpp/neuralnet/ryzenai/artifacts" + +OP = { + 0: "WRITE32", + 1: "BLOCKWRITE", + 3: "MASKWRITE", + 6: "PREEMPT", + 0x80: "WAIT_TCT", + 0x81: "DDR_PATCH", +} + +def u32s(data): + return list(struct.unpack("<%dI" % (len(data)//4), data)) + +def decode(words, verbose=True): + out = [] + w0, w1, ncmd, nbytes = words[0], words[1], words[2], words[3] + hdr = dict(n_rows=w0>>24, gen=(w0>>16)&0xFF, minor=(w0>>8)&0xFF, major=w0&0xFF, + mem_tile_rows=(w1>>8)&0xFF, num_cols=w1&0xFF, n_cmds=ncmd, n_bytes=nbytes) + out.append(f"HDR rows={hdr['n_rows']} gen={hdr['gen']} minor={hdr['minor']} major={hdr['major']} " + f"mem_tile_rows={hdr['mem_tile_rows']} num_cols={hdr['num_cols']} n_cmds={ncmd} n_bytes={nbytes}") + i = 4 + cmd_idx = 0 + while i < len(words): + op = words[i] + if op == 1: # BLOCKWRITE: 12 words + bd = words[i:i+12] + loc = bd[2] + col = (loc>>25)&0x7F; row=(loc>>20)&0x1F; bd_id=(loc>>5)&0xF; addr = loc & 0x1FFFF + opsize = bd[3]>>2 + buflen = bd[4]; bufoff = bd[5] + pkt = bd[6] + en_pkt = (pkt>>30)&1; ooo=(pkt>>24)&0x3F; pkt_id=(pkt>>19)&0x1F; pkt_ty=(pkt>>16)&7 + d0 = bd[7]; d1 = bd[8]; d2 = bd[9]; it = bd[10]; nb = bd[11] + is_lin = (d0 == 0) + d0s = (d0>>20)&0x3FF; d0st = (d0 & 0xFFFFF)+1 + d1s = (d1>>20)&0x3FF; d1st = (d1 & 0xFFFFF)+1 + d2st = (d2 & 0xFFFFF)+1; cache=(d2>>24)&0xF + its = ((it>>20)&0x3FF)+1; itst = (it & 0xFFFFF)+1 + nextbd=(nb>>27)&0xF; use_next=(nb>>26)&1; valid=(nb>>25)&1 + relval=(nb>>18)&0xFF; relid=(nb>>13)&0xF; acqen=(nb>>12)&1; acqval=(nb>>5)&0x7F; acqid=nb&0xF + d2s = buflen//(d0s*d1s) if (not is_lin and d0s*d1s) else 0 + out.append(f"[{cmd_idx:3d}@{i:4d}] BLOCKWRITE col={col} row={row} bd={bd_id} addr=0x{addr:x} opsz={opsize} " + f"len={buflen} bufoff={bufoff} pkt(en={en_pkt},ooo={ooo},id={pkt_id},ty={pkt_ty}) " + f"D0=({d0s},{d0st}) D1=({d1s},{d1st}) D2=({d2s},{d2st}) iter=({its},{itst}) cache={cache} " + f"next={nextbd} use_next={use_next} valid={valid} lock(rel={relval},{relid};acq={acqen},{acqval},{acqid})") + i += 12 + elif op == 0x81: # DDR_PATCH: 12 words + bd = words[i:i+12] + opsize = bd[1]>>2 + loc = bd[6] + col=(loc>>25)&0x7F; row=(loc>>20)&0x1F; bd_id=((loc-0x04)>>5)&0x1F; addr=loc&0x1FFFF + arg_idx = bd[8]; arg_off = bd[10] + out.append(f"[{cmd_idx:3d}@{i:4d}] DDR_PATCH col={col} row={row} bd={bd_id} addr=0x{addr:x} arg_idx={arg_idx} arg_off={arg_off}") + i += 12 + elif op == 0: # WRITE32: 6 words + bd = words[i:i+6] + loc = bd[2] + col=(loc>>25)&0x7F; row=(loc>>20)&0x1F; addr=loc&0xFFFFF + val = bd[4] + is_queue = (addr & 0x1FE00) == 0x1d200 + if is_queue: + ch = (loc>>3)&1; direction = "MM2S" if (addr&0x10) else "S2MM" + rep = (val>>16)&0xFF; itok=(val>>31)&1; bid=val&0xF + out.append(f"[{cmd_idx:3d}@{i:4d}] QUEUE_PUSH col={col} row={row} {direction} ch={ch} bd={bid} repeat={rep} issue_token={itok}") + else: + out.append(f"[{cmd_idx:3d}@{i:4d}] WRITE32 col={col} row={row} addr=0x{addr:05x} val=0x{val:08x}") + i += 6 + elif op == 3: # MASKWRITE: 7 words + bd = words[i:i+7] + loc = bd[2] + col=(loc>>25)&0x7F; row=(loc>>20)&0x1F; addr=loc&0xFFFFF + val=bd[4]; mask=bd[5] + # issue-token form: addr 0x1D2xx + if (addr & 0x1FE00) == 0x1d200: + ch=(loc>>3)&1; direction = "MM2S" if (addr&0x10) else "S2MM" + pktid = val>>8 + out.append(f"[{cmd_idx:3d}@{i:4d}] ISSUE_TOKEN col={col} row={row} {direction} ch={ch} pkt_id={pktid} mask=0x{mask:x}") + else: + out.append(f"[{cmd_idx:3d}@{i:4d}] MASKWRITE col={col} row={row} addr=0x{addr:05x} val=0x{val:08x} mask=0x{mask:08x}") + i += 7 + elif op == 0x80: # WAIT_TCT: 4 words + bd = words[i:i+4] + opsize=bd[1]>>2 + x=bd[2]; y=bd[3] + direction = "MM2S" if (x&1) else "S2MM" + row=(x>>8)&0xFF; col=(x>>16)&0xFF; ch=(y>>24)&0xFF + out.append(f"[{cmd_idx:3d}@{i:4d}] WAIT_TCT col={col} row={row} {direction} ch={ch} (w3=0x{y:x})") + i += 4 + elif op == 6: + out.append(f"[{cmd_idx:3d}@{i:4d}] PREEMPT level={(words[i]>>8)&3}") + i += 1 + else: + out.append(f"[{cmd_idx:3d}@{i:4d}] UNKNOWN op=0x{op:x} words={['%08x'%w for w in words[i:i+4]]}") + i += 1 + cmd_idx += 1 + return hdr, out + +def main(): + manifest = json.loads((ART/"manifest.json").read_text()) + seen = {} + for a in manifest["artifacts"]: + p = ART / a["insts"] + key = (a["arch"], a["n_aie_cols"], a["M"], a["K"], a["N"]) + if key in seen: + continue + seen[key] = True + data = p.read_bytes() + words = u32s(data) + hdr, lines = decode(words) + tag = f"{a['arch']}_{a['n_aie_cols']}col M{a['M']}K{a['K']}N{a['N']} tile={a['tile']['m']}x{a['tile']['k']}x{a['tile']['n']}" + print("="*100) + print(f"{p.relative_to(ART)} {tag}") + print("="*100) + for l in lines: + print(l) + +if __name__ == "__main__": + main() diff --git a/python/ryzenai_kernels/setup_env.ps1 b/python/ryzenai_kernels/setup_env.ps1 new file mode 100644 index 0000000000..351d059df9 --- /dev/null +++ b/python/ryzenai_kernels/setup_env.ps1 @@ -0,0 +1,193 @@ +<# +.SYNOPSIS +Set up the mlir-aie ("iron") Python environment that make_artifacts.py needs. + +.DESCRIPTION +Only kernel authors need this. Building katago itself needs nothing from here, +and running it needs nothing at all beyond the NPU driver - the .xclbin files +are already in the repository. This is for regenerating them. + +What it does, in order: + + 1. Checks the prerequisites (Python, the MSVC C++ toolchain, the XRT SDK) and + stops with an explanation if one is missing. It never installs any of them. + 2. Creates a virtual environment at -Prefix. + 3. Installs the mlir-aie wheels plus numpy and ml_dtypes into it. + 4. Writes activate_iron.bat next to this script, which enters the environment + with mlir_aie/bin and the XRT tools on PATH. + 5. Verifies by importing aie.iron and running make_artifacts.py --list. + +Nothing is downloaded or installed unless -Execute is passed. Without it the +script prints the exact commands it would run, so the several hundred megabytes +of wheels are never fetched by surprise. + +.PARAMETER Prefix +Where to create the environment. Required, deliberately: this puts a large +tree somewhere permanent, and guessing a location for that is not the script's +call to make. + +.PARAMETER Version +mlir-aie release tag to install. Defaults to the newest release. + +.PARAMETER Execute +Actually create the environment. Without this the script only reports. + +.EXAMPLE +.\setup_env.ps1 -Prefix C:\Envs\mlir-aie +Report what would be done, changing nothing. + +.EXAMPLE +.\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute +Create the environment for real. +#> +[CmdletBinding()] +param( + [string]$Prefix, + [string]$Version = "latest", + [switch]$Execute +) + +$ErrorActionPreference = "Stop" +$Here = Split-Path -Parent $MyInvocation.MyCommand.Path + +function Fail($msg) { Write-Host "ERROR: $msg" -ForegroundColor Red; exit 1 } +function Step($msg) { Write-Host "`n== $msg" -ForegroundColor Cyan } +function Note($msg) { Write-Host " $msg" } + +if (-not $Prefix) { + Write-Host @" +ERROR: -Prefix is required. + +Give the directory to create the mlir-aie environment in. It is not defaulted +because it holds a multi-gigabyte toolchain and where that belongs is your call, +not this script's. + + .\setup_env.ps1 -Prefix C:\Envs\mlir-aie # report only + .\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute # actually install + .\setup_env.ps1 -Prefix D:\tools\mlir-aie -Execute # anywhere else + +See Compiling.md, "Regenerating the RyzenAI NPU kernels", for the full flow. +"@ -ForegroundColor Red + exit 1 +} + +# ---- 1. prerequisites, checked but never installed -------------------------- + +Step "Checking prerequisites" + +$py = Get-Command python -ErrorAction SilentlyContinue +if (-not $py) { Fail "python is not on PATH. Install Python 3.10 or newer from python.org or via conda." } +$pyver = (& python -c "import sys;print('%d.%d'%sys.version_info[:2])").Trim() +if ([version]$pyver -lt [version]"3.10") { + Fail "python $pyver is too old; mlir-aie needs 3.10 or newer. The one on PATH is $($py.Source)." +} +Note "python $pyver at $($py.Source)" + +# vswhere sits at a documented fixed location under Program Files, so this +# neither hardcodes an edition nor a version. +$vswhere = $null +foreach ($pf in @(${env:ProgramFiles(x86)}, $env:ProgramFiles)) { + if ($pf) { + $cand = Join-Path $pf "Microsoft Visual Studio\Installer\vswhere.exe" + if (Test-Path $cand) { $vswhere = $cand; break } + } +} +if (-not $vswhere) { + Fail "vswhere.exe not found. Install Visual Studio Build Tools with the 'Desktop development with C++' workload - the kernel compiler shells out to cl.exe." +} +$vsPath = & $vswhere -all -sort -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath | Select-Object -First 1 +if (-not $vsPath) { + Fail "No Visual Studio C++ toolchain found. Install the 'Desktop development with C++' workload." +} +Note "MSVC toolchain at $vsPath" + +# XRT: the env var if it points somewhere real, else the conventional install +# root. Probe for xclbinutil.exe itself rather than for a bin\ directory - the +# Windows SDK puts its tools straight in the install root, and xclbinutil is the +# one thing aiecc actually shells out to. Both layouts are accepted. +$xrt = $null +foreach ($cand in @($env:XILINX_XRT, "C:\Xilinx\XRT")) { + if (-not $cand) { continue } + foreach ($sub in @("", "bin")) { + $dir = if ($sub) { Join-Path $cand $sub } else { $cand } + if (Test-Path (Join-Path $dir "xclbinutil.exe")) { $xrt = $dir; break } + } + if ($xrt) { break } +} +if (-not $xrt) { + Fail "xclbinutil.exe not found. Install AMD's XRT for Windows and either set XILINX_XRT to it or accept the default C:\Xilinx\XRT - aiecc shells out to xclbinutil to package each .xclbin." +} +Note "XRT at $xrt" + +# ---- 2..5. the plan --------------------------------------------------------- + +$venv = Join-Path $Prefix "ironenv" +$venvPy = Join-Path $venv "Scripts\python.exe" +$wheelIndex = "https://github.com/Xilinx/mlir-aie/releases" +$activateBat = Join-Path $Here "activate_iron.bat" + +$plan = @( + @{ What = "create venv"; Cmd = "python -m venv `"$venv`"" }, + @{ What = "upgrade pip"; Cmd = "`"$venvPy`" -m pip install --upgrade pip wheel" }, + @{ What = "install mlir-aie"; Cmd = "`"$venvPy`" -m pip install --find-links $wheelIndex/$Version mlir_aie mlir_aie_tools" }, + @{ What = "install deps"; Cmd = "`"$venvPy`" -m pip install numpy ml_dtypes" } +) + +Step "Plan" +Note "environment : $venv" +Note "mlir-aie : $Version" +Note "activator : $activateBat" +foreach ($p in $plan) { Note ("{0,-16} {1}" -f $p.What, $p.Cmd) } + +if (-not $Execute) { + Write-Host "`nDry run - nothing was downloaded or created. Re-run with -Execute to proceed." -ForegroundColor Yellow + Write-Host "The mlir-aie wheels are several hundred megabytes." -ForegroundColor Yellow + exit 0 +} + +Step "Creating the environment" +if (Test-Path $venvPy) { + Note "already exists, reusing: $venv" +} else { + New-Item -ItemType Directory -Force -Path $Prefix | Out-Null + & python -m venv $venv + if ($LASTEXITCODE -ne 0) { Fail "venv creation failed." } +} + +foreach ($p in $plan | Select-Object -Skip 1) { + Step $p.What + cmd /c $p.Cmd + if ($LASTEXITCODE -ne 0) { Fail "$($p.What) failed. See the pip output above." } +} + +# ---- the activator ---------------------------------------------------------- + +Step "Writing $activateBat" +$mlirBin = Join-Path $venv "Lib\site-packages\mlir_aie\bin" +@" +@echo off +rem Generated by setup_env.ps1. Enters the mlir-aie environment so that +rem make_artifacts.py can run: +rem +rem activate_iron.bat +rem python make_artifacts.py --for-model 512 8 --ffn-hidden 768 +rem +rem aiecc needs mlir_aie\bin for its own tools and XRT for xclbinutil. +set "PATH=$mlirBin;$xrt;%PATH%" +call "$venv\Scripts\activate.bat" +"@ | Set-Content -Path $activateBat -Encoding ascii +Note "written" + +# ---- verify ----------------------------------------------------------------- + +Step "Verifying" +$env:PATH = "$mlirBin;$xrt;$env:PATH" +& $venvPy -c "import aie.iron; print(' aie.iron imports OK')" +if ($LASTEXITCODE -ne 0) { Fail "the environment installed but 'import aie.iron' fails." } +& $venvPy (Join-Path $Here "make_artifacts.py") --list --for-model 384 6 +if ($LASTEXITCODE -ne 0) { Fail "make_artifacts.py could not run." } + +Write-Host "`nDone. Use it with:" -ForegroundColor Green +Write-Host " cd `"$Here`"" +Write-Host " activate_iron.bat" +Write-Host " python make_artifacts.py --for-model [points] [--ffn-hidden K]" From 1d50e62c072c8e12c85c5130dfbe8d1afd63815a Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 18 Aug 2026 22:00:23 +0800 Subject: [PATCH 33/37] Update README, cfg, setup_env.ps1 and gitignore --- .gitignore | 2 +- Compiling.md | 17 +-- README.md | 22 ++++ cpp/configs/gtp_example.cfg | 29 ++++- python/ryzenai_kernels/README.md | 105 +++++++++++++++ python/ryzenai_kernels/setup_env.ps1 | 186 ++++++++++++++++----------- 6 files changed, 264 insertions(+), 97 deletions(-) create mode 100644 python/ryzenai_kernels/README.md diff --git a/.gitignore b/.gitignore index 99b64501c2..e49a7a35b3 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,7 @@ cpp/tests/results/matchsgfs2/games.sgfs cpp/data/ versions/ -cpp/build +cpp/build* cpp/out export_model_cuda.sh diff --git a/Compiling.md b/Compiling.md index e02d1f8452..6e8aabe30a 100644 --- a/Compiling.md +++ b/Compiling.md @@ -127,22 +127,7 @@ As also mentioned in the instructions below but repeated here for visibility, if `ninja` works in place of `cmake --build .` if you have it on your PATH. If CMake cannot find something it names what and where to get it; `-DZLIB_ROOT=...` and `-DXRT_RUNTIME_DLL_DIR=...` override the search. * The build directory runs as-is: `katago.exe`, the XRT runtime DLLs beside it, and the NPU kernels in a `ryzenai` subdirectory. Copy all three together if you move it. * **Precision:** on XDNA2 the default is block floating point, which is faster; `ryzenaiDtype = bf16` in the config selects the more accurate format instead. XDNA1 only has bf16. Either way the NPU is not computing in fp32, so its outputs differ slightly from the CPU backends - enough to pick differently between two nearly-equal moves, not enough to matter for strength. - * **Regenerating the NPU kernels** - only needed for a network shape that has no kernel yet. The shipped set already covers every reduction dimension up to 6912, so most new models need nothing at all. Run katago with `-override-config ryzenaiShapeReport=true` to see what a model asks for; the log names any shape that fell back to the CPU. - * This needs the [mlir-aie](https://github.com/Xilinx/mlir-aie) toolchain, which is several gigabytes and is installed into a virtual environment of your choosing: - ``` - cd python\ryzenai_kernels - .\setup_env.ps1 -Prefix C:\Envs\mlir-aie # report the plan, download nothing - .\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute # install for real - ``` - `-Prefix` is required and has no default - any path works, e.g. `-Prefix D:\tools\mlir-aie`. Without `-Execute` the script only checks prerequisites and prints what it would do. - * Then generate. Artifacts land in `cpp/external/ryzenai_artifacts` in the layout the loader expects, intermediate build trees are cleaned up, and the next `cmake --build` copies everything next to `katago.exe`: - ``` - activate_iron.bat - python make_artifacts.py --list --for-model 512 8 # plan only - python make_artifacts.py --for-model 512 8 --ffn-hidden 768 # transformer - python make_artifacts.py --for-model 768 0 # convnet - ``` - The arguments are trunk channels, attention heads (0 for a convnet), and optionally board points (default 361, i.e. 19x19). `--ffn-hidden` is the FFN hidden width from the shape report; without it the SwiGLU activation runs unfused, which costs a few percent. + * **Regenerating the NPU kernels** - only needed for a network shape that has no kernel yet, which is rare: the shipped set covers every reduction dimension up to 6912. See [python/ryzenai_kernels/README.md](python/ryzenai_kernels/README.md). * Done! You should now have a compiled `katago.exe` executable in your working directory. * Note: You may need to copy the ".dll" files corresponding to the various ".lib" (".a") files you compiled with into the directory containing katago.exe. * MinGW has different dlls. If you use pacman, the necessary dlls (`libbz2-1.dll`, `libzip.dll`, `libzstd.dll`, `liblzma-5.dll`) should be copied from MinGW bin directory (like `C:\msys64\mingw64\bin`). diff --git a/README.md b/README.md index 32439a5739..5191eeecf4 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ * [OpenCL vs CUDA vs TensorRT vs RyzenAI vs Eigen](#opencl-vs-cuda-vs-tensorrt-vs-ryzenai-vs-eigen) * [How To Use](#how-to-use) * [Tuning for Performance](#tuning-for-performance) + * [RyzenAI config parameters](#ryzenai-config-parameters) * [Common Questions and Issues](#common-questions-and-issues) * [Issues with specific GPUs or GPU drivers](#issues-with-specific-gpus-or-gpu-drivers) * [Common Problems](#common-problems) @@ -174,6 +175,27 @@ The most important parameter to optimize for KataGo's performance is the number Secondarily, you can also read over the parameters in your GTP config (`default_gtp.cfg` or `gtp_example.cfg` or `configs/gtp_example.cfg`, etc). A lot of other settings are described in there that you can set to adjust KataGo's resource usage, or choose which GPUs to use. You can also adjust things like KataGo's resign threshold, pondering behavior or utility function. Most parameters are documented directly inline in the [example config file](cpp/configs/gtp_example.cfg). Many can also be interactively set when generating a config via the `genconfig` command described above. +#### RyzenAI config parameters + +All of these are optional - the defaults are what you want unless you are measuring something. Add them to whichever config you run with. + +| Parameter | Values | Default | What it does | +| --- | --- | --- | --- | +| `ryzenaiDtype` | `auto`, `bf16`, `bfp16` | `auto` | Numeric format for the NPU kernels. `auto` picks block floating point on XDNA2 and bf16 on XDNA1, which is the only format XDNA1 has. `bf16` is the more accurate of the two and costs roughly 10% throughput; set it explicitly if you would rather have the precision. | +| `ryzenaiMaxColumns` | 0-64 | `4` | How many of the NPU's columns one kernel may use. More is not automatically better: a small net gets *slower* with more columns, because each distinct kernel is its own hardware context and the driver ends up switching between them. Large nets do benefit. Measure with `katago benchmark` before changing it. | +| `ryzenaiForceNpuOnly` | bool | `false` | Refuse to fall back to the CPU. Normally a layer with no matching kernel quietly runs on the CPU instead, which is correct but slower; this turns that into a hard failure, which is what you want when verifying that the NPU is really being used. | +| `ryzenaiArtifactDir` | path | next to the executable | Where the `.xclbin` kernels live. Pointing it at a nonexistent directory forces the whole network onto the CPU reference path, which is the simplest way to compare NPU output against CPU output. | +| `ryzenaiVerboseDispatch` | bool | `false` | Log where the time went: host-side packing, NPU dispatch, unpacking, and the operators still running on the CPU. Also reports any kernel that was wanted but missing. Start here when performance is not what you expect. | +| `ryzenaiShapeReport` | bool | `false` | Log every matrix shape the loaded model asks for. Needed only when generating kernels for a new network - see [Compiling.md](Compiling.md). | +| `ryzenaiForceK` | -1 to 65536 | `-1` | Collapse every layer onto one kernel by padding their reduction dimensions up to this value, trading wasted arithmetic for fewer context switches. `-1` lets KataGo decide per model, which is almost always right. | +| `ryzenaiSelfTest` | bool | `false` | Run a built-in matrix-multiply check against the NPU at startup. | +| `ryzenaiDeviceToUse` | int | `0` | Which NPU, on a machine with more than one. `ryzenaiDeviceToUseThread0`, `...Thread1` and so on assign devices per neural net thread, exactly as the equivalent OpenCL and CUDA settings do. | + +Two things worth knowing beyond the parameters: + + * **Threads matter more here than the settings above.** The NPU pays a fixed cost per dispatch, and KataGo amortizes it by batching evaluations from several search threads into one. Going from `numSearchThreads = 1` to `16` measured about 1.9x more evaluations per second on the same hardware - a bigger win than anything in the table. `katago benchmark` will suggest a value for your machine. + * **The NPU does not compute in fp32**, so its policy and value outputs differ slightly from the CPU backends. The difference is small enough that the top moves come out the same, but large enough to flip the engine's choice between two moves it considers nearly equal. If you need bit-reproducibility across machines, use a CPU backend. + ### Common Questions and Issues This section summarizes a number of common questions and issues when running KataGo. diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index 7188d8890f..edd3fa1bc5 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -559,10 +559,6 @@ searchFactorWhenWinningThreshold = 0.95 # to a "ryzenai" subdirectory next to the katago executable. # ryzenaiArtifactDir = C:/path/to/ryzenai/artifacts -# Directory for cached data derived from the model. If unset, follows KataGo's -# usual home data dir convention (see homeDataDir), in a "ryzenaicache" subdir. -# ryzenaiCacheDir = C:/path/to/cache - # Numeric format requested for NPU kernels: auto, bf16, or bfp16. # # auto - bfp16 on XDNA2 (Strix and later), bf16 on XDNA1. This is the default. @@ -578,13 +574,34 @@ searchFactorWhenWinningThreshold = 0.95 # accuracy than the speed. # ryzenaiDtype = auto +# How many of the NPU's columns one kernel may use. More is not automatically +# better: each distinct kernel is its own hardware context, and a small net ends +# up losing more to context switching than it gains from the extra width. Large +# nets do benefit. Measure with `katago benchmark` before changing this. +# ryzenaiMaxColumns = 4 + # Set to true to fail hard if no NPU kernel artifacts are found, instead of -# falling back to the CPU reference forward path. +# falling back to the CPU reference forward path. Useful for confirming that the +# NPU really is being used, since the fallback is silent and correct - just slow. # ryzenaiForceNpuOnly = false -# Set to true to log per-thread dispatch details. +# Set to true to log where each evaluation's time went (host-side packing, NPU +# dispatch, unpacking, and the operators still on the CPU), plus any kernel that +# was wanted but missing. Start here when performance is not what you expect. # ryzenaiVerboseDispatch = false +# Set to true to log every matrix shape this model asks for. Needed only when +# generating kernels for a network that has none yet - see Compiling.md. +# ryzenaiShapeReport = false + +# Collapse every layer onto one kernel by padding reduction dimensions up to this +# value, trading wasted arithmetic for fewer context switches. -1 lets KataGo +# decide per model, which is almost always right. +# ryzenaiForceK = -1 + +# Set to true to run a built-in matrix-multiply check against the NPU at startup. +# ryzenaiSelfTest = false + # For one NPU: optionally uncomment and change this if the device to use is guessed incorrectly. # ryzenaiDeviceToUse = 0 diff --git a/python/ryzenai_kernels/README.md b/python/ryzenai_kernels/README.md new file mode 100644 index 0000000000..8293de2979 --- /dev/null +++ b/python/ryzenai_kernels/README.md @@ -0,0 +1,105 @@ +# RyzenAI NPU kernel generation + +Offline tooling that compiles the `.xclbin` kernels the RyzenAI backend runs on +the NPU. Nothing here is needed to build or run KataGo: the kernels are +committed under `cpp/external/ryzenai_artifacts`, and `cmake --build` copies +them next to `katago.exe`. You only come here to support a network shape that +has no kernel yet. + +## Do you actually need this? + +Usually not. An `.xclbin` bakes in exactly one thing about the network - the +reduction dimension `K` of a matrix multiply - and the shipped grid covers every +`K` up to 6912 in steps of 64. A network whose `K` is not in the grid still +runs: the loader picks the next size up and the extra columns are zero-filled, +costing some wasted arithmetic and nothing else. Everything else about a shape, +including batch size and output width, is generated at run time by +`cpp/neuralnet/ryzenaisequence.cpp`, which is why an arbitrary `.bin.gz` works +with no Python at all. + +What *does* need new kernels is a network using a fused operator geometry that +has not been compiled yet - a head count, board size, channel width or FFN +width outside the shipped set. Those operators are optional: without a matching +one the layer falls back to a slower path that produces identical numbers. + +To find out, run KataGo with the shape report on: + +``` +katago.exe gtp -model .bin.gz -config -override-config ryzenaiShapeReport=true +``` + +It lists every shape the model asks for. With `ryzenaiVerboseDispatch=true` the +log also names any operator that was wanted but missing, e.g. + +``` +bn+mish NOT on NPU for 192 channels x 384 rows: no 384x192 artifact +``` + +## Setting up + +The toolchain is a git checkout of [mlir-aie](https://github.com/Xilinx/mlir-aie), +not just a set of wheels - the GEMM generators compile against kernel sources in +its `aie_kernels` tree. `setup_env.ps1` clones it and runs the installer that +ships inside it, so the environment always matches that checkout: + +``` +.\setup_env.ps1 -Prefix C:\Envs\mlir-aie # report the plan, download nothing +.\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute # clone and install +``` + +`-Prefix` is required and has no default - the tree is several gigabytes, so +where it goes is your decision. Any path works. Without `-Execute` the script +only checks prerequisites (git, Python 3.10+, the MSVC C++ toolchain, XRT) and +prints what it would do; it never installs any of those for you. + +It writes `activate_iron.bat` here when it finishes. + +## Generating + +``` +activate_iron.bat +python make_artifacts.py --list --for-model 512 8 # plan only, build nothing +python make_artifacts.py --for-model 512 8 --ffn-hidden 768 # a transformer +python make_artifacts.py --for-model 768 0 # a convnet +python make_artifacts.py --gemm-grid # the shared K grid (hours) +``` + +The positional arguments are trunk channels, attention heads (`0` for a +convnet), and optionally board points (default 361, i.e. 19x19). + +`--ffn-hidden` is the FFN hidden width, read off the shape report. There is no +formula for it - 384 channels goes with 512, but 512 goes with 768 and 768 with +1152 - so it has to be given. Without it the SwiGLU activation runs unfused, +which costs a few percent. + +Artifacts land in `cpp/external/ryzenai_artifacts` in the layout the loader +expects, already-present ones are skipped, and the aiecc work trees are deleted +on the way out. The run ends with a per-directory count of what it added. + +## What each piece is + +| File | Role | +| --- | --- | +| `make_artifacts.py` | The entry point. Works out which artifacts a model geometry needs and calls the builders below. | +| `setup_env.ps1` | Clones mlir-aie and runs its installer. | +| `build_grid.py` | The shared GEMM grid, one binary per (dtype, arch, columns, K). `--reindex` rebuilds `grid.json` from what is on disk without compiling. | +| `build_swiglu_grid.py` | GEMM variants with the SwiGLU activation folded into the epilogue. | +| `build_attention.py` | Fused attention: QK^T, softmax and P*V on-chip, one dispatch per instance. | +| `build_softmax.py` | Standalone softmax rows. | +| `build_bn_mish.py` | Fused BatchNorm + Mish, for convnets. | +| `gemm_bf16.py`, `gemm_swiglu_bf16.py` | The GEMM designs the two grid drivers compile. | +| `kernels/*.cc` | AIE core sources for the fused operators. The plain GEMM uses mlir-aie's own templates instead. | +| `aiecc_cleanup.py` | Deletes the `.prj` work tree aiecc leaves beside each artifact. | +| `extract_layout.py` | Regenerates `cpp/neuralnet/ryzenaisequence_layout.h` from golden instruction streams. Only needed when changing which column counts are supported. | +| `parse_insts.py`, `INSTS_FORMAT.md` | Decoder and format notes for the DMA instruction streams that `ryzenaisequence.cpp` generates. | + +## Notes + +* Each builder can be run directly if you want one specific artifact; + `--xclbin` and `--insts` say where to put it. `make_artifacts.py` exists so + that you do not have to work out the names and geometry by hand. +* `--keep-work` on the operator builders keeps the aiecc `.prj` tree, which is + worth doing when a compile fails - the logs in there are the only record of + why. +* Compiling one operator takes tens of seconds. The full GEMM grid is hundreds + of binaries and takes hours; it is committed precisely so that nobody has to. diff --git a/python/ryzenai_kernels/setup_env.ps1 b/python/ryzenai_kernels/setup_env.ps1 index 351d059df9..85a0e3e248 100644 --- a/python/ryzenai_kernels/setup_env.ps1 +++ b/python/ryzenai_kernels/setup_env.ps1 @@ -1,36 +1,44 @@ <# .SYNOPSIS -Set up the mlir-aie ("iron") Python environment that make_artifacts.py needs. +Set up the mlir-aie ("IRON") toolchain that make_artifacts.py needs. .DESCRIPTION -Only kernel authors need this. Building katago itself needs nothing from here, -and running it needs nothing at all beyond the NPU driver - the .xclbin files -are already in the repository. This is for regenerating them. +Only kernel authors need this. Building katago needs nothing from here, and +running it needs nothing at all beyond the NPU driver - the .xclbin kernels are +committed to this repository. This is for regenerating them. + +The toolchain is a git checkout, not just a set of wheels: the GEMM generators +compile against kernel sources that live in the repository's aie_kernels tree +and are not part of any wheel. So this clones mlir-aie and runs the installer +that ships inside it (utils/iron_setup.py), which builds the virtual +environment and writes the iron_env activation scripts. Doing it that way means +the environment always matches whatever that checkout expects, rather than a +second guess maintained here. What it does, in order: - 1. Checks the prerequisites (Python, the MSVC C++ toolchain, the XRT SDK) and + 1. Checks the prerequisites (git, Python, the MSVC C++ toolchain, XRT) and stops with an explanation if one is missing. It never installs any of them. - 2. Creates a virtual environment at -Prefix. - 3. Installs the mlir-aie wheels plus numpy and ml_dtypes into it. - 4. Writes activate_iron.bat next to this script, which enters the environment - with mlir_aie/bin and the XRT tools on PATH. - 5. Verifies by importing aie.iron and running make_artifacts.py --list. + 2. Clones mlir-aie into -Prefix, or reuses the checkout already there. + 3. Runs its utils/iron_setup.py to create the environment. + 4. Writes activate_iron.bat next to this script, which enters that + environment from anywhere. + 5. Verifies: aie.iron imports, the aie_kernels tree the GEMM generators need + is present, and make_artifacts.py runs. -Nothing is downloaded or installed unless -Execute is passed. Without it the -script prints the exact commands it would run, so the several hundred megabytes -of wheels are never fetched by surprise. +Nothing is cloned or installed unless -Execute is passed. Without it the script +only checks prerequisites and prints what it would do, so several gigabytes are +never fetched by surprise. .PARAMETER Prefix -Where to create the environment. Required, deliberately: this puts a large -tree somewhere permanent, and guessing a location for that is not the script's -call to make. +Where to put the mlir-aie checkout and its environment. Required, deliberately: +this is a multi-gigabyte tree and where it belongs is your call. -.PARAMETER Version -mlir-aie release tag to install. Defaults to the newest release. +.PARAMETER Ref +Git ref (branch, tag or commit) to check out. Defaults to the default branch. .PARAMETER Execute -Actually create the environment. Without this the script only reports. +Actually clone and install. Without this the script only reports. .EXAMPLE .\setup_env.ps1 -Prefix C:\Envs\mlir-aie @@ -38,17 +46,18 @@ Report what would be done, changing nothing. .EXAMPLE .\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute -Create the environment for real. +Clone and install for real. #> [CmdletBinding()] param( [string]$Prefix, - [string]$Version = "latest", + [string]$Ref, [switch]$Execute ) $ErrorActionPreference = "Stop" $Here = Split-Path -Parent $MyInvocation.MyCommand.Path +$RepoUrl = "https://github.com/Xilinx/mlir-aie.git" function Fail($msg) { Write-Host "ERROR: $msg" -ForegroundColor Red; exit 1 } function Step($msg) { Write-Host "`n== $msg" -ForegroundColor Cyan } @@ -58,15 +67,15 @@ if (-not $Prefix) { Write-Host @" ERROR: -Prefix is required. -Give the directory to create the mlir-aie environment in. It is not defaulted -because it holds a multi-gigabyte toolchain and where that belongs is your call, -not this script's. +Give the directory to put the mlir-aie checkout and its environment in. It is +not defaulted because it is a multi-gigabyte tree and where that belongs is your +call, not this script's. .\setup_env.ps1 -Prefix C:\Envs\mlir-aie # report only .\setup_env.ps1 -Prefix C:\Envs\mlir-aie -Execute # actually install .\setup_env.ps1 -Prefix D:\tools\mlir-aie -Execute # anywhere else -See Compiling.md, "Regenerating the RyzenAI NPU kernels", for the full flow. +See Compiling.md, "Regenerating the NPU kernels", for the full flow. "@ -ForegroundColor Red exit 1 } @@ -75,8 +84,13 @@ See Compiling.md, "Regenerating the RyzenAI NPU kernels", for the full flow. Step "Checking prerequisites" +if (-not (Get-Command git -ErrorAction SilentlyContinue)) { + Fail "git is not on PATH. The toolchain is a git checkout, not just wheels." +} +Note "git present" + $py = Get-Command python -ErrorAction SilentlyContinue -if (-not $py) { Fail "python is not on PATH. Install Python 3.10 or newer from python.org or via conda." } +if (-not $py) { Fail "python is not on PATH. Install Python 3.10 or newer." } $pyver = (& python -c "import sys;print('%d.%d'%sys.version_info[:2])").Trim() if ([version]$pyver -lt [version]"3.10") { Fail "python $pyver is too old; mlir-aie needs 3.10 or newer. The one on PATH is $($py.Source)." @@ -96,74 +110,86 @@ if (-not $vswhere) { Fail "vswhere.exe not found. Install Visual Studio Build Tools with the 'Desktop development with C++' workload - the kernel compiler shells out to cl.exe." } $vsPath = & $vswhere -all -sort -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath | Select-Object -First 1 -if (-not $vsPath) { - Fail "No Visual Studio C++ toolchain found. Install the 'Desktop development with C++' workload." -} +if (-not $vsPath) { Fail "No Visual Studio C++ toolchain found. Install the 'Desktop development with C++' workload." } Note "MSVC toolchain at $vsPath" -# XRT: the env var if it points somewhere real, else the conventional install -# root. Probe for xclbinutil.exe itself rather than for a bin\ directory - the -# Windows SDK puts its tools straight in the install root, and xclbinutil is the -# one thing aiecc actually shells out to. Both layouts are accepted. -$xrt = $null -foreach ($cand in @($env:XILINX_XRT, "C:\Xilinx\XRT")) { +# XRT: probe for xclbinutil.exe rather than for a bin\ directory - the Windows +# SDK puts its tools straight in the install root, and xclbinutil is the one +# thing aiecc actually shells out to. +$xrtRoot = $null +foreach ($cand in @($env:XRT_ROOT, $env:XILINX_XRT, "C:\Xilinx\XRT")) { if (-not $cand) { continue } foreach ($sub in @("", "bin")) { $dir = if ($sub) { Join-Path $cand $sub } else { $cand } - if (Test-Path (Join-Path $dir "xclbinutil.exe")) { $xrt = $dir; break } + if (Test-Path (Join-Path $dir "xclbinutil.exe")) { $xrtRoot = $cand; break } } - if ($xrt) { break } + if ($xrtRoot) { break } } -if (-not $xrt) { - Fail "xclbinutil.exe not found. Install AMD's XRT for Windows and either set XILINX_XRT to it or accept the default C:\Xilinx\XRT - aiecc shells out to xclbinutil to package each .xclbin." +if (-not $xrtRoot) { + Fail "xclbinutil.exe not found. Install AMD's XRT for Windows and either set XRT_ROOT to it or accept the default C:\Xilinx\XRT - aiecc shells out to xclbinutil to package each .xclbin." } -Note "XRT at $xrt" +Note "XRT at $xrtRoot" -# ---- 2..5. the plan --------------------------------------------------------- +# ---- the plan --------------------------------------------------------------- -$venv = Join-Path $Prefix "ironenv" -$venvPy = Join-Path $venv "Scripts\python.exe" -$wheelIndex = "https://github.com/Xilinx/mlir-aie/releases" $activateBat = Join-Path $Here "activate_iron.bat" - -$plan = @( - @{ What = "create venv"; Cmd = "python -m venv `"$venv`"" }, - @{ What = "upgrade pip"; Cmd = "`"$venvPy`" -m pip install --upgrade pip wheel" }, - @{ What = "install mlir-aie"; Cmd = "`"$venvPy`" -m pip install --find-links $wheelIndex/$Version mlir_aie mlir_aie_tools" }, - @{ What = "install deps"; Cmd = "`"$venvPy`" -m pip install numpy ml_dtypes" } -) +$ironPs1 = Join-Path $Prefix "iron_env.ps1" +$cloneArgs = if ($Ref) { "clone $RepoUrl `"$Prefix`" && git -C `"$Prefix`" checkout $Ref" } else { "clone $RepoUrl `"$Prefix`"" } Step "Plan" -Note "environment : $venv" -Note "mlir-aie : $Version" -Note "activator : $activateBat" -foreach ($p in $plan) { Note ("{0,-16} {1}" -f $p.What, $p.Cmd) } +Note "checkout : $Prefix (from $RepoUrl$(if ($Ref) { ", ref $Ref" }))" +Note "installer : $Prefix\utils\iron_setup.py --xrt-root `"$xrtRoot`"" +Note "activator : $activateBat -> $ironPs1" +if (Test-Path (Join-Path $Prefix ".git")) { Note "note : a checkout already exists there and will be reused, not re-cloned" } if (-not $Execute) { - Write-Host "`nDry run - nothing was downloaded or created. Re-run with -Execute to proceed." -ForegroundColor Yellow - Write-Host "The mlir-aie wheels are several hundred megabytes." -ForegroundColor Yellow + Write-Host "`nDry run - nothing was cloned or installed. Re-run with -Execute to proceed." -ForegroundColor Yellow + Write-Host "The checkout plus its environment is several gigabytes." -ForegroundColor Yellow exit 0 } -Step "Creating the environment" -if (Test-Path $venvPy) { - Note "already exists, reusing: $venv" +# ---- 2. the checkout -------------------------------------------------------- + +Step "Getting mlir-aie" +if (Test-Path (Join-Path $Prefix ".git")) { + Note "reusing the checkout already at $Prefix" + if ($Ref) { + & git -C $Prefix fetch --all --quiet + & git -C $Prefix checkout $Ref + if ($LASTEXITCODE -ne 0) { Fail "could not check out $Ref." } + } } else { - New-Item -ItemType Directory -Force -Path $Prefix | Out-Null - & python -m venv $venv - if ($LASTEXITCODE -ne 0) { Fail "venv creation failed." } + if ((Test-Path $Prefix) -and (Get-ChildItem $Prefix -Force | Select-Object -First 1)) { + Fail "$Prefix exists and is not empty, but is not a git checkout. Point -Prefix somewhere else, or clear it." + } + & git clone $RepoUrl $Prefix + if ($LASTEXITCODE -ne 0) { Fail "git clone failed." } + if ($Ref) { + & git -C $Prefix checkout $Ref + if ($LASTEXITCODE -ne 0) { Fail "could not check out $Ref." } + } } +Note ("at commit " + (& git -C $Prefix rev-parse --short HEAD)) + +# ---- 3. its own installer --------------------------------------------------- -foreach ($p in $plan | Select-Object -Skip 1) { - Step $p.What - cmd /c $p.Cmd - if ($LASTEXITCODE -ne 0) { Fail "$($p.What) failed. See the pip output above." } +Step "Running the checkout's own installer (utils/iron_setup.py)" +Push-Location $Prefix +try { + & python (Join-Path $Prefix "utils\iron_setup.py") --xrt-root $xrtRoot + if ($LASTEXITCODE -ne 0) { Fail "iron_setup.py failed. See its output above." } +} finally { + Pop-Location +} +if (-not (Test-Path $ironPs1)) { + Fail "iron_setup.py finished but did not write $ironPs1. The checkout's layout may have changed." } -# ---- the activator ---------------------------------------------------------- +# ---- 4. the activator ------------------------------------------------------- Step "Writing $activateBat" -$mlirBin = Join-Path $venv "Lib\site-packages\mlir_aie\bin" +$ironCmd = Join-Path $Prefix "iron_env.cmd" +if (-not (Test-Path $ironCmd)) { Fail "expected $ironCmd from iron_setup.py, but it is not there." } @" @echo off rem Generated by setup_env.ps1. Enters the mlir-aie environment so that @@ -172,18 +198,30 @@ rem rem activate_iron.bat rem python make_artifacts.py --for-model 512 8 --ffn-hidden 768 rem -rem aiecc needs mlir_aie\bin for its own tools and XRT for xclbinutil. -set "PATH=$mlirBin;$xrt;%PATH%" -call "$venv\Scripts\activate.bat" +rem The real work is done by the checkout's own iron_env.cmd, which sets +rem MLIR_AIE_INSTALL_DIR, PEANO_INSTALL_DIR, XRT_ROOT and the rest. +call "$ironCmd" "@ | Set-Content -Path $activateBat -Encoding ascii Note "written" -# ---- verify ----------------------------------------------------------------- +# ---- 5. verify -------------------------------------------------------------- Step "Verifying" -$env:PATH = "$mlirBin;$xrt;$env:PATH" +$venvPy = Join-Path $Prefix "ironenv\Scripts\python.exe" +if (-not (Test-Path $venvPy)) { Fail "no interpreter at $venvPy." } + & $venvPy -c "import aie.iron; print(' aie.iron imports OK')" if ($LASTEXITCODE -ne 0) { Fail "the environment installed but 'import aie.iron' fails." } + +# The GEMM generators compile against kernel sources from the checkout, not from +# any wheel, so a wheel-only environment would pass the import above and then +# fail at the first build. +$kernels = Join-Path $Prefix "aie_kernels\aie2p" +if (-not (Test-Path $kernels)) { + Fail "$kernels is missing. The GEMM generators need the checkout's kernel sources; a wheels-only install is not enough." +} +Note "aie_kernels\aie2p present" + & $venvPy (Join-Path $Here "make_artifacts.py") --list --for-model 384 6 if ($LASTEXITCODE -ne 0) { Fail "make_artifacts.py could not run." } From 080fb29ee35f9b0fa022ccd4df3c2cfcb190fa57 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 18 Aug 2026 22:12:30 +0800 Subject: [PATCH 34/37] Restore the conda/vcpkg zlib fallback for the RyzenAI build The auto-fetch path from AMD_GPU covers vcpkg only when KATAGO_AUTO_FETCH_DEPS is on; this keeps a plain 'cmake .. -G Ninja -DUSE_BACKEND=RYZENAI' working on a machine whose only zlib came with conda. --- cpp/CMakeLists.txt | 122 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index a2000b9636..c4ec4f5d73 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -300,6 +300,86 @@ endfunction() # e.g. -DUSE_BACKEND=rocm would otherwise silently skip all the ROCm pre-project setup. string(TOUPPER "${USE_BACKEND}" USE_BACKEND) +# The RyzenAI backend compiles with cl.exe, so unlike the ROCm path above it +# needs no toolset probing and no version pin - just the environment vcvarsall +# would set, so that configuring with Ninja works from an ordinary shell instead +# of only from a Developer Command Prompt. Reuses the helpers defined above. +# +# CMAKE_HOST_WIN32 rather than WIN32: the latter is a result of platform +# detection inside project(), so it is still undefined here. The guard asks +# whether the environment is usable rather than whether a variable happens to +# exist, because a stray empty VCToolsInstallDir would otherwise skip the +# bootstrap and leave the build with no compiler at all. +if(USE_BACKEND STREQUAL "RYZENAI" AND CMAKE_HOST_WIN32 AND NOT CMAKE_CXX_COMPILER) + set(_katago_vctools "$ENV{VCToolsInstallDir}") + set(_katago_include "$ENV{INCLUDE}") + string(STRIP "${_katago_vctools}" _katago_vctools) + string(STRIP "${_katago_include}" _katago_include) + if(_katago_vctools STREQUAL "" OR _katago_include STREQUAL "") + katago_win_find_vswhere(_katago_vswhere) + if(_katago_vswhere) + execute_process( + COMMAND "${_katago_vswhere}" -all -products * -property installationPath + OUTPUT_VARIABLE _katago_vs_raw OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + string(REPLACE "\r\n" "\n" _katago_vs_raw "${_katago_vs_raw}") + string(REPLACE "\n" ";" _katago_vs_paths "${_katago_vs_raw}") + set(_katago_best_ver "") + set(_katago_best_bat "") + foreach(_p IN LISTS _katago_vs_paths) + if(_p STREQUAL "") + continue() + endif() + file(TO_CMAKE_PATH "${_p}" _p) + if(NOT EXISTS "${_p}/VC/Auxiliary/Build/vcvarsall.bat") + continue() + endif() + # Version comes from the toolset directory name; require its headers to + # be present so a partially-installed toolset is not selected. Compare + # as versions, not strings: list(SORT) mis-orders 14.9 against 14.40. + file(GLOB _katago_tool_dirs "${_p}/VC/Tools/MSVC/*") + foreach(_t IN LISTS _katago_tool_dirs) + if(IS_DIRECTORY "${_t}" AND EXISTS "${_t}/include/cmath") + get_filename_component(_ver "${_t}" NAME) + if(_ver MATCHES "^[0-9]+\\.[0-9]+" + AND (_katago_best_ver STREQUAL "" OR _ver VERSION_GREATER _katago_best_ver)) + set(_katago_best_ver "${_ver}") + set(_katago_best_bat "${_p}/VC/Auxiliary/Build/vcvarsall.bat") + endif() + endif() + endforeach() + endforeach() + if(_katago_best_ver STREQUAL "") + message(WARNING "KataGo: no Visual Studio C++ toolchain found via vswhere. Install the " + "\"Desktop development with C++\" workload, or configure from a Developer " + "Command Prompt.") + else() + katago_win_apply_vcvarsall("${_katago_best_bat}" "${_katago_best_ver}") + message(STATUS "KataGo: using MSVC toolset ${_katago_best_ver} (found via vswhere)") + # The environment applied above lasts only for this configure run. A + # later, separate `ninja` is a sibling process that inherits none of it, + # so cl.exe would be found by its baked-in full path and then fail on + # . Bake the resolved INCLUDE/LIB into flags after project(). + katago_win_pathlist_to_flags("$ENV{INCLUDE}" "/I" _katago_msvc_incflags) + katago_win_pathlist_to_flags("$ENV{LIB}" "/LIBPATH:" _katago_msvc_libflags) + # Visual Studio bundles Ninja, but only on the IDE's private PATH. + if(CMAKE_GENERATOR MATCHES "Ninja" AND NOT CMAKE_MAKE_PROGRAM) + find_program(_katago_ninja ninja) + if(NOT _katago_ninja) + get_filename_component(_katago_vs_root "${_katago_best_bat}" DIRECTORY) + get_filename_component(_katago_vs_root "${_katago_vs_root}/../../.." ABSOLUTE) + set(_katago_bundled_ninja + "${_katago_vs_root}/Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe") + if(EXISTS "${_katago_bundled_ninja}") + set(CMAKE_MAKE_PROGRAM "${_katago_bundled_ninja}" CACHE FILEPATH "" FORCE) + message(STATUS "KataGo: using Ninja bundled with Visual Studio") + endif() + endif() + endif() + endif() + endif() + endif() +endif() + if(USE_BACKEND STREQUAL "METAL") project(katago LANGUAGES CXX Swift) elseif(USE_BACKEND STREQUAL "ROCM") @@ -1857,6 +1937,48 @@ if(WIN32 AND ZLIB_LIBRARY) endif() endif() +# Last resort before giving up: a zlib from a toolchain that is already on the +# machine but does not advertise itself. conda ships one, so does vcpkg. This +# runs after the auto-fetch logic above, so it only fires when that was disabled +# or found nothing, and an explicit -DZLIB_ROOT= still wins over all of it. +if(CMAKE_HOST_WIN32 AND NOT ZLIB_ROOT AND NOT ZLIB_LIBRARY) + set(_katago_zlib_roots "") + if(DEFINED ENV{CONDA_PREFIX}) + file(TO_CMAKE_PATH "$ENV{CONDA_PREFIX}" _p) + list(APPEND _katago_zlib_roots "${_p}/Library") + endif() + if(DEFINED ENV{VCPKG_ROOT}) + file(TO_CMAKE_PATH "$ENV{VCPKG_ROOT}" _p) + list(APPEND _katago_zlib_roots "${_p}/installed/x64-windows") + endif() + if(DEFINED ENV{USERPROFILE}) + # A base conda install is not "activated", so it exports no CONDA_PREFIX; + # its default location under the user profile is the only thing to go on. + file(TO_CMAKE_PATH "$ENV{USERPROFILE}" _home) + foreach(_dist miniconda3 anaconda3 miniforge3 mambaforge) + list(APPEND _katago_zlib_roots "${_home}/${_dist}/Library") + endforeach() + endif() + foreach(_root IN LISTS _katago_zlib_roots) + if(EXISTS "${_root}/include/zlib.h") + # Prefer the import library for the DLL over the static one, to match how + # the rest of KataGo's dependencies are linked here. + foreach(_cand zdll.lib zlib.lib z.lib) + if(EXISTS "${_root}/lib/${_cand}") + set(ZLIB_ROOT "${_root}" CACHE PATH "Root of a zlib install" FORCE) + set(ZLIB_INCLUDE_DIR "${_root}/include" CACHE PATH "" FORCE) + set(ZLIB_LIBRARY "${_root}/lib/${_cand}" CACHE FILEPATH "" FORCE) + message(STATUS "KataGo: using zlib from ${_root}") + break() + endif() + endforeach() + endif() + if(ZLIB_ROOT) + break() + endif() + endforeach() +endif() + find_package(ZLIB) if(ZLIB_FOUND) include_directories(${ZLIB_INCLUDE_DIRS}) From a29925c8538b177e4376342943927514fcf2720b Mon Sep 17 00:00:00 2001 From: Looong01 Date: Tue, 18 Aug 2026 22:22:30 +0800 Subject: [PATCH 35/37] Revert the two ROCm fixes that are not yet upstream This branch is the base for a pull request against lightvector/master, and AMD_GPU carries two commits that master does not have yet: 62cb2932 Fix CDNA slowdown edd1b069 Fix slowdown and Compiling.md Both are ROCm work and unrelated to the NPU backend, so carrying them here would put unrelated changes in the pull request and conflict with whatever shape they land in upstream. Reverting them leaves cudaandrocmbackend.inc and analysis_example.cfg identical to master; Compiling.md and gtp_example.cfg keep only this branch's own RyzenAI sections. --- Compiling.md | 24 +-- cpp/configs/analysis_example.cfg | 3 +- cpp/configs/gtp_example.cfg | 10 +- cpp/neuralnet/cudaandrocmbackend.inc | 277 ++------------------------- 4 files changed, 33 insertions(+), 281 deletions(-) diff --git a/Compiling.md b/Compiling.md index 2bdff02eab..43b91450c2 100644 --- a/Compiling.md +++ b/Compiling.md @@ -33,7 +33,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using the OpenCL backend, a modern GPU that supports OpenCL 1.2 or greater, or else something like [this](https://software.intel.com/en-us/opencl-sdk) for CPU. But if using CPU, Eigen should be better. * If using the CUDA backend, CUDA 11 or later and a compatible version of CUDNN based on your CUDA version (https://developer.nvidia.com/cuda-toolkit) (https://developer.nvidia.com/cudnn) and a GPU capable of supporting them. * If using the TensorRT backend, in addition to a compatible CUDA Toolkit (https://developer.nvidia.com/cuda-toolkit), you also need TensorRT (https://developer.nvidia.com/tensorrt) that is at least version 8.5. - * If using the ROCm backend, ROCm 7.x (https://rocm.docs.amd.com/en/latest/install/rocm.html) and a GPU capable of supporting it. Install the ROCm developer packages, not just the ROCm runtime packages. + * If using the ROCm backend, ROCm 6.4 or later (https://rocm.docs.amd.com/projects/install-on-linux/en/latest/) and a GPU capable of supporting it. Install the ROCm developer packages, not just the ROCm runtime packages. * If using the Eigen backend, Eigen3. With Debian packages, (i.e. apt or apt-get), this should be `libeigen3-dev`. * zlib, libzip. With Debian packages (i.e. apt or apt-get), these should be `zlib1g-dev`, `libzip-dev`. * If you want to do self-play training and research, probably Google perftools `libgoogle-perftools-dev` for TCMalloc or some other better malloc implementation. For unknown reasons, the allocation pattern in self-play with large numbers of threads and parallel games causes a lot of memory fragmentation under glibc malloc that will eventually run your machine out of memory, but better mallocs handle it fine. @@ -56,13 +56,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * If using OpenCL, you will want to verify that KataGo is picking up the correct device when you run it (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). * **ROCm backend (Linux) - additional notes:** - * Install ROCm following the [official guide](https://rocm.docs.amd.com/en/latest/install/rocm.html). On the guide's selector panel, choose your Device family, your GPU, your Operating system and its version, Use case = **Compute**, and Installation method = the system package manager (e.g. `apt` on Ubuntu). **If you have ROCm 7.2.4 or older installed, please uninstall it before proceeding** (the guide documents `sudo amdgpu-uninstall` for that). - * Install the prerequisite libraries, then the ROCm 7.14 packages (developer stack, not just the runtime): - ``` - sudo apt install libatomic1 libquadmath0 - sudo apt install amdrocm7.14 amdrocm-core-dev7.14 amdrocm-developer-tools7.14 amdrocm-opencl7.14 amdrocm-core-sdk7.14 - ``` - * Verify the installation with `amd-smi` (it should report the ROCm version and list your GPU); `rocminfo` works too. + * Install ROCm following the [official guide](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/). Install the full developer stack (not just runtime): `sudo apt install rocm-dev miopen-hip-dev hipblas-dev rocblas-dev`. * Build: ``` cd KataGo/cpp @@ -179,13 +173,13 @@ As also mentioned in the instructions below but repeated here for visibility, if * You will probably want to edit `configs/gtp_example.cfg` (see "Tuning for Performance" above). * If using OpenCL, you will want to verify that KataGo is picking up the correct device (e.g. some systems may have both an Intel CPU OpenCL and GPU OpenCL, if KataGo appears to pick the wrong one, you can correct this by specifying `openclGpuToUse` in `configs/gtp_example.cfg`). - * **ROCm backend (Windows):** - * The ROCm (MIOpen) backend supports Windows, including transformer/attention models (model version 17+) and the optional Composable Kernel (CK) fused-attention fast path. + * **ROCm backend (Windows) - building via AMD TheRock:** + * The ROCm (MIOpen) backend supports Windows via [AMD TheRock](https://github.com/ROCm/TheRock) (tested with TheRock 7.13 / ROCm 7.13, RX 7900 XTX / gfx1100), including transformer/attention models (model version 17+) and the optional Composable Kernel (CK) fused-attention fast path. * **Prerequisites:** - * Install ROCm for Windows following the [official guide](https://rocm.docs.amd.com/en/latest/install/rocm.html). On the guide's selector panel, choose your Device family, your GPU, and Operating system = **Windows**, then follow the method it presents (the tarball method gives a system-wide install with all components, HIP/MIOpen/clang toolchain included). **If you have ROCm 7.2.4 or older installed, please uninstall it before proceeding.** + * Download [AMD TheRock](https://github.com/ROCm/TheRock) and extract it to e.g. `C:\TheRock\build`, adjusting the paths below if you extract elsewhere. * Install **Visual Studio Build Tools or Community** with the "Desktop development with C++" workload, for the MSVC toolchain and Windows SDK the HIP compiler needs. A **v143 toolset (MSVC 14.3x or 14.4x)** must be among the installed toolsets - newer toolsets alone (14.5x+) are not accepted by the HIP clang compatibility check. If more than one is installed side by side, `CMakeLists.txt` automatically probes them at configure time and picks a compatible one itself (see "Fully automatic" below), no manual toolset selection needed. * Install [Ninja](https://ninja-build.org) build tool: `winget install Ninja-build.Ninja`. - * Set the following **system environment variables** (via System Properties -> Advanced -> Environment Variables), adjusting the paths if you extracted the tarball elsewhere: + * Set the following **system environment variables** (via System Properties -> Advanced -> Environment Variables): ``` HIP_PATH=C:/TheRock/build HIP_PLATFORM=amd @@ -210,12 +204,12 @@ As also mentioned in the instructions below but repeated here for visibility, if install are needed beyond the prerequisites above. `CMakeLists.txt` handles the rest of the Windows-specific setup automatically at configure/build time: * **MSVC toolset selection:** if more than one MSVC toolset is installed side by side, a - newer one can conflict with the HIP clang (newer MSVC STL headers are not yet + newer one can conflict with TheRock's bundled clang (newer MSVC STL headers are not yet compatible with it). `CMakeLists.txt` finds the installed v143-family toolsets via `vswhere` and probes each with a real compile until one works, with no user action needed. - * **zlib:** if the ROCm Windows package on your system ships `zlib.h` but no - linkable `.lib`, `CMakeLists.txt` automatically bootstraps a local + * **zlib:** TheRock's Windows package ships `zlib.h` but (as of 7.13) no longer ships a + linkable `.lib`. `CMakeLists.txt` automatically bootstraps a local [vcpkg](https://github.com/microsoft/vcpkg) clone under `/deps/vcpkg` (this needs internet access and `git` on `PATH` the first time; subsequent reconfigures reuse the same local install) and builds zlib through it, via the diff --git a/cpp/configs/analysis_example.cfg b/cpp/configs/analysis_example.cfg index f66105a198..1b18627421 100644 --- a/cpp/configs/analysis_example.cfg +++ b/cpp/configs/analysis_example.cfg @@ -281,8 +281,7 @@ nnRandomize = true # force a particular behavior you can uncomment these lines and change them to "true" or "false", # e.g. if FP16 is giving an error or too much numerical inaccuracy on your card. # rocmUseFP16 = auto -# rocmUseNHWC = auto # Uses NHWC tensor layout. Default: auto - NCHW for convnets on all GPUs (MIOpen's NCHW conv solvers are its most mature path); transformers always use NHWC regardless. -# rocmUse1x1Matmul = auto # Whether 1x1 NHWC convs run as a hipBLAS GEMM instead of a MIOpen conv. auto = GEMM whenever the layout allows; recommended (MIOpen's NHWC conv solvers are slow on some GPUs, and FP16 GEMMs use FP32 accumulation). +# rocmUseNHWC = auto # Uses NHWC tensor layout. Default: auto - NHWC with FP16 on GPUs where NHWC convolutions are faster (CDNA), else NCHW; transformers always NHWC. # OpenCL-specific GPU settings-------------------------------------- diff --git a/cpp/configs/gtp_example.cfg b/cpp/configs/gtp_example.cfg index 82318ee6e7..e96b362fb0 100644 --- a/cpp/configs/gtp_example.cfg +++ b/cpp/configs/gtp_example.cfg @@ -613,14 +613,10 @@ searchFactorWhenWinningThreshold = 0.95 # compiled without FP16 kernel support). If you want to force a particular # behavior you can uncomment these lines and change them to "true" or "false". # rocmUseFP16 = auto -# Uses NHWC tensor layout. Default: auto - NCHW for convnets on all GPUs (MIOpen's NCHW -# conv solvers are its most mature path); transformer models always use NHWC regardless. +# Uses NHWC tensor layout. Default: auto - NHWC when using FP16 on GPUs whose matrix +# instructions make NHWC convolutions faster (CDNA), otherwise NCHW; transformer models +# always use NHWC. # rocmUseNHWC = auto -# Whether 1x1 NHWC convolutions run as a hipBLAS GEMM instead of a MIOpen convolution. -# "auto" (default) uses the GEMM whenever the layout allows it. Recommended to leave on: -# MIOpen's NHWC conv solvers are slow on some GPUs (e.g. CK grouped-conv kernels on -# gfx1100), while the GEMM is both faster and uses FP32 accumulation for FP16. -# rocmUse1x1Matmul = auto # ------------------------------ # OpenCL GPU settings diff --git a/cpp/neuralnet/cudaandrocmbackend.inc b/cpp/neuralnet/cudaandrocmbackend.inc index 205a4c8197..dd56dbc65b 100644 --- a/cpp/neuralnet/cudaandrocmbackend.inc +++ b/cpp/neuralnet/cudaandrocmbackend.inc @@ -57,7 +57,6 @@ #include "../core/simpleallocator.h" #include "../core/test.h" -#include #ifdef KATAGO_GPU_CUDA #include "../core/hash.h" #endif @@ -339,29 +338,25 @@ static bool isCkFmhaSupportedArch(const hipDeviceProp_t& prop) { size_t colonPos = arch.find(':'); // e.g. "gfx942:sramecc+:xnack-" if(colonPos != std::string::npos) arch = arch.substr(0, colonPos); - static constexpr std::string_view gfx908 = "gfx908"; - static constexpr std::string_view gfx90a = "gfx90a"; - static constexpr std::string_view gfx94 = "gfx94"; - static constexpr std::string_view gfx95 = "gfx95"; - static constexpr std::string_view gfx11 = "gfx11"; - static constexpr std::string_view gfx12 = "gfx12"; return - arch == gfx908 || arch == gfx90a || - arch.compare(0, gfx94.size(), gfx94) == 0 || arch.compare(0, gfx95.size(), gfx95) == 0 || - arch.compare(0, gfx11.size(), gfx11) == 0 || arch.compare(0, gfx12.size(), gfx12) == 0; + arch == "gfx908" || arch == "gfx90a" || + arch.compare(0, 5, "gfx94") == 0 || arch.compare(0, 5, "gfx95") == 0 || + arch.compare(0, 5, "gfx11") == 0 || arch.compare(0, 5, "gfx12") == 0; } -// Archs where MIOpen's NHWC convolutions are preferred in "Auto" mode. We enable NHWC -// automatically on the gfx9 family (CDNA/MI etc.), where NHWC measured faster on convnets. -// RDNA (gfx10/gfx11/gfx12) keeps NCHW as the "Auto" default because its NHWC solvers can -// fall back to naive implementations. Users can still force NHWC with rocmUseNHWC=true. -static bool isNhwcPreferredArch(const hipDeviceProp_t& prop) { +// Archs where MIOpen's NHWC FP16 convolutions (MFMA implicit GEMM) are known faster than NCHW, +// so NHWC mode "Auto" should enable NHWC when using FP16 - the analog of the CUDA backend +// enabling NHWC on tensor-core (Volta+) GPUs. Currently the CDNA/MFMA family only, where NHWC +// measured substantially faster on convnets. RDNA (WMMA) is unmeasured rather than known +// slower. Extend this list if NHWC measures faster there too, testable via rocmUseNHWC=true. +static bool isNhwcFp16PreferredArch(const hipDeviceProp_t& prop) { std::string arch(prop.gcnArchName); size_t colonPos = arch.find(':'); if(colonPos != std::string::npos) arch = arch.substr(0, colonPos); - static constexpr std::string_view prefix = "gfx9"; - return arch.compare(0, prefix.size(), prefix) == 0; + return + arch == "gfx908" || arch == "gfx90a" || + arch.compare(0, 5, "gfx94") == 0 || arch.compare(0, 5, "gfx95") == 0; } #endif @@ -471,9 +466,6 @@ struct CudaHandles { // the attempt (and its attention-bias materialization) entirely. Only touched by the single // server thread that owns this handle, hence no synchronization. bool fusedAttentionRuntimeDisabled; - // Controls whether 1x1 NHWC convs run as a hipBLAS GEMM (vs MIOpen). Auto = matmul iff FP16. - // True/False force the choice regardless of precision. - enabled_t use1x1MatmulMode; CudaHandles(int major, int minor, Logger* logger_, bool ckFmhaArchSupported_, bool disableFusedAttention_) : majorComputeCapability(major), @@ -481,8 +473,7 @@ struct CudaHandles { logger(logger_), ckFmhaArchSupported(ckFmhaArchSupported_), disableFusedAttention(disableFusedAttention_), - fusedAttentionRuntimeDisabled(false), - use1x1MatmulMode(enabled_t::Auto) + fusedAttentionRuntimeDisabled(false) { } @@ -1035,23 +1026,6 @@ struct ConvLayer { OwnedDesc convolutionDescriptor; std::unique_ptr> convolutionAlgorithms; //array of one for each batch size OwnedDeviceBuf filterBuf; - // A 1x1 conv is equivalent to a matmul. When use1x1Matmul is set we run it as a hipBLAS GEMM over - // batch*spatial tokens and build NO MIOpen objects. This is the default for 1x1 NHWC FP16 convs - // (see rocmUse1x1Matmul). matmulWeightBuf is [inC, outC] column-major (hipBLAS order); - // matmulSpatialSize is the spatial length. - bool use1x1Matmul; - int matmulSpatialSize; - OwnedDeviceBuf matmulWeightBuf; - // When MIOpen can only offer its naive direct-conv fallback for an NHWC conv (weak NHWC solver - // coverage), we instead re-express the conv as NCHW at runtime: transpose input, run the NCHW - // conv, transpose output back. Only ever set for NHWC-in/out convs. - bool useNchwFallback; - ByBatchSizeView nchwInputDescriptors; - ByBatchSizeView nchwOutputDescriptors; - OwnedDesc nchwFilterDescriptor; - OwnedDesc nchwConvolutionDescriptor; - std::unique_ptr> nchwConvolutionAlgorithms; - OwnedDeviceBuf nchwFilterBuf; ConvLayer() = delete; ConvLayer(const ConvLayer&) = delete; @@ -1092,102 +1066,11 @@ struct ConvLayer { testAssert(convXSize % 2 == 1); testAssert(convYSize % 2 == 1); - // A 1x1 conv is a matmul. MIOpen's NHWC conv solver coverage is weak on consumer GPUs in both - // FP16 and FP32 (e.g. on gfx1100 it picks CK grouped-conv WMMA kernels for FP16, ~2-4x slower - // per call than a GEMM with much more dispatch overhead, and falls back to its naive direct - // solver for some FP32 cases), while hipBLAS GEMM is fast - so on ROCm "auto" uses the GEMM - // whenever the layout allows it, regardless of precision. (The CUDA backend's FP32 exception - // was a cuDNN-specific benchmarking result and does not apply to MIOpen.) FP16 GEMMs use FP32 - // compute for accuracy, matching MatMulLayer. Supports NHWC only (the GEMM assumes - // channel-contiguous-per-position layout). - use1x1Matmul = false; - useNchwFallback = false; - if(convXSize == 1 && convYSize == 1 && useNHWCIn && useNHWCOut) { - enabled_t mode = cudaHandles->use1x1MatmulMode; - use1x1Matmul = (mode == enabled_t::True) || (mode == enabled_t::Auto); - } - matmulSpatialSize = use1x1Matmul ? (manager->nnYLen * manager->nnXLen) : 0; - - if(use1x1Matmul) { - // 1x1 conv weights are [outC, inC]. hipBLAS GEMM wants column-major, i.e. [inC, outC] in row-major notation. - // So transpose. No MIOpen objects are built. - vector wT((size_t)inChannels * outChannels); - for(int oc = 0; oc < outChannels; oc++) - for(int ic = 0; ic < inChannels; ic++) - wT[(size_t)oc + (size_t)ic * outChannels] = desc->weights[(size_t)oc * inChannels + ic]; - CudaUtils::mallocAndCopyToDevice(name + ":matmulW", wT, matmulWeightBuf.buf, useFP16); - return; - } - inputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,useNHWCIn); outputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,useNHWCOut); bool filterNHWC = useNHWCOut && dilationY == 1 && dilationX == 1; - bool anyNaive = buildMiopenConvPath( - cudaHandles, name, desc, useFP16, useNHWCIn, useNHWCOut, filterNHWC, maxBatchSize, - inputDescriptors, outputDescriptors, filterDescriptor, convolutionDescriptor, - convolutionAlgorithms, filterBuf); - - // MIOpen's NHWC solver coverage is patchy (e.g. on gfx1100 a 3x3 NHWC FP16 stem conv falls all - // the way back to ConvDirectNaiveConvFwd). When that happens, try re-expressing the conv as - // NCHW - MIOpen's NCHW solver coverage is much better - at the cost of a pair of transposes - // around each call. - if(anyNaive && useNHWCIn && useNHWCOut) { - string convDescStr = Global::intToString(inChannels) + "->" + Global::intToString(outChannels) + - " " + Global::intToString(convYSize) + "x" + Global::intToString(convXSize); - nchwInputDescriptors = manager->getTensorDesc4DByBatchSize(inChannels,useFP16,false); - nchwOutputDescriptors = manager->getTensorDesc4DByBatchSize(outChannels,useFP16,false); - bool nchwNaive = buildMiopenConvPath( - cudaHandles, name + ":nchw", desc, useFP16, false, false, false, maxBatchSize, - nchwInputDescriptors, nchwOutputDescriptors, nchwFilterDescriptor, nchwConvolutionDescriptor, - nchwConvolutionAlgorithms, nchwFilterBuf); - if(!nchwNaive) { - useNchwFallback = true; - if(cudaHandles->logger != NULL) - cudaHandles->logger->write( - "ROCm backend: MIOpen offers only its naive direct-conv fallback for NHWC conv layer '" + - name + "' (" + convDescStr + "); re-expressing it as NCHW with per-call transposes instead"); - } - else if(cudaHandles->logger != NULL) - cudaHandles->logger->write( - "ROCm backend: WARNING: MIOpen offers only its naive direct-conv fallback for NHWC conv layer '" + - name + "' (" + convDescStr + "), and the NCHW alternative is naive too - expect reduced conv performance"); - } - else if(anyNaive && cudaHandles->logger != NULL) - cudaHandles->logger->write( - "ROCm backend: WARNING: MIOpen offers only its naive direct-conv fallback for conv layer '" + - name + "' - expect reduced conv performance"); - } - - // Builds all the MIOpen objects for one layout choice of this conv across batch sizes, uploads - // the (layout-transposed if needed) filter, and compiles the chosen solution per batch size. - // Returns true if MIOpen's chosen solution for ANY batch size is its naive direct-conv fallback. - static bool buildMiopenConvPath( - CudaHandles* cudaHandles, - const string& name, - const ConvLayerDesc* desc, - bool useFP16, - bool useNHWCIn, - bool useNHWCOut, - bool filterNHWC, - int maxBatchSize, - ByBatchSizeView& inputDescriptors, - ByBatchSizeView& outputDescriptors, - OwnedDesc& filterDescriptor, - OwnedDesc& convolutionDescriptor, - std::unique_ptr>& convolutionAlgorithms, - OwnedDeviceBuf& filterBuf - ) { - int convYSize = desc->convYSize; - int convXSize = desc->convXSize; - int dilationY = desc->dilationY; - int dilationX = desc->dilationX; - int paddingX = (convXSize / 2) * dilationX; - int paddingY = (convYSize / 2) * dilationY; - int inChannels = desc->inChannels; - int outChannels = desc->outChannels; - CUDNN_ERR(name.c_str(),miopenCreateTensorDescriptor(&filterDescriptor.desc)); if(filterNHWC) { int lens[4] = {outChannels, inChannels, convYSize, convXSize}; @@ -1213,6 +1096,7 @@ struct ConvLayer { int yStride = 1; int xStride = 1; + CUDNN_ERR(name.c_str(),miopenCreateConvolutionDescriptor(&convolutionDescriptor.desc)); CUDNN_ERR(name.c_str(),miopenInitConvolutionDescriptor( convolutionDescriptor, @@ -1231,7 +1115,6 @@ struct ConvLayer { convolutionAlgorithms = std::make_unique>(maxBatchSize); - bool anyNaive = false; for(int batchSize = 1; batchSize <= maxBatchSize; batchSize++) { const miopenTensorDescriptor_t& inputDescriptor = inputDescriptors[batchSize]; const miopenTensorDescriptor_t& outputDescriptor = outputDescriptors[batchSize]; @@ -1261,11 +1144,6 @@ struct ConvLayer { if(returnedAlgoCount <= 0) throw StringError("miopenConvolutionForwardGetSolution returned no algorithms?"); (*convolutionAlgorithms)[batchSize] = solutions[0]; - // MIOpen hands back its naive direct-conv solver (ConvDirectNaiveConvFwd, registered solver - // id 55) as the last-resort fallback, stamped with a sentinel time of 1000ms. The numeric id - // is not a public-stable API, so treat the sentinel time as the primary signal. - if(solutions[0].time >= 999.0f || solutions[0].solution_id == 55) - anyNaive = true; CUDNN_ERR(name.c_str(),miopenConvolutionForwardCompileSolution( cudaHandles->cudnn, filterDescriptor, @@ -1296,28 +1174,12 @@ struct ConvLayer { else CudaUtils::mallocAndCopyToDevice(name,desc->weights,filterBuf.buf,useFP16); - return anyNaive; } size_t requiredWorkspaceBytes( CudaHandles* cudaHandles, int batchSize ) const { - if(use1x1Matmul) - return 0; - if(useNchwFallback) { - size_t workspaceBytes = 0; - CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( - cudaHandles->cudnn, - nchwFilterDescriptor, - nchwInputDescriptors[batchSize], - nchwConvolutionDescriptor, - nchwOutputDescriptors[batchSize], - (*nchwConvolutionAlgorithms)[batchSize].solution_id, - &workspaceBytes - )); - return workspaceBytes; - } size_t workspaceBytes = 0; CUDNN_ERR(name.c_str(),miopenConvolutionForwardGetSolutionWorkspaceSize( cudaHandles->cudnn, @@ -1341,57 +1203,6 @@ struct ConvLayer { void* workspaceBuf, size_t workspaceBytes ) const { - if(use1x1Matmul) { - // out[outC, tokens] = W[outC, inC] x in[inC, tokens] - // where tokens = batchSize * spatial. NHWC buffers are [tokens, C] row-major = [C, tokens] column-major - // matching hipBLAS's expectation. Same as MatMulLayer. - int tokens = batchSize * matmulSpatialSize; - if(!usingFP16) { - const float alpha = 1.0f; - const float beta = accumulate ? 1.0f : 0.0f; - CUBLAS_ERR(name.c_str(),cublasSgemm( - cudaHandles->cublas, CUBLAS_OP_N, CUBLAS_OP_N, - outChannels, tokens, inChannels, - &alpha, (const float*)matmulWeightBuf.buf, outChannels, - (const float*)inputBuf, inChannels, - &beta, (float*)outputBuf, outChannels)); - } - else { -#if defined(hipblasVersionMajor) && hipblasVersionMajor >= 2 - // Use FP32 compute for the same accuracy reason as MatMulLayer (hipblasHgemm's FP16 - // compute costs real accuracy on transformer nets). - const float alpha = 1.0f; - const float beta = accumulate ? 1.0f : 0.0f; - CUBLAS_ERR(name.c_str(),hipblasGemmEx( - cudaHandles->cublas, - HIPBLAS_OP_N, - HIPBLAS_OP_N, - outChannels, - tokens, - inChannels, - &alpha, - matmulWeightBuf.buf, HIP_R_16F, outChannels, - inputBuf, HIP_R_16F, inChannels, - &beta, - outputBuf, HIP_R_16F, outChannels, - HIPBLAS_COMPUTE_32F, - HIPBLAS_GEMM_DEFAULT - )); -#else - // hipBLAS older than 2.0 (below ROCm 6.0, below the minimum Compiling.md documents): - // fall back to the FP16-compute spelling. - const cublas_half_t* alpha = (const cublas_half_t*)scratch->oneBuf; - const cublas_half_t* betaHalf = (const cublas_half_t*)(accumulate ? scratch->oneBuf : scratch->zeroBuf); - CUBLAS_ERR(name.c_str(),cublasHgemm( - cudaHandles->cublas, CUBLAS_OP_N, CUBLAS_OP_N, - outChannels, tokens, inChannels, - alpha, (const cublas_half_t*)matmulWeightBuf.buf, outChannels, - (const cublas_half_t*)inputBuf, inChannels, - betaHalf, (cublas_half_t*)outputBuf, outChannels)); -#endif - } - return; - } // miopenConvolutionForwardImmediate does NOT support alpha/beta (unlike cuDNN). // When accumulate=true, we need: outputBuf = conv(inputBuf) + outputBuf (residual skip // connection). Save outputBuf's contents to a scratch buffer, run the conv, then add back. @@ -1413,43 +1224,6 @@ struct ConvLayer { CUDA_ERR(name.c_str(), hipMemcpyAsync(accumBuf->buf, outputBuf, outputElts * elemSize, hipMemcpyDeviceToDevice)); } - if(useNchwFallback) { - // Re-expressed NCHW conv: transpose input NHWC->NCHW, run the conv, transpose the output - // back to NHWC. Buffers are max-batch-sized pool allocations, same as everywhere else here. - int xySize = nnXLen * nnYLen; - SizedBuf inNchw(scratch->allocator, scratch->getBufSizeXY(inChannels)); - SizedBuf outNchw(scratch->allocator, scratch->getBufSizeXY(outChannels)); - if(usingFP16) - customCudaCopyNHWCtoNCHW((const half*)inputBuf, (half*)inNchw.buf, batchSize, inChannels, xySize); - else - customCudaCopyNHWCtoNCHW((const float*)inputBuf, (float*)inNchw.buf, batchSize, inChannels, xySize); - CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( - cudaHandles->cudnn, - nchwFilterDescriptor, - nchwFilterBuf.buf, - nchwInputDescriptors[batchSize], - inNchw.buf, - nchwConvolutionDescriptor, - nchwOutputDescriptors[batchSize], - outNchw.buf, - workspaceBuf, - workspaceBytes, - (*nchwConvolutionAlgorithms)[batchSize].solution_id - )); - if(usingFP16) - customCudaCopyNCHWtoNHWC((const half*)outNchw.buf, (half*)outputBuf, batchSize, outChannels, xySize); - else - customCudaCopyNCHWtoNHWC((const float*)outNchw.buf, (float*)outputBuf, batchSize, outChannels, xySize); - if(accumulate) { - if(usingFP16) - customCudaAddTensorInplace((half*)outputBuf, (const half*)accumBuf->buf, (int)outputElts); - else - customCudaAddTensorInplace((float*)outputBuf, (const float*)accumBuf->buf, (int)outputElts); - } - CUDA_ERR(name.c_str(), hipPeekAtLastError()); - return; - } - CUDNN_ERR(name.c_str(), miopenConvolutionForwardImmediate( cudaHandles->cudnn, filterDescriptor, @@ -4111,8 +3885,6 @@ struct ComputeContext { enabled_t useFP16Mode; enabled_t useNHWCMode; bool disableFusedAttention; - // Whether 1x1 NHWC convs use the hipBLAS GEMM path. Auto = matmul iff FP16. - enabled_t use1x1MatmulMode; }; #endif @@ -4169,11 +3941,6 @@ ComputeContext* NeuralNet::createComputeContext( // the CUDA backend's cudaDisableGraphSDPA. Only meaningful for transformer models. bool disableFusedAttention = cfg.contains("rocmDisableFusedAttention") ? cfg.getBool("rocmDisableFusedAttention") : false; - // Mirrors the CUDA backend's cudaUse1x1Matmul. On ROCm this matters much more than on CUDA: - // MIOpen 7.x's NHWC FP16 conv solver coverage is weak (e.g. on gfx1100 it routes 1x1 convs to - // slow CK grouped-conv kernels), while hipBLAS GEMM is fast. - enabled_t use1x1MatmulMode = - cfg.contains("rocmUse1x1Matmul") ? cfg.getEnabled("rocmUse1x1Matmul") : enabled_t::Auto; ComputeContext* context = new ComputeContext(); context->nnXLen = nnXLen; @@ -4181,7 +3948,6 @@ ComputeContext* NeuralNet::createComputeContext( context->useFP16Mode = useFP16Mode; context->useNHWCMode = useNHWCMode; context->disableFusedAttention = disableFusedAttention; - context->use1x1MatmulMode = use1x1MatmulMode; return context; } #endif @@ -4259,8 +4025,6 @@ struct ComputeHandle { { cudaHandles = std::make_unique( majorComputeCapability,minorComputeCapability,logger,ckFmhaArchSupported,context->disableFusedAttention); - // Must be set before building the model: ConvLayer reads it at construction to pick the 1x1 conv path. - cudaHandles->use1x1MatmulMode = context->use1x1MatmulMode; model = std::make_unique( cudaHandles.get(), &(loadedModel->modelDesc), maxBatchSize, nnXLen, nnYLen, inputsUseNHWC, useFP16, useNHWC @@ -4393,7 +4157,7 @@ ComputeHandle* NeuralNet::createComputeHandle( bool useNHWC = false; if(context->useFP16Mode == enabled_t::True || context->useFP16Mode == enabled_t::Auto) useFP16 = true; - if(context->useNHWCMode == enabled_t::True || (context->useNHWCMode == enabled_t::Auto && isNhwcPreferredArch(prop))) + if(context->useNHWCMode == enabled_t::True) useNHWC = true; // Every arch in the default CMAKE_HIP_ARCHITECTURES list supports packed FP16, so FP16 "Auto" @@ -4408,12 +4172,11 @@ ComputeHandle* NeuralNet::createComputeHandle( logger->write("ROCm backend: this build was compiled without FP16 kernel support; using FP32"); } - // ROCm "Auto" NHWC policy: on the gfx9 family (CDNA/MI etc.) we enable NHWC automatically, - // since MIOpen's NHWC solvers measured faster on convnets there. RDNA and newer (gfx10/gfx11/gfx12) - // keep NCHW in "Auto" because their NHWC solvers can fall back to naive implementations. - // NHWC is still forced for transformer models below and can always be requested with - // rocmUseNHWC=true. - // (useNHWC stays false here on non-gfx9 archs unless rocmUseNHWC=true was set above.) + // Mirror the CUDA backend's tensor-core rule: on archs whose matrix instructions make NHWC + // convolutions the fast path, NHWC "Auto" turns NHWC on together with FP16. Decided after the + // FP16-kernel check above so a build that just downgraded to FP32 does not also switch layouts. + if(context->useNHWCMode == enabled_t::Auto && useFP16 && isNhwcFp16PreferredArch(prop)) + useNHWC = true; // The transformer block implementation (attention/RoPE/FFN) only supports NHWC, since its channel // projections assume the channel dim is contiguous per spatial position. Force NHWC for transformer From 2f1153f791732365d5aafc680acd44a3d7af051f Mon Sep 17 00:00:00 2001 From: Looong01 Date: Wed, 19 Aug 2026 06:04:53 +0800 Subject: [PATCH 36/37] Update CMakeLists about checking MSVC toolsets version logic for ROCm backend building on Windows --- .gitignore | 4 ++- Compiling.md | 8 ++--- cpp/CMakeLists.txt | 87 ++++++++++++++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 7799d05291..e49a7a35b3 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,7 @@ cpp/tests/results/matchsgfs2/games.sgfs cpp/data/ versions/ -cpp/build +cpp/build* cpp/out export_model_cuda.sh @@ -92,3 +92,5 @@ cpp/build.ninja cpp/KataGoSwift.* cpp/include/KataGoSwift/KataGoSwift-swift.h cpp/external/katagocoreml/proto/ + +.claude \ No newline at end of file diff --git a/Compiling.md b/Compiling.md index 5fc0ebd319..fc4e71e797 100644 --- a/Compiling.md +++ b/Compiling.md @@ -164,7 +164,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * The ROCm (MIOpen) backend supports Windows, including transformer/attention models (model version 17+) and the optional Composable Kernel (CK) fused-attention fast path. * **Prerequisites:** * Install ROCm for Windows following the [official guide](https://rocm.docs.amd.com/en/latest/install/rocm.html). On the guide's selector panel, choose your Device family, your GPU, and Operating system = **Windows**, then follow the method it presents (the tarball method gives a system-wide install with all components, HIP/MIOpen/clang toolchain included). **If you have ROCm 7.2.4 or older installed, please uninstall it before proceeding.** - * Install **Visual Studio Build Tools or Community** with the "Desktop development with C++" workload, for the MSVC toolchain and Windows SDK the HIP compiler needs. A **v143 toolset (MSVC 14.3x or 14.4x)** must be among the installed toolsets - newer toolsets alone (14.5x+) are not accepted by the HIP clang compatibility check. If more than one is installed side by side, `CMakeLists.txt` automatically probes them at configure time and picks a compatible one itself (see "Fully automatic" below), no manual toolset selection needed. + * Install **Visual Studio Build Tools or Community** with the "Desktop development with C++" workload, for the MSVC toolchain and Windows SDK the HIP compiler needs. If several toolsets are installed side by side, `CMakeLists.txt` probes them at configure time - newest first - and picks the first one the HIP compiler actually accepts (see "Fully automatic" below), no manual toolset selection needed. Note that a very new MSVC STL can be ahead of the clang bundled with your ROCm install; if configure reports that no installed toolset works, add an older one such as **MSVC v143 (14.3x/14.4x)** from the Visual Studio Installer's "Individual Components" tab. * Install [Ninja](https://ninja-build.org) build tool: `winget install Ninja-build.Ninja`. * Set the following **system environment variables** (via System Properties -> Advanced -> Environment Variables), adjusting the paths if you extracted the tarball elsewhere: ``` @@ -192,9 +192,9 @@ As also mentioned in the instructions below but repeated here for visibility, if Windows-specific setup automatically at configure/build time: * **MSVC toolset selection:** if more than one MSVC toolset is installed side by side, a newer one can conflict with the HIP clang (newer MSVC STL headers are not yet - compatible with it). `CMakeLists.txt` finds the installed v143-family toolsets via - `vswhere` and probes each with a real compile until one works, with no user action - needed. + compatible with it). `CMakeLists.txt` enumerates every installed toolset via + `vswhere` and probes them newest-first with a real compile until one works, with + no user action needed. * **zlib:** if the ROCm Windows package on your system ships `zlib.h` but no linkable `.lib`, `CMakeLists.txt` automatically bootstraps a local [vcpkg](https://github.com/microsoft/vcpkg) clone under `/deps/vcpkg` (this diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 3cc803444d..172830d31b 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -137,15 +137,32 @@ function(katago_win_apply_vcvarsall vcvarsall_bat vcvars_ver) if(NOT _rc EQUAL 0 OR NOT EXISTS "${_out_file}") return() endif() - # Read line-by-line via file(STRINGS) rather than splitting the raw output ourselves - INCLUDE/ - # LIB/PATH are themselves semicolon-separated, which would corrupt a naive string(REPLACE "\n" ";" - # ...) split. file(STRINGS) keeps each real line, with its embedded semicolons, as one entry. - file(STRINGS "${_out_file}" _env_lines) - foreach(_line IN LISTS _env_lines) + # Walk the dump one line at a time with plain string operations, NOT via a cmake list (which is + # what file(STRINGS) hands back). Two properties of this output make list handling wrong: + # INCLUDE/LIB/PATH are themselves semicolon-separated, and Windows values routinely end in a + # backslash (VSINSTALLDIR, WindowsSdkBinPath, ...). A line ending in "\" turns the list + # separator that follows it into an escaped ";" when the list is expanded, silently gluing the + # next variable onto this one's value (e.g. VSINSTALLDIR ending up as + # "...\BuildTools;windir=C:\Windows") and losing that next variable entirely. A corrupt + # VSINSTALLDIR in turn breaks any *subsequent* vcvarsall call, whose -vcvars_ver check resolves + # against it ("Version '...' is not valid; directory does not exist"), which is exactly what + # probing more than one toolset in a single configure run does. + file(READ "${_out_file}" _env_raw) + string(REPLACE "\r\n" "\n" _env_raw "${_env_raw}") + while(NOT _env_raw STREQUAL "") + string(FIND "${_env_raw}" "\n" _nl) + if(_nl EQUAL -1) + set(_line "${_env_raw}") + set(_env_raw "") + else() + string(SUBSTRING "${_env_raw}" 0 ${_nl} _line) + math(EXPR _nl_next "${_nl} + 1") + string(SUBSTRING "${_env_raw}" ${_nl_next} -1 _env_raw) + endif() if(_line MATCHES "^([A-Za-z_][A-Za-z0-9_().]*)=(.*)$") set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") endif() - endforeach() + endwhile() endfunction() # Helper: with the given HIP compiler and whatever environment is currently active, try compiling a @@ -184,22 +201,23 @@ function(katago_win_pathlist_to_flags pathlist flagprefix out_var) set(${out_var} "${_flags}" PARENT_SCOPE) endfunction() -# Helper: find an MSVC "v143" toolset (possibly one of several 14.3x/14.4x versions installed -# side-by-side under one or more VS installs) whose STL doesn't conflict with the HIP compiler's -# own CUDA/HIP math forward-declare headers, apply the vcvarsall.bat environment for it (so the -# rest of THIS configure run - the HIP arch probing below, and project()'s own HIP compiler ABI -# test - see it), and also bake the resulting INCLUDE/LIB paths into cached compiler/linker flags -# so a later, separate `ninja` invocation (which does NOT inherit this configure run's environment -# - see katago_win_apply_vcvarsall's comment) keeps working too. +# Helper: find an MSVC toolset (possibly one of several versions installed side-by-side under one +# or more VS installs) whose STL doesn't conflict with the HIP compiler's own CUDA/HIP math +# forward-declare headers, apply the vcvarsall.bat environment for it (so the rest of THIS +# configure run - the HIP arch probing below, and project()'s own HIP compiler ABI test - see it), +# and also bake the resulting INCLUDE/LIB paths into cached compiler/linker flags so a later, +# separate `ninja` invocation (which does NOT inherit this configure run's environment - see +# katago_win_apply_vcvarsall's comment) keeps working too. # -# Deliberately pinned to the v143 toolset family (MSVC 14.3x/14.4x) rather than probing every -# installed toolset regardless of version: a newer MSVC STL (seen with a VS "18" preview-channel -# toolset, MSVC 14.51+, i.e. the next "v144" family) declares math functions like isgreater/isless -# in a way that conflicts with clang's forward declarations for CUDA/HIP device overloads ("device -# function cannot overload host device function"), because that clang version predates the STL's -# newly-added declarations. v143 is the toolset known to work with TheRock's clang. Probe within -# the v143 family (oldest first) rather than hardcoding one exact version, since multiple v143 -# point releases can be installed side by side and this needs one that's actually present. +# Every installed toolset is a candidate, probed NEWEST FIRST, and the compile probe - not a +# hardcoded version range - decides which one gets used. The conflict this guards against is real: +# some MSVC STL versions (first seen with a VS "18" preview-channel toolset, MSVC 14.51, i.e. the +# "v144" family) declare math functions like isgreater/isless in a way that clashes with clang's +# forward declarations for CUDA/HIP device overloads ("device function cannot overload host device +# function"), when that clang predates the STL's newly-added declarations. But that is a property +# of the specific STL/clang pair in front of us, not of the toolset family, so newer TheRock +# builds are free to start accepting newer toolsets without an edit here - they just get picked +# up. If the newest toolset fails the probe, the next-newest is tried, on down to the oldest. function(katago_win_autoselect_msvc_toolset hip_compiler) katago_win_find_vswhere(_vswhere) if(NOT _vswhere) @@ -226,11 +244,6 @@ function(katago_win_autoselect_msvc_toolset hip_compiler) foreach(_t IN LISTS _tool_dirs) if(IS_DIRECTORY "${_t}" AND EXISTS "${_t}/include/cmath") get_filename_component(_ver "${_t}" NAME) - # v143 toolset versions are 14.3x/14.4x (the next-generation "v144" toolset, seen with - # VS 18 preview builds, starts at 14.5x and is the one known to conflict - see above). - if(NOT _ver MATCHES "^14\\.[34][0-9]\\.") - continue() - endif() set(_vcvarsall "${_install_path}/VC/Auxiliary/Build/vcvarsall.bat") if(EXISTS "${_vcvarsall}") list(APPEND _toolsets "${_ver}|${_vcvarsall}") @@ -240,12 +253,28 @@ function(katago_win_autoselect_msvc_toolset hip_compiler) endforeach() if(NOT _toolsets) - message(FATAL_ERROR "No installed MSVC v143 toolset (14.3x/14.4x) found. Open the Visual Studio Installer, choose \"Modify\" on your VS installation, go to \"Individual Components\", and install \"MSVC v143 - VS 2022 C++ x64/x86 build tools\" (a newer toolset alone, e.g. a VS 18 preview's v144, is not compatible with TheRock's bundled clang).") + message(FATAL_ERROR "No installed MSVC toolset found under any Visual Studio installation. Open the Visual Studio Installer, choose \"Modify\" on your VS installation, go to \"Individual Components\", and install an \"MSVC ... C++ x64/x86 build tools\" component.") endif() list(REMOVE_DUPLICATES _toolsets) - list(SORT _toolsets COMPARE NATURAL ORDER ASCENDING) + # Newest first: prefer the most recent toolset installed, falling back to older ones only if the + # probe below rejects it. + list(SORT _toolsets COMPARE NATURAL ORDER DESCENDING) + + # vcvarsall.bat PREPENDS to these rather than replacing them, so probing a second toolset in the + # same cmake process would otherwise leave the rejected toolset's directories trailing behind the + # accepted one's - and those leftovers would get baked into the cached flags below. Snapshot the + # pre-vcvars values and restore them before each attempt so every probe starts from the same + # clean environment. + # Held in one variable per name rather than a list: these values are themselves + # semicolon-separated, which a cmake list would happily shred. + foreach(_env_var PATH INCLUDE LIB LIBPATH) + set(_orig_env_${_env_var} "$ENV{${_env_var}}") + endforeach() foreach(_entry IN LISTS _toolsets) + foreach(_env_var PATH INCLUDE LIB LIBPATH) + set(ENV{${_env_var}} "${_orig_env_${_env_var}}") + endforeach() string(REPLACE "|" ";" _entry_list "${_entry}") list(GET _entry_list 0 _ver) list(GET _entry_list 1 _vcvarsall) @@ -292,7 +321,7 @@ function(katago_win_autoselect_msvc_toolset hip_compiler) message(STATUS "MSVC toolset ${_ver} conflicts with the HIP compiler's CUDA/HIP math headers; trying another") endif() endforeach() - message(FATAL_ERROR "None of the installed MSVC v143 toolset(s) (14.3x/14.4x) compiled cleanly against TheRock's HIP compiler. This indicates a problem beyond the usual v143-vs-newer-toolset conflict this check is meant to catch - please report this along with the MSVC/TheRock versions involved.") + message(FATAL_ERROR "None of the installed MSVC toolsets compiled cleanly against TheRock's HIP compiler. A newer MSVC STL can conflict with an older bundled clang (\"device function cannot overload host device function\"); if every installed toolset is affected, install an older one - e.g. \"MSVC v143 - VS 2022 C++ x64/x86 build tools\" from the Visual Studio Installer's \"Individual Components\" tab - or use a newer TheRock distribution.") endfunction() # Normalize case here too (it is normalized again later next to the cache definition): the From d760314aa0d814ede6821a57bef8d75954579f65 Mon Sep 17 00:00:00 2001 From: Looong01 Date: Wed, 19 Aug 2026 06:31:46 +0800 Subject: [PATCH 37/37] Merge branch "AMD_GPU" Update --- Compiling.md | 8 ++--- cpp/CMakeLists.txt | 87 ++++++++++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/Compiling.md b/Compiling.md index 43b91450c2..01fba73c38 100644 --- a/Compiling.md +++ b/Compiling.md @@ -177,7 +177,7 @@ As also mentioned in the instructions below but repeated here for visibility, if * The ROCm (MIOpen) backend supports Windows via [AMD TheRock](https://github.com/ROCm/TheRock) (tested with TheRock 7.13 / ROCm 7.13, RX 7900 XTX / gfx1100), including transformer/attention models (model version 17+) and the optional Composable Kernel (CK) fused-attention fast path. * **Prerequisites:** * Download [AMD TheRock](https://github.com/ROCm/TheRock) and extract it to e.g. `C:\TheRock\build`, adjusting the paths below if you extract elsewhere. - * Install **Visual Studio Build Tools or Community** with the "Desktop development with C++" workload, for the MSVC toolchain and Windows SDK the HIP compiler needs. A **v143 toolset (MSVC 14.3x or 14.4x)** must be among the installed toolsets - newer toolsets alone (14.5x+) are not accepted by the HIP clang compatibility check. If more than one is installed side by side, `CMakeLists.txt` automatically probes them at configure time and picks a compatible one itself (see "Fully automatic" below), no manual toolset selection needed. + * Install **Visual Studio Build Tools or Community** with the "Desktop development with C++" workload, for the MSVC toolchain and Windows SDK the HIP compiler needs. If several toolsets are installed side by side, `CMakeLists.txt` probes them at configure time - newest first - and picks the first one the HIP compiler actually accepts (see "Fully automatic" below), no manual toolset selection needed. Note that a very new MSVC STL can be ahead of the clang bundled with TheRock; if configure reports that no installed toolset works, add an older one such as **MSVC v143 (14.3x/14.4x)** from the Visual Studio Installer's "Individual Components" tab. * Install [Ninja](https://ninja-build.org) build tool: `winget install Ninja-build.Ninja`. * Set the following **system environment variables** (via System Properties -> Advanced -> Environment Variables): ``` @@ -205,9 +205,9 @@ As also mentioned in the instructions below but repeated here for visibility, if Windows-specific setup automatically at configure/build time: * **MSVC toolset selection:** if more than one MSVC toolset is installed side by side, a newer one can conflict with TheRock's bundled clang (newer MSVC STL headers are not yet - compatible with it). `CMakeLists.txt` finds the installed v143-family toolsets via - `vswhere` and probes each with a real compile until one works, with no user action - needed. + compatible with it). `CMakeLists.txt` enumerates every installed toolset via + `vswhere` and probes them newest-first with a real compile until one works, with + no user action needed. * **zlib:** TheRock's Windows package ships `zlib.h` but (as of 7.13) no longer ships a linkable `.lib`. `CMakeLists.txt` automatically bootstraps a local [vcpkg](https://github.com/microsoft/vcpkg) clone under `/deps/vcpkg` (this diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index c4ec4f5d73..7598d9980f 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -137,15 +137,32 @@ function(katago_win_apply_vcvarsall vcvarsall_bat vcvars_ver) if(NOT _rc EQUAL 0 OR NOT EXISTS "${_out_file}") return() endif() - # Read line-by-line via file(STRINGS) rather than splitting the raw output ourselves - INCLUDE/ - # LIB/PATH are themselves semicolon-separated, which would corrupt a naive string(REPLACE "\n" ";" - # ...) split. file(STRINGS) keeps each real line, with its embedded semicolons, as one entry. - file(STRINGS "${_out_file}" _env_lines) - foreach(_line IN LISTS _env_lines) + # Walk the dump one line at a time with plain string operations, NOT via a cmake list (which is + # what file(STRINGS) hands back). Two properties of this output make list handling wrong: + # INCLUDE/LIB/PATH are themselves semicolon-separated, and Windows values routinely end in a + # backslash (VSINSTALLDIR, WindowsSdkBinPath, ...). A line ending in "\" turns the list + # separator that follows it into an escaped ";" when the list is expanded, silently gluing the + # next variable onto this one's value (e.g. VSINSTALLDIR ending up as + # "...\BuildTools;windir=C:\Windows") and losing that next variable entirely. A corrupt + # VSINSTALLDIR in turn breaks any *subsequent* vcvarsall call, whose -vcvars_ver check resolves + # against it ("Version '...' is not valid; directory does not exist"), which is exactly what + # probing more than one toolset in a single configure run does. + file(READ "${_out_file}" _env_raw) + string(REPLACE "\r\n" "\n" _env_raw "${_env_raw}") + while(NOT _env_raw STREQUAL "") + string(FIND "${_env_raw}" "\n" _nl) + if(_nl EQUAL -1) + set(_line "${_env_raw}") + set(_env_raw "") + else() + string(SUBSTRING "${_env_raw}" 0 ${_nl} _line) + math(EXPR _nl_next "${_nl} + 1") + string(SUBSTRING "${_env_raw}" ${_nl_next} -1 _env_raw) + endif() if(_line MATCHES "^([A-Za-z_][A-Za-z0-9_().]*)=(.*)$") set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") endif() - endforeach() + endwhile() endfunction() # Helper: with the given HIP compiler and whatever environment is currently active, try compiling a @@ -184,22 +201,23 @@ function(katago_win_pathlist_to_flags pathlist flagprefix out_var) set(${out_var} "${_flags}" PARENT_SCOPE) endfunction() -# Helper: find an MSVC "v143" toolset (possibly one of several 14.3x/14.4x versions installed -# side-by-side under one or more VS installs) whose STL doesn't conflict with the HIP compiler's -# own CUDA/HIP math forward-declare headers, apply the vcvarsall.bat environment for it (so the -# rest of THIS configure run - the HIP arch probing below, and project()'s own HIP compiler ABI -# test - see it), and also bake the resulting INCLUDE/LIB paths into cached compiler/linker flags -# so a later, separate `ninja` invocation (which does NOT inherit this configure run's environment -# - see katago_win_apply_vcvarsall's comment) keeps working too. +# Helper: find an MSVC toolset (possibly one of several versions installed side-by-side under one +# or more VS installs) whose STL doesn't conflict with the HIP compiler's own CUDA/HIP math +# forward-declare headers, apply the vcvarsall.bat environment for it (so the rest of THIS +# configure run - the HIP arch probing below, and project()'s own HIP compiler ABI test - see it), +# and also bake the resulting INCLUDE/LIB paths into cached compiler/linker flags so a later, +# separate `ninja` invocation (which does NOT inherit this configure run's environment - see +# katago_win_apply_vcvarsall's comment) keeps working too. # -# Deliberately pinned to the v143 toolset family (MSVC 14.3x/14.4x) rather than probing every -# installed toolset regardless of version: a newer MSVC STL (seen with a VS "18" preview-channel -# toolset, MSVC 14.51+, i.e. the next "v144" family) declares math functions like isgreater/isless -# in a way that conflicts with clang's forward declarations for CUDA/HIP device overloads ("device -# function cannot overload host device function"), because that clang version predates the STL's -# newly-added declarations. v143 is the toolset known to work with TheRock's clang. Probe within -# the v143 family (oldest first) rather than hardcoding one exact version, since multiple v143 -# point releases can be installed side by side and this needs one that's actually present. +# Every installed toolset is a candidate, probed NEWEST FIRST, and the compile probe - not a +# hardcoded version range - decides which one gets used. The conflict this guards against is real: +# some MSVC STL versions (first seen with a VS "18" preview-channel toolset, MSVC 14.51, i.e. the +# "v144" family) declare math functions like isgreater/isless in a way that clashes with clang's +# forward declarations for CUDA/HIP device overloads ("device function cannot overload host device +# function"), when that clang predates the STL's newly-added declarations. But that is a property +# of the specific STL/clang pair in front of us, not of the toolset family, so newer TheRock +# builds are free to start accepting newer toolsets without an edit here - they just get picked +# up. If the newest toolset fails the probe, the next-newest is tried, on down to the oldest. function(katago_win_autoselect_msvc_toolset hip_compiler) katago_win_find_vswhere(_vswhere) if(NOT _vswhere) @@ -226,11 +244,6 @@ function(katago_win_autoselect_msvc_toolset hip_compiler) foreach(_t IN LISTS _tool_dirs) if(IS_DIRECTORY "${_t}" AND EXISTS "${_t}/include/cmath") get_filename_component(_ver "${_t}" NAME) - # v143 toolset versions are 14.3x/14.4x (the next-generation "v144" toolset, seen with - # VS 18 preview builds, starts at 14.5x and is the one known to conflict - see above). - if(NOT _ver MATCHES "^14\\.[34][0-9]\\.") - continue() - endif() set(_vcvarsall "${_install_path}/VC/Auxiliary/Build/vcvarsall.bat") if(EXISTS "${_vcvarsall}") list(APPEND _toolsets "${_ver}|${_vcvarsall}") @@ -240,12 +253,28 @@ function(katago_win_autoselect_msvc_toolset hip_compiler) endforeach() if(NOT _toolsets) - message(FATAL_ERROR "No installed MSVC v143 toolset (14.3x/14.4x) found. Open the Visual Studio Installer, choose \"Modify\" on your VS installation, go to \"Individual Components\", and install \"MSVC v143 - VS 2022 C++ x64/x86 build tools\" (a newer toolset alone, e.g. a VS 18 preview's v144, is not compatible with TheRock's bundled clang).") + message(FATAL_ERROR "No installed MSVC toolset found under any Visual Studio installation. Open the Visual Studio Installer, choose \"Modify\" on your VS installation, go to \"Individual Components\", and install an \"MSVC ... C++ x64/x86 build tools\" component.") endif() list(REMOVE_DUPLICATES _toolsets) - list(SORT _toolsets COMPARE NATURAL ORDER ASCENDING) + # Newest first: prefer the most recent toolset installed, falling back to older ones only if the + # probe below rejects it. + list(SORT _toolsets COMPARE NATURAL ORDER DESCENDING) + + # vcvarsall.bat PREPENDS to these rather than replacing them, so probing a second toolset in the + # same cmake process would otherwise leave the rejected toolset's directories trailing behind the + # accepted one's - and those leftovers would get baked into the cached flags below. Snapshot the + # pre-vcvars values and restore them before each attempt so every probe starts from the same + # clean environment. + # Held in one variable per name rather than a list: these values are themselves + # semicolon-separated, which a cmake list would happily shred. + foreach(_env_var PATH INCLUDE LIB LIBPATH) + set(_orig_env_${_env_var} "$ENV{${_env_var}}") + endforeach() foreach(_entry IN LISTS _toolsets) + foreach(_env_var PATH INCLUDE LIB LIBPATH) + set(ENV{${_env_var}} "${_orig_env_${_env_var}}") + endforeach() string(REPLACE "|" ";" _entry_list "${_entry}") list(GET _entry_list 0 _ver) list(GET _entry_list 1 _vcvarsall) @@ -292,7 +321,7 @@ function(katago_win_autoselect_msvc_toolset hip_compiler) message(STATUS "MSVC toolset ${_ver} conflicts with the HIP compiler's CUDA/HIP math headers; trying another") endif() endforeach() - message(FATAL_ERROR "None of the installed MSVC v143 toolset(s) (14.3x/14.4x) compiled cleanly against TheRock's HIP compiler. This indicates a problem beyond the usual v143-vs-newer-toolset conflict this check is meant to catch - please report this along with the MSVC/TheRock versions involved.") + message(FATAL_ERROR "None of the installed MSVC toolsets compiled cleanly against TheRock's HIP compiler. A newer MSVC STL can conflict with an older bundled clang (\"device function cannot overload host device function\"); if every installed toolset is affected, install an older one - e.g. \"MSVC v143 - VS 2022 C++ x64/x86 build tools\" from the Visual Studio Installer's \"Individual Components\" tab - or use a newer TheRock distribution.") endfunction() # Normalize case here too (it is normalized again later next to the cache definition): the