OmniSciDB  bf83d84833
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ThrustAllocator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED 1
20 #include <boost/stacktrace.hpp>
21 
22 #include <cstdint>
23 
24 #include "CudaMgr/CudaMgr.h"
26 #include "DataMgr/DataMgr.h"
27 #include "Logger/Logger.h"
28 
29 int8_t* ThrustAllocator::allocate(std::ptrdiff_t num_bytes) {
30  VLOG(1) << "Thrust allocation: Device #" << device_id_ << " Allocation #"
31  << ++num_allocations_ << ": " << num_bytes << " bytes";
32 #ifdef HAVE_CUDA
33  if (!data_mgr_) { // only for unit tests
34  CUdeviceptr ptr;
35  const auto err = cuMemAlloc(&ptr, num_bytes);
36  CHECK_EQ(CUDA_SUCCESS, err);
37  return reinterpret_cast<int8_t*>(ptr);
38  }
41 #else
44  CHECK_EQ(ab->getPinCount(), 1);
45 #endif // HAVE_CUDA
46  int8_t* raw_ptr = reinterpret_cast<int8_t*>(ab->getMemoryPtr());
47  CHECK(!raw_to_ab_ptr_.count(raw_ptr));
48  raw_to_ab_ptr_.insert(std::make_pair(raw_ptr, ab));
49  return raw_ptr;
50 }
51 
52 void ThrustAllocator::deallocate(int8_t* ptr, size_t num_bytes) {
53 #ifdef HAVE_CUDA
54  if (!data_mgr_) { // only for unit tests
55  const auto err = cuMemFree(reinterpret_cast<CUdeviceptr>(ptr));
56  CHECK_EQ(CUDA_SUCCESS, err);
57  return;
58  }
59 #endif // HAVE_CUDA
60  PtrMapperType::iterator ab_it = raw_to_ab_ptr_.find(ptr);
61  CHECK(ab_it != raw_to_ab_ptr_.end());
62  data_mgr_->free(ab_it->second);
63  raw_to_ab_ptr_.erase(ab_it);
64 }
65 
66 int8_t* ThrustAllocator::allocateScopedBuffer(std::ptrdiff_t num_bytes) {
67 #ifdef HAVE_CUDA
68  if (!data_mgr_) { // only for unit tests
69  CUdeviceptr ptr;
70  const auto err = cuMemAlloc(&ptr, num_bytes);
71  CHECK_EQ(CUDA_SUCCESS, err);
72  default_alloc_scoped_buffers_.push_back(reinterpret_cast<int8_t*>(ptr));
73  return reinterpret_cast<int8_t*>(ptr);
74  }
77 #else
80  CHECK_EQ(ab->getPinCount(), 1);
81 #endif // HAVE_CUDA
82  scoped_buffers_.push_back(ab);
83  return reinterpret_cast<int8_t*>(ab->getMemoryPtr());
84 }
85 
87  for (auto ab : scoped_buffers_) {
88  data_mgr_->free(ab);
89  }
90 #ifdef HAVE_CUDA
91  for (auto ptr : default_alloc_scoped_buffers_) {
92  const auto err = cuMemFree(reinterpret_cast<CUdeviceptr>(ptr));
93  CHECK_EQ(CUDA_SUCCESS, err);
94  }
95 #endif // HAVE_CUDA
96  if (!raw_to_ab_ptr_.empty()) {
97  LOG(ERROR) << "Not all GPU buffers deallocated before destruction of Thrust "
98  "allocator for device "
99  << device_id_ << ". Remaining buffers: ";
100  for (auto& kv : raw_to_ab_ptr_) {
101  auto& ab = kv.second;
102  CHECK(ab);
103  LOG(ERROR) << (ab->pageCount() * ab->pageSize()) / (1024. * 1024.) << " MB";
104  }
105  VLOG(1) << boost::stacktrace::stacktrace();
106  }
107 }
#define CHECK_EQ(x, y)
Definition: Logger.h:205
int8_t * allocate(std::ptrdiff_t num_bytes)
#define LOG(tag)
Definition: Logger.h:188
std::vector< Data_Namespace::AbstractBuffer * > scoped_buffers_
virtual int8_t * getMemoryPtr()=0
unsigned long long CUdeviceptr
Definition: nocuda.h:27
void deallocate(int8_t *ptr, size_t num_bytes)
std::vector< int8_t * > default_alloc_scoped_buffers_
Data_Namespace::DataMgr * data_mgr_
const int device_id_
PtrMapperType raw_to_ab_ptr_
int8_t * allocateScopedBuffer(std::ptrdiff_t num_bytes)
An AbstractBuffer is a unit of data management for a data manager.
static Data_Namespace::AbstractBuffer * allocGpuAbstractBuffer(Data_Namespace::DataMgr *data_mgr, const size_t num_bytes, const int device_id)
#define CHECK(condition)
Definition: Logger.h:197
Allocate GPU memory using GpuBuffers via DataMgr.
void free(AbstractBuffer *buffer)
Definition: DataMgr.cpp:469
#define VLOG(n)
Definition: Logger.h:291
AbstractBuffer * alloc(const MemoryLevel memoryLevel, const int deviceId, const size_t numBytes)
Definition: DataMgr.cpp:460