cmake_minimum_required(VERSION 3.10)
project(hnsw_cpp)

set(CMAKE_CXX_STANDARD 17)

find_package(pybind11 REQUIRED)
find_package(OpenMP)

pybind11_add_module(hnsw_cpp
    bindings.cpp
    hnsw.cpp
    simd_dispatch.cpp
    simd_avx2.cpp
)

# AVX2/FMA instructions are isolated to simd_avx2.cpp ONLY, via per-file compile
# options below -- never applied to the rest of the library. Previously -mavx2
# -mfma / -mavx2 applied to the whole hnsw_cpp target, meaning the compiler was
# free to emit AVX2 instructions anywhere in the binary (not just inside the
# explicitly SIMD-guarded code), so the shipped .so hard-required an AVX2/FMA
# CPU and crashed with an illegal-instruction error (not a catchable exception)
# on any CPU without it. Runtime dispatch (simd::detect_level(), see
# simd_dispatch.h) now decides at HNSW construction whether the AVX2 kernels in
# simd_avx2.cpp are safe to call on the current CPU; the portable kernels in
# simd_dispatch.cpp are always available as the baseline. Found 2026-08-18.
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    target_compile_options(hnsw_cpp PRIVATE -O3)
    set_source_files_properties(simd_avx2.cpp PROPERTIES COMPILE_OPTIONS "-mavx2;-mfma")
    if(OpenMP_CXX_FOUND)
        target_link_libraries(hnsw_cpp PRIVATE OpenMP::OpenMP_CXX)
        target_compile_options(hnsw_cpp PRIVATE ${OpenMP_CXX_FLAGS})
    endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    target_compile_options(hnsw_cpp PRIVATE /O2)
    set_source_files_properties(simd_avx2.cpp PROPERTIES COMPILE_OPTIONS "/arch:AVX2")
endif()
