The MLAS POWER kernels are VSX code, and inc/mlas.h only defines MLAS_TARGET_POWER when __VSX__ is set. The CMake side instead keys off CMAKE_SYSTEM_PROCESSOR, so pre-VSX 64-bit PowerPC targets (POWER4/POWER5, 970/G5, Cell) compile POWER kernels that platform.cpp never dispatches to, while the generic code path is left without its MlasSgemmKernelZero/Add implementation. Probe __VSX__ the same way the sources do and fall back to the scalar kernels when the target has no VSX. --- opencv-5.0.0.vanilla/3rdparty/mlas/CMakeLists.txt +++ opencv-5.0.0/3rdparty/mlas/CMakeLists.txt @@ -156,6 +156,21 @@ endif() # POWER (ppc64le / AIX). Always compile the base SgemmKernelPower; opt-in # POWER10 if the compiler supports -mcpu=power10. if(MLAS_POWER) + # The POWER kernels are VSX code, and inc/mlas.h only defines + # MLAS_TARGET_POWER when __VSX__ is set. Pre-VSX 64-bit PowerPC targets + # (POWER4/POWER5, 970/G5, Cell) match the CMAKE_SYSTEM_PROCESSOR test above + # but build kernels platform.cpp never dispatches to, so key the kernel + # choice off the same __VSX__ the sources use. + include(CheckCXXSourceCompiles) + check_cxx_source_compiles(" + #if !defined(__VSX__) + #error target has no VSX + #endif + int main() { return 0; }" MLAS_HAS_VSX) + set(MLAS_HAS_VSX ${MLAS_HAS_VSX} CACHE INTERNAL "" FORCE) +endif() + +if(MLAS_POWER AND MLAS_HAS_VSX) list(APPEND mlas_platform_srcs ${MLAS_SRC_DIR}/power/SgemmKernelPower.cpp) set_source_files_properties(${MLAS_SRC_DIR}/power/SgemmKernelPower.cpp PROPERTIES COMPILE_FLAGS "-DSINGLE") @@ -172,6 +187,10 @@ if(MLAS_POWER) set_source_files_properties(${MLAS_SRC_DIR}/power/SgemmKernelPOWER10.cpp PROPERTIES COMPILE_FLAGS "-O2 -mcpu=power10 -DSINGLE") endif() +elseif(MLAS_POWER) + message(STATUS "MLAS: ${CMAKE_SYSTEM_PROCESSOR} target has no VSX; " + "using the scalar SGEMM kernels") + list(APPEND mlas_platform_srcs ${MLAS_SRC_DIR}/scalar/SgemmKernelScalar.cpp) endif() # LoongArch 64 (LSX + LASX).