Initial commit

This commit is contained in:
yichuan520030910320
2025-06-30 09:05:05 +00:00
commit 46f6cc100b
1231 changed files with 278432 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
target_sources(faiss_c PRIVATE
DeviceUtils_c.cpp
GpuAutoTune_c.cpp
GpuClonerOptions_c.cpp
GpuIndex_c.cpp
GpuResources_c.cpp
StandardGpuResources_c.cpp
)
file(GLOB FAISS_C_API_GPU_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
faiss_install_headers("${FAISS_C_API_GPU_HEADERS}" c_api/gpu)
if (FAISS_ENABLE_ROCM)
target_link_libraries(faiss_c PUBLIC hip::host roc::hipblas)
target_link_libraries(faiss_c_avx2 PUBLIC hip::host roc::hipblas)
target_link_libraries(faiss_c_avx512 PUBLIC hip::host roc::hipblas)
target_link_libraries(faiss_c_avx512_spr PUBLIC hip::host roc::hipblas)
target_link_libraries(faiss_c_sve PUBLIC hip::host roc::hipblas)
else()
find_package(CUDAToolkit REQUIRED)
target_link_libraries(faiss_c PUBLIC CUDA::cudart CUDA::cublas $<$<BOOL:${FAISS_ENABLE_CUVS}>:cuvs::cuvs>)
target_link_libraries(faiss_c_avx2 PUBLIC CUDA::cudart CUDA::cublas $<$<BOOL:${FAISS_ENABLE_CUVS}>:cuvs::cuvs>)
target_link_libraries(faiss_c_avx512 PUBLIC CUDA::cudart CUDA::cublas $<$<BOOL:${FAISS_ENABLE_CUVS}>:cuvs::cuvs>)
target_link_libraries(faiss_c_avx512_spr PUBLIC CUDA::cudart CUDA::cublas $<$<BOOL:${FAISS_ENABLE_CUVS}>:cuvs::cuvs>)
target_link_libraries(faiss_c_sve PUBLIC CUDA::cudart CUDA::cublas $<$<BOOL:${FAISS_ENABLE_CUVS}>:cuvs::cuvs>)
endif()
add_executable(example_gpu_c EXCLUDE_FROM_ALL example_gpu_c.c)
target_link_libraries(example_gpu_c PRIVATE faiss_c)

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#include "DeviceUtils_c.h"
#include <faiss/gpu/utils/DeviceUtils.h>
#include "macros_impl.h"
/// Returns the number of available GPU devices
int faiss_get_num_gpus(int* p_output) {
try {
int output = faiss::gpu::getNumDevices();
*p_output = output;
}
CATCH_AND_HANDLE
}
/// Starts the CUDA profiler (exposed via SWIG)
int faiss_gpu_profiler_start() {
try {
faiss::gpu::profilerStart();
}
CATCH_AND_HANDLE
}
/// Stops the CUDA profiler (exposed via SWIG)
int faiss_gpu_profiler_stop() {
try {
faiss::gpu::profilerStop();
}
CATCH_AND_HANDLE
}
/// Synchronizes the CPU against all devices (equivalent to
/// cudaDeviceSynchronize for each device)
int faiss_gpu_sync_all_devices() {
try {
faiss::gpu::synchronizeAllDevices();
}
CATCH_AND_HANDLE
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_DEVICE_UTILS_C_H
#define FAISS_DEVICE_UTILS_C_H
#include <cublas_v2.h>
#include <cuda_runtime_api.h>
#include "../faiss_c.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Returns the number of available GPU devices
int faiss_get_num_gpus(int* p_output);
/// Starts the CUDA profiler (exposed via SWIG)
int faiss_gpu_profiler_start();
/// Stops the CUDA profiler (exposed via SWIG)
int faiss_gpu_profiler_stop();
/// Synchronizes the CPU against all devices (equivalent to
/// cudaDeviceSynchronize for each device)
int faiss_gpu_sync_all_devices();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#include "GpuAutoTune_c.h"
#include <faiss/Index.h>
#include <faiss/gpu/GpuAutoTune.h>
#include <faiss/gpu/GpuCloner.h>
#include <faiss/gpu/GpuClonerOptions.h>
#include <faiss/gpu/GpuResources.h>
#include <vector>
#include "GpuClonerOptions_c.h"
#include "macros_impl.h"
using faiss::Index;
using faiss::gpu::GpuClonerOptions;
using faiss::gpu::GpuMultipleClonerOptions;
using faiss::gpu::GpuResourcesProvider;
int faiss_index_gpu_to_cpu(const FaissIndex* gpu_index, FaissIndex** p_out) {
try {
auto cpu_index = faiss::gpu::index_gpu_to_cpu(
reinterpret_cast<const Index*>(gpu_index));
*p_out = reinterpret_cast<FaissIndex*>(cpu_index);
}
CATCH_AND_HANDLE
}
/// converts any CPU index that can be converted to GPU
int faiss_index_cpu_to_gpu(
FaissGpuResourcesProvider* provider,
int device,
const FaissIndex* index,
FaissGpuIndex** p_out) {
try {
auto res = reinterpret_cast<GpuResourcesProvider*>(provider);
auto gpu_index = faiss::gpu::index_cpu_to_gpu(
res, device, reinterpret_cast<const Index*>(index));
*p_out = reinterpret_cast<FaissGpuIndex*>(gpu_index);
}
CATCH_AND_HANDLE
}
int faiss_index_cpu_to_gpu_with_options(
FaissGpuResourcesProvider* provider,
int device,
const FaissIndex* index,
const FaissGpuClonerOptions* options,
FaissGpuIndex** p_out) {
try {
auto res = reinterpret_cast<GpuResourcesProvider*>(provider);
auto gpu_index = faiss::gpu::index_cpu_to_gpu(
res,
device,
reinterpret_cast<const Index*>(index),
reinterpret_cast<const GpuClonerOptions*>(options));
*p_out = reinterpret_cast<FaissGpuIndex*>(gpu_index);
}
CATCH_AND_HANDLE
}
int faiss_index_cpu_to_gpu_multiple(
FaissGpuResourcesProvider* const* providers_vec,
const int* devices,
size_t devices_size,
const FaissIndex* index,
FaissGpuIndex** p_out) {
try {
std::vector<GpuResourcesProvider*> res(devices_size);
for (auto i = 0u; i < devices_size; ++i) {
res[i] = reinterpret_cast<GpuResourcesProvider*>(providers_vec[i]);
}
std::vector<int> dev(devices, devices + devices_size);
auto gpu_index = faiss::gpu::index_cpu_to_gpu_multiple(
res, dev, reinterpret_cast<const Index*>(index));
*p_out = reinterpret_cast<FaissGpuIndex*>(gpu_index);
}
CATCH_AND_HANDLE
}
int faiss_index_cpu_to_gpu_multiple_with_options(
FaissGpuResourcesProvider* const* providers_vec,
size_t providers_vec_size,
const int* devices,
size_t devices_size,
const FaissIndex* index,
const FaissGpuMultipleClonerOptions* options,
FaissGpuIndex** p_out) {
try {
std::vector<GpuResourcesProvider*> res(providers_vec_size);
for (auto i = 0u; i < providers_vec_size; ++i) {
res[i] = reinterpret_cast<GpuResourcesProvider*>(providers_vec[i]);
}
std::vector<int> dev(devices, devices + devices_size);
auto gpu_index = faiss::gpu::index_cpu_to_gpu_multiple(
res,
dev,
reinterpret_cast<const Index*>(index),
reinterpret_cast<const GpuMultipleClonerOptions*>(options));
*p_out = reinterpret_cast<FaissGpuIndex*>(gpu_index);
}
CATCH_AND_HANDLE
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_GPU_AUTO_TUNE_C_H
#define FAISS_GPU_AUTO_TUNE_C_H
#include <stddef.h>
#include "../Index_c.h"
#include "../faiss_c.h"
#include "GpuClonerOptions_c.h"
#include "GpuIndex_c.h"
#include "GpuResources_c.h"
#ifdef __cplusplus
extern "C" {
#endif
/// converts any GPU index inside gpu_index to a CPU index
int faiss_index_gpu_to_cpu(const FaissIndex* gpu_index, FaissIndex** p_out);
/// converts any CPU index that can be converted to GPU
int faiss_index_cpu_to_gpu(
FaissGpuResourcesProvider* provider,
int device,
const FaissIndex* index,
FaissGpuIndex** p_out);
/// converts any CPU index that can be converted to GPU
int faiss_index_cpu_to_gpu_with_options(
FaissGpuResourcesProvider* provider,
int device,
const FaissIndex* index,
const FaissGpuClonerOptions* options,
FaissGpuIndex** p_out);
/// converts any CPU index that can be converted to GPU
int faiss_index_cpu_to_gpu_multiple(
FaissGpuResourcesProvider* const* providers_vec,
const int* devices,
size_t devices_size,
const FaissIndex* index,
FaissGpuIndex** p_out);
/// converts any CPU index that can be converted to GPU
int faiss_index_cpu_to_gpu_multiple_with_options(
FaissGpuResourcesProvider* const* providers_vec,
size_t providers_vec_size,
const int* devices,
size_t devices_size,
const FaissIndex* index,
const FaissGpuMultipleClonerOptions* options,
FaissGpuIndex** p_out);
/// parameter space and setters for GPU indexes
FAISS_DECLARE_CLASS_INHERITED(GpuParameterSpace, ParameterSpace)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#include "GpuClonerOptions_c.h"
#include <faiss/gpu/GpuClonerOptions.h>
#include "macros_impl.h"
using faiss::gpu::GpuClonerOptions;
using faiss::gpu::GpuMultipleClonerOptions;
using faiss::gpu::IndicesOptions;
int faiss_GpuClonerOptions_new(FaissGpuClonerOptions** p) {
try {
*p = reinterpret_cast<FaissGpuClonerOptions*>(new GpuClonerOptions());
}
CATCH_AND_HANDLE
}
int faiss_GpuMultipleClonerOptions_new(FaissGpuMultipleClonerOptions** p) {
try {
*p = reinterpret_cast<FaissGpuMultipleClonerOptions*>(
new GpuMultipleClonerOptions());
}
CATCH_AND_HANDLE
}
DEFINE_DESTRUCTOR(GpuClonerOptions)
DEFINE_DESTRUCTOR(GpuMultipleClonerOptions)
DEFINE_GETTER(GpuClonerOptions, FaissIndicesOptions, indicesOptions)
DEFINE_GETTER(GpuClonerOptions, int, useFloat16CoarseQuantizer)
DEFINE_GETTER(GpuClonerOptions, int, useFloat16)
DEFINE_GETTER(GpuClonerOptions, int, usePrecomputed)
DEFINE_GETTER(GpuClonerOptions, long, reserveVecs)
DEFINE_GETTER(GpuClonerOptions, int, storeTransposed)
DEFINE_GETTER(GpuClonerOptions, int, verbose)
DEFINE_GETTER(GpuMultipleClonerOptions, int, shard)
DEFINE_GETTER(GpuMultipleClonerOptions, int, shard_type)
DEFINE_SETTER_STATIC(
GpuClonerOptions,
IndicesOptions,
FaissIndicesOptions,
indicesOptions)
DEFINE_SETTER_STATIC(GpuClonerOptions, bool, int, useFloat16CoarseQuantizer)
DEFINE_SETTER_STATIC(GpuClonerOptions, bool, int, useFloat16)
DEFINE_SETTER_STATIC(GpuClonerOptions, bool, int, usePrecomputed)
DEFINE_SETTER(GpuClonerOptions, long, reserveVecs)
DEFINE_SETTER_STATIC(GpuClonerOptions, bool, int, storeTransposed)
DEFINE_SETTER_STATIC(GpuClonerOptions, bool, int, verbose)
DEFINE_SETTER_STATIC(GpuMultipleClonerOptions, bool, int, shard)
DEFINE_SETTER(GpuMultipleClonerOptions, int, shard_type)

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_GPU_CLONER_OPTIONS_C_H
#define FAISS_GPU_CLONER_OPTIONS_C_H
#include "../faiss_c.h"
#include "GpuIndicesOptions_c.h"
#ifdef __cplusplus
extern "C" {
#endif
FAISS_DECLARE_CLASS(GpuClonerOptions)
FAISS_DECLARE_DESTRUCTOR(GpuClonerOptions)
/// Default constructor for GpuClonerOptions
int faiss_GpuClonerOptions_new(FaissGpuClonerOptions**);
/// how should indices be stored on index types that support indices
/// (anything but GpuIndexFlat*)?
FAISS_DECLARE_GETTER_SETTER(
GpuClonerOptions,
FaissIndicesOptions,
indicesOptions)
/// (boolean) is the coarse quantizer in float16?
FAISS_DECLARE_GETTER_SETTER(GpuClonerOptions, int, useFloat16CoarseQuantizer)
/// (boolean) for GpuIndexIVFFlat, is storage in float16?
/// for GpuIndexIVFPQ, are intermediate calculations in float16?
FAISS_DECLARE_GETTER_SETTER(GpuClonerOptions, int, useFloat16)
/// (boolean) use precomputed tables?
FAISS_DECLARE_GETTER_SETTER(GpuClonerOptions, int, usePrecomputed)
/// reserve vectors in the invfiles?
FAISS_DECLARE_GETTER_SETTER(GpuClonerOptions, long, reserveVecs)
/// (boolean) For GpuIndexFlat, store data in transposed layout?
FAISS_DECLARE_GETTER_SETTER(GpuClonerOptions, int, storeTransposed)
/// (boolean) Set verbose options on the index
FAISS_DECLARE_GETTER_SETTER(GpuClonerOptions, int, verbose)
FAISS_DECLARE_CLASS_INHERITED(GpuMultipleClonerOptions, GpuClonerOptions)
FAISS_DECLARE_DESTRUCTOR(GpuMultipleClonerOptions)
/// Default constructor for GpuMultipleClonerOptions
int faiss_GpuMultipleClonerOptions_new(FaissGpuMultipleClonerOptions**);
/// (boolean) Whether to shard the index across GPUs, versus replication
/// across GPUs
FAISS_DECLARE_GETTER_SETTER(GpuMultipleClonerOptions, int, shard)
/// IndexIVF::copy_subset_to subset type
FAISS_DECLARE_GETTER_SETTER(GpuMultipleClonerOptions, int, shard_type)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#include "GpuIndex_c.h"
#include <faiss/gpu/GpuIndex.h>
#include "macros_impl.h"
using faiss::gpu::GpuIndexConfig;
DEFINE_GETTER(GpuIndexConfig, int, device)

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_GPU_INDEX_C_H
#define FAISS_GPU_INDEX_C_H
#include "../faiss_c.h"
#ifdef __cplusplus
extern "C" {
#endif
FAISS_DECLARE_CLASS(GpuIndexConfig)
FAISS_DECLARE_GETTER(GpuIndexConfig, int, device)
FAISS_DECLARE_CLASS_INHERITED(GpuIndex, Index)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_GPU_INDICES_OPTIONS_C_H
#define FAISS_GPU_INDICES_OPTIONS_C_H
#ifdef __cplusplus
extern "C" {
#endif
/// How user vector index data is stored on the GPU
typedef enum FaissIndicesOptions {
/// The user indices are only stored on the CPU; the GPU returns
/// (inverted list, offset) to the CPU which is then translated to
/// the real user index.
INDICES_CPU = 0,
/// The indices are not stored at all, on either the CPU or
/// GPU. Only (inverted list, offset) is returned to the user as the
/// index.
INDICES_IVF = 1,
/// Indices are stored as 32 bit integers on the GPU, but returned
/// as 64 bit integers
INDICES_32_BIT = 2,
/// Indices are stored as 64 bit integers on the GPU
INDICES_64_BIT = 3,
} FaissIndicesOptions;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,129 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#include "GpuResources_c.h"
#include <faiss/gpu/GpuResources.h>
#include "macros_impl.h"
using faiss::gpu::GpuResources;
using faiss::gpu::GpuResourcesProvider;
DEFINE_DESTRUCTOR(GpuResources)
int faiss_GpuResources_initializeForDevice(FaissGpuResources* res, int device) {
try {
reinterpret_cast<GpuResources*>(res)->initializeForDevice(device);
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getBlasHandle(
FaissGpuResources* res,
int device,
cublasHandle_t* out) {
try {
auto o = reinterpret_cast<GpuResources*>(res)->getBlasHandle(device);
*out = o;
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getDefaultStream(
FaissGpuResources* res,
int device,
cudaStream_t* out) {
try {
auto o = reinterpret_cast<GpuResources*>(res)->getDefaultStream(device);
*out = o;
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getPinnedMemory(
FaissGpuResources* res,
void** p_buffer,
size_t* p_size) {
try {
auto o = reinterpret_cast<GpuResources*>(res)->getPinnedMemory();
*p_buffer = o.first;
*p_size = o.second;
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getAsyncCopyStream(
FaissGpuResources* res,
int device,
cudaStream_t* out) {
try {
auto o = reinterpret_cast<GpuResources*>(res)->getAsyncCopyStream(
device);
*out = o;
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getBlasHandleCurrentDevice(
FaissGpuResources* res,
cublasHandle_t* out) {
try {
auto o = reinterpret_cast<GpuResources*>(res)
->getBlasHandleCurrentDevice();
*out = o;
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getDefaultStreamCurrentDevice(
FaissGpuResources* res,
cudaStream_t* out) {
try {
auto o = reinterpret_cast<GpuResources*>(res)
->getDefaultStreamCurrentDevice();
*out = o;
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_syncDefaultStream(FaissGpuResources* res, int device) {
try {
reinterpret_cast<GpuResources*>(res)->syncDefaultStream(device);
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_syncDefaultStreamCurrentDevice(FaissGpuResources* res) {
try {
reinterpret_cast<GpuResources*>(res)->syncDefaultStreamCurrentDevice();
}
CATCH_AND_HANDLE
}
int faiss_GpuResources_getAsyncCopyStreamCurrentDevice(
FaissGpuResources* res,
cudaStream_t* out) {
try {
auto o = reinterpret_cast<GpuResources*>(res)
->getAsyncCopyStreamCurrentDevice();
*out = o;
}
CATCH_AND_HANDLE
}
DEFINE_DESTRUCTOR(GpuResourcesProvider)
int faiss_GpuResourcesProvider_getResources(
FaissGpuResourcesProvider* res,
FaissGpuResources** out) {
try {
auto o = reinterpret_cast<GpuResourcesProvider*>(res)->getResources();
*out = reinterpret_cast<FaissGpuResources*>(o.get());
}
CATCH_AND_HANDLE
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_GPU_RESOURCES_C_H
#define FAISS_GPU_RESOURCES_C_H
#include <cublas_v2.h>
#include <cuda_runtime_api.h>
#include "../faiss_c.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Base class of GPU-side resource provider; hides provision of
/// cuBLAS handles, CUDA streams and a temporary memory manager
FAISS_DECLARE_CLASS(GpuResources)
FAISS_DECLARE_DESTRUCTOR(GpuResources)
/// Call to pre-allocate resources for a particular device. If this is
/// not called, then resources will be allocated at the first time
/// of demand
int faiss_GpuResources_initializeForDevice(FaissGpuResources*, int);
/// Returns the cuBLAS handle that we use for the given device
int faiss_GpuResources_getBlasHandle(FaissGpuResources*, int, cublasHandle_t*);
/// Returns the stream that we order all computation on for the
/// given device
int faiss_GpuResources_getDefaultStream(FaissGpuResources*, int, cudaStream_t*);
/// Returns the available CPU pinned memory buffer
int faiss_GpuResources_getPinnedMemory(FaissGpuResources*, void**, size_t*);
/// Returns the stream on which we perform async CPU <-> GPU copies
int faiss_GpuResources_getAsyncCopyStream(
FaissGpuResources*,
int,
cudaStream_t*);
/// Calls getBlasHandle with the current device
int faiss_GpuResources_getBlasHandleCurrentDevice(
FaissGpuResources*,
cublasHandle_t*);
/// Calls getDefaultStream with the current device
int faiss_GpuResources_getDefaultStreamCurrentDevice(
FaissGpuResources*,
cudaStream_t*);
/// Synchronizes the CPU with respect to the default stream for the
/// given device
// equivalent to cudaDeviceSynchronize(getDefaultStream(device))
int faiss_GpuResources_syncDefaultStream(FaissGpuResources*, int);
/// Calls syncDefaultStream for the current device
int faiss_GpuResources_syncDefaultStreamCurrentDevice(FaissGpuResources*);
/// Calls getAsyncCopyStream for the current device
int faiss_GpuResources_getAsyncCopyStreamCurrentDevice(
FaissGpuResources*,
cudaStream_t*);
FAISS_DECLARE_CLASS(GpuResourcesProvider)
FAISS_DECLARE_DESTRUCTOR(GpuResourcesProvider)
int faiss_GpuResourcesProvider_getResources(
FaissGpuResourcesProvider*,
FaissGpuResources**);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#include "StandardGpuResources_c.h"
#include <faiss/gpu/StandardGpuResources.h>
#include "macros_impl.h"
using faiss::gpu::StandardGpuResources;
DEFINE_DESTRUCTOR(StandardGpuResources)
int faiss_StandardGpuResources_new(FaissStandardGpuResources** p_res) {
try {
auto p = new StandardGpuResources();
*p_res = reinterpret_cast<FaissStandardGpuResources*>(p);
}
CATCH_AND_HANDLE
}
int faiss_StandardGpuResources_noTempMemory(FaissStandardGpuResources* res) {
try {
reinterpret_cast<StandardGpuResources*>(res)->noTempMemory();
}
CATCH_AND_HANDLE
}
int faiss_StandardGpuResources_setTempMemory(
FaissStandardGpuResources* res,
size_t size) {
try {
reinterpret_cast<StandardGpuResources*>(res)->setTempMemory(size);
}
CATCH_AND_HANDLE
}
int faiss_StandardGpuResources_setPinnedMemory(
FaissStandardGpuResources* res,
size_t size) {
try {
reinterpret_cast<StandardGpuResources*>(res)->setPinnedMemory(size);
}
CATCH_AND_HANDLE
}
int faiss_StandardGpuResources_setDefaultStream(
FaissStandardGpuResources* res,
int device,
cudaStream_t stream) {
try {
reinterpret_cast<StandardGpuResources*>(res)->setDefaultStream(
device, stream);
}
CATCH_AND_HANDLE
}
int faiss_StandardGpuResources_setDefaultNullStreamAllDevices(
FaissStandardGpuResources* res) {
try {
reinterpret_cast<StandardGpuResources*>(res)
->setDefaultNullStreamAllDevices();
}
CATCH_AND_HANDLE
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#ifndef FAISS_STANDARD_GPURESOURCES_C_H
#define FAISS_STANDARD_GPURESOURCES_C_H
#include <cuda_runtime_api.h>
#include "../faiss_c.h"
#include "GpuResources_c.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Default implementation of GpuResourcesProvider that allocates a cuBLAS
/// stream and 2 streams for use, as well as temporary memory
FAISS_DECLARE_CLASS_INHERITED(StandardGpuResources, GpuResourcesProvider)
FAISS_DECLARE_DESTRUCTOR(StandardGpuResources)
/// Default constructor for StandardGpuResources
int faiss_StandardGpuResources_new(FaissStandardGpuResources**);
/// Disable allocation of temporary memory; all temporary memory
/// requests will call cudaMalloc / cudaFree at the point of use
int faiss_StandardGpuResources_noTempMemory(FaissStandardGpuResources*);
/// Specify that we wish to use a certain fixed size of memory on
/// all devices as temporary memory
int faiss_StandardGpuResources_setTempMemory(
FaissStandardGpuResources*,
size_t size);
/// Set amount of pinned memory to allocate, for async GPU <-> CPU
/// transfers
int faiss_StandardGpuResources_setPinnedMemory(
FaissStandardGpuResources*,
size_t size);
/// Called to change the stream for work ordering
int faiss_StandardGpuResources_setDefaultStream(
FaissStandardGpuResources*,
int device,
cudaStream_t stream);
/// Called to change the work ordering streams to the null stream
/// for all devices
int faiss_StandardGpuResources_setDefaultNullStreamAllDevices(
FaissStandardGpuResources*);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c -*-
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "../AutoTune_c.h"
#include "../Index_c.h"
#include "../error_c.h"
#include "../index_factory_c.h"
#include "DeviceUtils_c.h"
#include "GpuAutoTune_c.h"
#include "StandardGpuResources_c.h"
#define FAISS_TRY(C) \
{ \
if (C) { \
fprintf(stderr, "%s", faiss_get_last_error()); \
exit(-1); \
} \
}
double drand() {
return (double)rand() / (double)RAND_MAX;
}
int main() {
time_t seed = time(NULL);
srand(seed);
int gpus = -1;
FAISS_TRY(faiss_get_num_gpus(&gpus));
printf("%d GPU devices are available\n", gpus);
printf("Generating some data...\n");
int d = 128; // dimension
int nb = 100000; // database size
int nq = 10000; // nb of queries
float* xb = malloc(d * nb * sizeof(float));
float* xq = malloc(d * nq * sizeof(float));
for (int i = 0; i < nb; i++) {
for (int j = 0; j < d; j++)
xb[d * i + j] = drand();
xb[d * i] += i / 1000.;
}
for (int i = 0; i < nq; i++) {
for (int j = 0; j < d; j++)
xq[d * i + j] = drand();
xq[d * i] += i / 1000.;
}
printf("Loading standard GPU resources...\n");
FaissStandardGpuResources* gpu_res = NULL;
FAISS_TRY(faiss_StandardGpuResources_new(&gpu_res));
printf("Building an index...\n");
FaissIndex* cpu_index = NULL;
FAISS_TRY(faiss_index_factory(
&cpu_index, d, "Flat", METRIC_L2)); // use factory to create index
printf("Moving index to the GPU...\n");
FaissGpuIndex* index = NULL;
FaissGpuClonerOptions* options = NULL;
FAISS_TRY(faiss_GpuClonerOptions_new(&options));
FAISS_TRY(faiss_index_cpu_to_gpu_with_options(
gpu_res, 0, cpu_index, options, &index));
printf("is_trained = %s\n",
faiss_Index_is_trained(index) ? "true" : "false");
FAISS_TRY(faiss_Index_add(index, nb, xb)); // add vectors to the index
printf("ntotal = %ld\n", faiss_Index_ntotal(index));
printf("Searching...\n");
int k = 5;
{ // sanity check: search 5 first vectors of xb
idx_t* I = malloc(k * 5 * sizeof(idx_t));
float* D = malloc(k * 5 * sizeof(float));
FAISS_TRY(faiss_Index_search(index, 5, xb, k, D, I));
printf("I=\n");
for (int i = 0; i < 5; i++) {
for (int j = 0; j < k; j++)
printf("%5ld (d=%2.3f) ", I[i * k + j], D[i * k + j]);
printf("\n");
}
free(I);
free(D);
}
{ // search xq
idx_t* I = malloc(k * nq * sizeof(idx_t));
float* D = malloc(k * nq * sizeof(float));
FAISS_TRY(faiss_Index_search(index, 5, xb, k, D, I));
printf("I=\n");
for (int i = 0; i < 5; i++) {
for (int j = 0; j < k; j++)
printf("%5ld (d=%2.3f) ", I[i * k + j], D[i * k + j]);
printf("\n");
}
free(I);
free(D);
}
printf("Freeing index...\n");
faiss_Index_free(index);
printf("Freeing GPU resources...\n");
faiss_GpuResources_free(gpu_res);
faiss_GpuClonerOptions_free(options);
printf("Done.\n");
return 0;
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// -*- c++ -*-
#ifndef GPU_MACROS_IMPL_H
#define GPU_MACROS_IMPL_H
#include "../macros_impl.h"
#undef DEFINE_GETTER
#define DEFINE_GETTER(clazz, ty, name) \
ty faiss_##clazz##_##name(const Faiss##clazz* obj) { \
return static_cast<ty>( \
reinterpret_cast<const faiss::gpu::clazz*>(obj)->name); \
}
#undef DEFINE_SETTER
#define DEFINE_SETTER(clazz, ty, name) \
void faiss_##clazz##_set_##name(Faiss##clazz* obj, ty val) { \
reinterpret_cast<faiss::gpu::clazz*>(obj)->name = val; \
}
#undef DEFINE_SETTER_STATIC
#define DEFINE_SETTER_STATIC(clazz, ty_to, ty_from, name) \
void faiss_##clazz##_set_##name(Faiss##clazz* obj, ty_from val) { \
reinterpret_cast<faiss::gpu::clazz*>(obj)->name = \
static_cast<ty_to>(val); \
}
#undef DEFINE_DESTRUCTOR
#define DEFINE_DESTRUCTOR(clazz) \
void faiss_##clazz##_free(Faiss##clazz* obj) { \
delete reinterpret_cast<faiss::gpu::clazz*>(obj); \
}
#endif