Skip to content

Conversation

beauby
Copy link
Contributor

@beauby beauby commented Feb 19, 2018

  • Remove transitional print import.
  • Add C++ code example for one GPU.
  • Add python/C++ code examples for several GPUs.

@mdouze
Copy link
Contributor

mdouze commented Feb 19, 2018

Have you tested with py2 + py3?

@beauby beauby changed the title Update tutorial [WIP] Update tutorial Feb 19, 2018
@beauby
Copy link
Contributor Author

beauby commented Feb 19, 2018

@mdouze Yes, python2.7 and python3.6.

Copy link
Contributor

@Enet4 Enet4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope you don't mind that I throw in a few comments on the C++ examples. Feel free to disregard them if they are not deemed important enough for this context. As code is copied all the time, I would say that providing examples with good practices is a plus.

xq[d * i] += i / 1000.;
}

faiss::gpu::GpuResources *res = new faiss::gpu::StandardGpuResources;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to allocate res with new here? It already seems to outlive all indexes in the example, so a plain object with automatic storage duration would suffice:

faiss::gpu::StandardGpuResources res;
faiss::GpuIndexFlatL2 index(&res, d);

std::vector<faiss::gpu::GpuResources*> res;
std::vector<int> devs;
for(int i = 0; i < ngpus; i++) {
res.push_back(new faiss::gpu::StandardGpuResources);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar reasoning could be applied here, but alas, it would require another vector to keep the pointers to the resource objects. Other than that, a vector of ngpu GPU resources can be even created inplace without a loop. I can't think of a better way to do this unfortunately. This is what it would look like:

std::vector<faiss::gpu::StandardGpuResources> owned_res{ngpus};
std::vector<faiss::gpu::GpuResources*> res{ngpus};
std::vector<int> devs{ngpus};
for (int i = 0; i < ngpus; i++) {
    res[i] = &owned_res[i];
    devs[i] = i;
}

int k = 4;

{ // sanity check: search 5 first vectors of xb
long *I = new long[k * 5];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When relying on C++11, one can wrap these data allocations around a unique_ptr. Not only it would be automatically freed when falling out of scope, it would protect also prevent leaks in case of exceptions.

#include <memory>

// ...

auto I = std::unique_ptr<long[]>(new long[k * 5]);
auto D = std::unique_ptr<float[]>(new float[k * 5]);

index.search(5, xb, k, D.get(), I.get());

devs.push_back(i);
}

faiss::Index *index =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this in a more complicated context, wouldn't want the index to leak. I believe a unique_ptr around the pointer to the GPU index works fine here.

auto index = std::unique_ptr<faiss::Index>(
    faiss::gpu::index_cpu_to_gpu_multiple(
        res,
        devs,
        new faiss::IndexFlat(d)
    ));

@beauby
Copy link
Contributor Author

beauby commented Feb 20, 2018

@Enet4 Thanks for your comments. Agreed that providing examples with good practices is a plus. I modified the example on one GPU to avoid using new, as it was totally unnecessary.

Regarding the (lack of) use of unique_ptrs, the rationale is to avoid scaring off people who are not familiar with it, and focus on the library usage.

@beauby beauby force-pushed the update-tutorial branch 2 times, most recently from b491746 to 33f6a01 Compare February 20, 2018 11:06
@beauby beauby force-pushed the update-tutorial branch 4 times, most recently from 1e729c0 to 8dd8f7c Compare February 20, 2018 12:09
@beauby beauby force-pushed the update-tutorial branch 3 times, most recently from b975870 to 0b23b79 Compare February 20, 2018 12:42
faiss::gpu::GpuResources *res = new faiss::gpu::StandardGpuResources;

faiss::GpuIndexFlatL2 index(res, d); // call constructor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inconsistent: resources is allocated with new, GpuIndexFlat is allocated on the stack

faiss::gpu::index_cpu_to_gpu_multiple( // call constructor
res,
devs,
new faiss::IndexFlatL2(d)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not be deallocated, so it should be declared separately.


int k = 4;

{ // sanity check: search 5 first vectors of xb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the sanity check, we will not comment it twice


gpu: tutorial4 tutorial5

tutorial1: 1-Flat.cpp ../../libfaiss.a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you call the executables 1-Flat, 2-IVFFlat, etc. ?

@beauby beauby merged commit 2c9aea2 into facebookresearch:master Feb 20, 2018
@beauby beauby deleted the update-tutorial branch February 20, 2018 14:54
@beauby beauby changed the title [WIP] Update tutorial Update tutorial Feb 20, 2018
std::vector<faiss::gpu::GpuResources*> res;
std::vector<int> devs;
for(int i = 0; i < ngpus; i++) {
res.push_back(new faiss::gpu::StandardGpuResources);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use std::unique_ptr at the least if you keep it by pointer, so you don't need the free at the end.

CaucherWang pushed a commit to CaucherWang/faiss-learned-termination that referenced this pull request Sep 16, 2022
* 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++.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants