Skip to content

Commit 26ca5d2

Browse files
authored
Add mean and median threshold modes to binary quantization (#716)
The current binary quantization function sets a bit when the corresponding input dataset element is positive. This method (zero threshold mode) does not work well for, for example, a dataset where all elements are positive. This PR adds mean and median modes that set bits when the corresponding elements are larger than the dim-wise mean and median, respectively. The new `transform` function requires NVIDIA/raft#2592 to be merged to support large datasets. TODO: - [x] C++ - [x] C - [x] test - [x] <del>python</del> The Python support will be added in a later PR, as the Python package build requires the C header file installed by `conda create` to include this update. Authors: - tsuki (https://github.com/enp1s0) - Corey J. Nolet (https://github.com/cjnolet) Approvers: - Tamas Bela Feher (https://github.com/tfeher) - Corey J. Nolet (https://github.com/cjnolet) URL: #716
1 parent ecea00e commit 26ca5d2

10 files changed

Lines changed: 908 additions & 70 deletions

File tree

cpp/include/cuvs/preprocessing/quantize/binary.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,89 @@
2424
extern "C" {
2525
#endif
2626

27+
/**
28+
* @brief In the cuvsBinaryQuantizerTransform function, a bit is set if the corresponding element in
29+
* the dataset vector is greater than the corresponding element in the threshold vector. The mean
30+
* and sampling_median thresholds are calculated separately for each dimension.
31+
*
32+
*/
33+
enum cuvsBinaryQuantizerThreshold { ZERO, MEAN, SAMPLING_MEDIAN };
34+
35+
/**
36+
* @brief Binary quantizer parameters.
37+
*/
38+
struct cuvsBinaryQuantizerParams {
39+
/*
40+
* specifies the threshold to set a bit in cuvsBinaryQuantizerTransform
41+
*/
42+
cuvsBinaryQuantizerThreshold threshold = MEAN;
43+
44+
/*
45+
* specifies the sampling ratio
46+
*/
47+
float sampling_ratio = 0.1;
48+
};
49+
50+
typedef struct cuvsBinaryQuantizerParams* cuvsBinaryQuantizerParams_t;
51+
52+
/**
53+
* @brief Allocate Binary Quantizer params, and populate with default values
54+
*
55+
* @param[in] params cuvsBinaryQuantizerParams_t to allocate
56+
* @return cuvsError_t
57+
*/
58+
cuvsError_t cuvsBinaryQuantizerParamsCreate(cuvsBinaryQuantizerParams_t* params);
59+
60+
/**
61+
* @brief De-allocate Binary Quantizer params
62+
*
63+
* @param[in] params
64+
* @return cuvsError_t
65+
*/
66+
cuvsError_t cuvsBinaryQuantizerParamsDestroy(cuvsBinaryQuantizerParams_t params);
67+
68+
/**
69+
* @brief Defines and stores threshold for quantization upon training
70+
*
71+
* The quantization is performed by a linear mapping of an interval in the
72+
* float data type to the full range of the quantized int type.
73+
*/
74+
typedef struct {
75+
uintptr_t addr;
76+
DLDataType dtype;
77+
} cuvsBinaryQuantizer;
78+
79+
typedef cuvsBinaryQuantizer* cuvsBinaryQuantizer_t;
80+
81+
/**
82+
* @brief Allocate Binary Quantizer and populate with default values
83+
*
84+
* @param[in] quantizer cuvsBinaryQuantizer_t to allocate
85+
* @return cuvsError_t
86+
*/
87+
cuvsError_t cuvsBinaryQuantizerCreate(cuvsBinaryQuantizer_t* quantizer);
88+
89+
/**
90+
* @brief De-allocate Binary Quantizer
91+
*
92+
* @param[in] quantizer
93+
* @return cuvsError_t
94+
*/
95+
cuvsError_t cuvsBinaryQuantizerDestroy(cuvsBinaryQuantizer_t quantizer);
96+
97+
/**
98+
* @brief Trains a scalar quantizer to be used later for quantizing the dataset.
99+
*
100+
* @param[in] res raft resource
101+
* @param[in] params configure binary quantizer, e.g. threshold
102+
* @param[in] dataset a row-major host or device matrix
103+
* @param[out] quantizer trained binary quantizer
104+
*/
105+
cuvsError_t cuvsBinaryQuantizerTrain(cuvsResources_t res,
106+
cuvsBinaryQuantizerParams_t params,
107+
DLManagedTensor* dataset,
108+
cuvsBinaryQuantizer_t quantizer);
109+
27110
/**
28111
* @brief Applies binary quantization transform to the given dataset
29112
*
@@ -39,6 +122,23 @@ cuvsError_t cuvsBinaryQuantizerTransform(cuvsResources_t res,
39122
DLManagedTensor* dataset,
40123
DLManagedTensor* out);
41124

125+
/**
126+
* @brief Applies binary quantization transform to the given dataset
127+
*
128+
* This applies binary quantization to a dataset, changing any values that are larger than the
129+
* threshold specified in the param to a bitwise 1. This is useful for searching with the
130+
* BitwiseHamming distance type.
131+
*
132+
* @param[in] res raft resource
133+
* @param[in] quantizer binary quantizer
134+
* @param[in] dataset a row-major host or device matrix to transform
135+
* @param[out] out a row-major host or device matrix to store transformed data
136+
*/
137+
cuvsError_t cuvsBinaryQuantizerTransformWithParams(cuvsResources_t res,
138+
cuvsBinaryQuantizer_t quantizer,
139+
DLManagedTensor* dataset,
140+
DLManagedTensor* out);
141+
42142
#ifdef __cplusplus
43143
}
44144
#endif

0 commit comments

Comments
 (0)