faiss icon indicating copy to clipboard operation
faiss copied to clipboard

Read access violation when calling search() on my IndexIDMap on GPU

Open EmielBoss opened this issue 2 years ago • 1 comments

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);
}

EmielBoss avatar Sep 12 '23 14:09 EmielBoss

Unfortunately IndexIDMap does not support data residing on GPU. Only GPU indexes do.

mdouze avatar Sep 26 '23 15:09 mdouze