Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
74da77a
refactor: use dlopen
richyreachy Jun 24, 2026
17a7fd5
refactor: use dlopen to load libaio
richyreachy Jun 25, 2026
8ef5d2d
fix: log out the warning only once
richyreachy Jun 26, 2026
50c6c8d
fix: add log
richyreachy Jun 26, 2026
ceee226
fix: add log
richyreachy Jun 26, 2026
5e77ee3
Merge branch 'refactor/diskann_dlopen' of github.com:richyreachy/zvec…
richyreachy Jun 26, 2026
6d774ed
refactor: merge main
richyreachy Jun 26, 2026
e2a2ede
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jun 30, 2026
a2524eb
fix: fix windows build
richyreachy Jul 1, 2026
ac109ae
Merge branch 'refactor/diskann_dlopen' of github.com:richyreachy/zvec…
richyreachy Jul 1, 2026
6688e1a
fix: remove libaio dependency
richyreachy Jul 1, 2026
760fb7a
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jul 2, 2026
f2559b5
fix: remove no use code
richyreachy Jul 2, 2026
d753080
fix: fix makefile
richyreachy Jul 2, 2026
bc7b843
Merge branch 'refactor/diskann_dlopen' of github.com:richyreachy/zvec…
richyreachy Jul 2, 2026
292322c
fix: fix ut
richyreachy Jul 3, 2026
a0a9ce9
fix: remove export map
richyreachy Jul 3, 2026
69b1e23
fix: clean code
richyreachy Jul 3, 2026
081aee3
fix: add ci job to test libaio
richyreachy Jul 3, 2026
058c67c
feat: add diskann on arm
richyreachy Jul 6, 2026
ab8901a
fix: fix on comment
richyreachy Jul 6, 2026
63f5ff7
fix: remove diskann runtime
richyreachy Jul 6, 2026
30a08f8
fix: fix ut
richyreachy Jul 7, 2026
5ffc23a
refactor: move libaio loader to ailego
richyreachy Jul 7, 2026
8bf1f15
fix: fix merge
richyreachy Jul 7, 2026
1c7ff60
fix: add io backend
richyreachy Jul 7, 2026
54eaa11
fix: add io backend
richyreachy Jul 7, 2026
d2fba31
fix: fix memcpy
richyreachy Jul 7, 2026
9870923
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jul 7, 2026
716adb9
fix: fix warning
richyreachy Jul 7, 2026
f19defb
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jul 7, 2026
241dd7a
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jul 8, 2026
e1048c0
fix: remove ci
richyreachy Jul 8, 2026
fde7813
fix: add ci
richyreachy Jul 8, 2026
6496a0b
Merge branch 'refactor/diskann_dlopen' of github.com:richyreachy/zvec…
richyreachy Jul 8, 2026
4567d99
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jul 8, 2026
ca89c30
fix: debug output
richyreachy Jul 8, 2026
01b702c
fix: run ci
richyreachy Jul 8, 2026
69144b5
Merge branch 'main' into feat/diskann_on_arm_new
richyreachy Jul 8, 2026
e0b12db
Merge branch 'main' into refactor/diskann_dlopen
richyreachy Jul 9, 2026
8dca6a6
fix: link core_knn_diskann in index_group_by_test
richyreachy Jul 9, 2026
11940a7
Merge branch 'refactor/diskann_dlopen' into feat/diskann_on_arm_new
richyreachy Jul 9, 2026
b7d0b0f
fix: fix make
richyreachy Jul 9, 2026
86806b4
support O_DIRECT
iaojnh Jul 13, 2026
e9dafa6
upd
iaojnh Jul 16, 2026
76711b5
Merge branch 'main' into feat/diskann_on_arm_new
iaojnh Jul 23, 2026
6e3872e
Merge branch 'main' into feat/diskann_on_arm_new
iaojnh Jul 23, 2026
a0d451b
fix
iaojnh Jul 23, 2026
15d864d
add ut
iaojnh Jul 23, 2026
c7db0a8
Merge commit 'd15a37e' into feat/diskann_on_arm_new
iaojnh Jul 30, 2026
e244e41
fix
iaojnh Jul 30, 2026
d9819d2
fix
iaojnh Jul 30, 2026
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
1 change: 0 additions & 1 deletion .github/workflows/03-macos-linux-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ jobs:
cd "$GITHUB_WORKSPACE"
python -m pytest python/tests/test_collection_diskann.py -v
shell: bash

# Verify installing libaio does not affect existing non-DiskAnn tests.
- name: Run HNSW Tests (w/ libaio)
if: matrix.platform == 'linux-x64'
Expand Down
9 changes: 6 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,17 @@ else()
endif()
message(STATUS "RABITQ_ARCH_FLAG: ${RABITQ_ARCH_FLAG}")

# DiskAnn support (Linux x86_64 only; libaio loaded at runtime via dlopen)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386" AND NOT ANDROID AND NOT IOS)
# DiskAnn support:
# - Linux (x86_64, i686, i386, aarch64, arm64) with libaio (loaded via dlopen)
# - macOS (x86_64, ARM64/Apple Silicon) with kqueue
if((CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386|aarch64|arm64" AND NOT ANDROID AND NOT IOS)
OR (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT IOS))
set(DISKANN_SUPPORTED ON)
add_definitions(-DDISKANN_SUPPORTED=1)
else()
set(DISKANN_SUPPORTED OFF)
add_definitions(-DDISKANN_SUPPORTED=0)
message(STATUS "DiskAnn support disabled - only supported on Linux x86_64")
message(STATUS "DiskAnn support disabled - supported on Linux (x86_64/ARM64 with libaio) and macOS (with kqueue)")
endif()
message(STATUS "DISKANN_SUPPORTED: ${DISKANN_SUPPORTED}")

Expand Down
1 change: 1 addition & 0 deletions examples/c++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ endif()
get_filename_component(ZVEC_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)

set(ZVEC_INCLUDE_DIR ${ZVEC_ROOT_DIR}/src/include)
set(ZVEC_SRC_DIR ${ZVEC_ROOT_DIR}/src)
set(ZVEC_LIB_DIR ${ZVEC_ROOT_DIR}/${HOST_BUILD_DIR}/lib)

include_directories(${ZVEC_INCLUDE_DIR})
Expand Down
13 changes: 5 additions & 8 deletions python/tests/detail/fixture_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
import logging
import platform

DISKANN_SUPPORTED = platform.system() == "Linux" and platform.machine() in (
"x86_64",
"AMD64",
"i686",
"i386",
)
DISKANN_SUPPORTED = (
platform.system() == "Linux"
and platform.machine() in ("x86_64", "AMD64", "i686", "i386", "aarch64", "arm64")
) or platform.system() == "Darwin"

from typing import Any, Generator
from zvec.typing import DataType, StatusCode, MetricType, QuantizeType
Expand All @@ -27,9 +25,8 @@ def _ensure_diskann_runtime_or_reason() -> str | None:
_DISKANN_PRELOAD_DONE = True

if not DISKANN_SUPPORTED:
_DISKANN_PRELOAD_REASON = "DiskAnn only supported on Linux x86_64"
_DISKANN_PRELOAD_REASON = "DiskAnn is supported on Linux (x86_64/ARM64 with libaio) and macOS (kqueue)"
return _DISKANN_PRELOAD_REASON

_DISKANN_PRELOAD_REASON = None
return None

Expand Down
14 changes: 10 additions & 4 deletions python/tests/test_collection_diskann.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

Two platform-level prerequisites are enforced at module import time:

1. DiskAnn is currently built only for Linux x86_64 — other platforms are
skipped wholesale.
1. DiskAnn is built for Linux (x86_64/ARM64 with libaio) and macOS (with kqueue) —
other platforms are skipped wholesale.
2. libaio is loaded eagerly (via dlopen) inside DiskAnnBuilder::init() /
DiskAnnStreamer::init(). If libaio is missing, DiskAnn falls back to
synchronous pread() — the tests still run but with degraded performance.
Expand All @@ -39,8 +39,14 @@
# Platform gating (must happen BEFORE we touch zvec).
# --------------------------------------------------------------------------- #
pytestmark = pytest.mark.skipif(
not (sys.platform == "linux" and platform.machine() in ("x86_64", "AMD64")),
reason="DiskAnn plugin is only supported on Linux x86_64",
not (
(
sys.platform == "linux"
and platform.machine() in ("x86_64", "AMD64", "aarch64", "arm64")
)
or sys.platform == "darwin"
),
reason="DiskAnn is supported on Linux (x86_64/ARM64 with libaio) and macOS (kqueue)",
)

import zvec # noqa: E402
Expand Down
46 changes: 26 additions & 20 deletions src/ailego/io/io_backend_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#pragma once

#include <mutex>
#include <ailego/io/libaio_loader.h>
#include <zvec/ailego/io/io_backend.h>

Expand Down Expand Up @@ -78,30 +79,16 @@ class IOBackend {
// Returns the loaded backend type.
// Idempotent — if already loaded, returns immediately.
IOBackendType available() {
if (type_ != IOBackendType::kPread) {
return type_;
}
return available(IOBackendType::kLibAio);
std::lock_guard<std::mutex> lock(mutex_);
return available_locked(IOBackendType::kLibAio);
}

// Try to load the requested backend. Returns the loaded backend type
// (may differ from requested if the load failed — falls back to kPread).
// Idempotent — if the same backend is already loaded, returns immediately.
IOBackendType available(IOBackendType requested) {
if (type_ == requested && type_ != IOBackendType::kPread) {
return type_;
}
#if defined(__linux) || defined(__linux__)
if (requested == IOBackendType::kLibAio) {
if (LibAioLoader::Instance().load() &&
LibAioLoader::Instance().is_available()) {
type_ = IOBackendType::kLibAio;
return type_;
}
}
#endif
type_ = IOBackendType::kPread;
return type_;
std::lock_guard<std::mutex> lock(mutex_);
return available_locked(requested);
}

bool is_pread() {
Expand All @@ -114,22 +101,41 @@ class IOBackend {

// Returns the loaded backend type.
IOBackendType type() const {
std::lock_guard<std::mutex> lock(mutex_);
return type_;
}

// Human-readable name for the selected backend.
const char *name() const {
return IOBackendTypeName(type_);
return IOBackendTypeName(type());
}

// Human-readable description for the selected backend.
const char *description() const {
return IOBackendDescription(type_);
return IOBackendDescription(type());
}

private:
IOBackend() = default;

IOBackendType available_locked(IOBackendType requested) {
if (type_ == requested && type_ != IOBackendType::kPread) {
return type_;
}
#if defined(__linux) || defined(__linux__)
if (requested == IOBackendType::kLibAio) {
if (LibAioLoader::Instance().load() &&
LibAioLoader::Instance().is_available()) {
type_ = IOBackendType::kLibAio;
return type_;
}
}
#endif
type_ = IOBackendType::kPread;
return type_;
}

mutable std::mutex mutex_;
IOBackendType type_{IOBackendType::kPread};
};

Expand Down
11 changes: 10 additions & 1 deletion src/binding/python/model/python_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,16 @@ void ZVecPyCollection::bind_dql_methods(
"given vector column. One of 'mmap', 'buffer_pool', 'contiguous'. "
"Raises KeyError if no HNSW index exists on the column, or "
"ValueError if the column's index is not an HNSW index. Intended "
"for introspection and testing only; not part of the stable API.");
"for introspection and testing only; not part of the stable API.")
.def(
"_debug_io_backend_type",
[](const Collection &self) {
const auto result = self.DebugGetIoBackendType();
return unwrap_expected(result);
},
"Debug-only: returns the I/O backend type used by DiskAnn. "
"One of 'libaio', 'pread'. Intended for introspection and "
"testing only; not part of the stable API.");
}

} // namespace zvec
2 changes: 1 addition & 1 deletion src/core/algorithm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ else()
# Empty stub library for unsupported platforms
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/diskann_stub.cc
"// Stub implementation for unsupported platforms\n"
"// DiskAnn only supports Linux x86_64\n"
"// DiskAnn supports Linux (x86_64/ARM64 with libaio) and macOS (kqueue)\n"
"namespace zvec { namespace core { /* empty namespace for compatibility */ } }\n"
)

Expand Down
4 changes: 2 additions & 2 deletions src/core/algorithm/diskann/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ file(GLOB_RECURSE ALL_SRCS *.cc *.c)
# ${CMAKE_DL_LIBS} for dlopen/dlsym/dlclose.
set(CORE_KNN_DISKANN_LIBS core_framework core_knn_cluster)

if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|i686|i386|aarch64|arm64")
list(APPEND CORE_KNN_DISKANN_LIBS ${CMAKE_DL_LIBS})
endif()

Expand All @@ -31,4 +31,4 @@ cc_library(
INCS . ${PROJECT_ROOT_DIR}/src/core ${PROJECT_ROOT_DIR}/src/core/algorithm
LDFLAGS "${CORE_KNN_DISKANN_LDFLAGS}"
VERSION "${PROXIMA_ZVEC_VERSION}"
)
)
Loading
Loading