Unverified Commit 2c9aea24 authored by Lucas Hosseini's avatar Lucas Hosseini Committed by GitHub

[WIP] Update tutorial examples (#342)

* Remove transitional print import.

* Add example for multiple GPUs in python.

* Add example on GPU in C++.

* Add example on multiple GPUs in C++.

* Add IVFFlat example on GPU in python.

* Add Makefile for C++ tutorial examples.

* Add IVF index on GPU example in C++.
parent d970473d
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD+Patents license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <faiss/IndexFlat.h>
#include <faiss/gpu/GpuIndexFlat.h>
#include <faiss/gpu/GpuIndexIVFFlat.h>
#include <faiss/gpu/StandardGpuResources.h>
int main() {
int d = 64; // dimension
int nb = 100000; // database size
int nq = 10000; // nb of queries
float *xb = new float[d * nb];
float *xq = new float[d * nq];
for(int i = 0; i < nb; i++) {
for(int j = 0; j < d; j++)
xb[d * i + j] = drand48();
xb[d * i] += i / 1000.;
}
for(int i = 0; i < nq; i++) {
for(int j = 0; j < d; j++)
xq[d * i + j] = drand48();
xq[d * i] += i / 1000.;
}
int k = 4;
faiss::gpu::StandardGpuResources res;
// Using a flat index
faiss::gpu::GpuIndexFlatL2 index_flat(&res, d);
printf("is_trained = %s\n", index_flat.is_trained ? "true" : "false");
index_flat.add(nb, xb); // add vectors to the index
printf("ntotal = %ld\n", index_flat.ntotal);
{ // search xq
long *I = new long[k * nq];
float *D = new float[k * nq];
index_flat.search(nq, xq, k, D, I);
// print results
printf("I (5 first results)=\n");
for(int i = 0; i < 5; i++) {
for(int j = 0; j < k; j++)
printf("%5ld ", I[i * k + j]);
printf("\n");
}
printf("I (5 last results)=\n");
for(int i = nq - 5; i < nq; i++) {
for(int j = 0; j < k; j++)
printf("%5ld ", I[i * k + j]);
printf("\n");
}
delete [] I;
delete [] D;
}
// Using an IVF index
int nlist = 100;
faiss::gpu::GpuIndexIVFFlat index_ivf(&res, d, nlist, faiss::METRIC_L2);
// here we specify METRIC_L2, by default it performs inner-product search
assert(!index_ivf.is_trained);
index_ivf.train(nb, xb);
assert(index_ivf.is_trained);
index_ivf.add(nb, xb); // add vectors to the index
printf("is_trained = %s\n", index_ivf.is_trained ? "true" : "false");
printf("ntotal = %ld\n", index_ivf.ntotal);
{ // search xq
long *I = new long[k * nq];
float *D = new float[k * nq];
index_ivf.search(nq, xq, k, D, I);
// print results
printf("I (5 first results)=\n");
for(int i = 0; i < 5; i++) {
for(int j = 0; j < k; j++)
printf("%5ld ", I[i * k + j]);
printf("\n");
}
printf("I (5 last results)=\n");
for(int i = nq - 5; i < nq; i++) {
for(int j = 0; j < k; j++)
printf("%5ld ", I[i * k + j]);
printf("\n");
}
delete [] I;
delete [] D;
}
delete [] xb;
delete [] xq;
return 0;
}
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD+Patents license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <cstdio>
#include <cstdlib>
#include <faiss/IndexFlat.h>
#include <faiss/gpu/GpuAutoTune.h>
#include <faiss/gpu/GpuIndexFlat.h>
#include <faiss/gpu/StandardGpuResources.h>
#include <faiss/gpu/utils/DeviceUtils.h>
int main() {
int d = 64; // dimension
int nb = 100000; // database size
int nq = 10000; // nb of queries
float *xb = new float[d * nb];
float *xq = new float[d * nq];
for(int i = 0; i < nb; i++) {
for(int j = 0; j < d; j++)
xb[d * i + j] = drand48();
xb[d * i] += i / 1000.;
}
for(int i = 0; i < nq; i++) {
for(int j = 0; j < d; j++)
xq[d * i + j] = drand48();
xq[d * i] += i / 1000.;
}
int ngpus = faiss::gpu::getNumDevices();
std::vector<faiss::gpu::GpuResources*> res;
std::vector<int> devs;
for(int i = 0; i < ngpus; i++) {
res.push_back(new faiss::gpu::StandardGpuResources);
devs.push_back(i);
}
faiss::IndexFlatL2 cpu_index(d);
faiss::Index *gpu_index =
faiss::gpu::index_cpu_to_gpu_multiple(
res,
devs,
&cpu_index
);
printf("is_trained = %s\n", gpu_index->is_trained ? "true" : "false");
gpu_index->add(nb, xb); // vectors to the index
printf("ntotal = %ld\n", gpu_index->ntotal);
int k = 4;
{ // search xq
long *I = new long[k * nq];
float *D = new float[k * nq];
gpu_index->search(nq, xq, k, D, I);
// print results
printf("I (5 first results)=\n");
for(int i = 0; i < 5; i++) {
for(int j = 0; j < k; j++)
printf("%5ld ", I[i * k + j]);
printf("\n");
}
printf("I (5 last results)=\n");
for(int i = nq - 5; i < nq; i++) {
for(int j = 0; j < k; j++)
printf("%5ld ", I[i * k + j]);
printf("\n");
}
delete [] I;
delete [] D;
}
delete gpu_index;
for(int i = 0; i < ngpus; i++) {
delete res[i];
}
delete [] xb;
delete [] xq;
return 0;
}
MAKEFILE_INC=../../makefile.inc
-include $(MAKEFILE_INC)
all: cpu gpu
cpu: 1-Flat 2-IVFFlat 3-IVFPQ
gpu: 4-GPU 5-Multiple-GPUs
1-Flat: 1-Flat.cpp ../../libfaiss.a
$(CC) -o $@ $(CFLAGS) $^ -I../../../ $(LDFLAGS) $(BLASLDFLAGS)
2-IVFFlat: 2-IVFFlat.cpp ../../libfaiss.a
$(CC) -o $@ $(CFLAGS) $^ -I../../../ $(LDFLAGS) $(BLASLDFLAGS)
3-IVFPQ: 3-IVFPQ.cpp ../../libfaiss.a
$(CC) -o $@ $(CFLAGS) $^ -I../../../ $(LDFLAGS) $(BLASLDFLAGS)
4-GPU: 4-GPU.cpp ../../libfaiss.a ../../gpu/libgpufaiss.a
$(NVCC) $(NVCCFLAGS) -o $@ $^ -I../../../ -Xcompiler -fopenmp -lcublas \
$(BLASLDFLAGSNVCC)
5-Multiple-GPUs: 5-Multiple-GPUs.cpp ../../libfaiss.a ../../gpu/libgpufaiss.a
$(NVCC) $(NVCCFLAGS) -o $@ $^ -I../../../ -Xcompiler -fopenmp -lcublas \
$(BLASLDFLAGSNVCC)
......@@ -4,7 +4,6 @@
# This source code is licensed under the BSD+Patents license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import print_function
import numpy as np
d = 64 # dimension
......
......@@ -4,7 +4,6 @@
# This source code is licensed under the BSD+Patents license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import print_function
import numpy as np
d = 64 # dimension
......
......@@ -4,7 +4,6 @@
# This source code is licensed under the BSD+Patents license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import print_function
import numpy as np
d = 64 # dimension
......
......@@ -4,7 +4,6 @@
# This source code is licensed under the BSD+Patents license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import print_function
import numpy as np
d = 64 # dimension
......@@ -16,20 +15,46 @@ xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.
import faiss # make faiss available
import faiss # make faiss available
print("number of GPUs:", faiss.get_num_gpus())
index = faiss.IndexFlatL2(d) # build the index
res = faiss.StandardGpuResources() # use a single GPU
res = faiss.StandardGpuResources()
## Using a flat index
index = faiss.index_cpu_to_gpu(res, 0, index)
index_flat = faiss.IndexFlatL2(d) # build a flat (CPU) index
index.add(xb) # add vectors to the index
print(index.ntotal)
# make it a flat GPU index
gpu_index_flat = faiss.index_cpu_to_gpu(res, 0, index_flat)
gpu_index_flat.add(xb) # add vectors to the index
print(gpu_index_flat.ntotal)
k = 4 # we want to see 4 nearest neighbors
D, I = gpu_index_flat.search(xq, k) # actual search
print(I[:5]) # neighbors of the 5 first queries
print(I[-5:]) # neighbors of the 5 last queries
## Using an IVF index
nlist = 100
quantizer = faiss.IndexFlatL2(d) # the other index
index_ivf = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2)
# here we specify METRIC_L2, by default it performs inner-product search
# make it an IVF GPU index
gpu_index_ivf = faiss.index_cpu_to_gpu(res, 0, index_ivf)
assert not gpu_index_ivf.is_trained
gpu_index_ivf.train(xb) # add vectors to the index
assert gpu_index_ivf.is_trained
gpu_index_ivf.add(xb) # add vectors to the index
print(gpu_index_ivf.ntotal)
k = 4 # we want to see 4 nearest neighbors
D, I = index.search(xq, k) # actual search
D, I = gpu_index_ivf.search(xq, k) # actual search
print(I[:5]) # neighbors of the 5 first queries
print(I[-5:]) # neighbors of the 5 last queries
# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD+Patents license found in the
# LICENSE file in the root directory of this source tree.
import numpy as np
d = 64 # dimension
nb = 100000 # database size
nq = 10000 # nb of queries
np.random.seed(1234) # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.
import faiss # make faiss available
ngpus = faiss.get_num_gpus()
print("number of GPUs:", ngpus)
index = faiss.index_cpu_to_all_gpus( # build the index
faiss.IndexFlatL2(d)
)
index.add(xb) # add vectors to the index
print(index.ntotal)
k = 4 # we want to see 4 nearest neighbors
D, I = index.search(xq, k) # actual search
print(I[:5]) # neighbors of the 5 first queries
print(I[-5:]) # neighbors of the 5 last queries
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment