Skip to content

Commit

Permalink
Deprecate ScopeDeleter and ScopeDeleter1 in favor of std::unique_ptr<…
Browse files Browse the repository at this point in the history
…[]> (facebookresearch#3108)

Summary: Pull Request resolved: facebookresearch#3108

Reviewed By: mlomeli1

Differential Revision: D50595705

Pulled By: mdouze

fbshipit-source-id: 8555c13609747b7b61201225fcd036d80b50ae59
  • Loading branch information
alexanderguzhva authored and abhinavdangeti committed Jul 12, 2024
1 parent 545cc14 commit bb2f42a
Show file tree
Hide file tree
Showing 20 changed files with 198 additions and 240 deletions.
8 changes: 4 additions & 4 deletions faiss/IVFlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,14 @@ void search_with_parameters(
double* ms_per_stage) {
FAISS_THROW_IF_NOT(params);
const float* prev_x = x;
ScopeDeleter<float> del;
std::unique_ptr<const float[]> del;

double t0 = getmillisecs();

if (auto ip = dynamic_cast<const IndexPreTransform*>(index)) {
x = ip->apply_chain(n, x);
if (x != prev_x) {
del.set(x);
del.reset(x);
}
index = ip->index;
}
Expand Down Expand Up @@ -376,14 +376,14 @@ void range_search_with_parameters(
double* ms_per_stage) {
FAISS_THROW_IF_NOT(params);
const float* prev_x = x;
ScopeDeleter<float> del;
std::unique_ptr<const float[]> del;

double t0 = getmillisecs();

if (auto ip = dynamic_cast<const IndexPreTransform*>(index)) {
x = ip->apply_chain(n, x);
if (x != prev_x) {
del.set(x);
del.reset(x);
}
index = ip->index;
}
Expand Down
2 changes: 1 addition & 1 deletion faiss/Index2Layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void Index2Layer::train(idx_t n, const float* x) {
verbose,
pq.cp.seed);

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

std::vector<idx_t> assign(n); // assignement to coarse centroids
q1.quantizer->assign(n, x, assign.data());
Expand Down
34 changes: 16 additions & 18 deletions faiss/IndexHNSW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,8 @@ void hnsw_add_vertices(
{
VisitedTable vt(ntotal);

DistanceComputer* dis =
storage_distance_computer(index_hnsw.storage);
ScopeDeleter1<DistanceComputer> del(dis);
std::unique_ptr<DistanceComputer> dis(
storage_distance_computer(index_hnsw.storage));
int prev_display =
verbose && omp_get_thread_num() == 0 ? 0 : -1;
size_t counter = 0;
Expand Down Expand Up @@ -301,8 +300,8 @@ void IndexHNSW::search(
{
VisitedTable vt(ntotal);

DistanceComputer* dis = storage_distance_computer(storage);
ScopeDeleter1<DistanceComputer> del(dis);
std::unique_ptr<DistanceComputer> dis(
storage_distance_computer(storage));

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

#pragma omp for
for (idx_t i = 0; i < ntotal; i++) {
Expand Down Expand Up @@ -507,8 +506,8 @@ void IndexHNSW::init_level_0_from_entry_points(
{
VisitedTable vt(ntotal);

DistanceComputer* dis = storage_distance_computer(storage);
ScopeDeleter1<DistanceComputer> del(dis);
std::unique_ptr<DistanceComputer> dis(
storage_distance_computer(storage));
std::vector<float> vec(storage->d);

#pragma omp for schedule(dynamic)
Expand Down Expand Up @@ -543,8 +542,8 @@ void IndexHNSW::reorder_links() {
std::vector<float> distances(M);
std::vector<size_t> order(M);
std::vector<storage_idx_t> tmp(M);
DistanceComputer* dis = storage_distance_computer(storage);
ScopeDeleter1<DistanceComputer> del(dis);
std::unique_ptr<DistanceComputer> dis(
storage_distance_computer(storage));

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

// collect coordinates of base
get_neighbor_table(i, tmp1);
get_neighbor_table(i, tmp1.get());

for (size_t sq = 0; sq < nsq; sq++) {
int d0 = sq * dsub;
Expand All @@ -816,7 +814,7 @@ void ReconstructFromNeighbors::estimate_code(
&ki,
&m1,
&one,
tmp1 + d0,
tmp1.get() + d0,
&di,
codebook.data() + sq * (m1 * k),
&m1,
Expand Down Expand Up @@ -1033,8 +1031,8 @@ void IndexHNSW2Level::search(
#pragma omp parallel
{
VisitedTable vt(ntotal);
DistanceComputer* dis = storage_distance_computer(storage);
ScopeDeleter1<DistanceComputer> del(dis);
std::unique_ptr<DistanceComputer> dis(
storage_distance_computer(storage));

int candidates_size = hnsw.upper_beam;
MinimaxHeap candidates(candidates_size);
Expand Down
5 changes: 2 additions & 3 deletions faiss/IndexIVF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,8 @@ void IndexIVF::search_preassigned(

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

/*****************************************************
* Depending on parallel_mode, there are two possible ways
Expand Down
31 changes: 15 additions & 16 deletions faiss/IndexIVFPQ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,20 @@ void IndexIVFPQ::add_core(
add_core_o(n, x, xids, nullptr, coarse_idx);
}

static float* compute_residuals(
static std::unique_ptr<float[]> compute_residuals(
const Index* quantizer,
idx_t n,
const float* x,
const idx_t* list_nos) {
size_t d = quantizer->d;
float* residuals = new float[n * d];
std::unique_ptr<float[]> residuals(new float[n * d]);
// TODO: parallelize?
for (size_t i = 0; i < n; i++) {
if (list_nos[i] < 0)
memset(residuals + i * d, 0, sizeof(*residuals) * d);
memset(residuals.get() + i * d, 0, sizeof(float) * d);
else
quantizer->compute_residual(
x + i * d, residuals + i * d, list_nos[i]);
x + i * d, residuals.get() + i * d, list_nos[i]);
}
return residuals;
}
Expand All @@ -164,9 +164,9 @@ void IndexIVFPQ::encode_vectors(
uint8_t* codes,
bool include_listnos) const {
if (by_residual) {
float* to_encode = compute_residuals(quantizer, n, x, list_nos);
ScopeDeleter<float> del(to_encode);
pq.compute_codes(to_encode, codes, n);
std::unique_ptr<float[]> to_encode =
compute_residuals(quantizer, n, x, list_nos);
pq.compute_codes(to_encode.get(), codes, n);
} else {
pq.compute_codes(x, codes, n);
}
Expand Down Expand Up @@ -241,31 +241,30 @@ void IndexIVFPQ::add_core_o(
FAISS_THROW_IF_NOT(is_trained);
double t0 = getmillisecs();
const idx_t* idx;
ScopeDeleter<idx_t> del_idx;
std::unique_ptr<idx_t[]> del_idx;

if (precomputed_idx) {
idx = precomputed_idx;
} else {
idx_t* idx0 = new idx_t[n];
del_idx.set(idx0);
del_idx.reset(idx0);
quantizer->assign(n, x, idx0);
idx = idx0;
}

double t1 = getmillisecs();
uint8_t* xcodes = new uint8_t[n * code_size];
ScopeDeleter<uint8_t> del_xcodes(xcodes);
std::unique_ptr<uint8_t[]> xcodes(new uint8_t[n * code_size]);

const float* to_encode = nullptr;
ScopeDeleter<float> del_to_encode;
std::unique_ptr<const float[]> del_to_encode;

if (by_residual) {
to_encode = compute_residuals(quantizer, n, x, idx);
del_to_encode.set(to_encode);
del_to_encode = compute_residuals(quantizer, n, x, idx);
to_encode = del_to_encode.get();
} else {
to_encode = x;
}
pq.compute_codes(to_encode, xcodes, n);
pq.compute_codes(to_encode, xcodes.get(), n);

double t2 = getmillisecs();
// TODO: parallelize?
Expand All @@ -281,7 +280,7 @@ void IndexIVFPQ::add_core_o(
continue;
}

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

if (residuals_2) {
Expand Down
34 changes: 16 additions & 18 deletions faiss/IndexIVFPQR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,16 @@ void IndexIVFPQR::add_core(
const float* x,
const idx_t* xids,
const idx_t* precomputed_idx) {
float* residual_2 = new float[n * d];
ScopeDeleter<float> del(residual_2);
std::unique_ptr<float[]> residual_2(new float[n * d]);

idx_t n0 = ntotal;

add_core_o(n, x, xids, residual_2, precomputed_idx);
add_core_o(n, x, xids, residual_2.get(), precomputed_idx);

refine_codes.resize(ntotal * refine_pq.code_size);

refine_pq.compute_codes(
residual_2, &refine_codes[n0 * refine_pq.code_size], n);
residual_2.get(), &refine_codes[n0 * refine_pq.code_size], n);
}
#define TIC t0 = get_cycles()
#define TOC get_cycles() - t0
Expand All @@ -121,20 +120,19 @@ void IndexIVFPQR::search_preassigned(
uint64_t t0;
TIC;
size_t k_coarse = long(k * k_factor);
idx_t* coarse_labels = new idx_t[k_coarse * n];
ScopeDeleter<idx_t> del1(coarse_labels);
{ // query with quantizer levels 1 and 2.
float* coarse_distances = new float[k_coarse * n];
ScopeDeleter<float> del(coarse_distances);
std::unique_ptr<idx_t[]> coarse_labels(new idx_t[k_coarse * n]);
{
// query with quantizer levels 1 and 2.
std::unique_ptr<float[]> coarse_distances(new float[k_coarse * n]);

IndexIVFPQ::search_preassigned(
n,
x,
k_coarse,
idx,
L1_dis,
coarse_distances,
coarse_labels,
coarse_distances.get(),
coarse_labels.get(),
true,
params);
}
Expand All @@ -148,13 +146,12 @@ void IndexIVFPQR::search_preassigned(
#pragma omp parallel reduction(+ : n_refine)
{
// tmp buffers
float* residual_1 = new float[2 * d];
ScopeDeleter<float> del(residual_1);
float* residual_2 = residual_1 + d;
std::unique_ptr<float[]> residual_1(new float[2 * d]);
float* residual_2 = residual_1.get() + d;
#pragma omp for
for (idx_t i = 0; i < n; i++) {
const float* xq = x + i * d;
const idx_t* shortlist = coarse_labels + k_coarse * i;
const idx_t* shortlist = coarse_labels.get() + k_coarse * i;
float* heap_sim = distances + k * i;
idx_t* heap_ids = labels + k * i;
maxheap_heapify(k, heap_sim, heap_ids);
Expand All @@ -172,7 +169,7 @@ void IndexIVFPQR::search_preassigned(
assert(ofs >= 0 && ofs < invlists->list_size(list_no));

// 1st level residual
quantizer->compute_residual(xq, residual_1, list_no);
quantizer->compute_residual(xq, residual_1.get(), list_no);

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

float dis = fvec_L2sqr(residual_1, residual_2, d);
float dis = fvec_L2sqr(residual_1.get(), residual_2, d);

if (dis < heap_sim[0]) {
idx_t id_or_pair = store_pairs ? sl : id;
Expand Down
28 changes: 13 additions & 15 deletions faiss/IndexLSH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <cstring>

#include <algorithm>
#include <memory>

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

float* transposed_x = new float[n * nbits];
ScopeDeleter<float> del2(transposed_x);
std::unique_ptr<float[]> transposed_x(new float[n * nbits]);

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

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

uint8_t* qcodes = new uint8_t[n * code_size];
ScopeDeleter<uint8_t> del2(qcodes);
std::unique_ptr<uint8_t[]> qcodes(new uint8_t[n * code_size]);

fvecs2bitvecs(xt, qcodes, nbits, n);
fvecs2bitvecs(xt, qcodes.get(), nbits, n);

int* idistances = new int[n * k];
ScopeDeleter<int> del3(idistances);
std::unique_ptr<int[]> idistances(new int[n * k]);

int_maxheap_array_t res = {size_t(n), size_t(k), labels, idistances};
int_maxheap_array_t res = {size_t(n), size_t(k), labels, idistances.get()};

hammings_knn_hc(&res, qcodes, codes.data(), ntotal, code_size, true);
hammings_knn_hc(&res, qcodes.get(), codes.data(), ntotal, code_size, true);

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

void IndexLSH::sa_decode(idx_t n, const uint8_t* bytes, float* x) const {
float* xt = x;
ScopeDeleter<float> del;
std::unique_ptr<float[]> del;
if (rotate_data || nbits != d) {
xt = new float[n * nbits];
del.set(xt);
del.reset(xt);
}
bitvecs2fvecs(bytes, xt, nbits, n);

Expand Down
Loading

0 comments on commit bb2f42a

Please sign in to comment.