Faiss
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
IVFPQ.cuh
1 /**
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD+Patents license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 // Copyright 2004-present Facebook. All Rights Reserved.
10 
11 #pragma once
12 
13 #include "IVFBase.cuh"
14 #include "../utils/Float16.cuh"
15 
16 namespace faiss { namespace gpu {
17 
18 /// Implementing class for IVFPQ on the GPU
19 class IVFPQ : public IVFBase {
20  public:
21  IVFPQ(GpuResources* resources,
22  /// We do not own this reference
23  FlatIndex* quantizer,
24  int numSubQuantizers,
25  int bitsPerSubQuantizer,
26  float* pqCentroidData,
27  IndicesOptions indicesOptions,
28  bool useFloat16LookupTables,
29  MemorySpace space);
30 
31  /// Returns true if we support PQ in this size
32  static bool isSupportedPQCodeLength(int size);
33 
34  /// For no precomputed codes, is this a supported sub-dimension
35  /// size?
36  /// FIXME: get MM implementation working again
37  static bool isSupportedNoPrecomputedSubDimSize(int dims);
38 
39  ~IVFPQ() override;
40 
41  /// Enable or disable pre-computed codes
42  void setPrecomputedCodes(bool enable);
43 
44  /// Adds a set of codes and indices to a list; the data can be
45  /// resident on either the host or the device
46  void addCodeVectorsFromCpu(int listId,
47  const void* codes,
48  const long* indices,
49  size_t numVecs);
50 
51  /// Calcuates the residual and quantizes the vectors, adding them to
52  /// this index
53  /// The input data must be on our current device.
54  /// Returns the number of vectors successfully added. Vectors may
55  /// not be able to be added because they contain NaNs.
57  Tensor<long, 1, true>& indices);
58 
59  /// Find the approximate k nearest neigbors for `queries` against
60  /// our database
61  void query(Tensor<float, 2, true>& queries,
62  int nprobe,
63  int k,
64  Tensor<float, 2, true>& outDistances,
65  Tensor<long, 2, true>& outIndices);
66 
67  /// Return the list codes of a particular list back to the CPU
68  std::vector<unsigned char> getListCodes(int listId) const;
69 
70  /// Returns our set of sub-quantizers of the form
71  /// (sub q)(code id)(sub dim)
73 
74  private:
75  /// Sets the current product quantizer centroids; the data can be
76  /// resident on either the host or the device. It will be transposed
77  /// into our preferred data layout
78  /// Data must be a row-major, 3-d array of size
79  /// (numSubQuantizers, numSubQuantizerCodes, dim / numSubQuantizers)
80  void setPQCentroids_(float* data);
81 
82  /// Calculate precomputed residual distance information
83  void precomputeCodes_();
84 
85  /// Runs kernels for scanning inverted lists with precomputed codes
86  void runPQPrecomputedCodes_(Tensor<float, 2, true>& queries,
87  DeviceTensor<float, 2, true>& coarseDistances,
88  DeviceTensor<int, 2, true>& coarseIndices,
89  int k,
90  Tensor<float, 2, true>& outDistances,
91  Tensor<long, 2, true>& outIndices);
92 
93  /// Runs kernels for scanning inverted lists without precomputed codes
94  void runPQNoPrecomputedCodes_(Tensor<float, 2, true>& queries,
95  DeviceTensor<float, 2, true>& coarseDistances,
96  DeviceTensor<int, 2, true>& coarseIndices,
97  int k,
98  Tensor<float, 2, true>& outDistances,
99  Tensor<long, 2, true>& outIndices);
100 
101  private:
102  /// Number of sub-quantizers per vector
103  const int numSubQuantizers_;
104 
105  /// Number of bits per sub-quantizer
106  const int bitsPerSubQuantizer_;
107 
108  /// Number of per sub-quantizer codes (2^bits)
109  const int numSubQuantizerCodes_;
110 
111  /// Number of dimensions per each sub-quantizer
112  const int dimPerSubQuantizer_;
113 
114  /// Do we maintain precomputed terms and lookup tables in float16
115  /// form?
116  const bool useFloat16LookupTables_;
117 
118  /// On the GPU, we prefer different PQ centroid data layouts for
119  /// different purposes.
120  ///
121  /// (sub q)(sub dim)(code id)
122  DeviceTensor<float, 3, true> pqCentroidsInnermostCode_;
123 
124  /// (sub q)(code id)(sub dim)
125  DeviceTensor<float, 3, true> pqCentroidsMiddleCode_;
126 
127  /// Are precomputed codes enabled? (additional factoring and
128  /// precomputation of the residual distance, to reduce query-time work)
129  bool precomputedCodes_;
130 
131  /// Precomputed term 2 in float form
132  /// (centroid id)(sub q)(code id)
133  DeviceTensor<float, 3, true> precomputedCode_;
134 
135 #ifdef FAISS_USE_FLOAT16
136  /// Precomputed term 2 in half form
137  DeviceTensor<half, 3, true> precomputedCodeHalf_;
138 #endif
139 };
140 
141 } } // namespace
void addCodeVectorsFromCpu(int listId, const void *codes, const long *indices, size_t numVecs)
Definition: IVFPQ.cu:349
Holder of GPU resources for a particular flat index.
Definition: FlatIndex.cuh:23
Base inverted list functionality for IVFFlat and IVFPQ.
Definition: IVFBase.cuh:27
static bool isSupportedPQCodeLength(int size)
Returns true if we support PQ in this size.
Definition: IVFPQ.cu:72
int classifyAndAddVectors(Tensor< float, 2, true > &vecs, Tensor< long, 1, true > &indices)
Definition: IVFPQ.cu:120
void query(Tensor< float, 2, true > &queries, int nprobe, int k, Tensor< float, 2, true > &outDistances, Tensor< long, 2, true > &outIndices)
Definition: IVFPQ.cu:519
Tensor< float, 3, true > getPQCentroids()
Definition: IVFPQ.cu:594
void setPrecomputedCodes(bool enable)
Enable or disable pre-computed codes.
Definition: IVFPQ.cu:102
std::vector< unsigned char > getListCodes(int listId) const
Return the list codes of a particular list back to the CPU.
Definition: IVFPQ.cu:586
Our tensor type.
Definition: Tensor.cuh:30
IVFPQ(GpuResources *resources, FlatIndex *quantizer, int numSubQuantizers, int bitsPerSubQuantizer, float *pqCentroidData, IndicesOptions indicesOptions, bool useFloat16LookupTables, MemorySpace space)
Definition: IVFPQ.cu:35
Implementing class for IVFPQ on the GPU.
Definition: IVFPQ.cuh:19
static bool isSupportedNoPrecomputedSubDimSize(int dims)
Definition: IVFPQ.cu:97