You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit aef66ea
Browse filesBrowse the repository at this point in the historyBrowse files
distance_cosine_float() and distance_cosine_int8() had no NEON kernel,
so cosine KNN queries in NEON builds, which include the macOS arm64
build, ran the scalar loop.
asg017/sqlite-vec 0de765f added cosine_float_neon() and
cosine_int8_neon(), dispatched above 16 and 15 dimensions. This ports
them with two changes. asg017's float32 kernel sums in float32, the
loss d75c245 fixed in the scalar loop for asg017#324: vectors with
elements below about 3e-23 or above about 2e19 get wrong distances.
Here each float32x4 load is widened to two float64x2 halves before it
is multiplied and added, in asg017's 16-element blocks with four
accumulators per sum. And the int8 kernel finishes in double, as
distance_cosine_int8() does, where asg017's finishes in float; both
sum the products exactly in 32-bit lanes. Neither kernel checks for a
zero vector: vec_distance_cosine() returns NULL for one, and vec0
refuses them in cosine columns, before any distance is computed.
Built with -DSQLITE_VEC_ENABLE_NEON on Linux arm64 (Clang 19, -O3), a
KNN query on a 100,000-row float[768] table takes 39.2 ms instead of
102.8 ms for k = 10 and 46.2 ms instead of 126.2 ms for k = 100
(medians of 20 queries), returning the same rows and distances. The
float32 distances match the scalar loop's on 12,000 random pairs of 16
to 1,536 dimensions, except that a vector's distance to itself, 0 or
about 2e-16 in either, can change between the two. The int8 distances
match up to 1,024 dimensions, where every sum is exact in float, and
past that the kernel's are closer to the exact value for vectors whose
squares sum past 2^24 (a mean error of 2.3e-8 instead of 2.5e-7 at
2,048 dimensions).
The cosine tests used vectors of 2 and 3 elements, below both kernels'
thresholds, and pass against asg017's float32 kernel as it is.
test_vec_distance_cosine now checks lengths of 17 to 768, with and
without a remainder past the 16-element blocks, against a reference
computed in float64, since numpy sums int8 products in int8, and the
extreme-magnitude test repeats at 40 dimensions, which asg017's
float32 kernel fails. test-loadable.py passes on the NEON build and on
the scalar one, and make test-unit, which builds without SIMD, passes
too.
0 commit comments