diff --git a/faiss/gpu/GpuCloner.cpp b/faiss/gpu/GpuCloner.cpp index 20583720f3..06ad082272 100644 --- a/faiss/gpu/GpuCloner.cpp +++ b/faiss/gpu/GpuCloner.cpp @@ -224,6 +224,8 @@ faiss::Index* index_cpu_to_gpu( int device, const faiss::Index* index, const GpuClonerOptions* options) { + auto index_pq = dynamic_cast(index); + FAISS_THROW_IF_MSG(index_pq, "This index type is not implemented on GPU."); GpuClonerOptions defaults; ToGpuCloner cl(provider, device, options ? *options : defaults); return cl.clone_Index(index); diff --git a/faiss/gpu/test/test_index_cpu_to_gpu.py b/faiss/gpu/test/test_index_cpu_to_gpu.py new file mode 100644 index 0000000000..84c35e2af7 --- /dev/null +++ b/faiss/gpu/test/test_index_cpu_to_gpu.py @@ -0,0 +1,29 @@ +import numpy as np +import unittest +import faiss + + +class TestMoveToGpu(unittest.TestCase): + def test_index_cpu_to_gpu(self): + dimension = 128 + n = 2500 + db_vectors = np.random.random((n, dimension)).astype('float32') + code_size = 16 + res = faiss.StandardGpuResources() + index_pq = faiss.IndexPQ(dimension, code_size, 6) + index_pq.train(db_vectors) + index_pq.add(db_vectors) + self.assertRaisesRegex(Exception, ".*not implemented.*", + faiss.index_cpu_to_gpu, res, 0, index_pq) + + def test_index_cpu_to_gpu_does_not_throw_with_index_flat(self): + dimension = 128 + n = 100 + db_vectors = np.random.random((n, dimension)).astype('float32') + res = faiss.StandardGpuResources() + index_flat = faiss.IndexFlatL2(dimension) + index_flat.add(db_vectors) + try: + faiss.index_cpu_to_gpu(res, 0, index_flat) + except Exception: + self.fail("index_cpu_to_gpu() threw an unexpected exception.") diff --git a/faiss/impl/FaissAssert.h b/faiss/impl/FaissAssert.h index 6f666f684c..2aea23e6a8 100644 --- a/faiss/impl/FaissAssert.h +++ b/faiss/impl/FaissAssert.h @@ -94,6 +94,13 @@ } \ } while (false) +#define FAISS_THROW_IF_MSG(X, MSG) \ + do { \ + if (X) { \ + FAISS_THROW_FMT("Error: '%s' failed: " MSG, #X); \ + } \ + } while (false) + #define FAISS_THROW_IF_NOT_MSG(X, MSG) \ do { \ if (!(X)) { \