Skip to content

Windows ARM64 (MSVC) build broken by NEON SIMD templatization (D95392150) #4993

@kyamagu

Description

@kyamagu

Summary

The NEON SIMD templatization landed via D95392150 (commit 8d8268c8a, GitHub PR #4866) breaks the build on Windows ARM64 with MSVC. The previous code (simdlib_neon.h before templatization) compiled successfully.

Environment

  • Compiler: MSVC (Visual Studio 2022), targeting arm64
  • OS: Windows 11 ARM64
  • faiss version: main branch at commit 8d8268c8a and later

Errors

Three categories of errors occur:

1. NEON intrinsics cannot be used as non-type template parameters

MSVC implements NEON intrinsics (vsubq_u16, vandq_u16, vorrq_u16, etc.) as compiler builtins, not as real functions. Their address cannot be taken, so the binary_func_impl::call<&vsubq_u16>() pattern in simdlib_neon.h fails:

faiss/impl/simdlib/simdlib_neon.h(540): error C2065: 'vsubq_u16': undeclared identifier
faiss/impl/simdlib/simdlib_neon.h(540): error C2975: 'F': invalid template argument, expected compile-time constant expression

This affects all lines using .call<&intrinsic>() (lines 540, 552, 564, etc.).

2. Duplicate function definitions due to MSVC ARM64 type aliasing

On MSVC ARM64, uint8x16x2_t and uint16x8x2_t (and other NEON struct types) resolve to the same underlying __n128x2 type. This causes overload ambiguity:

faiss/impl/simdlib/simdlib_neon.h(34): error C2084: function 'uint8x16_t faiss::detail::reinterpret_u8(const uint8x16x2_t &)' already has a body

3. Missing members/operators on NEON-specialized template types

Several members and operators are not defined for the NEON specializations:

faiss/impl/fast_scan/simd_result_handlers.h(184): error C2039: 'get_scalar_0': is not a member of 'faiss::simd16uint16_tpl<faiss::SIMDLevel::ARM_NEON>'
faiss/IndexIVFPQFastScan.cpp(206): error C2039: 'store': is not a member of 'faiss::simd8float32_tpl<faiss::SIMDLevel::ARM_NEON>'

Operators >> and & are also missing for NEON types in kernels_simd256.h.

Suggested Fixes

  1. Wrap NEON builtins in real functions so their addresses can be taken (or replace the function-pointer template pattern with a different dispatch mechanism for MSVC).
  2. Guard overloaded reinterpret_* functions with #ifndef _MSC_VER or use SFINAE / if constexpr to avoid ambiguity from collapsed NEON types on MSVC.
  3. Ensure all required members (get_scalar_0, store, operators >>, &) are defined for the ARM_NEON specializations.

Alternatively, falling back to SIMDLevel::NONE (emulated) on MSVC ARM64 would be a quick workaround until proper MSVC NEON support is added.

Related

Reproducer

Build faiss with CMake on Windows 11 ARM64 using MSVC:

cmake -B build -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF -A ARM64
cmake --build build

CI logs showing the failure: https://github.com/faiss-wheels/faiss-wheels/actions/runs/23570080174/job/68630487844?pr=158

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions