diff --git a/.github/actions/build_cmake/action.yml b/.github/actions/build_cmake/action.yml index 1cc7818b10..3fad247b6d 100644 --- a/.github/actions/build_cmake/action.yml +++ b/.github/actions/build_cmake/action.yml @@ -32,7 +32,7 @@ runs: conda update -y -q conda echo "$CONDA/bin" >> $GITHUB_PATH - conda install -y -q python=3.11 cmake make swig numpy scipy pytest + conda install -y -q python=3.11 cmake make swig numpy scipy pytest gflags # install base packages for ARM64 if [ "${{ runner.arch }}" = "ARM64" ]; then @@ -143,6 +143,11 @@ runs: run: | export GTEST_OUTPUT="xml:$(realpath .)/test-results/googletest/" make -C build test + - name: C++ perf benchmarks + shell: bash + if: inputs.rocm == 'OFF' + run: | + find ./build/perf_tests/ -executable -type f -name "bench*" -exec '{}' -v \; - name: Install Python extension shell: bash working-directory: build/faiss/python diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f1b30fa35..ae75fc17f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,11 +105,12 @@ add_subdirectory(demos) add_subdirectory(benchs) add_subdirectory(tutorial/cpp) + # CTest must be included in the top level to enable `make test` target. include(CTest) if(BUILD_TESTING) add_subdirectory(tests) - + add_subdirectory(perf_tests) if(FAISS_ENABLE_GPU) if(FAISS_ENABLE_ROCM) add_subdirectory(faiss/gpu-rocm/test) diff --git a/perf_tests/CMakeLists.txt b/perf_tests/CMakeLists.txt new file mode 100644 index 0000000000..b7c325dcb4 --- /dev/null +++ b/perf_tests/CMakeLists.txt @@ -0,0 +1,98 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +# @lint-ignore-every LINEWRAP +project(faiss_perf_tests) +set(BENCHMARK_ENABLE_TESTING OFF) + +include(FetchContent) +FetchContent_Declare(googlebenchmark + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG main) # need main for benchmark::benchmark +FetchContent_MakeAvailable( + googlebenchmark) + + +find_package(Threads REQUIRED) +find_package(OpenMP REQUIRED) +find_package(gflags REQUIRED) + +add_library(faiss_perf_tests_utils + utils.cpp +) +# `#include ` or any other headers +target_include_directories(faiss_perf_tests_utils PRIVATE + ${PROJECT_SOURCE_DIR}/../..) + +function(link_to_faiss_lib target) + if(NOT FAISS_OPT_LEVEL STREQUAL "avx2" AND NOT FAISS_OPT_LEVEL STREQUAL "avx512" AND NOT FAISS_OPT_LEVEL STREQUAL "sve") + target_link_libraries(${target} PRIVATE faiss) + endif() + + if(FAISS_OPT_LEVEL STREQUAL "avx2") + if(NOT WIN32) + target_compile_options(${target} PRIVATE $<$:-mavx2 -mfma>) + else() + target_compile_options(${target} PRIVATE $<$:/arch:AVX2>) + endif() + target_link_libraries(${target} PRIVATE faiss_avx2) + endif() + + if(FAISS_OPT_LEVEL STREQUAL "avx512") + if(NOT WIN32) + target_compile_options(${target} PRIVATE $<$:-mavx2 -mfma -mavx512f -mavx512f -mavx512cd -mavx512vl -mavx512dq -mavx512bw>) + else() + target_compile_options(${target} PRIVATE $<$:/arch:AVX512>) + endif() + target_link_libraries(${target} PRIVATE faiss_avx512) + endif() + + if(FAISS_OPT_LEVEL STREQUAL "sve") + if(NOT WIN32) + if("${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} " MATCHES "(^| )-march=native") + # Do nothing, expect SVE to be enabled by -march=native + elseif("${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} " MATCHES "(^| )(-march=armv[0-9]+(\\.[1-9]+)?-[^+ ](\\+[^+$ ]+)*)") + # Add +sve + target_compile_options(${target} PRIVATE $<$,$>:${CMAKE_MATCH_2}+sve>) + elseif(NOT "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} " MATCHES "(^| )-march=armv") + # No valid -march, so specify -march=armv8-a+sve as the default + target_compile_options(${target} PRIVATE $<$,$>:-march=armv8-a+sve>) + endif() + if("${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} " MATCHES "(^| )-march=native") + # Do nothing, expect SVE to be enabled by -march=native + elseif("${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} " MATCHES "(^| )(-march=armv[0-9]+(\\.[1-9]+)?-[^+ ](\\+[^+$ ]+)*)") + # Add +sve + target_compile_options(${target} PRIVATE $<$,$>:${CMAKE_MATCH_2}+sve>) + elseif(NOT "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} " MATCHES "(^| )-march=armv") + # No valid -march, so specify -march=armv8-a+sve as the default + target_compile_options(${target} PRIVATE $<$,$>:-march=armv8-a+sve>) + endif() + else() + # TODO: support Windows + endif() + target_link_libraries(${target} PRIVATE faiss_sve) + endif() +endfunction() + +link_to_faiss_lib(faiss_perf_tests_utils) + +set(FAISS_PERF_TEST_SRC + bench_no_multithreading_rcq_search.cpp + bench_scalar_quantizer_accuracy.cpp + bench_scalar_quantizer_decode.cpp + bench_scalar_quantizer_distance.cpp + bench_scalar_quantizer_encode.cpp +) +foreach(bench ${FAISS_PERF_TEST_SRC}) + get_filename_component(bench_exec ${bench} NAME_WE) + add_executable(${bench_exec} ${bench}) + link_to_faiss_lib(${bench_exec}) + target_link_libraries(${bench_exec} PRIVATE faiss_perf_tests_utils OpenMP::OpenMP_CXX benchmark::benchmark gflags) + # `#include ` or any other headers + target_include_directories(${bench_exec} PRIVATE + ${PROJECT_SOURCE_DIR}/../..) + +endforeach() diff --git a/faiss/perf_tests/bench_hnsw.py b/perf_tests/bench_hnsw.py similarity index 100% rename from faiss/perf_tests/bench_hnsw.py rename to perf_tests/bench_hnsw.py diff --git a/faiss/perf_tests/bench_no_multithreading_rcq_search.cpp b/perf_tests/bench_no_multithreading_rcq_search.cpp similarity index 100% rename from faiss/perf_tests/bench_no_multithreading_rcq_search.cpp rename to perf_tests/bench_no_multithreading_rcq_search.cpp diff --git a/faiss/perf_tests/bench_scalar_quantizer_accuracy.cpp b/perf_tests/bench_scalar_quantizer_accuracy.cpp similarity index 100% rename from faiss/perf_tests/bench_scalar_quantizer_accuracy.cpp rename to perf_tests/bench_scalar_quantizer_accuracy.cpp diff --git a/faiss/perf_tests/bench_scalar_quantizer_decode.cpp b/perf_tests/bench_scalar_quantizer_decode.cpp similarity index 100% rename from faiss/perf_tests/bench_scalar_quantizer_decode.cpp rename to perf_tests/bench_scalar_quantizer_decode.cpp diff --git a/faiss/perf_tests/bench_scalar_quantizer_distance.cpp b/perf_tests/bench_scalar_quantizer_distance.cpp similarity index 100% rename from faiss/perf_tests/bench_scalar_quantizer_distance.cpp rename to perf_tests/bench_scalar_quantizer_distance.cpp diff --git a/faiss/perf_tests/bench_scalar_quantizer_encode.cpp b/perf_tests/bench_scalar_quantizer_encode.cpp similarity index 100% rename from faiss/perf_tests/bench_scalar_quantizer_encode.cpp rename to perf_tests/bench_scalar_quantizer_encode.cpp diff --git a/faiss/perf_tests/utils.cpp b/perf_tests/utils.cpp similarity index 100% rename from faiss/perf_tests/utils.cpp rename to perf_tests/utils.cpp diff --git a/faiss/perf_tests/utils.h b/perf_tests/utils.h similarity index 100% rename from faiss/perf_tests/utils.h rename to perf_tests/utils.h