Skip to content

Commit d3692d2

Browse files
Deprecate ScopeDeleter and ScopeDeleter1 in favor of std::unique_ptr<[]> (facebookresearch#3108)
Summary: Pull Request resolved: facebookresearch#3108 Reviewed By: mlomeli1 Differential Revision: D50595705 Pulled By: mdouze fbshipit-source-id: 8555c13609747b7b61201225fcd036d80b50ae59
1 parent eb071f8 commit d3692d2

20 files changed

+198
-240
lines changed

faiss/IVFlib.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -326,14 +326,14 @@ void search_with_parameters(
326326
double* ms_per_stage) {
327327
FAISS_THROW_IF_NOT(params);
328328
const float* prev_x = x;
329-
ScopeDeleter<float> del;
329+
std::unique_ptr<const float[]> del;
330330

331331
double t0 = getmillisecs();
332332

333333
if (auto ip = dynamic_cast<const IndexPreTransform*>(index)) {
334334
x = ip->apply_chain(n, x);
335335
if (x != prev_x) {
336-
del.set(x);
336+
del.reset(x);
337337
}
338338
index = ip->index;
339339
}
@@ -376,14 +376,14 @@ void range_search_with_parameters(
376376
double* ms_per_stage) {
377377
FAISS_THROW_IF_NOT(params);
378378
const float* prev_x = x;
379-
ScopeDeleter<float> del;
379+
std::unique_ptr<const float[]> del;
380380

381381
double t0 = getmillisecs();
382382

383383
if (auto ip = dynamic_cast<const IndexPreTransform*>(index)) {
384384
x = ip->apply_chain(n, x);
385385
if (x != prev_x) {
386-
del.set(x);
386+
del.reset(x);
387387
}
388388
index = ip->index;
389389
}

faiss/Index2Layer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void Index2Layer::train(idx_t n, const float* x) {
8383
verbose,
8484
pq.cp.seed);
8585

86-
ScopeDeleter<float> del_x(x_in == x ? nullptr : x);
86+
std::unique_ptr<const float[]> del_x(x_in == x ? nullptr : x);
8787

8888
std::vector<idx_t> assign(n); // assignement to coarse centroids
8989
q1.quantizer->assign(n, x, assign.data());

faiss/IndexHNSW.cpp

+16-18
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,8 @@ void hnsw_add_vertices(
192192
{
193193
VisitedTable vt(ntotal);
194194

195-
DistanceComputer* dis =
196-
storage_distance_computer(index_hnsw.storage);
197-
ScopeDeleter1<DistanceComputer> del(dis);
195+
std::unique_ptr<DistanceComputer> dis(
196+
storage_distance_computer(index_hnsw.storage));
198197
int prev_display =
199198
verbose && omp_get_thread_num() == 0 ? 0 : -1;
200199
size_t counter = 0;
@@ -301,8 +300,8 @@ void IndexHNSW::search(
301300
{
302301
VisitedTable vt(ntotal);
303302

304-
DistanceComputer* dis = storage_distance_computer(storage);
305-
ScopeDeleter1<DistanceComputer> del(dis);
303+
std::unique_ptr<DistanceComputer> dis(
304+
storage_distance_computer(storage));
306305

307306
#pragma omp for reduction(+ : n1, n2, n3, ndis, nreorder) schedule(guided)
308307
for (idx_t i = i0; i < i1; i++) {
@@ -373,8 +372,8 @@ void IndexHNSW::reconstruct(idx_t key, float* recons) const {
373372
void IndexHNSW::shrink_level_0_neighbors(int new_size) {
374373
#pragma omp parallel
375374
{
376-
DistanceComputer* dis = storage_distance_computer(storage);
377-
ScopeDeleter1<DistanceComputer> del(dis);
375+
std::unique_ptr<DistanceComputer> dis(
376+
storage_distance_computer(storage));
378377

379378
#pragma omp for
380379
for (idx_t i = 0; i < ntotal; i++) {
@@ -507,8 +506,8 @@ void IndexHNSW::init_level_0_from_entry_points(
507506
{
508507
VisitedTable vt(ntotal);
509508

510-
DistanceComputer* dis = storage_distance_computer(storage);
511-
ScopeDeleter1<DistanceComputer> del(dis);
509+
std::unique_ptr<DistanceComputer> dis(
510+
storage_distance_computer(storage));
512511
std::vector<float> vec(storage->d);
513512

514513
#pragma omp for schedule(dynamic)
@@ -543,8 +542,8 @@ void IndexHNSW::reorder_links() {
543542
std::vector<float> distances(M);
544543
std::vector<size_t> order(M);
545544
std::vector<storage_idx_t> tmp(M);
546-
DistanceComputer* dis = storage_distance_computer(storage);
547-
ScopeDeleter1<DistanceComputer> del(dis);
545+
std::unique_ptr<DistanceComputer> dis(
546+
storage_distance_computer(storage));
548547

549548
#pragma omp for
550549
for (storage_idx_t i = 0; i < ntotal; i++) {
@@ -795,12 +794,11 @@ void ReconstructFromNeighbors::estimate_code(
795794
storage_idx_t i,
796795
uint8_t* code) const {
797796
// fill in tmp table with the neighbor values
798-
float* tmp1 = new float[d * (M + 1) + (d * k)];
799-
float* tmp2 = tmp1 + d * (M + 1);
800-
ScopeDeleter<float> del(tmp1);
797+
std::unique_ptr<float[]> tmp1(new float[d * (M + 1) + (d * k)]);
798+
float* tmp2 = tmp1.get() + d * (M + 1);
801799

802800
// collect coordinates of base
803-
get_neighbor_table(i, tmp1);
801+
get_neighbor_table(i, tmp1.get());
804802

805803
for (size_t sq = 0; sq < nsq; sq++) {
806804
int d0 = sq * dsub;
@@ -816,7 +814,7 @@ void ReconstructFromNeighbors::estimate_code(
816814
&ki,
817815
&m1,
818816
&one,
819-
tmp1 + d0,
817+
tmp1.get() + d0,
820818
&di,
821819
codebook.data() + sq * (m1 * k),
822820
&m1,
@@ -1033,8 +1031,8 @@ void IndexHNSW2Level::search(
10331031
#pragma omp parallel
10341032
{
10351033
VisitedTable vt(ntotal);
1036-
DistanceComputer* dis = storage_distance_computer(storage);
1037-
ScopeDeleter1<DistanceComputer> del(dis);
1034+
std::unique_ptr<DistanceComputer> dis(
1035+
storage_distance_computer(storage));
10381036

10391037
int candidates_size = hnsw.upper_beam;
10401038
MinimaxHeap candidates(candidates_size);

faiss/IndexIVF.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,8 @@ void IndexIVF::search_preassigned(
447447

448448
#pragma omp parallel if (do_parallel) reduction(+ : nlistv, ndis, nheap)
449449
{
450-
InvertedListScanner* scanner =
451-
get_InvertedListScanner(store_pairs, sel);
452-
ScopeDeleter1<InvertedListScanner> del(scanner);
450+
std::unique_ptr<InvertedListScanner> scanner(
451+
get_InvertedListScanner(store_pairs, sel));
453452

454453
/*****************************************************
455454
* Depending on parallel_mode, there are two possible ways

faiss/IndexIVFPQ.cpp

+15-16
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,20 @@ void IndexIVFPQ::add_core(
139139
add_core_o(n, x, xids, nullptr, coarse_idx);
140140
}
141141

142-
static float* compute_residuals(
142+
static std::unique_ptr<float[]> compute_residuals(
143143
const Index* quantizer,
144144
idx_t n,
145145
const float* x,
146146
const idx_t* list_nos) {
147147
size_t d = quantizer->d;
148-
float* residuals = new float[n * d];
148+
std::unique_ptr<float[]> residuals(new float[n * d]);
149149
// TODO: parallelize?
150150
for (size_t i = 0; i < n; i++) {
151151
if (list_nos[i] < 0)
152-
memset(residuals + i * d, 0, sizeof(*residuals) * d);
152+
memset(residuals.get() + i * d, 0, sizeof(float) * d);
153153
else
154154
quantizer->compute_residual(
155-
x + i * d, residuals + i * d, list_nos[i]);
155+
x + i * d, residuals.get() + i * d, list_nos[i]);
156156
}
157157
return residuals;
158158
}
@@ -164,9 +164,9 @@ void IndexIVFPQ::encode_vectors(
164164
uint8_t* codes,
165165
bool include_listnos) const {
166166
if (by_residual) {
167-
float* to_encode = compute_residuals(quantizer, n, x, list_nos);
168-
ScopeDeleter<float> del(to_encode);
169-
pq.compute_codes(to_encode, codes, n);
167+
std::unique_ptr<float[]> to_encode =
168+
compute_residuals(quantizer, n, x, list_nos);
169+
pq.compute_codes(to_encode.get(), codes, n);
170170
} else {
171171
pq.compute_codes(x, codes, n);
172172
}
@@ -241,31 +241,30 @@ void IndexIVFPQ::add_core_o(
241241
FAISS_THROW_IF_NOT(is_trained);
242242
double t0 = getmillisecs();
243243
const idx_t* idx;
244-
ScopeDeleter<idx_t> del_idx;
244+
std::unique_ptr<idx_t[]> del_idx;
245245

246246
if (precomputed_idx) {
247247
idx = precomputed_idx;
248248
} else {
249249
idx_t* idx0 = new idx_t[n];
250-
del_idx.set(idx0);
250+
del_idx.reset(idx0);
251251
quantizer->assign(n, x, idx0);
252252
idx = idx0;
253253
}
254254

255255
double t1 = getmillisecs();
256-
uint8_t* xcodes = new uint8_t[n * code_size];
257-
ScopeDeleter<uint8_t> del_xcodes(xcodes);
256+
std::unique_ptr<uint8_t[]> xcodes(new uint8_t[n * code_size]);
258257

259258
const float* to_encode = nullptr;
260-
ScopeDeleter<float> del_to_encode;
259+
std::unique_ptr<const float[]> del_to_encode;
261260

262261
if (by_residual) {
263-
to_encode = compute_residuals(quantizer, n, x, idx);
264-
del_to_encode.set(to_encode);
262+
del_to_encode = compute_residuals(quantizer, n, x, idx);
263+
to_encode = del_to_encode.get();
265264
} else {
266265
to_encode = x;
267266
}
268-
pq.compute_codes(to_encode, xcodes, n);
267+
pq.compute_codes(to_encode, xcodes.get(), n);
269268

270269
double t2 = getmillisecs();
271270
// TODO: parallelize?
@@ -281,7 +280,7 @@ void IndexIVFPQ::add_core_o(
281280
continue;
282281
}
283282

284-
uint8_t* code = xcodes + i * code_size;
283+
uint8_t* code = xcodes.get() + i * code_size;
285284
size_t offset = invlists->add_entry(key, id, code);
286285

287286
if (residuals_2) {

faiss/IndexIVFPQR.cpp

+16-18
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,16 @@ void IndexIVFPQR::add_core(
9292
const float* x,
9393
const idx_t* xids,
9494
const idx_t* precomputed_idx) {
95-
float* residual_2 = new float[n * d];
96-
ScopeDeleter<float> del(residual_2);
95+
std::unique_ptr<float[]> residual_2(new float[n * d]);
9796

9897
idx_t n0 = ntotal;
9998

100-
add_core_o(n, x, xids, residual_2, precomputed_idx);
99+
add_core_o(n, x, xids, residual_2.get(), precomputed_idx);
101100

102101
refine_codes.resize(ntotal * refine_pq.code_size);
103102

104103
refine_pq.compute_codes(
105-
residual_2, &refine_codes[n0 * refine_pq.code_size], n);
104+
residual_2.get(), &refine_codes[n0 * refine_pq.code_size], n);
106105
}
107106
#define TIC t0 = get_cycles()
108107
#define TOC get_cycles() - t0
@@ -121,20 +120,19 @@ void IndexIVFPQR::search_preassigned(
121120
uint64_t t0;
122121
TIC;
123122
size_t k_coarse = long(k * k_factor);
124-
idx_t* coarse_labels = new idx_t[k_coarse * n];
125-
ScopeDeleter<idx_t> del1(coarse_labels);
126-
{ // query with quantizer levels 1 and 2.
127-
float* coarse_distances = new float[k_coarse * n];
128-
ScopeDeleter<float> del(coarse_distances);
123+
std::unique_ptr<idx_t[]> coarse_labels(new idx_t[k_coarse * n]);
124+
{
125+
// query with quantizer levels 1 and 2.
126+
std::unique_ptr<float[]> coarse_distances(new float[k_coarse * n]);
129127

130128
IndexIVFPQ::search_preassigned(
131129
n,
132130
x,
133131
k_coarse,
134132
idx,
135133
L1_dis,
136-
coarse_distances,
137-
coarse_labels,
134+
coarse_distances.get(),
135+
coarse_labels.get(),
138136
true,
139137
params);
140138
}
@@ -148,13 +146,12 @@ void IndexIVFPQR::search_preassigned(
148146
#pragma omp parallel reduction(+ : n_refine)
149147
{
150148
// tmp buffers
151-
float* residual_1 = new float[2 * d];
152-
ScopeDeleter<float> del(residual_1);
153-
float* residual_2 = residual_1 + d;
149+
std::unique_ptr<float[]> residual_1(new float[2 * d]);
150+
float* residual_2 = residual_1.get() + d;
154151
#pragma omp for
155152
for (idx_t i = 0; i < n; i++) {
156153
const float* xq = x + i * d;
157-
const idx_t* shortlist = coarse_labels + k_coarse * i;
154+
const idx_t* shortlist = coarse_labels.get() + k_coarse * i;
158155
float* heap_sim = distances + k * i;
159156
idx_t* heap_ids = labels + k * i;
160157
maxheap_heapify(k, heap_sim, heap_ids);
@@ -172,7 +169,7 @@ void IndexIVFPQR::search_preassigned(
172169
assert(ofs >= 0 && ofs < invlists->list_size(list_no));
173170

174171
// 1st level residual
175-
quantizer->compute_residual(xq, residual_1, list_no);
172+
quantizer->compute_residual(xq, residual_1.get(), list_no);
176173

177174
// 2nd level residual
178175
const uint8_t* l2code = invlists->get_single_code(list_no, ofs);
@@ -185,9 +182,10 @@ void IndexIVFPQR::search_preassigned(
185182
idx_t id = invlists->get_single_id(list_no, ofs);
186183
assert(0 <= id && id < ntotal);
187184
refine_pq.decode(
188-
&refine_codes[id * refine_pq.code_size], residual_1);
185+
&refine_codes[id * refine_pq.code_size],
186+
residual_1.get());
189187

190-
float dis = fvec_L2sqr(residual_1, residual_2, d);
188+
float dis = fvec_L2sqr(residual_1.get(), residual_2, d);
191189

192190
if (dis < heap_sim[0]) {
193191
idx_t id_or_pair = store_pairs ? sl : id;

faiss/IndexLSH.cpp

+13-15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <cstring>
1212

1313
#include <algorithm>
14+
#include <memory>
1415

1516
#include <faiss/impl/FaissAssert.h>
1617
#include <faiss/utils/hamming.h>
@@ -75,18 +76,17 @@ void IndexLSH::train(idx_t n, const float* x) {
7576
thresholds.resize(nbits);
7677
train_thresholds = false;
7778
const float* xt = apply_preprocess(n, x);
78-
ScopeDeleter<float> del(xt == x ? nullptr : xt);
79+
std::unique_ptr<const float[]> del(xt == x ? nullptr : xt);
7980
train_thresholds = true;
8081

81-
float* transposed_x = new float[n * nbits];
82-
ScopeDeleter<float> del2(transposed_x);
82+
std::unique_ptr<float[]> transposed_x(new float[n * nbits]);
8383

8484
for (idx_t i = 0; i < n; i++)
8585
for (idx_t j = 0; j < nbits; j++)
8686
transposed_x[j * n + i] = xt[i * nbits + j];
8787

8888
for (idx_t i = 0; i < nbits; i++) {
89-
float* xi = transposed_x + i * n;
89+
float* xi = transposed_x.get() + i * n;
9090
// std::nth_element
9191
std::sort(xi, xi + n);
9292
if (n % 2 == 1)
@@ -110,19 +110,17 @@ void IndexLSH::search(
110110
FAISS_THROW_IF_NOT(k > 0);
111111
FAISS_THROW_IF_NOT(is_trained);
112112
const float* xt = apply_preprocess(n, x);
113-
ScopeDeleter<float> del(xt == x ? nullptr : xt);
113+
std::unique_ptr<const float[]> del(xt == x ? nullptr : xt);
114114

115-
uint8_t* qcodes = new uint8_t[n * code_size];
116-
ScopeDeleter<uint8_t> del2(qcodes);
115+
std::unique_ptr<uint8_t[]> qcodes(new uint8_t[n * code_size]);
117116

118-
fvecs2bitvecs(xt, qcodes, nbits, n);
117+
fvecs2bitvecs(xt, qcodes.get(), nbits, n);
119118

120-
int* idistances = new int[n * k];
121-
ScopeDeleter<int> del3(idistances);
119+
std::unique_ptr<int[]> idistances(new int[n * k]);
122120

123-
int_maxheap_array_t res = {size_t(n), size_t(k), labels, idistances};
121+
int_maxheap_array_t res = {size_t(n), size_t(k), labels, idistances.get()};
124122

125-
hammings_knn_hc(&res, qcodes, codes.data(), ntotal, code_size, true);
123+
hammings_knn_hc(&res, qcodes.get(), codes.data(), ntotal, code_size, true);
126124

127125
// convert distances to floats
128126
for (int i = 0; i < k * n; i++)
@@ -146,16 +144,16 @@ void IndexLSH::transfer_thresholds(LinearTransform* vt) {
146144
void IndexLSH::sa_encode(idx_t n, const float* x, uint8_t* bytes) const {
147145
FAISS_THROW_IF_NOT(is_trained);
148146
const float* xt = apply_preprocess(n, x);
149-
ScopeDeleter<float> del(xt == x ? nullptr : xt);
147+
std::unique_ptr<const float[]> del(xt == x ? nullptr : xt);
150148
fvecs2bitvecs(xt, bytes, nbits, n);
151149
}
152150

153151
void IndexLSH::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
154152
float* xt = x;
155-
ScopeDeleter<float> del;
153+
std::unique_ptr<float[]> del;
156154
if (rotate_data || nbits != d) {
157155
xt = new float[n * nbits];
158-
del.set(xt);
156+
del.reset(xt);
159157
}
160158
bitvecs2fvecs(bytes, xt, nbits, n);
161159

0 commit comments

Comments
 (0)