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
2 changes: 1 addition & 1 deletion c/src/neighbors/hnsw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ extern "C" cuvsError_t cuvsHnswIndexParamsCreate(cuvsHnswIndexParams_t* params)
{
return cuvs::core::translate_exceptions([=] {
*params = new cuvsHnswIndexParams{
.hierarchy = cuvsHnswHierarchy::NONE, .ef_construction = 200, .num_threads = 0};
.hierarchy = cuvsHnswHierarchy::GPU, .ef_construction = 200, .num_threads = 0};
});
}

Expand Down
2 changes: 2 additions & 0 deletions c/tests/neighbors/ann_hnsw_c.cu
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ TEST(CagraHnswC, BuildSearch)
hnsw_index->dtype = index->dtype;
cuvsHnswIndexParams_t hnsw_params;
cuvsHnswIndexParamsCreate(&hnsw_params);
// Use NONE hierarchy since cuvsCagraSerializeToHnswlib creates a base-layer-only index
hnsw_params->hierarchy = NONE;
cuvsHnswDeserialize(res, hnsw_params, "/tmp/cagra_hnswlib.index", 2, L2Expanded, hnsw_index);

// search index
Expand Down
2 changes: 1 addition & 1 deletion cpp/include/cuvs/neighbors/hnsw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ enum class HnswHierarchy {

struct index_params : cuvs::neighbors::index_params {
/** Hierarchy build type for HNSW index when converting from CAGRA index */
HnswHierarchy hierarchy = HnswHierarchy::NONE;
HnswHierarchy hierarchy = HnswHierarchy::GPU;
/** Size of the candidate list during hierarchy construction when hierarchy is `CPU`*/
int ef_construction = 200;
/** Number of host threads to use to construct hierarchy when hierarchy is `CPU` or `GPU`.
Expand Down
3 changes: 2 additions & 1 deletion examples/cpp/src/cagra_hnsw_ace_example.cu
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ void cagra_build_search_ace(raft::device_resources const& dev_resources,
// descriptor For in-memory indices: creates HNSW index in memory
std::cout << "Converting CAGRA index to HNSW" << std::endl;
hnsw::index_params hnsw_params;
auto hnsw_index = hnsw::from_cagra(dev_resources, hnsw_params, index);
hnsw_params.hierarchy = hnsw::HnswHierarchy::GPU; // Offload hierarchy construction to GPU
auto hnsw_index = hnsw::from_cagra(dev_resources, hnsw_params, index);

// HNSW search requires host matrices
auto queries_host = raft::make_host_matrix<float, int64_t>(n_queries, queries.extent(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ public enum CuvsHnswHierarchy {
/**
* Full hierarchy is built using the CPU
*/
CPU(1);
CPU(1),

/**
* Full hierarchy is built using the GPU
*/
GPU(2);

/**
* The value for the enum choice.
Expand All @@ -39,7 +44,16 @@ private CuvsHnswHierarchy(int value) {
}
};

private CuvsHnswHierarchy hierarchy = CuvsHnswHierarchy.NONE;
/**
* Alias for {@link CuvsHnswHierarchy} for convenience.
*/
public static class HnswHierarchy {
public static final CuvsHnswHierarchy NONE = CuvsHnswHierarchy.NONE;
public static final CuvsHnswHierarchy CPU = CuvsHnswHierarchy.CPU;
public static final CuvsHnswHierarchy GPU = CuvsHnswHierarchy.GPU;
}

private CuvsHnswHierarchy hierarchy = CuvsHnswHierarchy.GPU;
private int efConstruction = 200;
private int numThreads = 2;
private int vectorDimension;
Expand Down Expand Up @@ -102,7 +116,7 @@ public String toString() {
*/
public static class Builder {

private CuvsHnswHierarchy hierarchy = CuvsHnswHierarchy.NONE;
private CuvsHnswHierarchy hierarchy = CuvsHnswHierarchy.GPU;
private int efConstruction = 200;
private int numThreads = 2;
private int vectorDimension;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ private IndexReference deserialize(InputStream inputStream) throws Throwable {
*/
private CloseableHandle segmentFromIndexParams(HnswIndexParams params) {
var hnswParams = createHnswIndexParams();
cuvsHnswIndexParams.hierarchy(hnswParams.handle(), params.getHierarchy().value);
cuvsHnswIndexParams.ef_construction(hnswParams.handle(), params.getEfConstruction());
cuvsHnswIndexParams.num_threads(hnswParams.handle(), params.getNumThreads());
return hnswParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.carrotsearch.randomizedtesting.RandomizedRunner;
import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo;
import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType;
import com.nvidia.cuvs.HnswIndexParams.HnswHierarchy;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
Expand Down Expand Up @@ -186,7 +187,7 @@ public void testAceDiskBasedBuild() throws Throwable {
// Convert CAGRA index to HNSW using fromCagra
// This automatically handles disk-based indices
HnswIndexParams hnswIndexParams =
new HnswIndexParams.Builder().withVectorDimension(2).build();
new HnswIndexParams.Builder().withVectorDimension(2).withHierarchy(HnswHierarchy.GPU).build();

try (var hnswIndexSerialized = HnswIndex.fromCagra(hnswIndexParams, index)) {
var hnswIndexSerializedPath = buildDir.resolve("hnsw_index.bin");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo;
import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType;
import com.nvidia.cuvs.HnswIndexParams.HnswHierarchy;
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -70,8 +71,9 @@ private static void indexAndQueryOnce(
index.serializeToHNSW(outputStream);
}

// Use NONE hierarchy since serializeToHNSW creates a base-layer-only index
HnswIndexParams hnswIndexParams =
new HnswIndexParams.Builder().withVectorDimension(2).build();
new HnswIndexParams.Builder().withVectorDimension(2).withHierarchy(HnswHierarchy.NONE).build();
try (var inputStreamHNSW = Files.newInputStream(hnswIndexPath)) {
var hnswIndex =
HnswIndex.newBuilder(resources)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.carrotsearch.randomizedtesting.RandomizedRunner;
import com.nvidia.cuvs.CagraIndexParams.CagraGraphBuildAlgo;
import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType;
import com.nvidia.cuvs.HnswIndexParams.HnswHierarchy;
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -129,8 +130,9 @@ private void tmpResultsTopKWithRandomValues(boolean useNativeMemoryDataset) thro
index.serializeToHNSW(outputStream); // fails here
}

// Use NONE hierarchy since serializeToHNSW creates a base-layer-only index
HnswIndexParams hnswIndexParams =
new HnswIndexParams.Builder().withVectorDimension(dimensions).build();
new HnswIndexParams.Builder().withVectorDimension(dimensions).withHierarchy(HnswHierarchy.NONE).build();

try (var inputStreamHNSW = Files.newInputStream(hnswIndexPath)) {
HnswIndex hnswIndex =
Expand Down
8 changes: 4 additions & 4 deletions python/cuvs/cuvs/neighbors/hnsw/hnsw.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ cdef class IndexParams:

Parameters
----------
hierarchy : string, default = "none" (optional)
The hierarchy of the HNSW index. Valid values are ["none", "cpu"].
hierarchy : string, default = "gpu" (optional)
The hierarchy of the HNSW index. Valid values are ["none", "cpu", "gpu"].
- "none": No hierarchy is built.
- "cpu": Hierarchy is built using CPU.
- "gpu": Hierarchy is built using GPU.
Expand All @@ -61,7 +61,7 @@ cdef class IndexParams:
check_cuvs(cuvsHnswIndexParamsDestroy(self.params))

def __init__(self, *,
hierarchy="none",
hierarchy="gpu",
ef_construction=200,
num_threads=0):
if hierarchy == "none":
Expand All @@ -72,7 +72,7 @@ cdef class IndexParams:
self.params.hierarchy = cuvsHnswHierarchy.GPU
else:
raise ValueError("Invalid hierarchy type."
" Valid values are 'none' and 'cpu'.")
" Valid values are 'none', 'cpu', and 'gpu'.")
self.params.ef_construction = ef_construction
self.params.num_threads = num_threads

Expand Down
Loading