Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/05-windows-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ jobs:
matrix:
include:
- platform: windows-2022
msvc_arch: x64
python_version: '3.10'
- platform: windows-2025
msvc_arch: x64
python_version: '3.10'
# Windows ARM64: Python 3.10 has no official ARM64 installer;
# 3.11 is the first CPython release with a Windows-on-ARM build.
- platform: windows-11-arm
msvc_arch: arm64
python_version: '3.11'

env:
SCCACHE_GHA_ENABLED: "true"
Expand Down Expand Up @@ -47,14 +56,14 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: '3.10'
python-version: ${{ matrix.python_version }}
cache: 'pip'
cache-dependency-path: 'pyproject.toml'

- name: Set up MSVC environment
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: x64
arch: ${{ matrix.msvc_arch }}

- name: Set up environment variables
run: |
Expand Down
50 changes: 28 additions & 22 deletions src/ailego/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,29 +90,35 @@ if(NOT ANDROID AND AUTO_DETECT_ARCH)
)
endforeach()
elseif (HOST_ARCH MATCHES "^(arm|arm64)$")
if(MSVC)
return()
endif()
set(MATH_MARCH_FLAG_NEON "-march=armv8-a")

file(GLOB_RECURSE MATH_FILES_NEON
${CMAKE_CURRENT_SOURCE_DIR}/math/*_dispatch.cc
${CMAKE_CURRENT_SOURCE_DIR}/math/*_dispatch.c
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_dispatch.cc
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_dispatch.c
${CMAKE_CURRENT_SOURCE_DIR}/math/*_neon.cc
${CMAKE_CURRENT_SOURCE_DIR}/math/*_neon.c
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_neon.cc
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_neon.c
)
if(NOT MSVC)
set(MATH_MARCH_FLAG_NEON "-march=armv8-a")

file(GLOB_RECURSE MATH_FILES_NEON
${CMAKE_CURRENT_SOURCE_DIR}/math/*_dispatch.cc
${CMAKE_CURRENT_SOURCE_DIR}/math/*_dispatch.c
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_dispatch.cc
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_dispatch.c
${CMAKE_CURRENT_SOURCE_DIR}/math/*_neon.cc
${CMAKE_CURRENT_SOURCE_DIR}/math/*_neon.c
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_neon.cc
${CMAKE_CURRENT_SOURCE_DIR}/math_batch/*_neon.c
)

foreach(MATH_FILE ${MATH_FILES_NEON})
set_source_files_properties(
${MATH_FILE}
PROPERTIES
COMPILE_FLAGS "${MATH_MARCH_FLAG_NEON}"
)
endforeach()
foreach(MATH_FILE ${MATH_FILES_NEON})
set_source_files_properties(
${MATH_FILE}
PROPERTIES
COMPILE_FLAGS "${MATH_MARCH_FLAG_NEON}"
)
endforeach()
else()
# MSVC on ARM64: NEON is the ARMv8 baseline and is always enabled,
# so no `-march` flag is required (MSVC does not accept GCC-style
# `-march=` anyway). The NEON math kernels still get compiled via
# the ALL_SRCS glob above; their guards use the AILEGO_HAVE_NEON /
# AILEGO_ARM64 feature macros (defined in platform.h), which resolve
# to true on MSVC ARM64 so the bodies actually emit code.
endif()
Comment thread
feihongxu0824 marked this conversation as resolved.
endif()
endif()

Expand Down
17 changes: 10 additions & 7 deletions src/ailego/internal/cpu_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@

#include "cpu_features.h"
#include <cstddef>
#include <zvec/ailego/internal/platform.h>

#if defined(_MSC_VER)
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
#include <intrin.h>
#endif

#if (defined(__x86_64__) || defined(__i386__)) && !defined(_MSC_VER)
#elif defined(__x86_64__) || defined(__i386__)
#include <cpuid.h>
#endif
Comment thread
Aanerud marked this conversation as resolved.

Expand All @@ -43,7 +42,7 @@ namespace internal {

CpuFeatures::CpuFlags CpuFeatures::flags_;

#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
CpuFeatures::CpuFlags::CpuFlags(void)
: L1_ECX(0), L1_EDX(0), L7_EBX(0), L7_ECX(0), L7_EDX(0) {
int l1[4] = {0, 0, 0, 0};
Expand Down Expand Up @@ -347,7 +346,11 @@ bool CpuFeatures::HYPERVISOR(void) {
bool CpuFeatures::NEON(void) {
#if defined(__aarch64__) && defined(__linux__)
return !!(getauxval(AT_HWCAP) & HWCAP_ASIMD);
#elif defined(__ARM_NEON)
#elif defined(AILEGO_HAVE_NEON)
// NEON is part of the ARMv8 baseline, so it is unconditionally present when
// the target has it (including MSVC ARM64, which predefines only _M_ARM64).
// This must agree with Intrinsics()/version.i, which report "Neon" from the
// same macro.
return true;
#else
return false;
Expand All @@ -356,7 +359,7 @@ bool CpuFeatures::NEON(void) {

const char *CpuFeatures::Intrinsics(void) {
return ""
#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
"Neon"
#if defined(__ARM_FEATURE_CRC32)
"+CRC"
Expand Down
8 changes: 4 additions & 4 deletions src/ailego/math/distance_matrix_accum_fp32.i
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
_mm512_castps_si512(b)))
#endif // __AVX512DQ__

#if defined(__ARM_NEON) && !defined(__aarch64__)
#if defined(AILEGO_HAVE_NEON) && !defined(AILEGO_ARM64)
static inline float32_t vaddvq_f32(float32x4_t v) {
float32x2_t s = vadd_f32(vget_low_f32(v), vget_high_f32(v));
return vget_lane_f32(vpadd_f32(s, s), 0);
Expand All @@ -40,13 +40,13 @@ static inline int32_t vaddvq_s32(int32x4_t v) {
int32x2_t s = vadd_s32(vget_low_s32(v), vget_high_s32(v));
return vget_lane_s32(vpadd_s32(s, s), 0);
}
#endif //__ARM_NEON && !__aarch64__
#endif // AILEGO_HAVE_NEON && !AILEGO_ARM64

#if defined(__aarch64__)
#if defined(AILEGO_ARM64)
#define ACCUM_FP32_2X1_NEON ACCUM_FP32_2X1_NEON_A64
#else
#define ACCUM_FP32_2X1_NEON ACCUM_FP32_2X1_NEON_A32
#endif // __aarch64__
#endif // AILEGO_ARM64

//! Compute the distance between matrix and query (FP32, M=2, N=1)
#define ACCUM_FP32_2X1_SSE(m, q, dim, out, _NORM) \
Expand Down
4 changes: 2 additions & 2 deletions src/ailego/math/distance_matrix_fp32.i
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
_mm256_insertf128_ps(_mm256_castps128_ps256(b), (a), 1)
#endif // __AVX__

#if defined(__ARM_NEON) && !defined(__aarch64__)
#if defined(AILEGO_HAVE_NEON) && !defined(AILEGO_ARM64)
#define vdupq_laneq_f32(a, b) vdupq_n_f32(vgetq_lane_f32(a, b))
#endif // __ARM_NEON && __aarch64__
#endif // AILEGO_HAVE_NEON && !AILEGO_ARM64

//! Iterative process of computing distance (FP32, M=2, N=1)
#define MATRIX_FP32_ITER_2X1_SSE(m, q, _RES, _LOAD, _PROC) \
Expand Down
6 changes: 3 additions & 3 deletions src/ailego/math/euclidean_distance_matrix_fp32_dispatch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
namespace zvec {
namespace ailego {

#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
void SquaredEuclideanDistanceFp32NEON(const float *lhs, const float *rhs,
size_t size, float *out);
#endif
Expand Down Expand Up @@ -49,7 +49,7 @@ void SquaredEuclideanDistanceMatrix<float, 1, 1>::Compute(const ValueType *m,
const ValueType *q,
size_t dim,
float *out) {
#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
SquaredEuclideanDistanceFp32NEON(m, q, dim, out);
#else
#if defined(__AVX512F__)
Expand All @@ -72,7 +72,7 @@ void SquaredEuclideanDistanceMatrix<float, 1, 1>::Compute(const ValueType *m,
}
#endif // __SSE__
*out = SquaredEuclideanDistanceFp32Scalar(m, q, dim);
#endif // __ARM_NEON
#endif // AILEGO_HAVE_NEON
}

//-----------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/ailego/math/euclidean_distance_matrix_fp32_neon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
namespace zvec {
namespace ailego {

#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
//! Squared Euclidean Distance
void SquaredEuclideanDistanceFp32NEON(const float *lhs, const float *rhs,
size_t size, float *out) {
Expand Down Expand Up @@ -56,7 +56,7 @@ void SquaredEuclideanDistanceFp32NEON(const float *lhs, const float *rhs,
*out = result;
}

#endif // __ARM_NEON
#endif // AILEGO_HAVE_NEON

} // namespace ailego
} // namespace zvec
2 changes: 2 additions & 0 deletions src/ailego/math/fht_avx2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <zvec/ailego/internal/platform.h>

#if defined(__AVX2__)

#include <immintrin.h>
Expand Down
2 changes: 2 additions & 0 deletions src/ailego/math/fht_avx512.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <zvec/ailego/internal/platform.h>

#if defined(__AVX512F__)

#include <immintrin.h>
Expand Down
15 changes: 8 additions & 7 deletions src/ailego/math/fht_dispatch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include <ailego/internal/cpu_features.h>
#include <zvec/ailego/internal/platform.h>
#include "fht.h"

namespace zvec {
Expand Down Expand Up @@ -41,7 +42,7 @@ void fht_kacs_walk_avx512(float *data, size_t len);
void fht_inv_kacs_walk_avx512(float *data, size_t len);
void fht_inplace_avx512(float *data, size_t n);
#endif
#if defined(__ARM_NEON) && defined(__aarch64__)
#if defined(AILEGO_ARM64_NEON)
void fht_flip_sign_neon(const uint8_t *flip, float *data, size_t dim);
void fht_kacs_walk_neon(float *data, size_t len);
void fht_inv_kacs_walk_neon(float *data, size_t len);
Expand All @@ -52,7 +53,7 @@ void fht_inv_kacs_walk_neon(float *data, size_t len);
// ============================================================================

void fht_flip_sign(const uint8_t *flip, float *data, size_t dim) {
#if defined(__ARM_NEON) && defined(__aarch64__)
#if defined(AILEGO_ARM64_NEON)
fht_flip_sign_neon(flip, data, dim);
#else
#if defined(__AVX512F__)
Expand All @@ -75,11 +76,11 @@ void fht_flip_sign(const uint8_t *flip, float *data, size_t dim) {
}
#endif
fht_flip_sign_scalar(flip, data, dim);
#endif // __ARM_NEON
#endif // AILEGO_ARM64_NEON
}

void fht_kacs_walk(float *data, size_t len) {
#if defined(__ARM_NEON) && defined(__aarch64__)
#if defined(AILEGO_ARM64_NEON)
fht_kacs_walk_neon(data, len);
#else
#if defined(__AVX512F__)
Expand All @@ -101,11 +102,11 @@ void fht_kacs_walk(float *data, size_t len) {
}
#endif
fht_kacs_walk_scalar(data, len);
#endif // __ARM_NEON
#endif // AILEGO_ARM64_NEON
}

void fht_inv_kacs_walk(float *data, size_t len) {
#if defined(__ARM_NEON) && defined(__aarch64__)
#if defined(AILEGO_ARM64_NEON)
fht_inv_kacs_walk_neon(data, len);
#else
#if defined(__AVX512F__)
Expand All @@ -127,7 +128,7 @@ void fht_inv_kacs_walk(float *data, size_t len) {
}
#endif
fht_inv_kacs_walk_scalar(data, len);
#endif // __ARM_NEON
#endif // AILEGO_ARM64_NEON
}

void fht_inplace(float *data, size_t n) {
Expand Down
11 changes: 8 additions & 3 deletions src/ailego/math/fht_neon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#if defined(__ARM_NEON) && defined(__aarch64__)
#include <zvec/ailego/internal/platform.h>

#if defined(AILEGO_ARM64_NEON)

#include <cmath>
#include <cstddef>
Expand Down Expand Up @@ -40,7 +42,10 @@ void fht_flip_sign_neon(const uint8_t *flip, float *data, size_t dim) {
uint32_t b1 = (bits16 >> 1) & 1u;
uint32_t b2 = (bits16 >> 2) & 1u;
uint32_t b3 = (bits16 >> 3) & 1u;
uint32x4_t bit_mask = {b0, b1, b2, b3};
// Build the lane mask via vld1q_u32: MSVC's uint32x4_t is a union type,
// so GCC/Clang-style brace initialization of a vector is not portable.
const uint32_t bits[4] = {b0, b1, b2, b3};
uint32x4_t bit_mask = vld1q_u32(bits);
uint32x4_t sign_mask = vmulq_u32(bit_mask, sign_bit);
float32x4_t v = vld1q_f32(&data[i]);
v = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v), sign_mask));
Expand Down Expand Up @@ -104,4 +109,4 @@ void fht_inv_kacs_walk_neon(float *data, size_t len) {
} // namespace ailego
} // namespace zvec

#endif // __ARM_NEON && __aarch64__
#endif // AILEGO_ARM64_NEON
2 changes: 2 additions & 0 deletions src/ailego/math/fht_sse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <zvec/ailego/internal/platform.h>

#if defined(__SSE2__)

#include <emmintrin.h>
Expand Down
10 changes: 5 additions & 5 deletions src/ailego/math/inner_product_matrix_fp32_dispatch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace ailego {
//--------------------------------------------------
// Dense
//--------------------------------------------------
#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
float InnerProductFp32NEON(const float *lhs, const float *rhs, size_t size);
float MinusInnerProductFp32NEON(const float *lhs, const float *rhs,
size_t size);
Expand Down Expand Up @@ -49,7 +49,7 @@ float MinusInnerProductFp32Scalar(const float *lhs, const float *rhs,
//! Compute the distance between matrix and query (FP32, M=1, N=1)
void InnerProductMatrix<float, 1, 1>::Compute(const float *m, const float *q,
size_t dim, float *out) {
#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
*out = InnerProductFp32NEON(m, q, dim);
#else
#if defined(__AVX512F__)
Expand All @@ -73,14 +73,14 @@ void InnerProductMatrix<float, 1, 1>::Compute(const float *m, const float *q,
}
#endif // __SSE__
*out = InnerProductFp32Scalar(m, q, dim);
#endif // __ARM_NEON
#endif // AILEGO_HAVE_NEON
}

//! Compute the distance between matrix and query (FP32, M=1, N=1)
void MinusInnerProductMatrix<float, 1, 1>::Compute(const float *m,
const float *q, size_t dim,
float *out) {
#if defined(__ARM_NEON)
#if defined(AILEGO_HAVE_NEON)
*out = MinusInnerProductFp32NEON(m, q, dim);
#else
#if defined(__AVX512F__)
Expand All @@ -104,7 +104,7 @@ void MinusInnerProductMatrix<float, 1, 1>::Compute(const float *m,
}
#endif // __SSE__
*out = MinusInnerProductFp32Scalar(m, q, dim);
#endif // __ARM_NEON
#endif // AILEGO_HAVE_NEON
}

//--------------------------------------------------
Expand Down
Loading
Loading