diff --git a/.github/workflows/build_cpp.yml b/.github/workflows/build_cpp.yml index 28ee56f8c3..828d914bcb 100644 --- a/.github/workflows/build_cpp.yml +++ b/.github/workflows/build_cpp.yml @@ -2,238 +2,286 @@ name: C++ on: push: - branches: - - master + branches: [ master ] paths: - - ".github/workflows/build_cpp.yml" - - "**.cpp" - - "**.h" - - "**.c" - - "**.cu" - - "**.cmake" - - "**CMakeLists.txt" + - ".github/workflows/build_cpp.yml" + - "**.cpp" + - "**.h" + - "**.c" + - "**.cu" + - "**.cmake" + - "**CMakeLists.txt" pull_request: - branches: - - master + branches: [ master ] paths: - - ".github/workflows/build_cpp.yml" - - "**.cpp" - - "**.h" - - "**.c" - - "**.cu" - - "**.cmake" - - "**CMakeLists.txt" + - ".github/workflows/build_cpp.yml" + - "**.cpp" + - "**.h" + - "**.c" + - "**.cu" + - "**.cmake" + - "**CMakeLists.txt" defaults: run: shell: bash - working-directory: dlib/test jobs: - ubuntu-22-04-gcc-default-cmake-3-10-ffmpeg5: - runs-on: 'ubuntu-22.04' + linux: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: ubuntu-22.04-default-deps + os : ubuntu-22.04 + build_tests : true + build_examples : true + build_blas_bindings : true + c_compiler : gcc + cxx_compiler : g++ + extra_apt : libwebp-dev libavformat-dev libavcodec-dev libavdevice-dev libavfilter-dev libswresample-dev libswscale-dev libavutil-dev libopenblas-dev liblapack-dev + + - name: ubuntu-22.04-atlas + os : ubuntu-22.04 + build_tests : true + build_blas_bindings : true + c_compiler : gcc + cxx_compiler : g++ + extra_apt : libatlas-base-dev + + - name: ubuntu-22.04-ffmpeg-513 + os : ubuntu-22.04 + build_ffmpeg : true + build_ffmpeg_examples : true + ffmpeg_version : 5.1.3 + c_compiler : gcc + cxx_compiler : g++ + extra_apt : make yasm + configure_extra : -DCMAKE_PREFIX_PATH=/home/runner/ffmpeg-n5.1.3_installation + + - name: ubuntu-22.04-ffmpeg-701 + os : ubuntu-22.04 + build_ffmpeg : true + build_ffmpeg_examples : true + ffmpeg_version : 7.0.1 + c_compiler : gcc + cxx_compiler : g++ + extra_apt : make yasm + configure_extra : -DCMAKE_PREFIX_PATH=/home/runner/ffmpeg-n7.0.1_installation + + - name: ubuntu-22.04-ffmpeg-711 + os : ubuntu-22.04 + build_ffmpeg : true + build_ffmpeg_examples : true + ffmpeg_version : 7.1.1 + c_compiler : gcc + cxx_compiler : g++ + extra_apt : make yasm + configure_extra : -DCMAKE_PREFIX_PATH=/home/runner/ffmpeg-n7.1.1_installation + + - name: ubuntu-latest-gcc11-default-deps + os : ubuntu-latest + build_tests : true + build_examples : true + build_blas_bindings : true + c_compiler : gcc-11 + cxx_compiler : g++-11 + extra_apt : "libwebp-dev libavformat-dev libavcodec-dev libavdevice-dev libavfilter-dev libswresample-dev libswscale-dev libavutil-dev libopenblas-dev liblapack-dev gcc-11 g++-11" + + - name: ubuntu-latest-clang-default-avx + os : ubuntu-latest + build_tests : true + build_examples : true + c_compiler : clang + cxx_compiler : clang++ + extra_apt : "libwebp-dev libavformat-dev libavcodec-dev libavdevice-dev libavfilter-dev libswresample-dev libswscale-dev libavutil-dev clang" + configure_extra : -DUSE_AVX_INSTRUCTIONS=1 + + - name: ubuntu-latest-mkl-sequential + os : ubuntu-latest + build_tests : true + build_mkl : true + c_compiler : gcc + cxx_compiler : g++ + configure_extra : -DDLIB_USE_MKL_SEQUENTIAL=ON + + - name: ubuntu-latest-mkl-tbb + os : ubuntu-latest + build_tests : true + build_mkl : true + c_compiler : gcc + cxx_compiler : g++ + configure_extra : -DDLIB_USE_MKL_SEQUENTIAL=OFF -DDLIB_USE_MKL_WITH_TBB=ON + + - name: ubuntu-latest-mkl-thread + os : ubuntu-latest + build_tests : true + build_mkl : true + c_compiler : gcc + cxx_compiler : g++ + configure_extra : -DDLIB_USE_MKL_SEQUENTIAL=OFF -DDLIB_USE_MKL_WITH_TBB=OFF -DDLIB_USE_MKL_THREAD=ON + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Install dependencies - run: | - sudo apt update - sudo apt install libwebp-dev make yasm - - - name: Cache cmake 3.10.0 - uses: actions/cache@v3 - id: cache-cmake-download - with: - # cache this folder: - path: ~/cmake-3.10.0-Linux-x86_64 - key: cmake-3.10.0_try3 - - - run: | - # Get the minimum version of cmake dlib supports - wget https://cmake.org/files/v3.10/cmake-3.10.0-Linux-x86_64.tar.gz - tar -xf cmake-3.10.0-Linux-x86_64.tar.gz -C ~ - if: steps.cache-cmake-download.outputs.cache-hit != 'true' - - - name: Cache FFmpeg 5 - uses: actions/cache@v3 - id: cache-ffmpeg5 - with: - path: /home/runner/ffmpeg-n5.1.3_installation - key: ffmpeg-n5.1.3_try4 - - - name: Build FFmpeg 5 - if: steps.cache-ffmpeg5.outputs.cache-hit != 'true' - run: | - wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n5.1.3.tar.gz - tar -xf n5.1.3.tar.gz - cd FFmpeg-n5.1.3 - ./configure --prefix=/home/runner/ffmpeg-n5.1.3_installation --disable-doc --disable-programs - make -j4 - make install - cd .. - - - name: Configure - run: | - mkdir build - cd build - ~/cmake-3.10.0-Linux-x86_64/bin/cmake -DCMAKE_PREFIX_PATH=/home/runner/ffmpeg-n5.1.3_installation .. + - name: Install system dependencies + if: ${{ matrix.extra_apt != '' }} + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.extra_apt }} + + - name: Cache FFmpeg + if: ${{ matrix.build_ffmpeg }} + uses: actions/cache@v3 + id: cache-ffmpeg + with: + path: /home/runner/ffmpeg-n${{ matrix.ffmpeg_version }}_installation + key: ffmpeg-n${{ matrix.ffmpeg_version }} + + - name: Build FFmpeg + if: ${{ matrix.build_ffmpeg && (steps.cache-ffmpeg.outputs.cache-hit != 'true') }} + run: | + wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n${{ matrix.ffmpeg_version }}.tar.gz + tar -xf n${{ matrix.ffmpeg_version }}.tar.gz + cd FFmpeg-n${{ matrix.ffmpeg_version }} + ./configure --prefix=/home/runner/ffmpeg-n${{ matrix.ffmpeg_version }}_installation --disable-doc --disable-programs + make -j4 + make install + + - name: Prepare MKL dir for cache restore + if: ${{ matrix.build_mkl }} + run: sudo mkdir -p /opt/intel - - name: Build just tests - run: | - cd build - make -j4 dtest - - - name: Test - run: build/dtest --runall -q - - - name: Build examples, etc - run: | - cd build - make -j2 - - ubuntu-latest-gcc-11-blas: - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: | - sudo apt update - sudo apt install libwebp-dev libavformat-dev libavcodec-dev libavdevice-dev libavfilter-dev libswresample-dev libswscale-dev libavutil-dev - sudo apt install libopenblas-dev liblapack-dev - - name: Install gcc 11 - run: | - sudo apt install gcc-11 g++-11 - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110 --slave /usr/bin/g++ g++ /usr/bin/g++-11 --slave /usr/bin/gcov gcov /usr/bin/gcov-11 - - name: Configure - run: cmake ${{ github.workspace }}/dlib/test -B build - - name: Build just tests - run: cmake --build build --config Release --target dtest --parallel 4 - - name: Test - run: build/dtest --runall -q - - name: Build examples, etc - run: cmake --build build --config Release --parallel 2 - - # Test the BLAS bindings - - name: Configure BLAS binding tests - run: cmake ${{ github.workspace }}/dlib/test/blas_bindings -B build_blas_bindings - - name: Build blas binding tests - run: cmake --build build_blas_bindings --config Debug --parallel 4 - - name: Test BLAS bindings - run: build_blas_bindings/dtest --runall -q - - ubuntu-latest-clang-default-avx: - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: | - sudo apt update - sudo apt install libwebp-dev libavformat-dev libavcodec-dev libavdevice-dev libavfilter-dev libswresample-dev libswscale-dev libavutil-dev - - name: Configure - run: | - export CC=/usr/bin/clang - export CXX=/usr/bin/clang++ - cmake ${{ github.workspace }}/dlib/test -B build -DUSE_AVX_INSTRUCTIONS=1 - - name: Build just tests - run: cmake --build build --config Release --target dtest --parallel 4 - - name: Test - run: build/dtest --runall -q - - name: Build examples, etc - run: cmake --build build --config Release --parallel 2 - - ubuntu-22-04-ffmpeg701: - runs-on: 'ubuntu-22.04' - steps: - - uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt update - sudo apt install make yasm - - - name: Cache FFmpeg 7 - uses: actions/cache@v3 - id: cache-ffmpeg7 - with: - path: /home/runner/ffmpeg-n7.0.1_installation - key: ffmpeg-n7.0.1_try2 - - - name: Build FFmpeg 7 - if: steps.cache-ffmpeg7.outputs.cache-hit != 'true' - run: | - wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.0.1.tar.gz - tar -xf n7.0.1.tar.gz - cd FFmpeg-n7.0.1 - ./configure --prefix=/home/runner/ffmpeg-n7.0.1_installation --disable-doc --disable-programs - make -j4 - make install - cd .. + - name: Cache MKL + if: ${{ matrix.build_mkl}} + uses: actions/cache@v3 + id: cache-mkl + with: + path: | + /opt/intel/oneapi/mkl + /opt/intel/oneapi/tbb + /opt/intel/oneapi/compiler + key: mkl_try3 + + - name: Download MKL + if: ${{ matrix.build_mkl && (steps.cache-mkl.outputs.cache-hit != 'true') }} + run: | + wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/bd1d0273-a931-4f7e-ab76-6a2a67d646c7/intel-oneapi-base-toolkit-2025.2.0.592_offline.sh + sudo sh ./intel-oneapi-base-toolkit-2025.2.0.592_offline.sh -a --silent --eula accept + + - name: Configure + run: | + cmake dlib/test -B build \ + -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} \ + -DCMAKE_CXX_COMPILER=${{ matrix.cxx_compiler }} \ + ${{ matrix.configure_extra }} + + - name: Build tests + if: ${{ matrix.build_tests }} + run: cmake --build build --config Release --target dtest --parallel 4 + + - name: Test + if: ${{ matrix.build_tests }} + run: ./build/dtest --runall -q + + - name: Build examples + if: ${{ matrix.build_examples }} + run: cmake --build build --config Release --parallel 4 + + - name: Build FFMPEG examples + if: ${{ matrix.build_ffmpeg_examples }} + run: cmake --build build --config Release --target ffmpeg_video_muxing_ex --parallel 4 + + - name: Configure BLAS binding tests + if: ${{ matrix.build_blas_bindings }} + run: cmake dlib/test/blas_bindings -B build_blas_bindings + + - name: Build BLAS binding tests + if: ${{ matrix.build_blas_bindings }} + run: cmake --build build_blas_bindings --config Debug --parallel 4 - - name: Configure - run: cmake . -B build -DCMAKE_PREFIX_PATH=/home/runner/ffmpeg-n7.0.1_installation - - name: Build ffmpeg example - run: cmake --build build --config Release --target ffmpeg_video_muxing_ex --parallel 4 + - name: Test BLAS bindings + if: ${{ matrix.build_blas_bindings }} + run: ./build_blas_bindings/dtest --runall -q + + windows: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: windows-latest-openblas + os : windows-latest + build_openblas : true + build_tests : true + build_blas_bindings : true + configure_extra : -DCMAKE_PREFIX_PATH="C:/Program Files (x86)/openblas" + + - name: windows-latest-mkl + os : windows-latest + build_mkl : true + build_tests : true + build_blas_bindings : true - ubuntu-22-04-ffmpeg711: - runs-on: 'ubuntu-22.04' steps: - - uses: actions/checkout@v2 - - - name: Install dependencies - run: | - sudo apt update - sudo apt install make yasm - - - name: Cache FFmpeg 7 - uses: actions/cache@v3 - id: cache-ffmpeg7 - with: - path: /home/runner/ffmpeg-n7.1.1_installation - key: ffmpeg-n7.1.1_try1 - - - name: Build FFmpeg 7 - if: steps.cache-ffmpeg7.outputs.cache-hit != 'true' - run: | - wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.1.1.tar.gz - tar -xf n7.1.1.tar.gz - cd FFmpeg-n7.1.1 - ./configure --prefix=/home/runner/ffmpeg-n7.1.1_installation --disable-doc --disable-programs - make -j4 - make install - cd .. + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Prepare oneAPI dir for cache restore + if: ${{ matrix.build_mkl }} + run: mkdir -p "C:/Program Files (x86)/Intel/oneAPI/" + + - name: Cache oneMKL (Windows) + if: ${{ matrix.build_mkl}} + uses: actions/cache@v3 + id: cache-oneapi + with: + path: | + C:/Program Files (x86)/Intel/oneAPI/mkl + C:/Program Files (x86)/Intel/oneAPI/tbb + C:/Program Files (x86)/Intel/oneAPI/compiler + key: oneapi-mkl-try0 + + - name: Download MKL + if: ${{ matrix.build_mkl && (steps.cache-oneapi.outputs.cache-hit != 'true') }} + run: | + curl -L -o base.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/f5881e61-dcdc-40f1-9bd9-717081ac623c/intel-oneapi-base-toolkit-2025.2.1.46_offline.exe + ./base.exe -a --silent --eula accept + + - name: Download OpenBLAS + if: ${{ matrix.build_openblas}} + run: | + curl -L -o openblas.zip https://github.com/OpenMathLib/OpenBLAS/releases/download/v0.3.30/OpenBLAS-0.3.30-x64.zip + powershell -Command "Expand-Archive -Path openblas.zip -DestinationPath 'C:\Program Files (x86)\openblas' -Force" + echo 'C:\Program Files (x86)\openblas\bin' >> $GITHUB_PATH + + - name: Configure tests + if: ${{ matrix.build_tests }} + run: cmake dlib/test -B build ${{ matrix.configure_extra }} + + - name: Build tests + if: ${{ matrix.build_tests }} + run: cmake --build build --config Release --target dtest --parallel 4 + + - name: Test + if: ${{ matrix.build_tests }} + run: build/Release/dtest.exe --runall -q + + - name: Configure BLAS binding tests + if: ${{ matrix.build_blas_bindings }} + run: cmake dlib/test/blas_bindings -B build_blas_bindings ${{ matrix.configure_extra }} + + - name: Build BLAS binding tests + if: ${{ matrix.build_blas_bindings }} + run: cmake --build build_blas_bindings --config Debug --parallel 4 - - name: Configure - run: cmake . -B build -DCMAKE_PREFIX_PATH=/home/runner/ffmpeg-n7.1.1_installation - - name: Build ffmpeg example - run: cmake --build build --config Release --target ffmpeg_video_muxing_ex --parallel 4 - - windows-latest: - runs-on: 'windows-latest' - steps: - - uses: actions/checkout@v2 - - name: Configure - run: | - # don't use CMake 3.25.0 https://gitlab.kitware.com/cmake/cmake/-/issues/23975 - pip3 install cmake==3.24.0 - cmake . -B build - - name: Build just tests - run: cmake --build build --config Release --target dtest --parallel 4 - - name: Test - run: build/Release/dtest.exe --runall -q - - name: Build ancillary tools - run: cmake --build build --config Release --target imglab htmlify dtoc --parallel 4 - - # Disable this because macos targets aren't working on github actions right now. - #macos-latest: - # runs-on: 'macos-latest' - # steps: - # - uses: actions/checkout@v2 - # - name: Configure - # # MacOS machines often come with low quality BLAS libraries installed, so don't use those. - # run: cmake ${{ github.workspace }}/dlib/test -B build -DDLIB_USE_BLAS=0 -DDLIB_USE_LAPACK=0 - # - name: Build just tests - # run: cmake --build build --config Release --target dtest --parallel 4 - # - name: Test - # run: build/dtest --runall --no_test_timer -q - # - name: Build examples, etc - # run: cmake --build build --config Release --parallel 2 + - name: Test BLAS bindings + if: ${{ matrix.build_blas_bindings }} + run: build_blas_bindings/Debug/dtest --runall -q + + - name: Build ancillary tools + if: ${{ matrix.build_tests }} + run: cmake --build build --config Release --target imglab htmlify dtoc --parallel 4 \ No newline at end of file diff --git a/dlib/CMakeLists.txt b/dlib/CMakeLists.txt index d1ac826ce3..26b1e4c43a 100644 --- a/dlib/CMakeLists.txt +++ b/dlib/CMakeLists.txt @@ -26,7 +26,7 @@ if (NOT TARGET dlib) message(STATUS "Compiling dlib version: ${VERSION}") endif() - +include(CMakeDependentOption) include(cmake_utils/set_compiler_specific_options.cmake) @@ -167,6 +167,8 @@ if (NOT TARGET dlib) "Disable this if you don't want to use NVIDIA CUDA" ) set (DLIB_USE_CUDA_COMPUTE_CAPABILITIES_STR "Set this to a comma-separated list of CUDA compute capabilities" ) + set (DLIB_USE_MKL_THREAD_STR + "Enable this if you have MKL installed and want to use the openmp version." ) set (DLIB_USE_MKL_SEQUENTIAL_STR "Enable this if you have MKL installed and want to use the sequential version instead of the multi-core version." ) set (DLIB_USE_MKL_WITH_TBB_STR @@ -184,8 +186,6 @@ if (NOT TARGET dlib) set (DLIB_LINK_WITH_SQLITE3_STR "Disable this if you don't want to link against sqlite3" ) #set (DLIB_USE_FFTW_STR "Disable this if you don't want to link against fftw" ) - set (DLIB_USE_MKL_FFT_STR - "Disable this is you don't want to use the MKL DFTI FFT implementation" ) set (DLIB_ENABLE_ASSERTS_STR "Enable this if you want to turn on the DLIB_ASSERT macro" ) set (DLIB_USE_FFMPEG_STR @@ -198,8 +198,6 @@ if (NOT TARGET dlib) toggle_preprocessor_switch(DLIB_NO_GUI_SUPPORT) option(DLIB_ENABLE_STACK_TRACE ${DLIB_ENABLE_STACK_TRACE_STR} OFF) toggle_preprocessor_switch(DLIB_ENABLE_STACK_TRACE) - option(DLIB_USE_MKL_SEQUENTIAL ${DLIB_USE_MKL_SEQUENTIAL_STR} OFF) - option(DLIB_USE_MKL_WITH_TBB ${DLIB_USE_MKL_WITH_TBB_STR} OFF) if(DLIB_ENABLE_ASSERTS) # Set these variables so they are set in the config.h.in file when dlib @@ -233,21 +231,17 @@ if (NOT TARGET dlib) if (DLIB_ISO_CPP_ONLY) option(DLIB_JPEG_SUPPORT ${DLIB_JPEG_SUPPORT_STR} OFF) option(DLIB_LINK_WITH_SQLITE3 ${DLIB_LINK_WITH_SQLITE3_STR} OFF) - option(DLIB_USE_BLAS ${DLIB_USE_BLAS_STR} OFF) - option(DLIB_USE_LAPACK ${DLIB_USE_LAPACK_STR} OFF) option(DLIB_USE_CUDA ${DLIB_USE_CUDA_STR} OFF) option(DLIB_PNG_SUPPORT ${DLIB_PNG_SUPPORT_STR} OFF) option(DLIB_GIF_SUPPORT ${DLIB_GIF_SUPPORT_STR} OFF) option(DLIB_WEBP_SUPPORT ${DLIB_WEBP_SUPPORT_STR} OFF) option(DLIB_JXL_SUPPORT ${DLIB_JXL_SUPPORT_STR} OFF) #option(DLIB_USE_FFTW ${DLIB_USE_FFTW_STR} OFF) - option(DLIB_USE_MKL_FFT ${DLIB_USE_MKL_FFT_STR} OFF) option(DLIB_USE_FFMPEG ${DLIB_USE_FFMPEG_STR} OFF) else() + include(cmake_utils/find_blas.cmake) option(DLIB_JPEG_SUPPORT ${DLIB_JPEG_SUPPORT_STR} ON) option(DLIB_LINK_WITH_SQLITE3 ${DLIB_LINK_WITH_SQLITE3_STR} ON) - option(DLIB_USE_BLAS ${DLIB_USE_BLAS_STR} ON) - option(DLIB_USE_LAPACK ${DLIB_USE_LAPACK_STR} ON) option(DLIB_USE_CUDA ${DLIB_USE_CUDA_STR} ON) set(DLIB_USE_CUDA_COMPUTE_CAPABILITIES 50 CACHE STRING ${DLIB_USE_CUDA_COMPUTE_CAPABILITIES_STR}) option(DLIB_PNG_SUPPORT ${DLIB_PNG_SUPPORT_STR} ON) @@ -255,19 +249,20 @@ if (NOT TARGET dlib) option(DLIB_WEBP_SUPPORT ${DLIB_WEBP_SUPPORT_STR} ON) option(DLIB_JXL_SUPPORT ${DLIB_JXL_SUPPORT_STR} ON) #option(DLIB_USE_FFTW ${DLIB_USE_FFTW_STR} ON) - option(DLIB_USE_MKL_FFT ${DLIB_USE_MKL_FFT_STR} ON) option(DLIB_USE_FFMPEG ${DLIB_USE_FFMPEG_STR} ON) endif() + cmake_dependent_option(DLIB_USE_MKL_SEQUENTIAL ${DLIB_USE_MKL_SEQUENTIAL_STR} ON "mkl_seq_found" OFF) + cmake_dependent_option(DLIB_USE_MKL_WITH_TBB ${DLIB_USE_MKL_WITH_TBB_STR} ON "mkl_tbb_found" OFF) + cmake_dependent_option(DLIB_USE_MKL_THREAD ${DLIB_USE_MKL_THREAD_STR} ON "mkl_thread_found" OFF) + cmake_dependent_option(DLIB_USE_BLAS ${DLIB_USE_BLAS_STR} ON "mkl_found OR blas_found" OFF) + cmake_dependent_option(DLIB_USE_LAPACK ${DLIB_USE_LAPACK_STR} ON "mkl_found OR lapack_found" OFF) toggle_preprocessor_switch(DLIB_JPEG_SUPPORT) - toggle_preprocessor_switch(DLIB_USE_BLAS) - toggle_preprocessor_switch(DLIB_USE_LAPACK) toggle_preprocessor_switch(DLIB_USE_CUDA) toggle_preprocessor_switch(DLIB_PNG_SUPPORT) toggle_preprocessor_switch(DLIB_GIF_SUPPORT) toggle_preprocessor_switch(DLIB_WEBP_SUPPORT) toggle_preprocessor_switch(DLIB_JXL_SUPPORT) #toggle_preprocessor_switch(DLIB_USE_FFTW) - toggle_preprocessor_switch(DLIB_USE_MKL_FFT) toggle_preprocessor_switch(DLIB_USE_FFMPEG) @@ -599,55 +594,49 @@ if (NOT TARGET dlib) endif() endif() - - if (DLIB_USE_BLAS OR DLIB_USE_LAPACK OR DLIB_USE_MKL_FFT) - if (DLIB_USE_MKL_WITH_TBB AND DLIB_USE_MKL_SEQUENTIAL) - set(DLIB_USE_MKL_SEQUENTIAL OFF CACHE STRING ${DLIB_USE_MKL_SEQUENTIAL_STR} FORCE ) - toggle_preprocessor_switch(DLIB_USE_MKL_SEQUENTIAL) - message(STATUS "Disabling DLIB_USE_MKL_SEQUENTIAL. It cannot be used simultaneously with DLIB_USE_MKL_WITH_TBB.") - endif() - - - # Try to find BLAS, LAPACK and MKL - include(cmake_utils/find_blas.cmake) - - if (DLIB_USE_BLAS) - if (blas_found) - list (APPEND dlib_needed_public_libraries ${blas_libraries}) - else() - set(DLIB_USE_BLAS OFF CACHE STRING ${DLIB_USE_BLAS_STR} FORCE ) - toggle_preprocessor_switch(DLIB_USE_BLAS) - endif() + if (DLIB_USE_MKL_SEQUENTIAL OR DLIB_USE_MKL_WITH_TBB OR DLIB_USE_MKL_THREAD) + enable_preprocessor_switch(DLIB_USE_MKL_FFT) + list (APPEND dlib_needed_public_includes ${mkl_include_dir}) + if (DLIB_USE_MKL_SEQUENTIAL) + message(STATUS "Using MKL sequential") + enable_preprocessor_switch(DLIB_USE_MKL_SEQUENTIAL) + list (APPEND dlib_needed_public_libraries ${mkl_libraries_sequential}) + elseif(DLIB_USE_MKL_WITH_TBB) + message(STATUS "Using MKL tbb") + enable_preprocessor_switch(DLIB_USE_MKL_WITH_TBB) + list (APPEND dlib_needed_public_libraries ${mkl_libraries_tbb}) + elseif(DLIB_USE_MKL_THREAD) + message(STATUS "Using MKL thread") + enable_preprocessor_switch(DLIB_USE_MKL_THREAD) + list (APPEND dlib_needed_public_libraries ${mkl_libraries_thread}) endif() + endif() - if (DLIB_USE_LAPACK) - if (lapack_found) - list (APPEND dlib_needed_public_libraries ${lapack_libraries}) - if (lapack_with_underscore) - set(LAPACK_FORCE_UNDERSCORE 1) - enable_preprocessor_switch(LAPACK_FORCE_UNDERSCORE) - elseif (lapack_without_underscore) - set(LAPACK_FORCE_NOUNDERSCORE 1) - enable_preprocessor_switch(LAPACK_FORCE_NOUNDERSCORE) - endif () - else() - set(DLIB_USE_LAPACK OFF CACHE STRING ${DLIB_USE_LAPACK_STR} FORCE ) - toggle_preprocessor_switch(DLIB_USE_LAPACK) - endif() + if(DLIB_USE_BLAS) + enable_preprocessor_switch(DLIB_USE_BLAS) + if (NOT DLIB_USE_MKL_SEQUENTIAL AND NOT DLIB_USE_MKL_WITH_TBB AND NOT DLIB_USE_MKL_THREAD) + message(STATUS "Using BLAS ${blas_libraries}") + list (APPEND dlib_needed_public_libraries ${blas_libraries}) + else() + message(STATUS "Using MKL BLAS") endif() + endif() - if (DLIB_USE_MKL_FFT) - if (found_intel_mkl AND found_intel_mkl_headers) - list (APPEND dlib_needed_public_includes ${mkl_include_dir}) - list (APPEND dlib_needed_public_libraries ${mkl_libraries}) - else() - set(DLIB_USE_MKL_FFT OFF CACHE STRING ${DLIB_USE_MKL_FFT_STR} FORCE ) - toggle_preprocessor_switch(DLIB_USE_MKL_FFT) - endif() + if(DLIB_USE_LAPACK) + enable_preprocessor_switch(DLIB_USE_LAPACK) + if (NOT DLIB_USE_MKL_SEQUENTIAL AND NOT DLIB_USE_MKL_WITH_TBB AND NOT DLIB_USE_MKL_THREAD) + message(STATUS "Using LAPACK ${lapack_libraries}") + list (APPEND dlib_needed_public_libraries ${lapack_libraries}) + if (lapack_with_underscore) + enable_preprocessor_switch(LAPACK_FORCE_UNDERSCORE) + elseif (lapack_without_underscore) + enable_preprocessor_switch(LAPACK_FORCE_NOUNDERSCORE) + endif () + else() + message(STATUS "Using MKL LAPACK") endif() endif() - if (DLIB_USE_CUDA) find_package(CUDA 7.5) diff --git a/dlib/cmake_utils/find_blas.cmake b/dlib/cmake_utils/find_blas.cmake index bdd98cde56..14c794b43e 100644 --- a/dlib/cmake_utils/find_blas.cmake +++ b/dlib/cmake_utils/find_blas.cmake @@ -8,476 +8,199 @@ # attempts to find some other BLAS and LAPACK libraries if you don't have # the Intel MKL. # -# blas_found - True if BLAS is available -# lapack_found - True if LAPACK is available -# found_intel_mkl - True if the Intel MKL library is available -# found_intel_mkl_headers - True if Intel MKL headers are available -# blas_libraries - link against these to use BLAS library -# lapack_libraries - link against these to use LAPACK library -# mkl_libraries - link against these to use the MKL library -# mkl_include_dir - add to the include path to use the MKL library -# openmp_libraries - Set to Intel's OpenMP library if and only if we -# find the MKL. - -# setting this makes CMake allow normal looking if else statements +# mkl_seq_found - True if the Intel MKL sequential library is available +# mkl_tbb_found - True if the Intel MKL tbb library is available +# mkl_thread_found - True if the Intel MKL thread library is available +# mkl_found - True if at least one of (mkl_seq_found,mkl_tbb_found,mkl_thread_found) is true +# mkl_include_dir - MKL include directory +# mkl_libraries_sequential - MKL sequential libraries if found +# mkl_libraries_tbb - MKL tbb libraries if found +# mkl_libraries_thread - MKL thread libraries if found +# blas_found - True if BLAS is available +# blas_libraries - link against these to use BLAS library +# lapack_found - True if LAPACK is available +# lapack_libraries - link against these to use LAPACK library + +include(CheckTypeSize) +include(CheckFunctionExists) + +# setting this makes CMake allow normal looking if else statements (TODO: check if this is still necessary) SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) -SET(blas_found 0) -SET(lapack_found 0) -SET(found_intel_mkl 0) -SET(found_intel_mkl_headers 0) -SET(lapack_with_underscore 0) +set(mkl_found 0) +SET(mkl_seq_found 0) +SET(mkl_tbb_found 0) +SET(mkl_thread_found 0) +SET(blas_found 0) +SET(lapack_found 0) +SET(lapack_with_underscore 0) SET(lapack_without_underscore 0) -message(STATUS "Searching for BLAS and LAPACK") -INCLUDE(CheckFunctionExists) +SET(mkl_search_path_unix_64 + /opt/intel/oneapi/mkl/latest/lib + /opt/intel/oneapi/tbb/latest/lib + /opt/intel/oneapi/compiler/latest/lib + /opt/intel/mkl/*/lib/em64t + /opt/intel/mkl/lib/intel64 + /opt/intel/lib/intel64 + /opt/intel/mkl/lib + /opt/intel/tbb/*/lib/em64t/gcc4.7 + /opt/intel/tbb/lib/intel64/gcc4.7 + /opt/intel/tbb/lib/gcc4.7) + +SET(mkl_search_path_unix_32 + /opt/intel/oneapi/mkl/latest/lib/ia32 + /opt/intel/mkl/*/lib/32 + /opt/intel/mkl/lib/ia32 + /opt/intel/lib/ia32 + /opt/intel/tbb/*/lib/32/gcc4.7 + /opt/intel/tbb/lib/ia32/gcc4.7) + +set(mkl_include_search_path_unix + /opt/intel/oneapi/mkl/latest/include + /opt/intel/mkl/include + /opt/intel/include) + +set(mkl_search_path_win_64 + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/lib/intel64" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/tbb/lib/intel64/vc14" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/lib/intel64" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/intel64/vc14" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/intel64/vc_mt" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/intel64" + "C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64" + "C:/Program Files (x86)/Intel/Composer XE/tbb/lib/intel64/vc14" + "C:/Program Files (x86)/Intel/Composer XE/compiler/lib/intel64" + "C:/Program Files/Intel/Composer XE/mkl/lib/intel64" + "C:/Program Files/Intel/Composer XE/tbb/lib/intel64/vc14" + "C:/Program Files/Intel/Composer XE/compiler/lib/intel64" + "C:/Program Files (x86)/Intel/oneAPI/mkl/*/lib" + "C:/Program Files (x86)/Intel/oneAPI/compiler/*/lib" + "C:/Program Files (x86)/Intel/oneAPI/tbb/*/lib" + "C:/Program Files (x86)/Intel/oneAPI/mkl/*/lib/intel64" + "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/compiler/lib/intel64_win") + +set(mkl_search_path_win_32 + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/lib/ia32" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/tbb/lib/ia32/vc14" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/lib/ia32" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/ia32" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/ia32/vc14" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/ia32/vc_mt" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/ia32" + "C:/Program Files (x86)/Intel/Composer XE/mkl/lib/ia32" + "C:/Program Files (x86)/Intel/Composer XE/tbb/lib/ia32/vc14" + "C:/Program Files (x86)/Intel/Composer XE/compiler/lib/ia32" + "C:/Program Files/Intel/Composer XE/mkl/lib/ia32" + "C:/Program Files/Intel/Composer XE/tbb/lib/ia32/vc14" + "C:/Program Files/Intel/Composer XE/compiler/lib/ia32" + "C:/Program Files (x86)/Intel/oneAPI/mkl/*/lib/ia32" + "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/compiler/lib/ia32_win") + +set(mkl_redist_path_win_64 + "C:/Program Files (x86)/Intel/oneAPI/compiler/*/bin" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/redist/intel64/compiler" + "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/redist/intel64_win/compiler") + +set(mkl_redist_path_win_32 + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/redist/ia32/compiler" + "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/redist/ia32_win/compiler") + +set(mkl_include_search_path_win + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/include" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/include" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/include" + "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/include" + "C:/Program Files (x86)/Intel/Composer XE/mkl/include" + "C:/Program Files (x86)/Intel/Composer XE/compiler/include" + "C:/Program Files/Intel/Composer XE/mkl/include" + "C:/Program Files/Intel/Composer XE/compiler/include" + "C:/Program Files (x86)/Intel/oneAPI/mkl/*/include") + +set(CMAKE_REQUIRED_QUIET_SAV ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET true) +check_type_size("void*" SIZE_OF_VOID_PTR) +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAV}) if (UNIX OR MINGW) - message(STATUS "Searching for BLAS and LAPACK") - - if (BUILDING_MATLAB_MEX_FILE) - # # This commented out stuff would link directly to MATLAB's built in - # BLAS and LAPACK. But it's better to not link to anything and do a - #find_library(MATLAB_BLAS_LIBRARY mwblas PATHS ${MATLAB_LIB_FOLDERS} ) - #find_library(MATLAB_LAPACK_LIBRARY mwlapack PATHS ${MATLAB_LIB_FOLDERS} ) - #if (MATLAB_BLAS_LIBRARY AND MATLAB_LAPACK_LIBRARY) - # add_subdirectory(external/cblas) - # set(blas_libraries ${MATLAB_BLAS_LIBRARY} cblas ) - # set(lapack_libraries ${MATLAB_LAPACK_LIBRARY} ) - # set(blas_found 1) - # set(lapack_found 1) - # message(STATUS "Found MATLAB's BLAS and LAPACK libraries") - #endif() - - # We need cblas since MATLAB doesn't provide cblas symbols. - add_subdirectory(external/cblas) - set(blas_libraries cblas ) - set(blas_found 1) - set(lapack_found 1) - message(STATUS "Will link with MATLAB's BLAS and LAPACK at runtime (hopefully!)") - - - ## Don't try to link to anything other than MATLAB's own internal blas - ## and lapack libraries because doing so generally upsets MATLAB. So - ## we just end here no matter what. - return() - endif() - - - # First, search for libraries via pkg-config, which is the cleanest path - find_package(PkgConfig) - pkg_check_modules(BLAS_REFERENCE cblas) - pkg_check_modules(LAPACK_REFERENCE lapack) - # Make sure the cblas found by pkgconfig actually has cblas symbols. - SET(CMAKE_REQUIRED_LIBRARIES "${BLAS_REFERENCE_LDFLAGS}") - CHECK_FUNCTION_EXISTS(cblas_ddot PKGCFG_HAVE_CBLAS) - if (BLAS_REFERENCE_FOUND AND LAPACK_REFERENCE_FOUND AND PKGCFG_HAVE_CBLAS) - set(blas_libraries "${BLAS_REFERENCE_LDFLAGS}") - set(lapack_libraries "${LAPACK_REFERENCE_LDFLAGS}") - set(blas_found 1) - set(lapack_found 1) - set(REQUIRES_LIBS "${REQUIRES_LIBS} cblas lapack") - message(STATUS "Found BLAS and LAPACK via pkg-config") - return() - endif() - - include(CheckTypeSize) - check_type_size( "void*" SIZE_OF_VOID_PTR) - + set(mkl_include_search_path ${mkl_include_search_path_unix}) if (SIZE_OF_VOID_PTR EQUAL 8) - set( mkl_search_path - /opt/intel/oneapi/mkl/latest/lib/intel64 - /opt/intel/mkl/*/lib/em64t - /opt/intel/mkl/lib/intel64 - /opt/intel/lib/intel64 - /opt/intel/mkl/lib - /opt/intel/tbb/*/lib/em64t/gcc4.7 - /opt/intel/tbb/lib/intel64/gcc4.7 - /opt/intel/tbb/lib/gcc4.7 - ) - - find_library(mkl_intel mkl_intel_lp64 ${mkl_search_path}) - mark_as_advanced(mkl_intel) + set(mkl_search_path ${mkl_search_path_unix_64}) + set(mkl_intel_name mkl_intel_lp64) else() - set( mkl_search_path - /opt/intel/oneapi/mkl/latest/lib/ia32 - /opt/intel/mkl/*/lib/32 - /opt/intel/mkl/lib/ia32 - /opt/intel/lib/ia32 - /opt/intel/tbb/*/lib/32/gcc4.7 - /opt/intel/tbb/lib/ia32/gcc4.7 - ) - - find_library(mkl_intel mkl_intel ${mkl_search_path}) - mark_as_advanced(mkl_intel) - endif() - - include(CheckLibraryExists) - - # Get mkl_include_dir - set(mkl_include_search_path - /opt/intel/oneapi/mkl/latest/include - /opt/intel/mkl/include - /opt/intel/include - ) - find_path(mkl_include_dir mkl_version.h ${mkl_include_search_path}) - mark_as_advanced(mkl_include_dir) - - if(NOT DLIB_USE_MKL_SEQUENTIAL AND NOT DLIB_USE_MKL_WITH_TBB) - # Search for the needed libraries from the MKL. We will try to link against the mkl_rt - # file first since this way avoids linking bugs in some cases. - find_library(mkl_rt mkl_rt ${mkl_search_path}) - find_library(openmp_libraries iomp5 ${mkl_search_path}) - mark_as_advanced(mkl_rt openmp_libraries) - # if we found the MKL - if (mkl_rt) - set(mkl_libraries ${mkl_rt} ) - set(blas_libraries ${mkl_rt} ) - set(lapack_libraries ${mkl_rt} ) - set(blas_found 1) - set(lapack_found 1) - set(found_intel_mkl 1) - message(STATUS "Found Intel MKL BLAS/LAPACK library") - endif() - endif() - - - if (NOT found_intel_mkl) - # Search for the needed libraries from the MKL. This time try looking for a different - # set of MKL files and try to link against those. - find_library(mkl_core mkl_core ${mkl_search_path}) - set(mkl_libs ${mkl_intel} ${mkl_core}) - mark_as_advanced(mkl_libs mkl_intel mkl_core) - - if (DLIB_USE_MKL_WITH_TBB) - find_library(mkl_tbb_thread mkl_tbb_thread ${mkl_search_path}) - find_library(mkl_tbb tbb ${mkl_search_path}) - mark_as_advanced(mkl_tbb_thread mkl_tbb) - list(APPEND mkl_libs ${mkl_tbb_thread} ${mkl_tbb}) - elseif (DLIB_USE_MKL_SEQUENTIAL) - find_library(mkl_sequential mkl_sequential ${mkl_search_path}) - mark_as_advanced(mkl_sequential) - list(APPEND mkl_libs ${mkl_sequential}) - else() - find_library(mkl_thread mkl_intel_thread ${mkl_search_path}) - find_library(mkl_iomp iomp5 ${mkl_search_path}) - find_library(mkl_pthread pthread ${mkl_search_path}) - mark_as_advanced(mkl_thread mkl_iomp mkl_pthread) - list(APPEND mkl_libs ${mkl_thread} ${mkl_iomp} ${mkl_pthread}) - endif() - - # If we found the MKL - if (mkl_intel AND mkl_core AND ((mkl_tbb_thread AND mkl_tbb) OR (mkl_thread AND mkl_iomp AND mkl_pthread) OR mkl_sequential)) - set(mkl_libraries ${mkl_libs}) - set(blas_libraries ${mkl_libs}) - set(lapack_libraries ${mkl_libs}) - set(blas_found 1) - set(lapack_found 1) - set(found_intel_mkl 1) - message(STATUS "Found Intel MKL BLAS/LAPACK library") - endif() - endif() - - if (found_intel_mkl AND mkl_include_dir) - set(found_intel_mkl_headers 1) - endif() - - # try to find some other LAPACK libraries if we didn't find the MKL - set(extra_paths - /usr/lib64 - /usr/lib64/atlas-sse3 - /usr/lib64/atlas-sse2 - /usr/lib64/atlas - /usr/lib - /usr/lib/atlas-sse3 - /usr/lib/atlas-sse2 - /usr/lib/atlas - /usr/lib/openblas-base - /opt/OpenBLAS/lib - $ENV{OPENBLAS_HOME}/lib - ) - - if (NOT blas_found) - find_library(cblas_lib NAMES openblasp openblas PATHS ${extra_paths}) - if (cblas_lib) - set(blas_libraries ${cblas_lib}) - set(blas_found 1) - message(STATUS "Found OpenBLAS library") - set(CMAKE_REQUIRED_LIBRARIES ${blas_libraries}) - # If you compiled OpenBLAS with LAPACK in it then it should have the - # sgetrf_single function in it. So if we find that function in - # OpenBLAS then just use OpenBLAS's LAPACK. - CHECK_FUNCTION_EXISTS(sgetrf_single OPENBLAS_HAS_LAPACK) - if (OPENBLAS_HAS_LAPACK) - message(STATUS "Using OpenBLAS's built in LAPACK") - # set(lapack_libraries gfortran) - set(lapack_found 1) - endif() - endif() - mark_as_advanced( cblas_lib) - endif() - - - if (NOT lapack_found) - find_library(lapack_lib NAMES lapack lapack-3 PATHS ${extra_paths}) - if (lapack_lib) - set(lapack_libraries ${lapack_lib}) - set(lapack_found 1) - message(STATUS "Found LAPACK library") - endif() - mark_as_advanced( lapack_lib) - endif() - - - # try to find some other BLAS libraries if we didn't find the MKL - - if (NOT blas_found) - find_library(atlas_lib atlas PATHS ${extra_paths}) - find_library(cblas_lib cblas PATHS ${extra_paths}) - if (atlas_lib AND cblas_lib) - set(blas_libraries ${atlas_lib} ${cblas_lib}) - set(blas_found 1) - message(STATUS "Found ATLAS BLAS library") - endif() - mark_as_advanced( atlas_lib cblas_lib) - endif() - - # CentOS 7 atlas - if (NOT blas_found) - find_library(tatlas_lib tatlas PATHS ${extra_paths}) - find_library(satlas_lib satlas PATHS ${extra_paths}) - if (tatlas_lib AND satlas_lib ) - set(blas_libraries ${tatlas_lib} ${satlas_lib}) - set(blas_found 1) - message(STATUS "Found ATLAS BLAS library") - endif() - mark_as_advanced( tatlas_lib satlas_lib) - endif() - - - if (NOT blas_found) - find_library(cblas_lib cblas PATHS ${extra_paths}) - if (cblas_lib) - set(blas_libraries ${cblas_lib}) - set(blas_found 1) - message(STATUS "Found CBLAS library") - endif() - mark_as_advanced( cblas_lib) - endif() - - - if (NOT blas_found) - find_library(generic_blas blas PATHS ${extra_paths}) - if (generic_blas) - set(blas_libraries ${generic_blas}) - set(blas_found 1) - message(STATUS "Found BLAS library") - endif() - mark_as_advanced( generic_blas) + set(mkl_search_path ${mkl_search_path_unix_32}) + set(mkl_intel_name mkl_intel) endif() - - - - - # Make sure we really found a CBLAS library. That is, it needs to expose - # the proper cblas link symbols. So here we test if one of them is present - # and assume everything is good if it is. Note that we don't do this check if - # we found the Intel MKL since for some reason CHECK_FUNCTION_EXISTS doesn't work - # with it. But it's fine since the MKL should always have cblas. - if (blas_found AND NOT found_intel_mkl) - set(CMAKE_REQUIRED_LIBRARIES ${blas_libraries}) - CHECK_FUNCTION_EXISTS(cblas_ddot FOUND_BLAS_HAS_CBLAS) - if (NOT FOUND_BLAS_HAS_CBLAS) - message(STATUS "BLAS library does not have cblas symbols, so dlib will not use BLAS or LAPACK") - set(blas_found 0) - set(lapack_found 0) - endif() - endif() - - - -elseif(WIN32 AND NOT MINGW) - message(STATUS "Searching for BLAS and LAPACK") - - include(CheckTypeSize) - check_type_size( "void*" SIZE_OF_VOID_PTR) +elseif(WIN32) + set(mkl_include_search_path ${mkl_include_search_path_win}) if (SIZE_OF_VOID_PTR EQUAL 8) - set( mkl_search_path - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/lib/intel64" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/tbb/lib/intel64/vc14" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/lib/intel64" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/intel64/vc14" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/intel64/vc_mt" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/intel64" - "C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64" - "C:/Program Files (x86)/Intel/Composer XE/tbb/lib/intel64/vc14" - "C:/Program Files (x86)/Intel/Composer XE/compiler/lib/intel64" - "C:/Program Files/Intel/Composer XE/mkl/lib/intel64" - "C:/Program Files/Intel/Composer XE/tbb/lib/intel64/vc14" - "C:/Program Files/Intel/Composer XE/compiler/lib/intel64" - "C:/Program Files (x86)/Intel/oneAPI/mkl/*/lib" - "C:/Program Files (x86)/Intel/oneAPI/compiler/*/lib" - "C:/Program Files (x86)/Intel/oneAPI/mkl/*/lib/intel64" - "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/compiler/lib/intel64_win" - ) - set (mkl_redist_path - "C:/Program Files (x86)/Intel/oneAPI/compiler/*/bin" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/redist/intel64/compiler" - "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/redist/intel64_win/compiler" - ) - find_library(mkl_intel mkl_intel_lp64 ${mkl_search_path}) + set(mkl_search_path ${mkl_search_path_win_64}) + set(mkl_intel_name mkl_intel_lp64) else() - set( mkl_search_path - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/lib/ia32" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/tbb/lib/ia32/vc14" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/lib/ia32" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/ia32" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/ia32/vc14" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/ia32/vc_mt" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/ia32" - "C:/Program Files (x86)/Intel/Composer XE/mkl/lib/ia32" - "C:/Program Files (x86)/Intel/Composer XE/tbb/lib/ia32/vc14" - "C:/Program Files (x86)/Intel/Composer XE/compiler/lib/ia32" - "C:/Program Files/Intel/Composer XE/mkl/lib/ia32" - "C:/Program Files/Intel/Composer XE/tbb/lib/ia32/vc14" - "C:/Program Files/Intel/Composer XE/compiler/lib/ia32" - "C:/Program Files (x86)/Intel/oneAPI/mkl/*/lib/ia32" - "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/compiler/lib/ia32_win" - - ) - set (mkl_redist_path - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/redist/ia32/compiler" - "C:/Program Files (x86)/Intel/oneAPI/compiler/*/windows/redist/ia32_win/compiler" - ) - find_library(mkl_intel mkl_intel_c ${mkl_search_path}) - endif() - - - # Get mkl_include_dir - set(mkl_include_search_path - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/include" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/include" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/include" - "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/include" - "C:/Program Files (x86)/Intel/Composer XE/mkl/include" - "C:/Program Files (x86)/Intel/Composer XE/compiler/include" - "C:/Program Files/Intel/Composer XE/mkl/include" - "C:/Program Files/Intel/Composer XE/compiler/include" - "C:/Program Files (x86)/Intel/oneAPI/mkl/*/include" - ) - find_path(mkl_include_dir mkl_version.h ${mkl_include_search_path}) - mark_as_advanced(mkl_include_dir) - - # Search for the needed libraries from the MKL. - find_library(mkl_core mkl_core ${mkl_search_path}) - set(mkl_libs ${mkl_intel} ${mkl_core}) - mark_as_advanced(mkl_libs mkl_intel mkl_core) - if (DLIB_USE_MKL_WITH_TBB) - find_library(mkl_tbb_thread mkl_tbb_thread ${mkl_search_path}) - find_library(mkl_tbb tbb ${mkl_search_path}) - mark_as_advanced(mkl_tbb_thread mkl_tbb) - list(APPEND mkl_libs ${mkl_tbb_thread} ${mkl_tbb}) - elseif (DLIB_USE_MKL_SEQUENTIAL) - find_library(mkl_sequential mkl_sequential ${mkl_search_path}) - mark_as_advanced(mkl_sequential) - list(APPEND mkl_libs ${mkl_sequential}) - else() - find_library(mkl_thread mkl_intel_thread ${mkl_search_path}) - mark_as_advanced(mkl_thread) - if (mkl_thread) - find_library(mkl_iomp libiomp5md ${mkl_search_path}) - mark_as_advanced(mkl_iomp) - list(APPEND mkl_libs ${mkl_thread} ${mkl_iomp}) - - # See if we can find the dll that goes with this, so we can copy it to - # the output folder, since a very large number of windows users don't - # understand that they need to add the Intel MKL's folders to their - # PATH to use the Intel MKL. They then complain on the dlib forums. - # Copying the Intel MKL dlls to the output directory removes the need - # to add the Intel MKL to the PATH. - find_file(mkl_iomp_dll "libiomp5md.dll" ${mkl_redist_path}) - if (mkl_iomp_dll) - message(STATUS "FOUND libiomp5md.dll: ${mkl_iomp_dll}") - endif() - endif() - endif() - - # If we found the MKL - if (mkl_intel AND mkl_core AND ((mkl_tbb_thread AND mkl_tbb) OR mkl_sequential OR (mkl_thread AND mkl_iomp))) - set(blas_libraries ${mkl_libs}) - set(lapack_libraries ${mkl_libs}) - set(blas_found 1) - set(lapack_found 1) - set(found_intel_mkl 1) - message(STATUS "Found Intel MKL BLAS/LAPACK library") - - # Make sure the version of the Intel MKL we found is compatible with - # the compiler we are using. One way to do this check is to see if we can - # link to it right now. - set(CMAKE_REQUIRED_LIBRARIES ${blas_libraries}) - CHECK_FUNCTION_EXISTS(cblas_ddot MKL_HAS_CBLAS) - if (NOT MKL_HAS_CBLAS) - message("BLAS library does not have cblas symbols, so dlib will not use BLAS or LAPACK") - set(blas_found 0) - set(lapack_found 0) - endif() - endif() - - if (found_intel_mkl AND mkl_include_dir) - set(found_intel_mkl_headers 1) + set(mkl_search_path ${mkl_search_path_win_32}) + set(mkl_intel_name mkl_intel_c) endif() +endif() +# Search for MKL +find_path( mkl_include_dir NAMES mkl_version.h HINTS ${mkl_include_search_path}) +find_library( mkl_core NAMES mkl_core HINTS ${mkl_search_path}) +find_library( mkl_tbb_thread NAMES mkl_tbb_thread HINTS ${mkl_search_path}) +find_library( mkl_sequential NAMES mkl_sequential HINTS ${mkl_search_path}) +find_library( mkl_thread NAMES mkl_intel_thread HINTS ${mkl_search_path}) +find_library( mkl_intel NAMES ${mkl_intel_name} HINTS ${mkl_search_path}) +find_library( mkl_tbb NAMES tbb HINTS ${mkl_search_path}) +find_library( mkl_iomp NAMES iomp5 HINTS ${mkl_search_path}) + +mark_as_advanced(mkl_include_dir) +mark_as_advanced(mkl_core) +mark_as_advanced(mkl_tbb_thread) +mark_as_advanced(mkl_sequential) +mark_as_advanced(mkl_thread) +mark_as_advanced(mkl_intel) +mark_as_advanced(mkl_tbb) +mark_as_advanced(mkl_iomp) + +if (mkl_include_dir AND mkl_intel AND mkl_sequential AND mkl_core) + message(STATUS "Found MKL sequential") + SET(mkl_seq_found 1) + SET(mkl_libraries_sequential ${mkl_intel} ${mkl_sequential} ${mkl_core}) endif() +if (mkl_include_dir AND mkl_intel AND mkl_tbb_thread AND mkl_core AND mkl_tbb) + message(STATUS "Found MKL tbb") + SET(mkl_tbb_found 1) + SET(mkl_libraries_tbb ${mkl_intel} ${mkl_tbb_thread} ${mkl_core} ${mkl_tbb}) +endif() -# When all else fails use CMake's built in functions to find BLAS and LAPACK -if (NOT blas_found) - find_package(BLAS QUIET) - if (${BLAS_FOUND}) - set(blas_libraries ${BLAS_LIBRARIES}) - set(blas_found 1) - if (NOT lapack_found) - find_package(LAPACK QUIET) - if (${LAPACK_FOUND}) - set(lapack_libraries ${LAPACK_LIBRARIES}) - set(lapack_found 1) - endif() - endif() - endif() +if (mkl_include_dir AND mkl_intel AND mkl_thread AND mkl_core AND mkl_iomp) + message(STATUS "Found MKL thread") + SET(mkl_thread_found 1) + set(mkl_libraries_thread ${mkl_intel} ${mkl_thread} ${mkl_core} ${mkl_iomp}) endif() +if (mkl_seq_found OR mkl_tbb_found OR mkl_thread_found) + set(mkl_found 1) + return() +endif() -# If using lapack, determine whether to mangle functions -if (lapack_found) - include(CheckFortranFunctionExists) - set(CMAKE_REQUIRED_LIBRARIES ${lapack_libraries}) +# Search for BLAS - FindBLAS +set(BLA_PREFER_PKGCONFIG 1) +find_package(BLAS) - check_function_exists("sgesv" LAPACK_FOUND_C_UNMANGLED) - check_function_exists("sgesv_" LAPACK_FOUND_C_MANGLED) - if (CMAKE_Fortran_COMPILER_LOADED) - check_fortran_function_exists("sgesv" LAPACK_FOUND_FORTRAN_UNMANGLED) - check_fortran_function_exists("sgesv_" LAPACK_FOUND_FORTRAN_MANGLED) - endif () - if (LAPACK_FOUND_C_MANGLED OR LAPACK_FOUND_FORTRAN_MANGLED) - set(lapack_with_underscore 1) - elseif (LAPACK_FOUND_C_UNMANGLED OR LAPACK_FOUND_FORTRAN_UNMANGLED) - set(lapack_without_underscore 1) - endif () +if (BLAS_FOUND) + message(STATUS "Found BLAS library") + set(blas_found 1) + set(blas_libraries ${BLAS_LIBRARIES}) endif() +# Search for LAPACK - FindLAPACK +set(BLA_PREFER_PKGCONFIG 1) +find_package(LAPACK) -if (UNIX OR MINGW) - if (NOT blas_found) - message(" *****************************************************************************") - message(" *** No BLAS library found so using dlib's built in BLAS. However, if you ***") - message(" *** install an optimized BLAS such as OpenBLAS or the Intel MKL your code ***") - message(" *** will run faster. On Ubuntu you can install OpenBLAS by executing: ***") - message(" *** sudo apt-get install libopenblas-dev liblapack-dev ***") - message(" *** Or you can easily install OpenBLAS from source by downloading the ***") - message(" *** source tar file from http://www.openblas.net, extracting it, and ***") - message(" *** running: ***") - message(" *** make; sudo make install ***") - message(" *****************************************************************************") - endif() -endif() +if (LAPACK_FOUND) + message(STATUS "Found LAPACK library") + set(lapack_found 1) + set(lapack_libraries ${LAPACK_LIBRARIES}) +endif() \ No newline at end of file diff --git a/dlib/fft/mkl_fft.h b/dlib/fft/mkl_fft.h index 1bbc10b07b..4977fd06f3 100644 --- a/dlib/fft/mkl_fft.h +++ b/dlib/fft/mkl_fft.h @@ -2,17 +2,135 @@ #define DLIB_MKL_FFT_H #include +#include +#include #include #include "fft_size.h" -#define DLIB_DFTI_CHECK_STATUS(s) \ - if((s) != 0 && !DftiErrorClass((s), DFTI_NO_ERROR)) \ - { \ - throw dlib::error(DftiErrorMessage((s))); \ - } +#ifdef DLIB_USE_MKL_WITH_TBB +// This is a workaround to make libdlib link to libtbb.so explicitly and adding its path to the build tree RPATH. +// This is because libmkl_tbb_threads.so depends on libtbb.so but dlib doesn't normally have any explicit symbols to libtbb. +// If you don't do this, the runtime path of libtbb.so is stripped after build time. +// Without this, at runtime you would get an error like "can't find libtbb.so" +// And you would have to manually set it via LD_LIBRARY_PATH or something. +// The better way to get around this is force cmake to add libtbb.so to RPATH. +// But i can't find a way to do it cleanly. Hopefully there isn't much performance impact here. +extern "C" const char* TBB_runtime_version(); +#endif namespace dlib { + namespace mkl_details + { + +//---------------------------------------------------------------------------------------------------------------- + + inline void check_status(MKL_LONG s) + { + if(s != 0 && !DftiErrorClass(s, DFTI_NO_ERROR)) + throw std::runtime_error(DftiErrorMessage(s)); + } + +//---------------------------------------------------------------------------------------------------------------- + + struct mkl_deleter { void operator()(DFTI_DESCRIPTOR* h) {DftiFreeDescriptor(&h);} }; + using mkl_ptr = std::unique_ptr; + +//---------------------------------------------------------------------------------------------------------------- + + struct plan_key + { + fft_size size; + bool is_inplace{}; + bool is_single_precision{}; + bool is_complex{}; + bool is_inverse{}; + }; + +//---------------------------------------------------------------------------------------------------------------- + + inline bool operator==(const plan_key& a, const plan_key& b) + { + return a.size == b.size && + a.is_inplace == b.is_inplace && + a.is_single_precision == b.is_single_precision && + a.is_complex == b.is_complex && + a.is_inverse == b.is_inverse; + } + +//---------------------------------------------------------------------------------------------------------------- + + struct hasher + { + uint32_t operator()(const plan_key& s) const noexcept + { + uint32_t hash = 0; + hash = dlib::hash(s.size, hash); + hash = dlib::hash((uint32_t)s.is_inplace, hash); + hash = dlib::hash((uint32_t)s.is_single_precision, hash); + hash = dlib::hash((uint32_t)s.is_complex, hash); + hash = dlib::hash((uint32_t)s.is_inverse, hash); + return hash; + } + }; + +//---------------------------------------------------------------------------------------------------------------- + + inline const auto& get_handle(const plan_key& key) + { + thread_local std::unordered_map plans; + + if (plans.find(key) == plans.end()) + { +#ifdef DLIB_USE_MKL_WITH_TBB + (void)TBB_runtime_version(); +#endif + + const DFTI_CONFIG_VALUE dfti_type = key.is_single_precision ? DFTI_SINGLE : DFTI_DOUBLE; + const DFTI_CONFIG_VALUE inplacefft = key.is_inplace ? DFTI_INPLACE : DFTI_NOT_INPLACE; + const DFTI_CONFIG_VALUE domain = key.is_complex ? DFTI_COMPLEX : DFTI_REAL; + DFTI_DESCRIPTOR_HANDLE h; + + if (key.size.num_dims() == 1) + { + check_status(DftiCreateDescriptor(&h, dfti_type, domain, 1, key.size[0])); + } + else if (key.is_complex) + { + MKL_LONG size[] = {key.size[0], key.size[1]}; + MKL_LONG strides[] = {0, size[1], 1}; + check_status(DftiCreateDescriptor(&h, dfti_type, domain, 2, size)); + check_status(DftiSetValue(h, DFTI_INPUT_STRIDES, strides)); + check_status(DftiSetValue(h, DFTI_OUTPUT_STRIDES, strides)); + } + else + { + const long lastdim = key.size[1]/2+1; + MKL_LONG size[] = {key.size[0], key.size[1]}; + MKL_LONG input_strides[] = {0, size[1], 1}; + MKL_LONG output_strides[] = {0, lastdim, 1}; + + check_status(DftiCreateDescriptor(&h, dfti_type, domain, 2, size)); + check_status(DftiSetValue(h, DFTI_INPUT_STRIDES, !key.is_inverse ? input_strides : output_strides)); + check_status(DftiSetValue(h, DFTI_OUTPUT_STRIDES, !key.is_inverse ? output_strides : input_strides)); + check_status(DftiSetValue(h, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX)); + } + + check_status(DftiSetValue(h, DFTI_PLACEMENT, inplacefft)); + check_status(DftiSetValue(h, DFTI_THREAD_LIMIT, 1)); // Unless we use sequential mode, the fft results are not correct. + check_status(DftiCommitDescriptor(h)); + plans[key].reset(h); + } + + return plans.at(key); + } + +//---------------------------------------------------------------------------------------------------------------- + + } + +//---------------------------------------------------------------------------------------------------------------- + template void mkl_fft(const fft_size& dims, const std::complex* in, std::complex* out, bool is_inverse) /*! @@ -27,56 +145,14 @@ namespace dlib otherwise a forward FFT is performed. !*/ { + using namespace mkl_details; static_assert(std::is_floating_point::value, "template parameter needs to be a floatint point type"); DLIB_ASSERT(dims.num_dims() > 0, "dims can't be empty"); DLIB_ASSERT(dims.num_dims() < 3, "we currently only support up to 2D FFT. Please submit an issue on github if 3D or above is required."); - constexpr DFTI_CONFIG_VALUE dfti_type = std::is_same::value ? DFTI_SINGLE : DFTI_DOUBLE; - - DFTI_DESCRIPTOR_HANDLE h; - MKL_LONG status; - - if (dims.num_dims() == 1) - { - status = DftiCreateDescriptor(&h, dfti_type, DFTI_COMPLEX, 1, dims[0]); - DLIB_DFTI_CHECK_STATUS(status); - } - else - { - MKL_LONG size[] = {dims[0], dims[1]}; - status = DftiCreateDescriptor(&h, dfti_type, DFTI_COMPLEX, 2, size); - DLIB_DFTI_CHECK_STATUS(status); - - MKL_LONG strides[3]; - strides[0] = 0; - strides[1] = size[1]; - strides[2] = 1; - - status = DftiSetValue(h, DFTI_INPUT_STRIDES, strides); - DLIB_DFTI_CHECK_STATUS(status); - status = DftiSetValue(h, DFTI_OUTPUT_STRIDES, strides); - DLIB_DFTI_CHECK_STATUS(status); - } - - const DFTI_CONFIG_VALUE inplacefft = in == out ? DFTI_INPLACE : DFTI_NOT_INPLACE; - status = DftiSetValue(h, DFTI_PLACEMENT, inplacefft); - DLIB_DFTI_CHECK_STATUS(status); - - // Unless we use sequential mode, the fft results are not correct. - status = DftiSetValue(h, DFTI_THREAD_LIMIT, 1); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiCommitDescriptor(h); - DLIB_DFTI_CHECK_STATUS(status); - - if (is_inverse) - status = DftiComputeBackward(h, (void*)in, (void*)out); - else - status = DftiComputeForward(h, (void*)in, (void*)out); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiFreeDescriptor(&h); - DLIB_DFTI_CHECK_STATUS(status); + const auto& h = get_handle(plan_key{dims, in == out, std::is_same::value, true, is_inverse}); + if (is_inverse) check_status(DftiComputeBackward(h.get(), (void*)in, (void*)out)); + else check_status(DftiComputeForward(h.get(), (void*)in, (void*)out)); } /* @@ -97,66 +173,14 @@ namespace dlib - performs a real FFT on `in` and stores the result in `out`. !*/ { + using namespace mkl_details; static_assert(std::is_floating_point::value, "template parameter needs to be a floatint point type"); DLIB_ASSERT(dims.num_dims() > 0, "dims can't be empty"); DLIB_ASSERT(dims.num_dims() < 3, "we currently only support up to 2D FFT. Please submit an issue on github if 3D or above is required."); DLIB_ASSERT(dims.back() % 2 == 0, "last dimension needs to be even"); - - constexpr DFTI_CONFIG_VALUE dfti_type = std::is_same::value ? DFTI_SINGLE : DFTI_DOUBLE; - - DFTI_DESCRIPTOR_HANDLE h; - MKL_LONG status; - - if (dims.num_dims() == 1) - { - status = DftiCreateDescriptor(&h, dfti_type, DFTI_REAL, 1, dims[0]); - DLIB_DFTI_CHECK_STATUS(status); - } - else - { - const long lastdim = dims[1]/2+1; - MKL_LONG size[] = {dims[0], dims[1]}; - status = DftiCreateDescriptor(&h, dfti_type, DFTI_REAL, 2, size); - DLIB_DFTI_CHECK_STATUS(status); - - { - MKL_LONG strides[3]; - strides[0] = 0; - strides[1] = size[1]; - strides[2] = 1; - - status = DftiSetValue(h, DFTI_INPUT_STRIDES, strides); - DLIB_DFTI_CHECK_STATUS(status); - } - { - MKL_LONG strides[3]; - strides[0] = 0; - strides[1] = lastdim; - strides[2] = 1; - status = DftiSetValue(h, DFTI_OUTPUT_STRIDES, strides); - DLIB_DFTI_CHECK_STATUS(status); - } - } - - const DFTI_CONFIG_VALUE inplacefft = (void*)in == (void*)out ? DFTI_INPLACE : DFTI_NOT_INPLACE; - status = DftiSetValue(h, DFTI_PLACEMENT, inplacefft); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiSetValue(h, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX); - DLIB_DFTI_CHECK_STATUS(status); - - // Unless we use sequential mode, the fft results are not correct. - status = DftiSetValue(h, DFTI_THREAD_LIMIT, 1); - DLIB_DFTI_CHECK_STATUS(status); - status = DftiCommitDescriptor(h); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiComputeForward(h, (void*)in, (void*)out); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiFreeDescriptor(&h); - DLIB_DFTI_CHECK_STATUS(status); + const auto& h = get_handle(plan_key{dims, (void*)in == (void*)out, std::is_same::value, false, false}); + check_status(DftiComputeForward(h.get(), (void*)in, (void*)out)); } /* @@ -177,66 +201,14 @@ namespace dlib - performs an inverse real FFT on `in` and stores the result in `out`. !*/ { + using namespace mkl_details; static_assert(std::is_floating_point::value, "template parameter needs to be a floatint point type"); DLIB_ASSERT(dims.num_dims() > 0, "dims can't be empty"); DLIB_ASSERT(dims.num_dims() < 3, "we currently only support up to 2D FFT. Please submit an issue on github if 3D or above is required."); DLIB_ASSERT(dims.back() % 2 == 0, "last dimension needs to be even"); - constexpr DFTI_CONFIG_VALUE dfti_type = std::is_same::value ? DFTI_SINGLE : DFTI_DOUBLE; - - DFTI_DESCRIPTOR_HANDLE h; - MKL_LONG status; - - if (dims.num_dims() == 1) - { - status = DftiCreateDescriptor(&h, dfti_type, DFTI_REAL, 1, dims[0]); - DLIB_DFTI_CHECK_STATUS(status); - } - else - { - const long lastdim = dims[1]/2+1; - MKL_LONG size[] = {dims[0], dims[1]}; - status = DftiCreateDescriptor(&h, dfti_type, DFTI_REAL, 2, size); - DLIB_DFTI_CHECK_STATUS(status); - - { - MKL_LONG strides[3]; - strides[0] = 0; - strides[1] = lastdim; - strides[2] = 1; - - status = DftiSetValue(h, DFTI_INPUT_STRIDES, strides); - DLIB_DFTI_CHECK_STATUS(status); - } - { - MKL_LONG strides[3]; - strides[0] = 0; - strides[1] = dims[1]; - strides[2] = 1; - status = DftiSetValue(h, DFTI_OUTPUT_STRIDES, strides); - DLIB_DFTI_CHECK_STATUS(status); - } - } - - const DFTI_CONFIG_VALUE inplacefft = (void*)in == (void*)out ? DFTI_INPLACE : DFTI_NOT_INPLACE; - status = DftiSetValue(h, DFTI_PLACEMENT, inplacefft); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiSetValue(h, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX); - DLIB_DFTI_CHECK_STATUS(status); - - // Unless we use sequential mode, the fft results are not correct. - status = DftiSetValue(h, DFTI_THREAD_LIMIT, 1); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiCommitDescriptor(h); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiComputeBackward(h, (void*)in, (void*)out); - DLIB_DFTI_CHECK_STATUS(status); - - status = DftiFreeDescriptor(&h); - DLIB_DFTI_CHECK_STATUS(status); + const auto& h = get_handle(plan_key{dims, (void*)in == (void*)out, std::is_same::value, false, true}); + check_status(DftiComputeBackward(h.get(), (void*)in, (void*)out)); } } diff --git a/dlib/test/active_learning.cpp b/dlib/test/active_learning.cpp index 9dc0013a52..3b261fcd98 100644 --- a/dlib/test/active_learning.cpp +++ b/dlib/test/active_learning.cpp @@ -151,7 +151,8 @@ namespace // When we pick the best/front ranked element then the active learning method // shouldn't do much worse than random selection (and often much better). DLIB_TEST(test_rank_unlabeled_training_samples(samples, labels, max_min_margin, 35, true) >= 0.97); - DLIB_TEST(test_rank_unlabeled_training_samples(samples, labels, ratio_margin, 25, true) >= 0.96); + const auto v1 = test_rank_unlabeled_training_samples(samples, labels, ratio_margin, 25, true); + DLIB_TEST_MSG(v1 >= 0.96, v1); // However, picking the worst ranked element should do way worse than random // selection. DLIB_TEST(test_rank_unlabeled_training_samples(samples, labels, max_min_margin, 25, false) < 0.8); diff --git a/dlib/test/dnn.cpp b/dlib/test/dnn.cpp index c564e277e1..cad64c7d8e 100644 --- a/dlib/test/dnn.cpp +++ b/dlib/test/dnn.cpp @@ -4505,7 +4505,7 @@ void test_multm_prev() trainer.train(samples, labels); const auto error_after = compute_error(); - DLIB_TEST_MSG(error_after < error_before && error_after == 0, "multibinary_log error increased after training"); + DLIB_TEST_MSG(error_after < error_before && error_after == 0, "multibinary_log error increased after training error_after = " << error_after << " error_before " << error_before); } // ---------------------------------------------------------------------------------------- diff --git a/dlib/test/fft.cpp b/dlib/test/fft.cpp index 43cbc6f89f..e2ff82a3bb 100644 --- a/dlib/test/fft.cpp +++ b/dlib/test/fft.cpp @@ -12,8 +12,8 @@ #include #ifdef DLIB_USE_MKL_FFT -#include -#include +#include +#include #endif #include "tester.h" #include "fftr_good_data.h"