opencv / opencv_contrib

Repository for OpenCV's extra modules
Apache License 2.0
9.32k stars 5.74k forks source link

opencv_rgbd - Windows ARM64 / ARM64EC - Build issue - 4.10.0 #3767

Closed danoli3 closed 2 months ago

danoli3 commented 2 months ago
System information (version)
Detailed description

Compile for VS2022 - MSVC - CMakeList - ARM64 / ARM64EC

Steps to reproduce
echoInfo "building $TYPE | $ARCH | $VS_VER | vs: $VS_VER_GEN - "${PLATFORM}""
    echoInfo "--------------------"
    GENERATOR_NAME="Visual Studio ${VS_VER_GEN}" 
    mkdir -p "build_${TYPE}_${PLATFORM}"
    cd "build_${TYPE}_${PLATFORM}"
    rm -f CMakeCache.txt || true

    ZLIB_ROOT="$LIBS_ROOT/zlib/"
    ZLIB_INCLUDE_DIR="$LIBS_ROOT/zlib/include"
    ZLIB_LIBRARY="$LIBS_ROOT/zlib/lib/$TYPE/$PLATFORM/zlib.lib"

    LIBPNG_ROOT="$LIBS_ROOT/libpng/"
    LIBPNG_INCLUDE_DIR="$LIBS_ROOT/libpng/include"
    LIBPNG_LIBRARY="$LIBS_ROOT/libpng/lib/$TYPE/$PLATFORM/libpng.lib"

    DEFS="
        -DCMAKE_C_STANDARD=${C_STANDARD} \
        -DCMAKE_CXX_STANDARD=${CPP_STANDARD} \
        -DCMAKE_CXX_STANDARD_REQUIRED=ON \
        -DCMAKE_CXX_EXTENSIONS=OFF \
        -DBUILD_SHARED_LIBS=ON \
        -DCMAKE_INSTALL_PREFIX=install \
        -DCMAKE_INSTALL_INCLUDEDIR=include \
        -DCMAKE_INSTALL_LIBDIR="lib" \
        -DCMAKE_INCLUDE_OUTPUT_DIRECTORY=include \
        -DWITH_OPENCLAMDBLAS=OFF \
        -DBUILD_TESTS=OFF \
        -DWITH_CUDA=OFF \
        -DWITH_FFMPEG=OFF \
        -DWITH_WIN32UI=OFF \
        -DBUILD_PACKAGE=OFF \
        -DWITH_JASPER=OFF \
        -DWITH_OPENEXR=OFF \
        -DWITH_GIGEAPI=OFF \
        -DWITH_JPEG=OFF \
        -DBUILD_WITH_DEBUG_INFO=OFF \
        -DWITH_CUFFT=OFF \
        -DBUILD_TIFF=OFF \
        -DBUILD_JPEG=OFF \
        -DWITH_OPENCLAMDFFT=OFF \
        -DBUILD_WITH_STATIC_CRT=OFF \
        -DBUILD_opencv_java=OFF \
        -DBUILD_opencv_python=OFF \
        -DBUILD_opencv_python2=OFF \
        -DBUILD_opencv_python3=OFF \
        -DBUILD_NEW_PYTHON_SUPPORT=OFF \
        -DBUILD_opencv_objdetect=ON \
        -DHAVE_opencv_python3=OFF \
        -DHAVE_opencv_python=OFF \
        -DHAVE_opencv_python2=OFF \
        -DBUILD_opencv_apps=OFF \
        -DBUILD_opencv_videoio=OFF \
        -DBUILD_opencv_videostab=OFF \
        -DBUILD_opencv_highgui=OFF \
        -DBUILD_opencv_imgcodecs=ON \
        -DBUILD_opencv_stitching=ON \
        -DBUILD_opencv_calib3d=ON \
        -DBUILD_PERF_TESTS=OFF \
        -DBUILD_JASPER=OFF \
        -DBUILD_DOCS=OFF \
        -DWITH_TIFF=OFF \
        -DWITH_1394=OFF \
        -DWITH_EIGEN=OFF \
        -DBUILD_OPENEXR=OFF \
        -DWITH_DSHOW=OFF \
        -DWITH_VFW=OFF \
        -DWITH_PNG=ON \
        -DBUILD_PNG=OFF \
        -DWITH_OPENCL=OFF \
        -DWITH_PVAPI=OFF\
        -DBUILD_OBJC=OFF \
        -DWITH_TIFF=OFF \
        -DWITH_OPENEXR=OFF \
        -DWITH_OPENGL=OFF \
        -DWITH_OPENVX=OFF \
        -DWITH_1394=OFF \
        -DWITH_ADE=OFF \
        -DWITH_JPEG=OFF \
        -DWITH_FFMPEG=OFF \
        -DWITH_GIGEAPI=OFF \
        -DWITH_CUDA=OFF \
        -DWITH_CUFFT=OFF \
        -DWITH_GIGEAPI=OFF \
        -DWITH_GPHOTO2=OFF \
        -DWITH_GSTREAMER=OFF \
        -DWITH_GSTREAMER_0_10=OFF \
        -DWITH_JASPER=OFF \
        -DWITH_IMAGEIO=OFF \
        -DWITH_IPP=OFF \
        -DWITH_IPP_A=OFF \
        -DWITH_OPENNI=OFF \
        -DWITH_OPENNI2=OFF \
        -DWITH_QT=OFF \
        -DWITH_QUICKTIME=OFF \
        -DWITH_V4L=OFF \
        -DWITH_LIBV4L=OFF \
        -DWITH_MATLAB=OFF \
        -DWITH_OPENCL=OFF \
        -DWITH_OPENCLCLAMDBLAS=OFF \
        -DWITH_OPENCLCLAMDFFT=OFF \
        -DWITH_OPENCL_SVM=OFF \
        -DWITH_LAPACK=OFF \
        -DBUILD_ZLIB=OFF \
        -DWITH_ZLIB=ON \
        -DWITH_WEBP=OFF \
        -DWITH_VTK=OFF \
        -DWITH_PVAPI=OFF \
        -DWITH_EIGEN=OFF \
        -DWITH_GTK=OFF \
        -DWITH_GTK_2_X=OFF \
        -DWITH_OPENCLAMDBLAS=OFF \
        -DWITH_OPENCLAMDFFT=OFF \
        -DBUILD_TESTS=OFF \
        -DCV_DISABLE_OPTIMIZATION=OFF"

      if [[ ${ARCH} == "arm64ec" || "${ARCH}" == "arm64" ]]; then
        EXTRA_DEFS="-DCV_ENABLE_INTRINSICS=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_SSE3=OFF -DENABLE_SSE41=OFF -DENABLE_SSE42=OFF -DENABLE_SSSE3=OFF"
      else 
        EXTRA_DEFS="-DCV_ENABLE_INTRINSICS=ON -DENABLE_SSE=ON -DENABLE_SSE2=ON -DENABLE_SSE3=ON -DENABLE_SSE41=ON -DENABLE_SSE42=ON -DENABLE_SSSE3=ON"
      fi

    cmake .. ${DEFS} \
        -A "${PLATFORM}" \
        -G "${GENERATOR_NAME}" \
        -DCMAKE_PREFIX_PATH="${LIBS_ROOT}" \
        -DCMAKE_INSTALL_PREFIX=Debug \
        -DCMAKE_BUILD_TYPE="Debug" \
        -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
        -DCMAKE_CXX_FLAGS_DEBUG="-DUSE_PTHREADS=1 ${VS_C_FLAGS} ${FLAGS_DEBUG} ${EXCEPTION_FLAGS}" \
        -DCMAKE_C_FLAGS_DEBUG="-DUSE_PTHREADS=1 ${VS_C_FLAGS} ${FLAGS_DEBUG} ${EXCEPTION_FLAGS}" \
        -DCMAKE_VERBOSE_MAKEFILE=${VERBOSE_MAKEFILE} \
        -D BUILD_SHARED_LIBS=ON \
        -DCMAKE_SYSTEM_PROCESSOR="${PLATFORM}" \
        ${EXTRA_DEFS} \
        ${CMAKE_WIN_SDK} \
        -DZLIB_ROOT=${ZLIB_ROOT} \
        -DZLIB_LIBRARY=${ZLIB_LIBRARY} \
        -DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE_DIR} \
        -DPNG_ROOT=${LIBPNG_ROOT} \
        -DPNG_PNG_INCLUDE_DIR=${LIBPNG_INCLUDE_DIR} \
        -DPNG_LIBRARY=${LIBPNG_LIBRARY} \
        -DBUILD_WITH_STATIC_CRT=OFF 
     cmake --build . --target install --config Debug
     cmake .. ${DEFS} \
        -A "${PLATFORM}" \
        -G "${GENERATOR_NAME}" \
        -DCMAKE_PREFIX_PATH="${LIBS_ROOT}" \
        -DCMAKE_INSTALL_PREFIX=Release \
        -DCMAKE_BUILD_TYPE="Release" \
        -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
        -DCMAKE_VERBOSE_MAKEFILE=${VERBOSE_MAKEFILE} \
        -DCMAKE_SYSTEM_PROCESSOR="${PLATFORM}" \
        -DCMAKE_CXX_FLAGS_RELEASE="-DUSE_PTHREADS=1 ${VS_C_FLAGS} ${FLAGS_RELEASE} ${EXCEPTION_FLAGS}" \
        -DCMAKE_C_FLAGS_RELEASE="-DUSE_PTHREADS=1 ${VS_C_FLAGS} ${FLAGS_RELEASE} ${EXCEPTION_FLAGS}" \
        -D BUILD_SHARED_LIBS=ON \
        ${EXTRA_DEFS} \
        -DZLIB_ROOT=${ZLIB_ROOT} \
        -DZLIB_LIBRARY=${ZLIB_LIBRARY} \
        -DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE_DIR} \
        -DPNG_ROOT=${LIBPNG_ROOT} \
        -DPNG_PNG_INCLUDE_DIR=${LIBPNG_INCLUDE_DIR} \
        -DPNG_LIBRARY=${LIBPNG_LIBRARY} \
        -DBUILD_WITH_STATIC_CRT=OFF \
        ${CMAKE_WIN_SDK}
    cmake --build . --target install --config Release
    cd ..   

Error:

  D:\a\apothecary\apothecary\apothecary\build\opencv\build_vs_ARM64EC\modules\rgbd\opencv_rgbd.vcxproj]
  utils.cpp
  volume.cpp
  warpfield.cpp
  opencl_kernels_rgbd.cpp
  opencv_rgbd_main.cpp
     Creating library D:/a/apothecary/apothecary/apothecary/build/opencv/build_vs_ARM64EC/lib/Debug/opencv_rgbd4100d.lib and object D:/a/apothecary/apothecary/apothecary/build/opencv/build_vs_ARM64EC/lib/Debug/opencv_rgbd4100d.exp
hash_tsdf.obj : error LNK2019: unresolved external symbol _tzcnt_u32 referenced in function #_tzcnt_u32$exit_thunk (EC Symbol) [D:\a\apothecary\apothecary\apothecary\build\opencv\build_vs_ARM64EC\modules\rgbd\opencv_rgbd.vcxproj]
D:\a\apothecary\apothecary\apothecary\build\opencv\build_vs_ARM64EC\bin\Debug\opencv_rgbd4100d.dll : fatal error LNK1120: 1 unresolved externals [D:\a\apothecary\apothecary\apothecary\build\opencv\build_vs_ARM64EC\modules\rgbd\opencv_rgbd.vcxproj]

https://github.com/openframeworks/apothecary/actions/runs/9874992463/job/27270618800?pr=390

buildarm64ec.log

Issue submission checklist
danoli3 commented 2 months ago

Fix ideas:

#ifdef _M_X64 // or another macro specific to x86/64
    #include <immintrin.h> // Include necessary headers for x86/64 intrinsics
    // Use _tzcnt_u32 for x86/64
    #define TZS_INTRINSIC _tzcnt_u32
#elif defined(__aarch64__) // Macro for ARM64 architecture
    static inline uint32_t TZS_INTRINSIC(uint32_t x) {
        return __builtin_ctz(x); // GCC/Clang intrinsic for count trailing zeros
    }
#else
    #error Unsupported architecture
#endif
uint32_t result = TZS_INTRINSIC(value);

Current work around:

-DBUILD_opencv_rgbd=OFF \
Kumataro commented 2 months ago

Hello, I'm not friendly to "ARM64EC", so I'm sorry if I have mistake. And I have no test environment about ARM64EC building. If my patch works well, please could you response ? I'l create pull requests.

On OpenCV code, cnt is used only for zlib-ng and hal.

kmtr@kmtr-VMware-Virtual-Platform:~/work/opencv4/modules$ git reset --hard
HEAD is now at 15783d6598 Merge pull request #25792 from asmorkalov:as/HAL_fast_GaussianBlur
kmtr@kmtr-VMware-Virtual-Platform:~/work/opencv4/modules$ git grep tzcnt
core/include/opencv2/core/hal/intrin.hpp:    // clang-cl doesn't export _tzcnt_u32 for non BMI systems
core/include/opencv2/core/hal/intrin.hpp:    return _tzcnt_u32(value);

I think we have to add condition for ARM64EC to stop using _tzcnt_u32().

Microsoft document is https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170

For ARM64EC target, "_M_ARM" and "_M_ARM64" is undefined. So OpenCV try to use _tzcnt_u32() like x86-64.

  • _M_ARM Defined as the integer literal value 7 for compilations that target ARM processors. Undefined for ARM64, ARM64EC, and other targets.
  • _M_ARM64 Defined as 1 for compilations that target ARM64. Otherwise, undefined.
  • _M_ARM64EC Defined as 1 for compilations that target ARM64EC. Otherwise, undefined.

So I think we should add condition for M_ARM64 .

https://github.com/opencv/opencv/blob/15783d65981d8978597c6b60e830e21e964cbdf9/modules/core/include/opencv2/core/hal/intrin.hpp#L64-L73

- #if (_MSC_VER < 1700) || defined(_M_ARM) || defined(_M_ARM64)
+ #if (_MSC_VER < 1700) || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC)
      unsigned long index = 0;
      _BitScanForward(&index, value);
      return (unsigned int)index;
danoli3 commented 2 months ago

Yeah that should fix it!

Kumataro commented 2 months ago

Thank you for your report ! I'll change pull request status to remove draft !