Merge branch 'main-dev' of https://github.com/unum-cloud/usearch into… #1070
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Pre-Release | |
| on: | |
| push: | |
| branches: ['main-dev'] | |
| pull_request: | |
| branches: ['main-dev'] | |
| env: | |
| GH_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }} | |
| PYTHONUTF8: 1 | |
| PYTHON_VERSION: 3.11 | |
| DOTNET_VERSION: 8.0.x | |
| NODE_VERSION: 20 | |
| JAVA_VERSION: 21 | |
| GO_VERSION: '^1.21.0' | |
| ANDROID_NDK_VERSION: 26.3.11579264 | |
| ANDROID_SDK_VERSION: 21 | |
| # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages | |
| permissions: | |
| contents: read | |
| jobs: | |
| versioning: | |
| name: Update Version | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Run TinySemVer | |
| uses: ashvardanian/[email protected] | |
| with: | |
| verbose: 'true' | |
| version-file: 'VERSION' | |
| update-version-in: | | |
| package.json:"version": "(\d+\.\d+\.\d+)" | |
| package-lock.json:"usearch",\n\s+"version": "(\d+\.\d+\.\d+)" | |
| CITATION.cff:^version: (\d+\.\d+\.\d+) | |
| Cargo.toml:^version = "(\d+\.\d+\.\d+)" | |
| Cargo.lock:name = "usearch"\nversion = "(\d+\.\d+\.\d+)" | |
| wasmer.toml:^version = "(\d+\.\d+\.\d+)" | |
| conanfile.py:version = "(\d+\.\d+\.\d+)" | |
| java/README.md:usearchVersion = '(\d+\.\d+\.\d+)' | |
| java/README.md:version: '(\d+\.\d+\.\d+)' | |
| README.md:version = {(\d+\.\d+\.\d+)} | |
| csharp/nuget/nuget-package.props:>(\d+\.\d+\.\d+)</Version> | |
| CMakeLists.txt:VERSION (\d+\.\d+\.\d+) | |
| update-major-version-in: | | |
| include/usearch/index.hpp:^#define USEARCH_VERSION_MAJOR (\d+) | |
| update-minor-version-in: | | |
| include/usearch/index.hpp:^#define USEARCH_VERSION_MINOR (\d+) | |
| update-patch-version-in: | | |
| include/usearch/index.hpp:^#define USEARCH_VERSION_PATCH (\d+) | |
| dry-run: 'true' | |
| test_ubuntu_gcc: | |
| name: Ubuntu (GCC 14) | |
| runs-on: ubuntu-24.04 | |
| env: | |
| CC: gcc | |
| CXX: g++ | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| # C/C++ | |
| - name: Build C/C++ | |
| run: | | |
| sudo apt update | |
| sudo apt install -y cmake build-essential libjemalloc-dev libomp-dev gcc-12 g++-12 | |
| cmake -B build_artifacts -D CMAKE_BUILD_TYPE=RelWithDebInfo -D USEARCH_BUILD_TEST_CPP=1 -D USEARCH_BUILD_TEST_C=1 -D USEARCH_BUILD_LIB_C=1 -D USEARCH_BUILD_SQLITE=1 -D USEARCH_USE_OPENMP=1 -D USEARCH_USE_SIMSIMD=1 -D USEARCH_USE_JEMALLOC=1 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| - name: Test C++ | |
| run: build_artifacts/test_cpp | |
| - name: Test C | |
| run: build_artifacts/test_c | |
| # Python | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Build Python | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pytest pytest-repeat numpy numba cppyy | |
| pip install --upgrade git+https://github.com/Maratyszcza/PeachPy | |
| python -m pip install . | |
| - name: Test Python | |
| run: pytest | |
| # JavaScript | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Install dependencies | |
| run: npm ci --skip-scripts | |
| - name: Build JavaScript | |
| run: npm run build-js | |
| - name: Test JavaScript | |
| run: npm test | |
| # Rust | |
| - name: Set up Rust | |
| run: | | |
| rustup update stable | |
| rustup default stable | |
| rustc -vV | |
| - name: Build Rust | |
| run: cargo build | |
| - name: Test Rust | |
| run: cargo test | |
| # Java | |
| - name: Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'adopt' | |
| - name: Setup Gradle | |
| uses: gradle/[email protected] | |
| - name: Check Java formatting | |
| run: gradle spotlessCheck | |
| - name: Test Java | |
| run: gradle clean build | |
| # C# | |
| - name: Setup .NET ${{ env.DOTNET_VERSION }} | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Test .NET | |
| run: | | |
| mkdir -p "${{ github.workspace }}/csharp/lib/runtimes/linux-x64/native" | |
| cp "${{ github.workspace }}/build_artifacts/libusearch_c.so" "${{ github.workspace }}/csharp/lib/runtimes/linux-x64/native" | |
| dotnet test -c Debug --logger "console;verbosity=detailed" | |
| shell: bash | |
| working-directory: ${{ github.workspace }}/csharp | |
| # GoLang | |
| # With `LD_DEBUG=all` we detect the addresses of the libraries that are loaded | |
| - name: Test GoLang | |
| run: | | |
| sudo cp ${{ github.workspace }}/build_artifacts/libusearch_c.so /usr/lib/libusearch_c.so | |
| sudo cp ${{ github.workspace }}/c/usearch.h /usr/include/usearch.h | |
| LD_DEBUG=all go test -v | |
| working-directory: ${{ github.workspace }}/golang/ | |
| test_ubuntu_clang: | |
| name: Ubuntu (Clang 18) | |
| runs-on: ubuntu-24.04 | |
| env: | |
| CC: clang | |
| CXX: clang++ | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| # C/C++ | |
| # Clang 16 isn't available from default repos on Ubuntu 22.04, so we have to install it manually | |
| - name: Build C/C++ | |
| run: | | |
| sudo apt update | |
| sudo apt install -y cmake build-essential libjemalloc-dev clang | |
| cmake -B build_artifacts -D CMAKE_BUILD_TYPE=RelWithDebInfo -D USEARCH_BUILD_TEST_CPP=1 -D USEARCH_BUILD_TEST_C=1 -D USEARCH_BUILD_LIB_C=1 -D USEARCH_BUILD_SQLITE=1 -D USEARCH_USE_OPENMP=0 -D USEARCH_USE_SIMSIMD=1 -D USEARCH_USE_JEMALLOC=1 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| - name: Test C++ | |
| run: build_artifacts/test_cpp | |
| - name: Test C | |
| run: build_artifacts/test_c | |
| # JavaScript | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Install dependencies | |
| run: npm ci --skip-scripts | |
| - name: Build JavaScript | |
| run: npm run build-js | |
| - name: Test JavaScript | |
| run: npm test | |
| # Python | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Build Python | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pytest pytest-repeat numpy numba cppyy | |
| pip install --upgrade git+https://github.com/Maratyszcza/PeachPy | |
| python -m pip install . | |
| env: | |
| CXX: clang++ | |
| CC: clang++ # Override the default compiler | |
| - name: Test Python | |
| run: pytest | |
| # Rust | |
| - name: Set up Rust | |
| run: | | |
| rustup update stable | |
| rustup default stable | |
| rustc -vV | |
| - name: Build Rust | |
| run: cargo build | |
| - name: Test Rust | |
| run: cargo test | |
| # C# | |
| - name: Setup .NET ${{ env.DOTNET_VERSION }} | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Test .NET | |
| run: | | |
| mkdir -p "${{ github.workspace }}/csharp/lib/runtimes/linux-x64/native" | |
| cp "${{ github.workspace }}/build_artifacts/libusearch_c.so" "${{ github.workspace }}/csharp/lib/runtimes/linux-x64/native" | |
| dotnet test -c Debug --logger "console;verbosity=detailed" | |
| shell: bash | |
| working-directory: ${{ github.workspace }}/csharp | |
| test_macos: | |
| name: MacOS | |
| runs-on: macos-15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| # C/C++ | |
| - name: Build C/C++ | |
| run: | | |
| brew update | |
| brew reinstall cmake | |
| cmake -B build_artifacts -D CMAKE_BUILD_TYPE=RelWithDebInfo -D USEARCH_BUILD_TEST_CPP=1 -D USEARCH_BUILD_TEST_C=1 -D USEARCH_BUILD_LIB_C=1 -D USEARCH_BUILD_SQLITE=1 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| - name: Test C++ | |
| run: build_artifacts/test_cpp | |
| - name: Test C | |
| run: build_artifacts/test_c | |
| # JavaScript | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Install dependencies | |
| run: npm ci --skip-scripts | |
| - name: Build JavaScript | |
| run: npm run build-js | |
| - name: Test JavaScript | |
| run: npm test | |
| # Python | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Build Python | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pytest pytest-repeat numpy | |
| python -m pip install . | |
| env: | |
| CXX: clang++ | |
| CC: clang++ # Override the default compiler | |
| - name: Test Python | |
| run: pytest | |
| # ObjC/Swift | |
| - name: Build ObjC/Swift | |
| run: swift build | |
| - name: Test ObjC/Swift | |
| run: swift test | |
| # Rust | |
| - name: Set up Rust | |
| run: | | |
| rustup update stable | |
| rustup default stable | |
| rustc -vV | |
| - name: Build Rust | |
| run: cargo build | |
| - name: Test Rust | |
| run: cargo test | |
| # C# | |
| - name: Setup .NET ${{ env.DOTNET_VERSION }} | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Test .NET | |
| run: | | |
| mkdir -p "${{ github.workspace }}/csharp/lib/runtimes/osx-arm64/native" | |
| cp "${{ github.workspace }}/build_artifacts/libusearch_c.dylib" "${{ github.workspace }}/csharp/lib/runtimes/osx-arm64/native" | |
| dotnet test -c Debug --logger "console;verbosity=detailed" --filter "FullyQualifiedName!=Cloud.Unum.USearch.Tests.UsearchIndexTests.PersistAndRestore" | |
| shell: bash | |
| working-directory: ${{ github.workspace }}/csharp | |
| env: | |
| DYLD_PRINT_LIBRARIES: 1 | |
| test_windows_x86: | |
| name: Windows (x86) | |
| runs-on: windows-2022 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| # C/C++ | |
| - name: Build C/C++ | |
| run: | | |
| choco install cmake | |
| cmake -B build_artifacts -D CMAKE_BUILD_TYPE=RelWithDebInfo -D USEARCH_BUILD_TEST_CPP=1 -D USEARCH_BUILD_TEST_C=1 -D USEARCH_BUILD_LIB_C=1 -D USEARCH_BUILD_SQLITE=0 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| - name: Test C++ | |
| run: .\build_artifacts\test_cpp.exe | |
| - name: Test C | |
| run: .\build_artifacts\test_c.exe | |
| # Python | |
| - name: Set up Python ${{ env.PYTHON_VERSION }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Build Python | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pytest pytest-repeat numpy | |
| python -m pip install . | |
| - name: Test Python | |
| run: pytest | |
| # JavaScript | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Install dependencies | |
| run: npm ci --skip-scripts | |
| - name: Build JavaScript | |
| run: npm run build-js | |
| - name: Test JavaScript | |
| run: npm test | |
| # Rust | |
| - name: Set up Rust | |
| run: | | |
| rustup update stable | |
| rustup default stable | |
| rustc -vV | |
| - name: Build Rust | |
| run: cargo build | |
| - name: Test Rust | |
| run: cargo test | |
| # C# | |
| - name: Setup .NET ${{ env.DOTNET_VERSION }} | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Test .NET | |
| run: | | |
| mkdir -p "${{ github.workspace }}\csharp\lib\runtimes\win-x64\native" | |
| cp "${{ github.workspace }}\build_artifacts\libusearch_c.dll" "${{ github.workspace }}\csharp\lib\runtimes\win-x64\native" | |
| dotnet test -c Debug --logger "console;verbosity=detailed" | |
| shell: bash | |
| working-directory: ${{ github.workspace }}/csharp | |
| test_windows_arm: | |
| name: Windows (Arm) | |
| runs-on: windows-2022 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| - name: Setup MSVC for ARM64 | |
| uses: microsoft/setup-msbuild@v2 | |
| # C/C++ | |
| - name: Build C/C++ (ARM64) | |
| run: | | |
| choco install cmake | |
| cmake -G "Visual Studio 17 2022" -A ARM64 -B build_artifacts -D CMAKE_BUILD_TYPE=RelWithDebInfo -D USEARCH_BUILD_LIB_C=1 -D USEARCH_BUILD_SQLITE=0 -D USEARCH_BUILD_TEST_CPP=0 -D USEARCH_BUILD_TEST_C=0 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| - name: Verify ARM64 build artifacts | |
| run: | | |
| if (!(Test-Path "build_artifacts\libusearch_c.dll")) { exit 1 } | |
| Write-Host "ARM64 DLL built successfully" | |
| build_docker: | |
| name: Docker | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| - name: Build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| load: true | |
| push: false | |
| build_wheels: | |
| name: Build Python Wheels | |
| runs-on: ${{ matrix.os }} | |
| needs: | |
| [ | |
| test_ubuntu_gcc, | |
| test_ubuntu_clang, | |
| test_macos, | |
| test_windows_x86, | |
| test_windows_arm, | |
| ] | |
| strategy: | |
| matrix: | |
| os: [ubuntu-24.04, macos-14, windows-2022] | |
| python-version: ['38', '39', '310', '311', '312', '313', '313t'] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: 3.x | |
| # We only need QEMU for Linux builds | |
| - name: Setup QEMU | |
| if: matrix.os == 'ubuntu-24.04' | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Install cibuildwheel | |
| run: python -m pip install cibuildwheel | |
| - name: Build wheels | |
| run: cibuildwheel --output-dir wheelhouse | |
| env: | |
| CIBW_BUILD: cp${{ matrix.python-version }}-* | |
| CIBW_ENABLE: cpython-freethreading # No-GIL 3.13t builds | |
| test_ubuntu_cross_compilation: | |
| name: Cross Compilation | |
| runs-on: ubuntu-22.04 | |
| env: | |
| CC: clang | |
| CXX: clang++ | |
| AR: llvm-ar | |
| NM: llvm-nm | |
| RANLIB: llvm-ranlib | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| target: x86_64-linux-gnu | |
| - arch: arm64 | |
| target: aarch64-linux-gnu | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| # C/C++ | |
| # We need to install the cross-compilation toolchain for ARM64 and ARMHF | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y clang lld make crossbuild-essential-arm64 crossbuild-essential-armhf libjemalloc-dev | |
| - name: Build C/C++ | |
| run: | | |
| cmake -B build_artifacts \ | |
| -D CMAKE_BUILD_TYPE=RelWithDebInfo \ | |
| -D CMAKE_EXPORT_COMPILE_COMMANDS=1 \ | |
| -D CMAKE_C_COMPILER_TARGET=${{ matrix.target }} \ | |
| -D CMAKE_CXX_COMPILER_TARGET=${{ matrix.target }} \ | |
| -D CMAKE_SYSTEM_NAME=Linux \ | |
| -D CMAKE_SYSTEM_PROCESSOR=${{ matrix.arch }} \ | |
| -D USEARCH_BUILD_LIB_C=1 \ | |
| -D USEARCH_BUILD_SQLITE=1 \ | |
| -D USEARCH_BUILD_TEST_CPP=0 \ | |
| -D USEARCH_BUILD_BENCH_CPP=0 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| # We can't run the produced builds, but we can make sure they exist | |
| - name: Test artifacts presence | |
| run: | | |
| test -e build_artifacts/libusearch_c.so | |
| test -e build_artifacts/libusearch_sqlite.so | |
| test_android: | |
| name: Android | |
| runs-on: ubuntu-22.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - processor: armv7a | |
| abi: armeabi-v7a | |
| target: armv7-linux-androideabi | |
| arch: arm32 | |
| - processor: aarch64 | |
| abi: arm64-v8a | |
| target: aarch64-linux-android | |
| arch: arm64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Pull Git submodules | |
| run: git submodule update --init --recursive | |
| - name: Install NDK | |
| run: | | |
| ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --install "ndk;${{ env.ANDROID_NDK_VERSION }}" | |
| - name: Build C/C++ | |
| run: | | |
| cmake -B build_artifacts \ | |
| -D CMAKE_BUILD_TYPE=RelWithDebInfo \ | |
| -D CMAKE_EXPORT_COMPILE_COMMANDS=1 \ | |
| -D CMAKE_TOOLCHAIN_FILE=${ANDROID_HOME}/ndk/${{ env.ANDROID_NDK_VERSION }}/build/cmake/android.toolchain.cmake \ | |
| -D CMAKE_ANDROID_STL_TYPE=c++_static \ | |
| -D ANDROID_PLATFORM=${{ env.ANDROID_SDK_VERSION }} \ | |
| -D ANDROID_ABI=${{ matrix.abi }} \ | |
| -D USEARCH_BUILD_LIB_C=1 \ | |
| -D USEARCH_BUILD_TEST_CPP=0 \ | |
| -D USEARCH_BUILD_BENCH_CPP=0 | |
| cmake --build build_artifacts --config RelWithDebInfo | |
| # We can't run the produced builds, but we can make sure they exist | |
| - name: Test artifacts presence | |
| run: test -e build_artifacts/libusearch_c.so | |
| # Rust | |
| - name: Set up Rust | |
| run: | | |
| rustup update stable | |
| rustup default stable | |
| rustup target add ${{ matrix.target }} | |
| rustc -vV | |
| - name: Set up Rust Env | |
| run: | | |
| TOOLCHAIN=${ANDROID_HOME}/ndk/${{ env.ANDROID_NDK_VERSION }}/toolchains/llvm/prebuilt/linux-x86_64/bin/ | |
| NDK_CLANG=$(find ${TOOLCHAIN} -name "${{ matrix.processor }}*${{ env.ANDROID_SDK_VERSION }}-clang") | |
| echo "CC_${{ matrix.target }}=${NDK_CLANG}" >> ${GITHUB_ENV} | |
| echo "CXX_${{ matrix.target }}=${NDK_CLANG}++" >> ${GITHUB_ENV} | |
| echo "AR_${{ matrix.target }}=${TOOLCHAIN}/llvm-ar" >> ${GITHUB_ENV} | |
| echo "CARGO_${{ matrix.target }}=${NDK_CLANG}" >> ${GITHUB_ENV} | |
| echo "CARGO_${{ matrix.target }}=${TOOLCHAIN}/llvm-ar" >> ${GITHUB_ENV} | |
| - name: Build Rust | |
| run: cargo build --target ${{ matrix.target }} | |
| # Java | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: ${{ env.JAVA_VERSION }} | |
| distribution: 'adopt' | |
| # We skip native compilation with Gradle and focus just on the Java part, | |
| # assuming the we won't be able to tun the tests without emulation | |
| - name: Check Java formatting | |
| run: gradle spotlessCheck | |
| - name: Test Java bindings with Android library | |
| run: | | |
| mkdir -p build/libs/usearch/shared/ | |
| cp build_artifacts/libusearch_c.so build/libs/usearch/shared/ | |
| javac -cp . java/cloud/unum/usearch/*.java | |
| echo "Java compilation successful with Android NDK library" | |
| - name: Package Android libraries for release | |
| run: | | |
| version=$(cat VERSION) | |
| zip -r usearch_android_${{ matrix.arch }}_${version}.zip build_artifacts/libusearch_c.so c/usearch.h | |
| - name: Upload Android libraries | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-${{ matrix.abi }}-libraries | |
| path: usearch_android_*.zip |