Skip to content

Commit 31b5bd8

Browse files
CascadingRadiumLikith101Copilot
authored
MB-59670: GPU-Accelerated Vector Search (#2236)
- Add a flag: `gpu` to indicate whether the vector field must use GPUs for indexing/searching. - Github project: https://github.com/orgs/blevesearch/projects/4/ --------- Co-authored-by: Likith B <likith.b@couchbase.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 936ca1f commit 31b5bd8

7 files changed

Lines changed: 120 additions & 9 deletions

File tree

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ go 1.25.0
55
require (
66
github.com/RoaringBitmap/roaring/v2 v2.14.5
77
github.com/bits-and-blooms/bitset v1.24.2
8-
github.com/blevesearch/bleve_index_api v1.3.9
8+
github.com/blevesearch/bleve_index_api v1.3.10
99
github.com/blevesearch/geo v0.2.5
1010
github.com/blevesearch/go-faiss v1.0.34
1111
github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475
1212
github.com/blevesearch/go-porterstemmer v1.0.3
1313
github.com/blevesearch/goleveldb v1.0.1
1414
github.com/blevesearch/gtreap v0.1.1
15-
github.com/blevesearch/scorch_segment_api/v2 v2.4.5
15+
github.com/blevesearch/scorch_segment_api/v2 v2.4.6
1616
github.com/blevesearch/segment v0.9.1
1717
github.com/blevesearch/snowball v0.6.1
1818
github.com/blevesearch/snowballstem v0.9.0
@@ -25,7 +25,7 @@ require (
2525
github.com/blevesearch/zapx/v14 v14.4.3
2626
github.com/blevesearch/zapx/v15 v15.4.3
2727
github.com/blevesearch/zapx/v16 v16.3.4
28-
github.com/blevesearch/zapx/v17 v17.0.10
28+
github.com/blevesearch/zapx/v17 v17.0.11
2929
github.com/couchbase/moss v0.2.0
3030
github.com/spf13/cobra v1.10.2
3131
go.etcd.io/bbolt v1.4.0

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ github.com/RoaringBitmap/roaring/v2 v2.14.5 h1:ckd0o545JqDPeVJDgeFoaM21eBixUnlWf
22
github.com/RoaringBitmap/roaring/v2 v2.14.5/go.mod h1:eq4wdNXxtJIS/oikeCzdX1rBzek7ANzbth041hrU8Q4=
33
github.com/bits-and-blooms/bitset v1.24.2 h1:M7/NzVbsytmtfHbumG+K2bremQPMJuqv1JD3vOaFxp0=
44
github.com/bits-and-blooms/bitset v1.24.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
5-
github.com/blevesearch/bleve_index_api v1.3.9 h1:TLoiBaqcfWGfI1Il0+zzky452uYCPoSMosDSltkCfKs=
6-
github.com/blevesearch/bleve_index_api v1.3.9/go.mod h1:xvd48t5XMeeioWQ5/jZvgLrV98flT2rdvEJ3l/ki4Ko=
5+
github.com/blevesearch/bleve_index_api v1.3.10 h1:a7G+IOMa2xuO6f8vtutbTsqjVLpLuCuH3uoTZHkGiYg=
6+
github.com/blevesearch/bleve_index_api v1.3.10/go.mod h1:xvd48t5XMeeioWQ5/jZvgLrV98flT2rdvEJ3l/ki4Ko=
77
github.com/blevesearch/geo v0.2.5 h1:yJg9FX1oRwLnjXSXF+ECHfXFTF4diF02Ca/qUGVjJhE=
88
github.com/blevesearch/geo v0.2.5/go.mod h1:Jhq7WE2K6mJTx1xS44M2pUO6Io+wjCSHh1+co3YOgH4=
99
github.com/blevesearch/go-faiss v1.0.34 h1:cFE1jRkjJfk7qMMsqXBqGEivbYQz/tjSf5yyoH50xbY=
@@ -19,8 +19,8 @@ github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgY
1919
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
2020
github.com/blevesearch/mmap-go v1.2.0 h1:l33nNKPFcBjJUMwem6sAYJPUzhUCABoK9FxZDGiFNBI=
2121
github.com/blevesearch/mmap-go v1.2.0/go.mod h1:Vd6+20GBhEdwJnU1Xohgt88XCD/CTWcqbCNxkZpyBo0=
22-
github.com/blevesearch/scorch_segment_api/v2 v2.4.5 h1:Q7Bzpyk86xS22TgTd4VQfSvzZAybDEJ90hNOGqyNqlI=
23-
github.com/blevesearch/scorch_segment_api/v2 v2.4.5/go.mod h1:xWYn3EwRM7zBFAPt/J136OugUNzftpYLvPBBx31IpCw=
22+
github.com/blevesearch/scorch_segment_api/v2 v2.4.6 h1:6D0ZarXRbBIIartND0QMhpzH6YR0eDWbRs7k+nS+zd8=
23+
github.com/blevesearch/scorch_segment_api/v2 v2.4.6/go.mod h1:Ry0cjO/wbmjBU0Vxf/+TW6IGcXYCdWMwAicvxUWNNeU=
2424
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
2525
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
2626
github.com/blevesearch/snowball v0.6.1 h1:cDYjn/NCH+wwt2UdehaLpr2e4BwLIjN4V/TdLsL+B5A=
@@ -45,8 +45,8 @@ github.com/blevesearch/zapx/v15 v15.4.3 h1:iJiMJOHrz216jyO6lS0m9RTCEkprUnzvqAI2l
4545
github.com/blevesearch/zapx/v15 v15.4.3/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw=
4646
github.com/blevesearch/zapx/v16 v16.3.4 h1:hDAqA8qusZTNbPEL7//w5P65UZ2de6yhSeUaTbp0Po0=
4747
github.com/blevesearch/zapx/v16 v16.3.4/go.mod h1:zqkPPqs9GS9FzVWzCO3Wf1X044yWAV17+4zb+FTiEHg=
48-
github.com/blevesearch/zapx/v17 v17.0.10 h1:4+J+31dzyGaLljIk7vshKFoRZ0xpxx9UsvqaYvB9CJY=
49-
github.com/blevesearch/zapx/v17 v17.0.10/go.mod h1:0xsOiwLjhQWlyZl7hMeLXrgX5gAY4yvP+oRX5GOTIiw=
48+
github.com/blevesearch/zapx/v17 v17.0.11 h1:3OKEe8NpD4n14GW+GY/op5nh8/x8dmYNwgLdRgvv5go=
49+
github.com/blevesearch/zapx/v17 v17.0.11/go.mod h1:62wlIX0vYZoLoLLKmix4zQvyCevvUt7RLuvcV5D3/N0=
5050
github.com/couchbase/ghistogram v0.1.0 h1:b95QcQTCzjTUocDXp/uMgSNQi8oj1tGwnJ4bODWZnps=
5151
github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k=
5252
github.com/couchbase/moss v0.2.0 h1:VCYrMzFwEryyhRSeI+/b3tRBSeTpi/8gn5Kf6dxqn+o=

index_update.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,9 @@ func compareFieldMapping(original, updated *mapping.FieldMapping) (*index.Update
511511
if original.VectorIndexOptimizedFor != updated.VectorIndexOptimizedFor {
512512
return nil, fmt.Errorf("vectorIndexOptimizedFor cannot be updated for vector and vector_base64 fields")
513513
}
514+
if original.GPU != updated.GPU {
515+
return nil, fmt.Errorf("gpu cannot be updated for vector and vector_base64 fields")
516+
}
514517
}
515518
if original.IncludeInAll != updated.IncludeInAll {
516519
return nil, fmt.Errorf("includeInAll cannot be changed")

index_update_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,42 @@ func TestCompareFieldMapping(t *testing.T) {
140140
indexFieldInfo: nil,
141141
err: true,
142142
},
143+
{ // gpu changed for vector => not updatable
144+
original: &mapping.FieldMapping{
145+
Type: "vector",
146+
Similarity: "dot_product",
147+
Dims: 128,
148+
VectorIndexOptimizedFor: "memory-efficient",
149+
GPU: false,
150+
},
151+
updated: &mapping.FieldMapping{
152+
Type: "vector",
153+
Similarity: "dot_product",
154+
Dims: 128,
155+
VectorIndexOptimizedFor: "memory-efficient",
156+
GPU: true,
157+
},
158+
indexFieldInfo: nil,
159+
err: true,
160+
},
161+
{ // gpu changed for vectorbase64 => not updatable
162+
original: &mapping.FieldMapping{
163+
Type: "vector_base64",
164+
Similarity: "dot_product",
165+
Dims: 128,
166+
VectorIndexOptimizedFor: "memory-efficient",
167+
GPU: false,
168+
},
169+
updated: &mapping.FieldMapping{
170+
Type: "vector_base64",
171+
Similarity: "dot_product",
172+
Dims: 128,
173+
VectorIndexOptimizedFor: "memory-efficient",
174+
GPU: true,
175+
},
176+
indexFieldInfo: nil,
177+
err: true,
178+
},
143179
{ // includeinall changed => not updatable
144180
original: &mapping.FieldMapping{
145181
Type: "numeric",

mapping/field.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ type FieldMapping struct {
8383
VectorIndexOptimizedFor string `json:"vector_index_optimized_for,omitempty"`
8484

8585
SynonymSource string `json:"synonym_source,omitempty"`
86+
87+
// Applicable to vector fields only - enables GPU acceleration for indexing and searching
88+
GPU bool `json:"gpu,omitempty"`
8689
}
8790

8891
// NewTextFieldMapping returns a default field mapping for text
@@ -226,6 +229,9 @@ func (fm *FieldMapping) Options() index.FieldIndexingOptions {
226229
if fm.SkipFreqNorm {
227230
rv |= index.SkipFreqNorm
228231
}
232+
if fm.GPU {
233+
rv |= index.GPU
234+
}
229235
return rv
230236
}
231237

@@ -479,6 +485,11 @@ func (fm *FieldMapping) UnmarshalJSON(data []byte) error {
479485
if err != nil {
480486
return err
481487
}
488+
case "gpu":
489+
err := util.UnmarshalJSON(v, &fm.GPU)
490+
if err != nil {
491+
return err
492+
}
482493
default:
483494
invalidKeys = append(invalidKeys, k)
484495
}

mapping/mapping_vectors.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ func validateVectorFieldAlias(field *FieldMapping, path []string,
277277
"(different vector index optimization values %s and %s)", effectiveFieldName,
278278
effectiveOptimizedFor, aliasOptimizedFor)
279279
}
280+
if field.GPU != fieldAlias.GPU {
281+
return fmt.Errorf("field: '%s', invalid alias "+
282+
"(different gpu values %v and %v)", effectiveFieldName,
283+
field.GPU, fieldAlias.GPU)
284+
}
280285

281286
return nil
282287
}

mapping/mapping_vectors_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,62 @@ func TestVectorFieldAliasValidation(t *testing.T) {
247247
expValidity: false,
248248
errMsgs: []string{`field: 'cityVec', invalid vector dimension: 5000, value should be in range [1, 4096]`},
249249
},
250+
// Test 8b: Different GPU usage in alias should be invalid
251+
{
252+
name: "different_gpu_usage_alias",
253+
mappingStr: `
254+
{
255+
"default_mapping": {
256+
"properties": {
257+
"cityVec": {
258+
"fields": [
259+
{
260+
"type": "vector",
261+
"dims": 3,
262+
"gpu": true
263+
},
264+
{
265+
"name": "cityVec",
266+
"type": "vector",
267+
"dims": 3,
268+
"gpu": false
269+
}
270+
]
271+
}
272+
}
273+
}
274+
}`,
275+
expValidity: false,
276+
errMsgs: []string{`field: 'cityVec', invalid alias (different gpu values false and true)`},
277+
},
278+
// Test 8c: Matching GPU usage in alias should be valid
279+
{
280+
name: "same_gpu_usage_alias",
281+
mappingStr: `
282+
{
283+
"default_mapping": {
284+
"properties": {
285+
"cityVec": {
286+
"fields": [
287+
{
288+
"type": "vector",
289+
"dims": 3,
290+
"gpu": true
291+
},
292+
{
293+
"name": "cityVec",
294+
"type": "vector",
295+
"dims": 3,
296+
"gpu": true
297+
}
298+
]
299+
}
300+
}
301+
}
302+
}`,
303+
expValidity: true,
304+
errMsgs: []string{},
305+
},
250306
// Test 9: Invalid similarity metric
251307
{
252308
name: "invalid_similarity_metric",

0 commit comments

Comments
 (0)