Read access violation when calling search() on my IndexIDMap on GPU
Summary
I'm trying to use IndexIDMap as a wrapper around the GpuIndexFlatL2 index in order to supply my own custom IDs. This piece of code works:
#include <cuda_runtime.h>
#include <faiss/gpu/StandardGpuResources.h>
#include <faiss/gpu/GpuIndexIVFFlat.h>
#include <faiss/gpu/GpuIndexFlat.h>
#include <faiss/IndexIDMap.h>
// ..._n, _k, _d, dataPtr, dataPtrQuery, idxPtr, nQuery and all buffers defined somewhere...
// Create temporary space for storing 64 bit indices
void* tempIndicesHandle;
cudaMalloc(&tempIndicesHandle, _n * _k * sizeof(faiss::idx_t));
faiss::gpu::StandardGpuResources faissResources;
faiss::gpu::GpuIndexFlatConfig faissConfig;
faissConfig.device = 0;
faiss::gpu::GpuIndexFlatL2 faissIndex(&faissResources, _d, faissConfig);
faissIndex.add(_n, dataPtr);
faissIndex.search(nQuery, dataPtrQuery, _k, (float*) _interopBuffers(Type::eDistances).cuHandle(), (faiss::idx_t*) tempIndicesHandle);
However, when I replace the last two lines with:
faiss::IndexIDMap faissIndexWrapped = faiss::IndexIDMap(&faissIndex);
faissIndexWrapped.add_with_ids(_n, dataPtr, idxPtr);
faissIndexWrapped.search(nQuery, dataPtrQuery, _k, (float*) _interopBuffers(Type::eDistances).cuHandle(), (faiss::idx_t*) tempIndicesHandle);
I get
Unhandled exception thrown: read access violation.
li was 0x11101180433271A.
at this line in IndexIDMap.cpp. Does anyone know what is going on or what I'm doing wrong? I can't access the labels pointer in the debuffer. The same issue occurs in Faiss 1.7.2. I tried GpuIndexIVFFlat; same problem. It does work on CPU. I'm assuming I'm simply using IndexIDMap wrong?
Platform
OS: Windows 10 64-bit. Using CUDA V11.8.89
Faiss version: d87888b13e7eb339bb9c45825e9d20def6665171(Version 1.7.4)
Installed from: vcpkg
Faiss compilation options: Compiled with Visual Studio Community 2022 compiler in debug mode.
Running on:
- [ ] CPU
- [X] GPU
Interface:
- [X] C++
- [ ] Python
Reproduction instructions
The code below throws the exception. Switching to the index itself doesn't throw anything.
#include <exception>
#include <cstdlib>
#include <string>
#include <vector>
#include <cmath>
#include <random>
#include <iostream>
#include <cuda_runtime.h>
#include <faiss/VectorTransform.h>
#include <faiss/gpu/StandardGpuResources.h>
#include <faiss/gpu/GpuIndexIVFFlat.h>
#include <faiss/gpu/GpuIndexFlat.h>
#include <faiss/IndexIDMap.h>
using uint = unsigned int;
// Generate n random d-dimensional vectors
void randomInit(std::vector<float>& data, uint n, uint d, uint seed) {
std::mt19937 rng(seed);
std::normal_distribution<float> dist(0.f, 1.f);
for (uint i = 0; i < n * d; ++i) {
data[i] = dist(rng);
}
}
int main(int argc, char** argv) {
int d = 64; // dimension
int nb = 100000; // database size
int nq = 10000; // nb of queries
uint k = 10;
std::vector<float> xb(d * nb);
std::vector<float> xq(d * nq);
std::vector<faiss::idx_t> idxb(nb);
randomInit(xb, nb, d, 123);
randomInit(xq, nq, d, 456);
for(uint i = 0; i < nb; i++) {
idxb[i] = (int64_t) i;
}
// Create temporary spaces
void* distancesHandle;
cudaMalloc(&distancesHandle, nq * k * sizeof(float));
void* indicesHandle;
cudaMalloc(&indicesHandle, nq * k * sizeof(faiss::idx_t));
faiss::gpu::StandardGpuResources faissResources;
faiss::gpu::GpuIndexFlatConfig faissConfig;
faissConfig.device = 0;
faiss::gpu::GpuIndexFlatL2 faissIndex(&faissResources, d, faissConfig);
// faissIndex.add(nb, xb.data());
// faissIndex.search(nq, xq.data(), k, (float*) distancesHandle, (faiss::idx_t*) indicesHandle);
// vs.
faiss::IndexIDMap faissIndexWrapped = faiss::IndexIDMap(&faissIndex);
faissIndexWrapped.add_with_ids(nb, xb.data(), idxb.data());
faissIndexWrapped.search(nq, xq.data(), k, (float*) distancesHandle, (faiss::idx_t*) indicesHandle);
cudaFree(distancesHandle);
cudaFree(indicesHandle);
}
Unfortunately IndexIDMap does not support data residing on GPU. Only GPU indexes do.