11 #include "../../FaissAssert.h"
12 #include "DeviceUtils.h"
13 #include "MemorySpace.h"
14 #include "StaticUtils.h"
19 namespace faiss {
namespace gpu {
41 freeMemorySpace(space_, data_);
47 size_t size()
const {
return num_; }
48 size_t capacity()
const {
return capacity_; }
49 T* data() {
return data_; }
50 const T* data()
const {
return data_; }
52 template <
typename OutT>
53 std::vector<OutT> copyToHost(cudaStream_t stream)
const {
54 FAISS_ASSERT(num_ *
sizeof(T) %
sizeof(OutT) == 0);
56 std::vector<OutT> out((num_ *
sizeof(T)) /
sizeof(OutT));
57 CUDA_VERIFY(cudaMemcpyAsync(out.data(), data_, num_ *
sizeof(T),
58 cudaMemcpyDeviceToHost, stream));
66 bool append(
const T* d,
69 bool reserveExact =
false) {
73 size_t reserveSize = num_ + n;
75 reserveSize = getNewCapacity_(reserveSize);
78 mem = reserve(reserveSize, stream);
80 int dev = getDeviceForAddress(d);
82 CUDA_VERIFY(cudaMemcpyAsync(data_ + num_, d, n *
sizeof(T),
83 cudaMemcpyHostToDevice, stream));
85 CUDA_VERIFY(cudaMemcpyAsync(data_ + num_, d, n *
sizeof(T),
86 cudaMemcpyDeviceToDevice, stream));
95 bool resize(
size_t newSize, cudaStream_t stream) {
99 mem = reserve(getNewCapacity_(newSize), stream);
113 size_t reclaim(
bool exact, cudaStream_t stream) {
114 size_t free = capacity_ - num_;
117 realloc_(num_, stream);
118 return free *
sizeof(T);
125 if (free > (capacity_ / 4)) {
126 size_t newFree = capacity_ / 8;
127 size_t newCapacity = num_ + newFree;
129 size_t oldCapacity = capacity_;
130 FAISS_ASSERT(newCapacity < oldCapacity);
132 realloc_(newCapacity, stream);
134 return (oldCapacity - newCapacity) *
sizeof(T);
141 bool reserve(
size_t newCapacity, cudaStream_t stream) {
142 if (newCapacity <= capacity_) {
147 realloc_(newCapacity, stream);
152 void realloc_(
size_t newCapacity, cudaStream_t stream) {
153 FAISS_ASSERT(num_ <= newCapacity);
155 T* newData =
nullptr;
156 allocMemorySpace(space_, &newData, newCapacity *
sizeof(T));
157 CUDA_VERIFY(cudaMemcpyAsync(newData, data_, num_ *
sizeof(T),
158 cudaMemcpyDeviceToDevice, stream));
159 freeMemorySpace(space_, data_);
162 capacity_ = newCapacity;
165 size_t getNewCapacity_(
size_t preferredSize) {
166 return utils::nextHighestPowerOf2(preferredSize);