From a21f8b8ce023c4b32822e70889df63e7729dfa7f Mon Sep 17 00:00:00 2001 From: chenzhengyong Date: Mon, 14 Sep 2026 21:12:21 +0800 Subject: [PATCH 1/2] Only pass -mfpmath=sse on x86 The GNU/Clang branch treated "not ARM" as "is x86", so every non-x86 ISA (loongarch64, riscv64, ppc64le, mips64, ...) was handed -mfpmath=sse and failed to compile any translation unit with "unrecognized command-line option '-mfpmath=sse'". The flag is already a no-op on x86-64 - SSE-based IEEE float math is the ABI default there and x87 excess precision cannot occur - so restricting it to x86 changes no behavior on existing targets while making the rest build. --- cpp/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 32852705a1..a4a4aed084 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1980,7 +1980,9 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "C # For ARM architecture, as a hack, ensure that char is signed message(STATUS "ARM architecture detected: adding -fsigned-char flag") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char") - else() + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86_64|amd64|AMD64|i386|i486|i586|i686|x86)") + # -mfpmath=sse only exists on x86, so non-x86 ISAs (loongarch64, riscv64, ppc64le, mips64, + # ...) must not get it - they hard-error with "unrecognized command-line option". # KataGo wants IEEE-compliant float math. # On x86-64 SSE-based IEEE float math is already the ABI default (x87 excess precision cannot occur), # but mandate it explicitly anyway. From 4ac49bb3126c8856c52e8a86ff4be1cc464592c5 Mon Sep 17 00:00:00 2001 From: chenzhengyong Date: Mon, 14 Sep 2026 21:12:30 +0800 Subject: [PATCH 2/2] Normalize NHWC and FP16 test args for the Eigen backend The Eigen backend only implements the NHWC float32 path and hard-errors on NCHW (eigenbackend.cpp:2425) and on FP16 (eigenbackend.cpp:2663). Nothing compensated for that: TestCommon::overrideForBackends only knew about OpenCL and TensorRT, and testsearchmisc.cpp never called it at all. So every NN test invoked with NCHW or FP16 args - which is how runsearchtestslimited.sh and runsearchtests.sh invoke them - aborted with SIGABRT instead of running. Clamp in the two startNNEval helpers instead of extending overrideForBackends: they are the single choke point all NN tests go through, which also covers testsearchmisc.cpp's runNNSymmetriesTest and runNNBatchingTest. Guarded by USE_EIGEN_BACKEND, so other backends are unaffected. --- cpp/tests/testsearchcommon.cpp | 18 ++++++++++++++++++ cpp/tests/testtrainingwrite.cpp | 13 +++++++++++++ 2 files changed, 31 insertions(+) diff --git a/cpp/tests/testsearchcommon.cpp b/cpp/tests/testsearchcommon.cpp index 6cd6936427..87d8bdc823 100644 --- a/cpp/tests/testsearchcommon.cpp +++ b/cpp/tests/testsearchcommon.cpp @@ -203,6 +203,24 @@ NNEvaluator* TestSearchCommon::startNNEval( const string& modelName = modelFile; const string homeDataDirOverride = ""; ConfigParser cfg; +#if defined(USE_EIGEN_BACKEND) + //The Eigen backend only implements the NHWC float32 path and hard-errors on anything else + //(see eigenbackend.cpp), but the tests and the runsearchtests*.sh scripts are written for the + //GPU backends and pass NCHW and/or FP16. Normalize here, at the one choke point every NN test + //goes through, rather than fixing up each call site. + if(!inputsUseNHWC) { + std::cout << "Backend is Eigen, ignoring args and forcing inputsUseNHWC=true" << std::endl; + inputsUseNHWC = true; + } + if(!useNHWC) { + std::cout << "Backend is Eigen, ignoring args and forcing useNHWC=true" << std::endl; + useNHWC = true; + } + if(useFP16) { + std::cout << "Backend is Eigen, ignoring args and forcing useFP16=false" << std::endl; + useFP16 = false; + } +#endif //NHWC layout is no longer a generic NNEvaluator option; only the CUDA backend reads it (off cfg). //Route the test's useNHWC param into a cudaUseNHWC override so it still drives the CUDA layout. cfg.overrideKey("cudaUseNHWC", useNHWC ? "true" : "false"); diff --git a/cpp/tests/testtrainingwrite.cpp b/cpp/tests/testtrainingwrite.cpp index 80d12d87e8..3a979f8548 100644 --- a/cpp/tests/testtrainingwrite.cpp +++ b/cpp/tests/testtrainingwrite.cpp @@ -24,6 +24,19 @@ static NNEvaluator* startNNEval( bool debugSkipNeuralNet = modelFile == "/dev/null"; const string homeDataDirOverride = ""; ConfigParser cfg; +#if defined(USE_EIGEN_BACKEND) + //The Eigen backend only implements the NHWC float32 path and hard-errors on NCHW + //(see eigenbackend.cpp). These tests default to useNHWC=false, which the GPU backends accept + //but Eigen does not, so normalize here at the one choke point they all go through. + if(!inputsUseNHWC) { + cout << "Backend is Eigen, ignoring args and forcing inputsUseNHWC=true" << endl; + inputsUseNHWC = true; + } + if(!useNHWC) { + cout << "Backend is Eigen, ignoring args and forcing useNHWC=true" << endl; + useNHWC = true; + } +#endif //NHWC layout is no longer a generic NNEvaluator option; only the CUDA backend reads it (off cfg). //Route the test's useNHWC param into a cudaUseNHWC override so it still drives the CUDA layout. cfg.overrideKey("cudaUseNHWC", useNHWC ? "true" : "false");