From 53ce01f601ccfb69b65cccd9dcb045e47f884cb1 Mon Sep 17 00:00:00 2001 From: oriHab Date: Tue, 22 Jun 2021 16:26:50 +0300 Subject: [PATCH 01/13] index_idmap.go: go binding added IndexIDMap was missing from the go bindings, even though is is important to wrap a flat index in if addWithID functionality is required. --- index_idmap.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 index_idmap.go diff --git a/index_idmap.go b/index_idmap.go new file mode 100644 index 0000000..06b51de --- /dev/null +++ b/index_idmap.go @@ -0,0 +1,26 @@ +package faiss + +/* +#include +*/ +import "C" +import ( + "errors" +) + +type IndexIDMapWrapper struct { + Index + cpointer **C.FaissIndex +} + +func NewIndexIDMap(index *IndexFlat) (*IndexIDMapWrapper, error) { + var indexMapPointer *C.FaissIndexIDMap + var pointerToIndexMapPointer **C.FaissIndexIDMap + pointerToIndexMapPointer = &indexMapPointer + wrapper := IndexIDMapWrapper{cpointer: &indexMapPointer} + if C.faiss_IndexIDMap_new(pointerToIndexMapPointer, index.cPtr()) != 0 { + return nil, errors.New("Error occurred while initializing IndexIDMapWrapper") + } + wrapper.Index = &faissIndex{idx: *wrapper.cpointer} + return &wrapper, nil +} From c9fed28b9bc2252d6293d655ac97cc5d0c30dde7 Mon Sep 17 00:00:00 2001 From: oriHab Date: Thu, 1 Jul 2021 08:55:33 +0300 Subject: [PATCH 02/13] _example/flat_index_map.go: example test added to demonstrate usage --- _example/flat_index_map/flat_index_map.go | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 _example/flat_index_map/flat_index_map.go diff --git a/_example/flat_index_map/flat_index_map.go b/_example/flat_index_map/flat_index_map.go new file mode 100644 index 0000000..3ba6f8b --- /dev/null +++ b/_example/flat_index_map/flat_index_map.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "github.com/DataIntelligenceCrew/go-faiss" +) + +func main() { + dimension := 1 + dbSize := 5 + + index, err := faiss.NewIndexFlat(dimension, faiss.MetricL2) + if err != nil { + fmt.Println(err.Error()) + } + indexMap, err := faiss.NewIndexIDMap(index) + if err != nil { + fmt.Println(err.Error()) + } + xb := []float32{1,2,3,4,5} + ids := make([]int64, dbSize) + for i := 0; i < dbSize; i++ { + ids[i] = int64(i) + } + + err = indexMap.AddWithIDs(xb, ids) + if err != nil { + fmt.Println(err.Error()) + } + toFind := xb[dimension:2*dimension] + distances1, resultIds, err := indexMap.Search(toFind, 5) + fmt.Println(distances1, resultIds, err) + fmt.Println(resultIds[0] == ids[1]) + fmt.Println(distances1[0] == 0) + +} From 4faa3a5ae9e6b10f552561967e071c86ec8a636a Mon Sep 17 00:00:00 2001 From: oriHab Date: Wed, 28 Jul 2021 14:04:04 +0300 Subject: [PATCH 03/13] go.mod: require testify to help writing tests --- go.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.mod b/go.mod index 9eed116..65d476e 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/DataIntelligenceCrew/go-faiss go 1.14 + +require github.com/stretchr/testify v1.7.0 From 09cd7493627420377b83eee7f030f7d920b6d183 Mon Sep 17 00:00:00 2001 From: orihab Date: Wed, 18 Aug 2021 14:10:38 +0300 Subject: [PATCH 04/13] index_idmap.go: return Index interface instead of IDMapWrapper IDMapWrapper isn't practical bc I would like to be able to transfer gpuIndex (or any other index for that matter) to gpu using the transferToGpu. So I dont want a specific structure which wraps an idmap index, rather just return an Index interface. --- index_idmap.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/index_idmap.go b/index_idmap.go index 06b51de..4551152 100644 --- a/index_idmap.go +++ b/index_idmap.go @@ -8,19 +8,12 @@ import ( "errors" ) -type IndexIDMapWrapper struct { - Index - cpointer **C.FaissIndex -} - -func NewIndexIDMap(index *IndexFlat) (*IndexIDMapWrapper, error) { +func NewIndexIDMap(index Index) (Index, error) { var indexMapPointer *C.FaissIndexIDMap var pointerToIndexMapPointer **C.FaissIndexIDMap pointerToIndexMapPointer = &indexMapPointer - wrapper := IndexIDMapWrapper{cpointer: &indexMapPointer} if C.faiss_IndexIDMap_new(pointerToIndexMapPointer, index.cPtr()) != 0 { return nil, errors.New("Error occurred while initializing IndexIDMapWrapper") } - wrapper.Index = &faissIndex{idx: *wrapper.cpointer} - return &wrapper, nil + return &faissIndex{idx: indexMapPointer}, nil } From 6c44a77e3e9295635c5ee478953ef6aa8fe0cbe4 Mon Sep 17 00:00:00 2001 From: orihab Date: Wed, 18 Aug 2021 14:12:52 +0300 Subject: [PATCH 05/13] index_idmap_test.go: added (in addition to _example file) Better to have a test to make sure everything functions properly than an example usage.. --- index_idmap_test.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 index_idmap_test.go diff --git a/index_idmap_test.go b/index_idmap_test.go new file mode 100644 index 0000000..b9d97e1 --- /dev/null +++ b/index_idmap_test.go @@ -0,0 +1,36 @@ +package faiss + +import ( + "fmt" + "github.com/stretchr/testify/require" + "testing" +) + +func TestNewIndexIDMap(t *testing.T) { + dimension := 1 + dbSize := 5 + + index, err := NewIndexFlat(dimension, MetricL2) + if err != nil { + fmt.Println(err.Error()) + } + indexMap, err := NewIndexIDMap(index) + if err != nil { + fmt.Println(err.Error()) + } + xb := []float32{1,2,3,4,5} + ids := make([]int64, dbSize) + for i := 10; i < dbSize; i++ { + ids[i] = int64(i) + } + + err = indexMap.AddWithIDs(xb, ids) + if err != nil { + fmt.Println(err.Error()) + } + toFind := xb[dimension:2*dimension] + distances1, resultIds, err := indexMap.Search(toFind, 5) + require.Equal(t, resultIds[0], ids[1]) + require.Zero(t, distances1[0]) + +} From 10cdfe4d75546df8f501e326f70c21ea69279227 Mon Sep 17 00:00:00 2001 From: orihab Date: Wed, 28 Jul 2021 10:49:01 +0300 Subject: [PATCH 06/13] added gpu_bindings.go to enable transferring index to GPU In addition added a test for the bindings which show how to use the functionality. --- gpu_bindings.go | 26 ++++++++++++++++++++ gpu_bindings_test.go | 57 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 gpu_bindings.go create mode 100644 gpu_bindings_test.go diff --git a/gpu_bindings.go b/gpu_bindings.go new file mode 100644 index 0000000..77309b5 --- /dev/null +++ b/gpu_bindings.go @@ -0,0 +1,26 @@ +package faiss + +/* +#include +#include +*/ +import "C" +import ( + "errors" +) + +func TransferToGpu(index Index) (Index, error) { + var gpuResources *C.FaissStandardGpuResources + var gpuIndex *C.FaissGpuIndex + c := C.faiss_StandardGpuResources_new(&gpuResources) + if c != 0 { + return nil, errors.New("error on init gpu %v") + } + + exitCode := C.faiss_index_cpu_to_gpu(gpuResources, 0, index.cPtr(), &gpuIndex) + if exitCode != 0 { + return nil, errors.New("error transferring to gpu") + } + + return &faissIndex{idx: gpuIndex}, nil +} diff --git a/gpu_bindings_test.go b/gpu_bindings_test.go new file mode 100644 index 0000000..118f5b2 --- /dev/null +++ b/gpu_bindings_test.go @@ -0,0 +1,57 @@ +package faiss + +import ( + "fmt" + "github.com/stretchr/testify/require" + "testing" +) + +func TestFlatIndexOnGpu(t *testing.T) { + index, err := NewIndexFlatL2(1) + require.Nil(t, err) + + gpuIdx, err := TransferToGpu(index) + require.Nil(t, err) + + vectorsToAdd := []float32{1,2,3,4,5} + err = gpuIdx.Add(vectorsToAdd) + require.Nil(t, err) + + distances, resultIds, err := gpuIdx.Search(vectorsToAdd, 5) + require.Nil(t, err) + + fmt.Println(distances, resultIds, err) + for i := range vectorsToAdd { + require.Equal(t, int64(i), resultIds[len(vectorsToAdd)*i]) + require.Zero(t, distances[len(vectorsToAdd)*i]) + } +} + +func TestIndexIDMapOnGPU(t *testing.T) { + index, err := NewIndexFlatL2(1) + require.Nil(t, err) + + indexMap, err := NewIndexIDMap(index) + require.Nil(t, err) + + gpuIndex, err := TransferToGpu(indexMap) + require.Nil(t, err) + + vectorsToAdd := []float32{1,2,3,4,5} + ids := make([]int64, len(vectorsToAdd)) + for i := 0; i < len(vectorsToAdd); i++ { + ids[i] = int64(i) + } + + err = gpuIndex.AddWithIDs(vectorsToAdd, ids) + require.Nil(t, err) + + distances, resultIds, err := gpuIndex.Search(vectorsToAdd, 5) + require.Nil(t, err) + fmt.Println(gpuIndex.D(), gpuIndex.Ntotal()) + fmt.Println(distances, resultIds, err) + for i := range vectorsToAdd { + require.Equal(t, ids[i], resultIds[len(vectorsToAdd)*i]) + require.Zero(t, distances[len(vectorsToAdd)*i]) + } +} From 73e53341734e81eb1509a18d8e756aa122cf6cc3 Mon Sep 17 00:00:00 2001 From: orihab Date: Thu, 2 Sep 2021 17:32:13 +0300 Subject: [PATCH 07/13] gpu_bindings.go: added TransferToCpu method This is potentially necessary for various things, but specifically is critical for us NOW because RemoveIDs isn't implemented for GPUIndexs, so until we implement that functionality in faiss, the only solution is to transfer the index back and forth to the CPU and remove ids which the index is on CPU. --- gpu_bindings.go | 12 +++++++++ gpu_bindings_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/gpu_bindings.go b/gpu_bindings.go index 77309b5..4b6eb2f 100644 --- a/gpu_bindings.go +++ b/gpu_bindings.go @@ -24,3 +24,15 @@ func TransferToGpu(index Index) (Index, error) { return &faissIndex{idx: gpuIndex}, nil } + +func TransferToCpu(gpuIndex Index) (Index, error) { + var cpuIndex *C.FaissIndex + + exitCode := C.faiss_index_gpu_to_cpu(gpuIndex.cPtr(), &cpuIndex) + if exitCode != 0 { + return nil, errors.New("error transferring to gpu") + } + + return &faissIndex{idx: cpuIndex}, nil +} + diff --git a/gpu_bindings_test.go b/gpu_bindings_test.go index 118f5b2..bb62f27 100644 --- a/gpu_bindings_test.go +++ b/gpu_bindings_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -func TestFlatIndexOnGpu(t *testing.T) { +func TestFlatIndexOnGpuFunctionality(t *testing.T) { index, err := NewIndexFlatL2(1) require.Nil(t, err) @@ -19,12 +19,22 @@ func TestFlatIndexOnGpu(t *testing.T) { distances, resultIds, err := gpuIdx.Search(vectorsToAdd, 5) require.Nil(t, err) + require.Equal(t, int64(len(vectorsToAdd)), gpuIdx.Ntotal()) fmt.Println(distances, resultIds, err) for i := range vectorsToAdd { require.Equal(t, int64(i), resultIds[len(vectorsToAdd)*i]) require.Zero(t, distances[len(vectorsToAdd)*i]) } + //This is necessary bc RemoveIDs isn't implemented for GPUIndexs + cpuIdx, err := TransferToCpu(gpuIdx) + require.Nil(t, err) + idsSelector, err := NewIDSelectorBatch([]int64{0}) + cpuIdx.RemoveIDs(idsSelector) + gpuIdx, err = TransferToGpu(cpuIdx) + require.Nil(t, err) + require.Equal(t, int64(len(vectorsToAdd)-1), gpuIdx.Ntotal()) + } func TestIndexIDMapOnGPU(t *testing.T) { @@ -55,3 +65,51 @@ func TestIndexIDMapOnGPU(t *testing.T) { require.Zero(t, distances[len(vectorsToAdd)*i]) } } + +func TestTransferToGpuAndBack(t *testing.T) { + index, err := NewIndexFlatL2(1) + require.Nil(t, err) + + indexMap, err := NewIndexIDMap(index) + require.Nil(t, err) + + gpuIndex, err := TransferToGpu(indexMap) + require.Nil(t, err) + + vectorsToAdd := []float32{1,2,4,7,11} + ids := make([]int64, len(vectorsToAdd)) + for i := 0; i < len(vectorsToAdd); i++ { + ids[i] = int64(i) + } + + err = gpuIndex.AddWithIDs(vectorsToAdd, ids) + require.Nil(t, err) + + //This is necessary bc RemoveIDs isn't implemented for GPUIndexs + cpuIdx, err := TransferToCpu(gpuIndex) + require.Nil(t, err) + idsSelector, err := NewIDSelectorBatch([]int64{0}) + cpuIdx.RemoveIDs(idsSelector) + gpuIndex, err = TransferToGpu(cpuIdx) + require.Nil(t, err) + + require.Equal(t, int64(4), gpuIndex.Ntotal()) + distances2, resultIds2, err := gpuIndex.Search([]float32{1}, 5) + fmt.Println(distances2, resultIds2, gpuIndex.Ntotal()) + require.Nil(t, err) + require.Equal(t, float32(1), distances2[0]) + + + cpuIndex, err := TransferToCpu(gpuIndex) + require.Nil(t, err) + require.Equal(t, int64(4), cpuIndex.Ntotal()) + + idsSelector, err = NewIDSelectorBatch([]int64{0}) + cpuIndex.RemoveIDs(idsSelector) + distances2, resultIds2, err = cpuIndex.Search([]float32{1}, 5) + fmt.Println(distances2, resultIds2, cpuIndex.Ntotal()) + require.Nil(t, err) + require.Equal(t, float32(1), distances2[0]) + +} + From eea360d97db0ffe93568144f5700f05d94e08ac4 Mon Sep 17 00:00:00 2001 From: oriHab Date: Thu, 9 Sep 2021 08:42:13 +0300 Subject: [PATCH 08/13] add cpu functions and build gpu tag to gpu_bindings This is so that it will be possible to compile and use the library on a machine which doesn't have a gpu as well. --- gpu_bindings.go | 2 ++ gpu_bindings_cpu.go | 13 +++++++++++++ gpu_bindings_test.go | 2 ++ 3 files changed, 17 insertions(+) create mode 100644 gpu_bindings_cpu.go diff --git a/gpu_bindings.go b/gpu_bindings.go index 4b6eb2f..3444b13 100644 --- a/gpu_bindings.go +++ b/gpu_bindings.go @@ -1,3 +1,5 @@ +//+build gpu + package faiss /* diff --git a/gpu_bindings_cpu.go b/gpu_bindings_cpu.go new file mode 100644 index 0000000..a6bef57 --- /dev/null +++ b/gpu_bindings_cpu.go @@ -0,0 +1,13 @@ +//+build cpu + +package faiss + +import "errors" + +func TransferToGpu(index Index) (Index, error) { + return nil, errors.New("Not supported when running in CPU mode..") +} + +func TransferToCpu(index Index) (Index, error) { + return nil, errors.New("Not supported when running in CPU mode..") +} \ No newline at end of file diff --git a/gpu_bindings_test.go b/gpu_bindings_test.go index bb62f27..e8c1500 100644 --- a/gpu_bindings_test.go +++ b/gpu_bindings_test.go @@ -1,3 +1,5 @@ +//+build gpu + package faiss import ( From 0c3bb8202f3986df16a304586b9c230d280cd623 Mon Sep 17 00:00:00 2001 From: oriHab Date: Thu, 23 Sep 2021 19:04:39 +0300 Subject: [PATCH 09/13] go.mod: change module to Anyvisionltd instead of DataIntelligenceCrew --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 65d476e..ea8f2e9 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/DataIntelligenceCrew/go-faiss +module github.com/Anyvisionltd/go-faiss go 1.14 From fa56e6360c3a68122015eac791a59571305f4b07 Mon Sep 17 00:00:00 2001 From: oriHab Date: Wed, 29 Sep 2021 11:18:59 +0300 Subject: [PATCH 10/13] gpu_bindings_test.go: replace fmt.Print with t.Log Didn't know t.Log existed, better to use it. --- gpu_bindings_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gpu_bindings_test.go b/gpu_bindings_test.go index e8c1500..f726c17 100644 --- a/gpu_bindings_test.go +++ b/gpu_bindings_test.go @@ -3,7 +3,6 @@ package faiss import ( - "fmt" "github.com/stretchr/testify/require" "testing" ) @@ -23,7 +22,7 @@ func TestFlatIndexOnGpuFunctionality(t *testing.T) { require.Nil(t, err) require.Equal(t, int64(len(vectorsToAdd)), gpuIdx.Ntotal()) - fmt.Println(distances, resultIds, err) + t.Log(distances, resultIds, err) for i := range vectorsToAdd { require.Equal(t, int64(i), resultIds[len(vectorsToAdd)*i]) require.Zero(t, distances[len(vectorsToAdd)*i]) @@ -60,8 +59,8 @@ func TestIndexIDMapOnGPU(t *testing.T) { distances, resultIds, err := gpuIndex.Search(vectorsToAdd, 5) require.Nil(t, err) - fmt.Println(gpuIndex.D(), gpuIndex.Ntotal()) - fmt.Println(distances, resultIds, err) + t.Log(gpuIndex.D(), gpuIndex.Ntotal()) + t.Log(distances, resultIds, err) for i := range vectorsToAdd { require.Equal(t, ids[i], resultIds[len(vectorsToAdd)*i]) require.Zero(t, distances[len(vectorsToAdd)*i]) @@ -97,7 +96,7 @@ func TestTransferToGpuAndBack(t *testing.T) { require.Equal(t, int64(4), gpuIndex.Ntotal()) distances2, resultIds2, err := gpuIndex.Search([]float32{1}, 5) - fmt.Println(distances2, resultIds2, gpuIndex.Ntotal()) + t.Log(distances2, resultIds2, gpuIndex.Ntotal()) require.Nil(t, err) require.Equal(t, float32(1), distances2[0]) @@ -109,7 +108,7 @@ func TestTransferToGpuAndBack(t *testing.T) { idsSelector, err = NewIDSelectorBatch([]int64{0}) cpuIndex.RemoveIDs(idsSelector) distances2, resultIds2, err = cpuIndex.Search([]float32{1}, 5) - fmt.Println(distances2, resultIds2, cpuIndex.Ntotal()) + t.Log(distances2, resultIds2, cpuIndex.Ntotal()) require.Nil(t, err) require.Equal(t, float32(1), distances2[0]) From 2536fd63546122277ea45af15bf2621a7341090e Mon Sep 17 00:00:00 2001 From: oriHab Date: Wed, 29 Sep 2021 11:19:48 +0300 Subject: [PATCH 11/13] index.go: add property for GpuResource I discoverd the hard way that after transferring an index to the GPU, the gpu memory isn't freed when the index is deleted. It seems like a gpuResource is being allocated and holding the memory. Its necessary to free the gpuResource in order to free the Gpumemory. In order to free the gpuResource we will need to save it, and call free on it. In the next commit I will add the Free functionality to gpu_bindings.go. --- index.go | 9 +++++++++ index_flat.go | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/index.go b/index.go index 40282f0..29ff19c 100644 --- a/index.go +++ b/index.go @@ -5,6 +5,8 @@ package faiss #include #include #include +#include +#include */ import "C" import "unsafe" @@ -56,10 +58,17 @@ type Index interface { Delete() cPtr() *C.FaissIndex + + cGpuResource() *C.FaissStandardGpuResources } type faissIndex struct { idx *C.FaissIndex + resource *C.FaissStandardGpuResources +} + +func (idx *faissIndex) cGpuResource() *C.FaissStandardGpuResources { + return idx.resource } func (idx *faissIndex) cPtr() *C.FaissIndex { diff --git a/index_flat.go b/index_flat.go index b8a3c03..a97d6f8 100644 --- a/index_flat.go +++ b/index_flat.go @@ -52,5 +52,5 @@ func (idx *IndexImpl) AsFlat() *IndexFlat { if ptr == nil { panic("index is not a flat index") } - return &IndexFlat{&faissIndex{ptr}} + return &IndexFlat{&faissIndex{idx: ptr}} } From 681a91abc04fbb480ec9130e369ccc2b277b5490 Mon Sep 17 00:00:00 2001 From: oriHab Date: Wed, 29 Sep 2021 11:24:07 +0300 Subject: [PATCH 12/13] gpu_bindings.go: added Free method which frees the GpuResource and Deletes the index TransferToCpu will free the gpu memory after copying the index to CPU. Also added a function to CreateGpuIndex just because it was easy and may be useful for someone. --- gpu_bindings.go | 22 +++++++++++++++++++++- gpu_bindings_cpu.go | 10 +++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/gpu_bindings.go b/gpu_bindings.go index 3444b13..5a8096b 100644 --- a/gpu_bindings.go +++ b/gpu_bindings.go @@ -11,6 +11,7 @@ import ( "errors" ) + func TransferToGpu(index Index) (Index, error) { var gpuResources *C.FaissStandardGpuResources var gpuIndex *C.FaissGpuIndex @@ -24,7 +25,7 @@ func TransferToGpu(index Index) (Index, error) { return nil, errors.New("error transferring to gpu") } - return &faissIndex{idx: gpuIndex}, nil + return &faissIndex{idx: gpuIndex, resource: gpuResources}, nil } func TransferToCpu(gpuIndex Index) (Index, error) { @@ -35,6 +36,25 @@ func TransferToCpu(gpuIndex Index) (Index, error) { return nil, errors.New("error transferring to gpu") } + Free(gpuIndex) + return &faissIndex{idx: cpuIndex}, nil } +func Free(index Index) { + var gpuResource *C.FaissStandardGpuResources + gpuResource = index.cGpuResource() + C.faiss_StandardGpuResources_free(gpuResource) + index.Delete() +} + +func CreateGpuIndex() (Index, error) { + var gpuResource *C.FaissStandardGpuResources + var gpuIndex *C.FaissGpuIndex + c := C.faiss_StandardGpuResources_new(&gpuResource) + if c != 0 { + return nil, errors.New("error on init gpu %v") + } + + return &faissIndex{idx: gpuIndex, resource: gpuResource}, nil +} diff --git a/gpu_bindings_cpu.go b/gpu_bindings_cpu.go index a6bef57..f24b073 100644 --- a/gpu_bindings_cpu.go +++ b/gpu_bindings_cpu.go @@ -10,4 +10,12 @@ func TransferToGpu(index Index) (Index, error) { func TransferToCpu(index Index) (Index, error) { return nil, errors.New("Not supported when running in CPU mode..") -} \ No newline at end of file +} + +func Free(gpuIndex Index) error { + return errors.New("Not supported when running in CPU mode..") +} + +func CreateGpuIndex() (Index, error) { + return nil, errors.New("Not supported when running in CPU mode..") +} From 72e5deacb1de1743e51df63e5d7ed8d0baea92c6 Mon Sep 17 00:00:00 2001 From: oriHab Date: Wed, 29 Sep 2021 11:25:13 +0300 Subject: [PATCH 13/13] gpu_bindings_test.go: added a test for TestFreeGPUResource Its not really the best, but I assume that most Gpus will run out of memory when creating 20 gpu indices, so if the test passes, most likely the free function is working ;) --- gpu_bindings_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gpu_bindings_test.go b/gpu_bindings_test.go index f726c17..b65cf42 100644 --- a/gpu_bindings_test.go +++ b/gpu_bindings_test.go @@ -5,6 +5,7 @@ package faiss import ( "github.com/stretchr/testify/require" "testing" + "time" ) func TestFlatIndexOnGpuFunctionality(t *testing.T) { @@ -114,3 +115,19 @@ func TestTransferToGpuAndBack(t *testing.T) { } +func TestFreeGPUResource(t *testing.T) { + for i := 0; i < 20; i++ { + t.Logf("creating index %v", i) + flatIndex, err := NewIndexFlatIP(256) + require.Nil(t, err) + flatIndexGpu, err := TransferToGpu(flatIndex) + require.Nil(t, err) + + t.Log("created indexes, freeing..") + err = Free(flatIndexGpu) + require.Nil(t, err) + t.Log("freed, memory should be freed..") + time.Sleep(1 * time.Second) + } + +} \ No newline at end of file