Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go API - [WIP] #212

Merged
merged 78 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
7961798
wip
ajit283 Jun 14, 2024
764dc1e
cleanup
ajit283 Jun 14, 2024
b0fd0b1
Added support for different data types and device allocation in NewMa…
ajit283 Jun 19, 2024
b47cf5b
bruteforce works
ajit283 Jun 19, 2024
1ec0c8c
refactor
ajit283 Jun 19, 2024
d5c0dc3
improve resources
ajit283 Jun 19, 2024
cc6319e
add ivf_flat, modules not working yet
ajit283 Jun 25, 2024
01af7c9
sync
ajit283 Jun 29, 2024
ed9bf47
cleanup
ajit283 Jul 2, 2024
4e79d8e
Merge branch 'rapidsai:branch-24.08' into go
ajit283 Jul 2, 2024
d278abc
rename
ajit283 Jul 2, 2024
b91721d
sync
ajit283 Jul 2, 2024
6b90861
.
ajit283 Jul 2, 2024
773fd94
Merge branch 'rapidsai:branch-24.08' into go
ajit283 Jul 3, 2024
7cbc1f9
sync
ajit283 Jul 10, 2024
46ec2f7
ivf_pq + cagra
ajit283 Jul 10, 2024
9dcffbd
Merge branch 'branch-24.08' into go
ajit283 Jul 10, 2024
f82216c
CI/CD attempt
ajit283 Jul 10, 2024
486d40a
add distance
ajit283 Jul 10, 2024
6f5c5a6
replace string arguments
ajit283 Jul 21, 2024
bfdf3be
make library easier to use
ajit283 Jul 21, 2024
de3cea0
graph degrees
ajit283 Jul 23, 2024
57e8dc0
fix top-level tests
ajit283 Jul 24, 2024
ab173dc
Merge branch 'branch-24.08' into go
cjnolet Jul 24, 2024
2d5fb95
renaming
ajit283 Aug 1, 2024
505d8dc
Merge branch 'go' of https://github.com/ajit283/cuvs into go
ajit283 Aug 1, 2024
c3360ee
change package name
ajit283 Aug 5, 2024
e261c8a
package name change (rapidsai)
ajit283 Aug 5, 2024
a4890ed
dlpack add expand
ajit283 Aug 7, 2024
f2bac2d
cagra: expose some types
ajit283 Aug 11, 2024
a684b01
Merge branch 'branch-24.08' into go
ajit283 Aug 11, 2024
7d45e24
extend
ajit283 Aug 22, 2024
a7084c2
add extend with return (wip, test missing)
ajit283 Aug 22, 2024
3af1b73
Merge branch 'branch-24.10' into go
cjnolet Aug 22, 2024
44d9e58
fix brute_force, add pool
ajit283 Aug 26, 2024
9447f63
update, add search_width
ajit283 Oct 14, 2024
04b6532
add memory resource test
ajit283 Oct 16, 2024
a082f67
thread_local fix
ajit283 Oct 17, 2024
a84e764
change pool memory
ajit283 Oct 28, 2024
853d538
Merge branch 'branch-24.10' into go
cjnolet Nov 4, 2024
4021229
Merge branch 'branch-24.12' into go
cjnolet Nov 4, 2024
6dd2044
simplify memory_resource
ajit283 Nov 5, 2024
3e33692
Merge branch 'go' of https://github.com/ajit283/cuvs into go
ajit283 Nov 5, 2024
b1a0476
Merge branch 'branch-24.12' into go
cjnolet Nov 15, 2024
dddb165
Merge branch 'branch-24.12' into go
ajit283 Nov 21, 2024
e05782a
cleanup top-level packages
ajit283 Nov 21, 2024
a315632
cleanup neighbors
ajit283 Nov 22, 2024
3c97864
.
ajit283 Nov 22, 2024
bd2dd76
build
ajit283 Nov 22, 2024
bd76cf8
ci
ajit283 Nov 22, 2024
1e5a756
ci
ajit283 Nov 22, 2024
927f2be
fix pointer pinning issues
ajit283 Nov 26, 2024
f7fac35
add docstrings
ajit283 Dec 4, 2024
d814e37
Merge branch 'branch-24.12' into go
ajit283 Dec 4, 2024
2708bc0
Merge branch 'branch-25.02' into go
ajit283 Dec 10, 2024
e634821
filter improv. + tests
ajit283 Dec 27, 2024
8c9105a
add doc. for cagra filter
ajit283 Jan 4, 2025
4a80cf7
Merge branch 'branch-25.02' into go
cjnolet Jan 8, 2025
f5b8e72
fix dependencies.yml
ajit283 Jan 10, 2025
7b93510
fix style checker
benfred Jan 15, 2025
f738da4
Merge branch 'branch-25.02' into go
benfred Jan 15, 2025
51b5747
update build branch
ajit283 Jan 17, 2025
ff36031
Merge branch 'branch-25.02' into go
ajit283 Jan 17, 2025
3a45833
Merge branch 'branch-25.02' into go
ajit283 Jan 23, 2025
78e9b1a
update build
ajit283 Jan 24, 2025
3287f7c
Merge branch 'branch-25.02' into go
cjnolet Jan 25, 2025
e2b6104
Merge branch 'branch-25.02' into go
cjnolet Jan 25, 2025
a656870
Merge branch 'branch-25.02' into go
cjnolet Jan 29, 2025
b70d6e2
Merge branch 'branch-25.02' into go
benfred Feb 3, 2025
ef2187c
fix merge
benfred Feb 3, 2025
23e67f7
fix merge
benfred Feb 3, 2025
aa38afc
add dlpack to go conda env
benfred Feb 4, 2025
35bc1f1
Merge branch 'branch-25.02' into go
benfred Feb 4, 2025
dba8cfc
use rapids version in setting up go conda env
benfred Feb 5, 2025
5d97c8e
Merge branch 'go' of https://github.com/ajit283/cuvs into go
benfred Feb 5, 2025
bf50e3f
Merge branch 'branch-25.02' into go
cjnolet Feb 5, 2025
a93d286
fix extend
ajit283 Feb 5, 2025
20f41b9
adjust ld_library_path
ajit283 Feb 5, 2025
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: 13 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ jobs:
node_type: "gpu-v100-latest-1"
run_script: "ci/build_rust.sh"
sha: ${{ inputs.sha }}
go-build:
needs: cpp-build
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
with:
build_type: ${{ inputs.build_type || 'branch' }}
branch: ${{ inputs.branch }}
arch: "amd64"
date: ${{ inputs.date }}
container_image: "rapidsai/ci-conda:latest"
node_type: "gpu-v100-latest-1"
run_script: "ci/build_go.sh"
sha: ${{ inputs.sha }}
python-build:
needs: [cpp-build]
secrets: inherit
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- conda-python-tests
- docs-build
- rust-build
- go-build
- wheel-build-libcuvs
- wheel-build-cuvs
- wheel-tests-cuvs
Expand Down Expand Up @@ -58,13 +59,15 @@ jobs:
- '!notebooks/**'
- '!python/**'
- '!rust/**'
- '!go/**'
- '!thirdparty/LICENSES/**'
test_notebooks:
- '**'
- '!.devcontainer/**'
- '!.pre-commit-config.yaml'
- '!README.md'
- '!rust/**'
- '!go/**'
- '!thirdparty/LICENSES/**'
test_python:
- '**'
Expand All @@ -75,6 +78,7 @@ jobs:
- '!img/**'
- '!notebooks/**'
- '!rust/**'
- '!go/**'
- '!thirdparty/LICENSES/**'
checks:
secrets: inherit
Expand Down Expand Up @@ -136,6 +140,16 @@ jobs:
arch: "amd64"
container_image: "rapidsai/ci-conda:latest"
run_script: "ci/build_rust.sh"
go-build:
needs: conda-cpp-build
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
with:
build_type: pull-request
node_type: "gpu-v100-latest-1"
Copy link
Contributor

@bdice bdice Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not able to give a full CI/packaging review at the moment, but wanted to mention this.

Build jobs must be CPU only unless the build is less than 3-4 minutes. Otherwise please create binary artifacts from the CPU build, upload them, and use them for GPU testing in a separate job. We are too lax about this already and the GPU CI load is going up with all the Rust/Java/Go language bindings being added to cuVS.

It appears that the Go jobs pass in ~6 minutes but if that changes in the future we may need to work on this.

arch: "amd64"
container_image: "rapidsai/ci-conda:latest"
run_script: "ci/build_go.sh"
wheel-build-libcuvs:
needs: checks
secrets: inherit
Expand Down
10 changes: 9 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ ARGS=$*
# scripts, and that this script resides in the repo dir!
REPODIR=$(cd $(dirname $0); pwd)

VALIDARGS="clean libcuvs python rust java docs tests bench-ann examples --uninstall -v -g -n --compile-static-lib --allgpuarch --no-mg --no-cpu --cpu-only --no-shared-libs --no-nvtx --show_depr_warn --incl-cache-stats --time -h"
VALIDARGS="clean libcuvs python rust go java docs tests bench-ann examples --uninstall -v -g -n --compile-static-lib --allgpuarch --no-mg --no-cpu --cpu-only --no-shared-libs --no-nvtx --show_depr_warn --incl-cache-stats --time -h"
HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<tool>] [--limit-tests=<targets>] [--limit-bench-ann=<targets>] [--build-metrics=<filename>]
where <target> is:
clean - remove all existing build artifacts and configuration (start over)
libcuvs - build the cuvs C++ code only. Also builds the C-wrapper library
around the C++ code.
python - build the cuvs Python package
rust - build the cuvs Rust bindings
go - build the cuvs Go bindings
java - build the cuvs Java bindings
docs - build the documentation
tests - build the tests
Expand Down Expand Up @@ -447,6 +448,13 @@ if (( ${NUMARGS} == 0 )) || hasArg rust; then
cargo test
fi

# Build the cuvs Go bindings
if (( ${NUMARGS} == 0 )) || hasArg go; then
cd ${REPODIR}/go
go build ./...
go test ./...
fi

# Build the cuvs Java bindings
if (( ${NUMARGS} == 0 )) || hasArg java; then
if ! hasArg libcuvs; then
Expand Down
40 changes: 40 additions & 0 deletions ci/build_go.sh
Copy link
Contributor Author

@ajit283 ajit283 Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benfred do you know how to install/find dlpack?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rust and java bindings both install through cmake - but it might be easier to add to the dependencies.yaml to add to the conda environment. I tried that out in the last commit - hopefully this will resolve

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we got past the dlpack error - but now I'm seeing

cagra/cagra.go:109:11: could not determine kind of name for C.BITSET
cagra/cagra.go:104:11: could not determine kind of name for C.NO_FILTER
cagra/cagra.go:60:39: could not determine kind of name for C.cuvsCagraExtend
cagra/cagra.go:91:13: could not determine kind of name for C.cuvsFilter

Copy link
Contributor Author

@ajit283 ajit283 Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like it installs the previous release from the conda channels, where some features aren't available yet which it relies on. Is there any way to do this through conda or would cmake be better? @benfred

Copy link
Member

@benfred benfred Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm - it should be grabbing the built cpp artifacts from S3 from the conda cpp build, but it looks like its installing 24.12 libcuvs instead:

2025-02-04T04:56:30.6535505Z   + libraft               24.12.00  cuda12_241211_geaf9cc72_0        rapidsai          2MB
2025-02-04T04:56:30.6537604Z   + libcuvs               24.12.00  cuda12_241211_g0ce6a03_0         rapidsai        595MB

(from the build-go GHA log ).

fwiw I just checked the rust build, which is set up very similar - and seems to be pulling the right libcuvs package.

2025-02-04T04:56:49.5413345Z   + libcuvs               25.02.00a184  cuda12_250204_g35bc1f1_184  /tmp/cpp_channel     864MB

I'm not quite sure why this is going wrong here - @bdice or @vyasr do you have any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the difference in build scripts between build_go.sh and build_rust.sh - and I think it might just be that the rust build is specifying the rapids version.

$  diff ci/build_rust.sh ci/build_go.sh
13c13
<   --file-key rust \
---
>   --file-key go \
16c16
< rapids-mamba-retry env create --yes -f env.yaml -n rust
---
> rapids-mamba-retry env create --yes -f env.yaml -n go
21c21
< conda activate rust
---
> conda activate go
26,29c26,28
< # we need to set up LIBCLANG_PATH to allow rust bindgen to work,
< # grab it from the conda env
< export LIBCLANG_PATH=$(dirname $(find /opt/conda -name libclang.so | head -n 1))
< echo "LIBCLANG_PATH=$LIBCLANG_PATH"
---
> export CGO_CFLAGS="-I${CONDA_PREFIX}/include"
> export CGO_LDFLAGS="-L${CONDA_PREFIX}/lib -lcudart -lcuvs -lcuvs_c"
> export CC=clang
37,38c36,38
<   "libcuvs=${RAPIDS_VERSION}" \
<   "libraft=${RAPIDS_VERSION}"
---
>   libcuvs  \
>   libraft  \
>   cuvs
40c40
< bash ./build.sh rust
---
> bash ./build.sh go

going to try updating the go build to match

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash
# Copyright (c) 2024, NVIDIA CORPORATION.

set -euo pipefail

rapids-logger "Create test conda environment"
. /opt/conda/etc/profile.d/conda.sh

RAPIDS_VERSION="$(rapids-version)"

rapids-dependency-file-generator \
--output conda \
--file-key go \
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you know how I could add this file key to rapids-dependency-file-generator?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @bdice @vyasr @AyodeAwe any suggestions here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a key under files: in dependencies.yaml, then add dependency lists with the conda packages you need. Here’s the rust one for comparison:

rust:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More explanation in the README here: https://github.com/rapidsai/dependency-file-generator

--matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" | tee env.yaml

rapids-mamba-retry env create --yes -f env.yaml -n go

# seeing failures on activating the environment here on unbound locals
# apply workaround from https://github.com/conda/conda/issues/8186#issuecomment-532874667
set +eu
conda activate go
set -eu

rapids-print-env

export CGO_CFLAGS="-I${CONDA_PREFIX}/include"
export CGO_LDFLAGS="-L${CONDA_PREFIX}/lib -lcudart -lcuvs -lcuvs_c"
export CC=clang

rapids-logger "Downloading artifacts from previous jobs"
CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp)

# installing libcuvs/libraft will speed up the rust build substantially
rapids-mamba-retry install \
--channel "${CPP_CHANNEL}" \
libcuvs \
libraft \
cuvs

bash ./build.sh go
1 change: 1 addition & 0 deletions conda/environments/all_cuda-118_arch-aarch64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies:
- dlpack>=0.8,<1.0
- doxygen>=1.8.20
- gcc_linux-aarch64=11.*
- go
- graphviz
- ipython
- libclang==16.0.6
Expand Down
1 change: 1 addition & 0 deletions conda/environments/all_cuda-118_arch-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies:
- dlpack>=0.8,<1.0
- doxygen>=1.8.20
- gcc_linux-64=11.*
- go
- graphviz
- ipython
- libclang==16.0.6
Expand Down
1 change: 1 addition & 0 deletions conda/environments/all_cuda-128_arch-aarch64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies:
- dlpack>=0.8,<1.0
- doxygen>=1.8.20
- gcc_linux-aarch64=13.*
- go
- graphviz
- ipython
- libclang==16.0.6
Expand Down
1 change: 1 addition & 0 deletions conda/environments/all_cuda-128_arch-x86_64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies:
- dlpack>=0.8,<1.0
- doxygen>=1.8.20
- gcc_linux-64=13.*
- go
- graphviz
- ipython
- libclang==16.0.6
Expand Down
14 changes: 14 additions & 0 deletions dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ files:
- rapids_build
- run_py_cuvs
- rust
- go
- test_libcuvs
- test_python_common
- test_py_cuvs
Expand Down Expand Up @@ -81,6 +82,14 @@ files:
- cuda_version
- rapids_build
- rust
go:
output: none
includes:
- clang
- cuda
- cuda_version
- rapids_build
- go
py_build_libcuvs:
output: pyproject
pyproject_dir: python/libcuvs
Expand Down Expand Up @@ -470,6 +479,11 @@ dependencies:
packages:
- make
- rust
go:
common:
- output_types: [conda]
packages:
- go
build_wheels:
common:
- output_types: [requirements, pyproject]
Expand Down
83 changes: 83 additions & 0 deletions go/brute_force/brute_force.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package brute_force

// #include <cuvs/neighbors/brute_force.h>
import "C"

import (
"errors"
"unsafe"

cuvs "github.com/rapidsai/cuvs/go"
)

// Brute Force KNN Index
type BruteForceIndex struct {
index C.cuvsBruteForceIndex_t
trained bool
}

// Creates a new empty Brute Force KNN Index
func CreateIndex() (*BruteForceIndex, error) {
var index C.cuvsBruteForceIndex_t

err := cuvs.CheckCuvs(cuvs.CuvsError(C.cuvsBruteForceIndexCreate(&index)))
if err != nil {
return nil, err
}

return &BruteForceIndex{index: index, trained: false}, nil
}

// Destroys the Brute Force KNN Index
func (index *BruteForceIndex) Close() error {
err := cuvs.CheckCuvs(cuvs.CuvsError(C.cuvsBruteForceIndexDestroy(index.index)))
if err != nil {
return err
}
return nil
}

// Builds a new Brute Force KNN Index from the dataset for efficient search.
//
// # Arguments
//
// * `Resources` - Resources to use
// * `Dataset` - A row-major matrix on either the host or device to index
// * `metric` - Distance type to use for building the index
// * `metric_arg` - Value of `p` for Minkowski distances - set to 2.0 if not applicable
func BuildIndex[T any](Resources cuvs.Resource, Dataset *cuvs.Tensor[T], metric cuvs.Distance, metric_arg float32, index *BruteForceIndex) error {
CMetric, exists := cuvs.CDistances[metric]

if !exists {
return errors.New("cuvs: invalid distance metric")
}

err := cuvs.CheckCuvs(cuvs.CuvsError(C.cuvsBruteForceBuild(C.cuvsResources_t(Resources.Resource), (*C.DLManagedTensor)(unsafe.Pointer(Dataset.C_tensor)), C.cuvsDistanceType(CMetric), C.float(metric_arg), index.index)))
if err != nil {
return err
}
index.trained = true

return nil
}

// Perform a Nearest Neighbors search on the Index
//
// # Arguments
//
// * `Resources` - Resources to use
// * `queries` - Tensor in device memory to query for
// * `neighbors` - Tensor in device memory that receives the indices of the nearest neighbors
// * `distances` - Tensor in device memory that receives the distances of the nearest neighbors
func SearchIndex[T any](resources cuvs.Resource, index BruteForceIndex, queries *cuvs.Tensor[T], neighbors *cuvs.Tensor[int64], distances *cuvs.Tensor[T]) error {
if !index.trained {
return errors.New("index needs to be built before calling search")
}

prefilter := C.cuvsFilter{
addr: 0,
_type: C.NO_FILTER,
}

return cuvs.CheckCuvs(cuvs.CuvsError(C.cuvsBruteForceSearch(C.ulong(resources.Resource), index.index, (*C.DLManagedTensor)(unsafe.Pointer(queries.C_tensor)), (*C.DLManagedTensor)(unsafe.Pointer(neighbors.C_tensor)), (*C.DLManagedTensor)(unsafe.Pointer(distances.C_tensor)), prefilter)))
}
Loading
Loading