32 #include <sys/sysctl.h>
33 #include <sys/types.h>
36 #include <boost/filesystem.hpp>
44 bool g_enable_tiered_cpu_mem{
false};
49 namespace Data_Namespace {
70 std::unique_ptr<CudaMgr_Namespace::CudaMgr> cudaMgr,
72 const size_t reservedGpuMem,
73 const size_t numReaderThreads,
75 : cudaMgr_{std::move(cudaMgr)}
78 , reservedGpuMem_{reservedGpuMem} {
86 std::atexit(atExitHandler);
88 LOG(
ERROR) <<
"CudaMgr instance is invalid, falling back to CPU-only mode.";
101 populateMgrs(system_parameters, numReaderThreads, cache_config);
102 createTopLevelMetadata();
115 for (
int level = numLevels - 1; level >= 0; --level) {
116 for (
size_t device = 0; device <
bufferMgrs_[level].size(); device++) {
138 usage.
free = mi[
"MemAvailable"];
139 usage.
total = mi[
"MemTotal"];
146 int64_t resident = 0;
149 std::ifstream fstatm(
"/proc/self/statm");
150 fstatm >> size >> resident >> shared;
154 sysconf(_SC_PAGE_SIZE);
156 usage.
resident = resident * page_size;
157 usage.
vtotal = size * page_size;
158 usage.
regular = (resident - shared) * page_size;
159 usage.
shared = shared * page_size;
182 size_t physical_memory;
187 length =
sizeof(size_t);
188 sysctl(mib, 2, &physical_memory, &length, NULL, 0);
189 return physical_memory;
190 #elif defined(_MSC_VER)
191 MEMORYSTATUSEX status;
192 status.dwLength =
sizeof(status);
193 GlobalMemoryStatusEx(&status);
194 return status.ullTotalPhys;
196 long pages = sysconf(_SC_PHYS_PAGES);
197 long page_size = sysconf(_SC_PAGE_SIZE);
198 return pages * page_size;
203 size_t total_cpu_size,
204 size_t minCpuSlabSize,
205 size_t maxCpuSlabSize,
208 #ifdef ENABLE_MEMKIND
209 if (g_enable_tiered_cpu_mem) {
233 const size_t num_reader_threads,
236 for (
int level = numLevels - 1; level >= 0; --level) {
237 for (
size_t device = 0; device <
bufferMgrs_[level].size(); device++) {
242 populateMgrs(sys_params, num_reader_threads, cache_config);
247 const size_t userSpecifiedNumReaderThreads,
258 if (cpuBufferSize == 0) {
260 VLOG(1) <<
"Detected " << (float)total_system_memory / (1024 * 1024)
261 <<
"M of total system memory.";
262 cpuBufferSize = total_system_memory *
265 size_t minCpuSlabSize = std::min(system_parameters.
min_cpu_slab_size, cpuBufferSize);
266 minCpuSlabSize = (minCpuSlabSize / page_size) * page_size;
267 size_t maxCpuSlabSize = std::min(system_parameters.
max_cpu_slab_size, cpuBufferSize);
268 maxCpuSlabSize = (maxCpuSlabSize / page_size) * page_size;
269 LOG(
INFO) <<
"Min CPU Slab Size is " << (float)minCpuSlabSize / (1024 * 1024) <<
"MB";
270 LOG(
INFO) <<
"Max CPU Slab Size is " << (float)maxCpuSlabSize / (1024 * 1024) <<
"MB";
271 LOG(
INFO) <<
"Max memory pool size for CPU is " << (float)cpuBufferSize / (1024 * 1024)
274 size_t total_cpu_size = 0;
276 #ifdef ENABLE_MEMKIND
279 if (g_enable_tiered_cpu_mem) {
281 LOG(
INFO) <<
"Max memory pool size for PMEM is " << (float)
g_pmem_size / (1024 * 1024)
284 for (
auto cpu_tier_size : cpu_tier_sizes) {
285 total_cpu_size += cpu_tier_size;
289 total_cpu_size = cpuBufferSize;
294 <<
"MB includes render buffer allocation";
297 0, total_cpu_size, minCpuSlabSize, maxCpuSlabSize, page_size, cpu_tier_sizes);
300 int numGpus =
cudaMgr_->getDeviceCount();
301 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
302 size_t gpuMaxMemSize =
306 size_t minGpuSlabSize =
308 minGpuSlabSize = (minGpuSlabSize / page_size) * page_size;
309 size_t maxGpuSlabSize =
311 maxGpuSlabSize = (maxGpuSlabSize / page_size) * page_size;
312 LOG(
INFO) <<
"Min GPU Slab size for GPU " << gpuNum <<
" is "
313 << (float)minGpuSlabSize / (1024 * 1024) <<
"MB";
314 LOG(
INFO) <<
"Max GPU Slab size for GPU " << gpuNum <<
" is "
315 << (float)maxGpuSlabSize / (1024 * 1024) <<
"MB";
316 LOG(
INFO) <<
"Max memory pool size for GPU " << gpuNum <<
" is "
317 << (float)gpuMaxMemSize / (1024 * 1024) <<
"MB";
329 0, total_cpu_size, minCpuSlabSize, maxCpuSlabSize, page_size, cpu_tier_sizes);
339 boost::filesystem::path path(mapdDataPath);
340 if (boost::filesystem::exists(path)) {
341 if (!boost::filesystem::is_directory(path)) {
343 "\" to convert DB is not a directory.";
347 "\" to convert DB does not exist.";
354 LOG(
INFO) <<
"Database conversion started.";
361 LOG(
INFO) <<
"Database conversion completed.";
374 auto fm_top = gfm->getFileMgr(chunkKey);
375 if (
auto fm = dynamic_cast<File_Namespace::FileMgr*>(fm_top)) {
376 fm->createOrMigrateTopLevelMetadata();
387 std::vector<MemoryInfo> mem_info;
401 for (
size_t slab_num = 0; slab_num < slab_segments.size(); ++slab_num) {
402 for (
auto const& segment : slab_segments[slab_num]) {
407 md.
touch = segment.last_touched;
410 md.
chunk_key.end(), segment.chunk_key.begin(), segment.chunk_key.end());
414 mem_info.push_back(mi);
416 int numGpus =
cudaMgr_->getDeviceCount();
417 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
430 for (
size_t slab_num = 0; slab_num < slab_segments.size(); ++slab_num) {
431 for (
auto const& segment : slab_segments[slab_num]) {
436 md.
touch = segment.last_touched;
438 md.
chunk_key.end(), segment.chunk_key.begin(), segment.chunk_key.end());
443 mem_info.push_back(mi);
454 int numGpus =
cudaMgr_->getDeviceCount();
455 std::ostringstream tss;
456 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
457 tss <<
bufferMgrs_[memLevel][gpuNum]->printSlabs();
471 int numGpus =
cudaMgr_->getDeviceCount();
472 for (
int gpuNum = 0; gpuNum < numGpus; ++gpuNum) {
473 auto buffer_mgr_for_gpu =
475 CHECK(buffer_mgr_for_gpu);
476 buffer_mgr_for_gpu->clearSlabs();
479 LOG(
WARNING) <<
"Unable to clear GPU memory: No GPUs detected";
482 auto buffer_mgr_for_cpu =
484 CHECK(buffer_mgr_for_cpu);
485 buffer_mgr_for_cpu->clearSlabs();
491 const int deviceId) {
493 return bufferMgrs_[memLevel][deviceId]->isBufferOnDevice(key);
499 bufferMgrs_[0][0]->getChunkMetadataVecForKeyPrefix(chunkMetadataVec, keyPrefix);
505 const size_t page_size) {
507 int level =
static_cast<int>(memoryLevel);
508 return bufferMgrs_[level][deviceId]->createBuffer(key, page_size);
514 const size_t numBytes) {
516 const auto level =
static_cast<size_t>(memoryLevel);
519 return bufferMgrs_[level][deviceId]->getBuffer(key, numBytes);
526 for (
int level = numLevels - 1; level >= 0; --level) {
527 for (
int device = 0; device <
levelSizes_[level]; ++device) {
528 bufferMgrs_[level][device]->deleteBuffersWithPrefix(keyPrefix);
541 for (
int device = 0; device <
levelSizes_[memLevel]; ++device) {
542 bufferMgrs_[memLevel][device]->deleteBuffersWithPrefix(keyPrefix);
549 const int device_id) {
552 bufferMgrs_[memLevel][device_id]->deleteBuffer(key);
557 const size_t numBytes) {
559 const auto level =
static_cast<int>(memoryLevel);
561 return bufferMgrs_[level][deviceId]->alloc(numBytes);
566 int level =
static_cast<int>(buffer->
getType());
590 for (
auto deviceIt = levelIt->begin(); deviceIt != levelIt->end(); ++deviceIt) {
591 (*deviceIt)->checkpoint(db_id, tb_id);
602 for (
int device_id = 0; device_id <
levelSizes_[memory_level]; device_id++) {
603 bufferMgrs_[memory_level][device_id]->checkpoint(db_id, table_id);
613 for (
auto deviceIt = levelIt->begin(); deviceIt != levelIt->end(); ++deviceIt) {
614 (*deviceIt)->checkpoint();
621 bufferMgrs_[0][0]->removeTableRelatedDS(db_id, tb_id);
628 gfm->setTableEpoch(db_id, tb_id, start_epoch);
635 return gfm->getTableEpoch(db_id, tb_id);
642 gfm->resetTableEpochFloor(db_id, tb_id);
649 CHECK(global_file_mgr);
650 return global_file_mgr;
661 os <<
" \"name\": \"CPU Memory Info\",";
662 os <<
" \"TotalMB\": " << mem_info.
total / (1024. * 1024.) <<
",";
663 os <<
" \"FreeMB\": " << mem_info.
free / (1024. * 1024.) <<
",";
664 os <<
" \"ProcessMB\": " << mem_info.
resident / (1024. * 1024.) <<
",";
665 os <<
" \"VirtualMB\": " << mem_info.
vtotal / (1024. * 1024.) <<
",";
666 os <<
" \"ProcessPlusSwapMB\": " << mem_info.
regular / (1024. * 1024.) <<
",";
667 os <<
" \"ProcessSharedMB\": " << mem_info.
shared / (1024. * 1024.) <<
",";
668 os <<
" \"FragmentationPercent\": " << mem_info.
frag;
684 return static_cast<size_t>(0);
686 size_t total_gpu_buffer_pools_size{0};
688 total_gpu_buffer_pools_size +=
691 return total_gpu_buffer_pools_size;
size_t getAllocated() override
std::mutex buffer_access_mutex_
static bool at_exit_called
std::vector< int > ChunkKey
const std::string kDataDirectoryName
std::vector< MemoryData > nodeMemoryData
Buffer_Namespace::MemStatus memStatus
void deleteChunk(const ChunkKey &key, const MemoryLevel mem_level, const int device_id)
size_t getMaxSize() override
std::vector< std::vector< AbstractBufferMgr * > > bufferMgrs_
This file includes the class specification for the FILE manager (FileMgr), and related data structure...
std::vector< int > levelSizes_
static DataMgr * g_data_mgr_ptr
std::ostream & operator<<(std::ostream &os, const DataMgr::SystemMemoryUsage &mem_info)
SystemMemoryUsage getSystemMemoryUsage() const
size_t cpu_buffer_mem_bytes
PersistentStorageMgr * getPersistentStorageMgr() const
virtual int8_t * getMemoryPtr()=0
virtual MemoryLevel getType() const =0
void clearMemory(const MemoryLevel memLevel)
std::vector< MemoryInfo > getMemoryInfoUnlocked(const MemoryLevel memLevel) const
void resetTableEpochFloor(const int32_t db_id, const int32_t tb_id)
std::string dumpLevel(const MemoryLevel memLevel)
size_t getCpuBufferPoolSize() const
void convertDB(const std::string basePath)
size_t getGpuBufferPoolSize() const
constexpr size_t numCpuTiers
static size_t getTotalSystemMemory()
Note(s): Forbid Copying Idiom 4.1.
size_t getTableEpoch(const int db_id, const int tb_id)
Buffer_Namespace::GpuCudaBufferMgr * getGpuBufferMgr(int32_t device_id) const
std::shared_ptr< ForeignStorageInterface > getForeignStorageInterface() const
void createTopLevelMetadata() const
bool isAllocationCapped() override
static void atExitHandler()
std::unique_ptr< CudaMgr_Namespace::CudaMgr > cudaMgr_
void getChunkMetadataVecForKeyPrefix(ChunkMetadataVector &chunkMetadataVec, const ChunkKey &keyPrefix)
void populateMgrs(const SystemParameters &system_parameters, const size_t userSpecifiedNumReaderThreads, const File_Namespace::DiskCacheConfig &cache_config)
An AbstractBuffer is a unit of data management for a data manager.
virtual void write(int8_t *src, const size_t num_bytes, const size_t offset=0, const MemoryLevel src_buffer_type=CPU_LEVEL, const int src_device_id=-1)=0
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
Parse /proc/meminfo into key/value pairs.
void deleteChunksWithPrefix(const ChunkKey &keyPrefix)
const std::vector< BufferList > & getSlabSegments()
bool isBufferOnDevice(const ChunkKey &key, const MemoryLevel memLevel, const int deviceId)
AbstractBuffer * getChunkBuffer(const ChunkKey &key, const MemoryLevel memoryLevel, const int deviceId=0, const size_t numBytes=0)
std::vector< MemoryInfo > getMemoryInfo(const MemoryLevel memLevel) const
void removeTableRelatedDS(const int db_id, const int tb_id)
DataMgr(const std::string &dataDir, const SystemParameters &system_parameters, std::unique_ptr< CudaMgr_Namespace::CudaMgr > cudaMgr, const bool useGpus, const size_t reservedGpuMem=(1<< 27), const size_t numReaderThreads=0, const File_Namespace::DiskCacheConfig cacheConfig=File_Namespace::DiskCacheConfig())
Buffer_Namespace::CpuBufferMgr * getCpuBufferMgr() const
void copy(AbstractBuffer *destBuffer, AbstractBuffer *srcBuffer)
size_t gpu_buffer_mem_bytes
void resetBufferMgrs(const File_Namespace::DiskCacheConfig &cache_config, const size_t num_reader_threads, const SystemParameters &sys_params)
std::vector< int32_t > chunk_key
AbstractBuffer * createChunkBuffer(const ChunkKey &key, const MemoryLevel memoryLevel, const int deviceId=0, const size_t page_size=0)
Allocate GPU memory using GpuBuffers via DataMgr.
void free(AbstractBuffer *buffer)
auto getFragmentationPercent()
void allocateCpuBufferMgr(int32_t device_id, size_t total_cpu_size, size_t minCpuSlabSize, size_t maxCpuSlabSize, size_t page_size, const std::vector< size_t > &cpu_tier_sizes)
std::vector< size_t > CpuTierSizeVector
Parse /proc/buddyinfo into a Fragmentation health score.
void setTableEpoch(const int db_id, const int tb_id, const int start_epoch)
AbstractBuffer * alloc(const MemoryLevel memoryLevel, const int deviceId, const size_t numBytes)