From 2620a4d0f641cf733940f693c79071ae5095eeab Mon Sep 17 00:00:00 2001 From: znan Date: Mon, 16 Jul 2018 15:44:10 -0700 Subject: [PATCH 001/110] add constant memory files, ready for test --- examples/CMakeLists.txt | 6 + examples/device_const_mem_real_case.cu | 149 ++++++++++++++++++ src/umpire/ResourceManager.cpp | 41 ++--- src/umpire/resource/CMakeLists.txt | 15 +- src/umpire/resource/ConstantMemoryResource.cu | 90 +++++++++++ .../resource/ConstantMemoryResource.hpp | 63 ++++++++ .../resource/DeviceConstResourceFactory.cpp | 41 +++++ .../resource/DeviceConstResourceFactory.hpp | 39 +++++ src/umpire/resource/MemoryResourceTypes.hpp | 3 +- 9 files changed, 406 insertions(+), 41 deletions(-) create mode 100644 examples/device_const_mem_real_case.cu create mode 100644 src/umpire/resource/ConstantMemoryResource.cu create mode 100644 src/umpire/resource/ConstantMemoryResource.hpp create mode 100644 src/umpire/resource/DeviceConstResourceFactory.cpp create mode 100644 src/umpire/resource/DeviceConstResourceFactory.hpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 33b0a6007..d0f699057 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -39,6 +39,12 @@ blt_add_executable( DEPENDS_ON umpire) +blt_add_executable( + NAME device_const_test_case + SOURCES device_const_mem_real_case.cu + DEPENDS_ON + umpire) + if (ENABLE_STATISTICS) blt_add_executable( NAME statistics_example diff --git a/examples/device_const_mem_real_case.cu b/examples/device_const_mem_real_case.cu new file mode 100644 index 000000000..039ffd439 --- /dev/null +++ b/examples/device_const_mem_real_case.cu @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include + +#include "umpire/ResourceManager.hpp" +#include + +__global__ void add_constant_kernel(const double *a, double *d, double *c, int size) +{ + const int i = blockDim.x * blockIdx.x + threadIdx.x; + if (i < size) + { + c[i] = a[i] + d[i]; + } +} + +__global__ void add_kernel(const double *a, const double *b, double *c, int size) +{ + const int i = blockDim.x * blockIdx.x + threadIdx.x; + if (i < size) + c[i] = a[i] + b[i]; +} + +void check_error(void) +{ + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + std::cerr << "Error: " << cudaGetErrorString(err) << std::endl; + exit(err); + } +} + +int main(int, char**) +{ + // auto& rm = umpire::ResourceManager::getInstance(); + + const int size = 1024 * 8; + + auto& rm = umpire::ResourceManager::getInstance(); + + std::cout << "Available allocators: "; + for (auto s : rm.getAvailableAllocators()){ + std::cout << s << " "; + } + std::cout << std::endl; + + // double *a = (double*)malloc(sizeof(double) * size); + // double *b = (double*)malloc(sizeof(double) * size); + // double *sum = (double*)malloc(sizeof(double) * size); + + auto host_alloc = rm.getAllocator("HOST"); + double *sum = static_cast(host_alloc.allocate(size*sizeof(double))); + double *a = static_cast(host_alloc.allocate(size*sizeof(double))); + double *b = static_cast(host_alloc.allocate(size*sizeof(double))); + std::cout << "Host memory allocation finished\n"; + + // double *d_a; + // double *d_b; + // double *d_sum; + + auto dev_alloc = rm.getAllocator("DEVICE"); + double *d_sum = static_cast(dev_alloc.allocate(size*sizeof(double))); + double *d_a = static_cast(dev_alloc.allocate(size*sizeof(double))); + double *d_b = static_cast(dev_alloc.allocate(size*sizeof(double))); + std::cout << "Device memory allocation finished\n"; + + + auto dev_const_alloc = rm.getAllocator("DEVICE_CONST"); + double *d_d = static_cast(dev_const_alloc.allocate(size*sizeof(double))); + std::cout << "Device constant memory allocation finished\n"; + + + + for (int i=0; i(i); + b[i] = a[i]; + sum[i] = 1; + } + + // cudaMemcpy(d_a, a, size*sizeof(double), cudaMemcpyHostToDevice); + rm.copy(d_a, a, size*sizeof(double)); + check_error(); + + // cudaMemcpy(d_b, b, size*sizeof(double), cudaMemcpyHostToDevice); + rm.copy(d_b, b, size*sizeof(double)); + check_error(); + + // cudaMemcpy(d_d, b, size*sizeof(double), cudaMemcpyHostToDevice); + rm.copy(d_d, b, size*sizeof(double)); + check_error(); + + std::cout << "Memory copy finished\n"; + +// ----------------add kernel------------------------- + add_kernel<<<256, 1024>>>(d_a, d_b, d_sum, size); + check_error(); + + // cudaMemcpy(sum, d_sum, size*sizeof(double), cudaMemcpyDeviceToHost); + rm.copy(sum, d_sum, size*sizeof(double)); + check_error(); + + int final_sum = 0; + for (int i=0; i>>(d_a, d_d, d_sum, size); + check_error(); + + // cudaMemcpy(sum, d_sum, size*sizeof(double), cudaMemcpyDeviceToHost); + rm.copy(sum, d_sum, size*sizeof(double)); + check_error(); + + int final_sum_const = 0; + for (int i=0; i()); + + // constant memory + registry.registerMemoryResource( + std::make_shared()); #endif initialize(); @@ -86,6 +91,8 @@ ResourceManager::initialize() m_memory_resources[resource::Device] = registry.makeMemoryResource("DEVICE", getNextId()); m_memory_resources[resource::UnifiedMemory] = registry.makeMemoryResource("UM", getNextId()); m_memory_resources[resource::PinnedMemory] = registry.makeMemoryResource("PINNED", getNextId()); + // constant memory + m_memory_resources[resource::Device_Const] = registry.makeMemoryResource("DEVICE_CONST", getNextId()); #endif /* @@ -114,6 +121,11 @@ ResourceManager::initialize() auto pinned_allocator = m_memory_resources[resource::PinnedMemory]; m_allocators_by_name["PINNED"] = pinned_allocator; m_allocators_by_id[pinned_allocator->getId()] = pinned_allocator; + + // constant memory + auto device_const_allocator = m_memory_resources[resource::Device_Const]; + m_allocators_by_name["DEVICE_CONST"] = device_const_allocator; + m_allocators_by_id[device_const_allocator->getId()] = device_const_allocator; #endif UMPIRE_LOG(Debug, "() leaving"); } @@ -150,29 +162,6 @@ ResourceManager::getAllocator(resource::MemoryResourceType resource_type) return Allocator(m_memory_resources[resource_type]); } -Allocator -ResourceManager::getAllocator(int id) -{ - UMPIRE_LOG(Debug, "(\"" << id << "\")"); - - auto allocator = m_allocators_by_id.find(id); - if (allocator == m_allocators_by_id.end()) { - UMPIRE_ERROR("Allocator \"" << id << "\" not found."); - } - - return Allocator(m_allocators_by_id[id]); -} - -void -ResourceManager::registerAllocator(const std::string& name, Allocator allocator) -{ - if (isAllocator(name)) { - UMPIRE_ERROR("Allocator " << name << " is already registered."); - } - - m_allocators_by_name[name] = allocator.getAllocationStrategy(); -} - Allocator ResourceManager::getAllocator(void* ptr) { @@ -180,12 +169,6 @@ ResourceManager::getAllocator(void* ptr) return Allocator(findAllocatorForPointer(ptr)); } -bool -ResourceManager::isAllocator(const std::string& name) -{ - return (m_allocators_by_name.find(name) != m_allocators_by_name.end()); -} - bool ResourceManager::hasAllocator(void* ptr) { diff --git a/src/umpire/resource/CMakeLists.txt b/src/umpire/resource/CMakeLists.txt index 593c015bb..db7ba718e 100644 --- a/src/umpire/resource/CMakeLists.txt +++ b/src/umpire/resource/CMakeLists.txt @@ -34,12 +34,16 @@ set (umpire_resource_depends if (ENABLE_CUDA) set (umpire_resource_headers ${umpire_resource_headers} + DeviceConstResourceFactory.hpp + ConstantMemoryResource.hpp DeviceResourceFactory.hpp PinnedMemoryResourceFactory.hpp UnifiedMemoryResourceFactory.hpp) set (umpire_resource_sources ${umpire_resource_sources} + DeviceConstResourceFactory.cpp + ConstantMemoryResource.cu DeviceResourceFactory.cpp PinnedMemoryResourceFactory.cpp UnifiedMemoryResourceFactory.cpp) @@ -56,20 +60,9 @@ blt_add_library( HEADERS_OUTPUT_SUBDIR umpire/resource DEPENDS_ON ${umpire_resource_depends}) -target_include_directories( - umpire_resource - PUBLIC - $ - $ - $) - install(TARGETS umpire_resource EXPORT umpire-targets RUNTIME DESTINATION lib LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) - -install(FILES - ${umpire_resource_headers} - DESTINATION include/umpire/resource) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu new file mode 100644 index 000000000..bc50d7482 --- /dev/null +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by Zifan Nan, nan1@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +// #ifndef UMPIRE_DefaultMemoryResource_INL +// #define UMPIRE_DefaultMemoryResource_INL + +#include "umpire/resource/ConstantMemoryResource.hpp" +#include "umpire/ResourceManager.hpp" +#include "umpire/util/Macros.hpp" + +#include +#include + +namespace umpire { +namespace resource { + +// template +ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::string& name, int id) : + MemoryResource(name, id), + // m_allocator(), + m_current_size(0l), + m_highwatermark(0l), + m_platform(platform) +{ +} + +// template +void* ConstantMemoryResource::allocate(size_t bytes) +{ + // void* ptr = m_allocator.allocate(bytes); + + void* ptr = nullptr; + cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); + + ResourceManager::getInstance().registerAllocation(ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); + + m_current_size += bytes; + if (m_current_size > m_highwatermark) + m_highwatermark = m_current_size; + + UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ptr); + + return ptr; +} + +// template +void ConstantMemoryResource::deallocate(void* ptr) +{ + UMPIRE_LOG(Debug, "(ptr=" << ptr << ")"); + + // m_allocator.deallocate(ptr); + util::AllocationRecord* record = ResourceManager::getInstance().deregisterAllocation(ptr); + m_current_size -= record->m_size; + delete record; +} + +// template +long ConstantMemoryResource::getCurrentSize() +{ + UMPIRE_LOG(Debug, "() returning " << m_current_size); + return m_current_size; +} + +// template +long ConstantMemoryResource::getHighWatermark() +{ + UMPIRE_LOG(Debug, "() returning " << m_highwatermark); + return m_highwatermark; +} + +// template +Platform ConstantMemoryResource::getPlatform() +{ + return m_platform; +} + +} // end of namespace resource +} // end of namespace umpire +// #endif // UMPIRE_DefaultMemoryResource_INL diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp new file mode 100644 index 000000000..76f3811cb --- /dev/null +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by Zifan Nan, nan1@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#ifndef UMPIRE_ConstantMemoryResource_HPP +#define UMPIRE_ConstantMemoryResource_HPP + +#include "umpire/resource/MemoryResource.hpp" + +#include "umpire/util/AllocationRecord.hpp" +#include "umpire/util/Platform.hpp" + +#include + +__constant__ char umpire_internal_device_constant_memory[64*1024]; + +namespace umpire { +namespace resource { + + + /*! + * \brief Concrete MemoryResource object that uses the template _allocator to + * allocate and deallocate memory. + */ +class ConstantMemoryResource : + public MemoryResource +{ + public: + ConstantMemoryResource(Platform platform, const std::string& name, int id); + + void* allocate(size_t bytes); + void deallocate(void* ptr); + + long getCurrentSize(); + long getHighWatermark(); + + Platform getPlatform(); + + protected: + // _allocator m_allocator; + + long m_current_size; + long m_highwatermark; + + Platform m_platform; +}; + +} // end of namespace resource +} // end of namespace umpire + +// #include "umpire/resource/ConstantMemoryResource.inl" + +#endif // UMPIRE_DefaultMemoryResource_HPP diff --git a/src/umpire/resource/DeviceConstResourceFactory.cpp b/src/umpire/resource/DeviceConstResourceFactory.cpp new file mode 100644 index 000000000..cf85bbca7 --- /dev/null +++ b/src/umpire/resource/DeviceConstResourceFactory.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/resource/DeviceConstResourceFactory.hpp" + +#include "umpire/resource/ConstantMemoryResource.hpp" +// #include "umpire/alloc/CudaConstMemAllocator.hpp" + +namespace umpire { +namespace resource { + +bool +DeviceConstResourceFactory::isValidMemoryResourceFor(const std::string& name) +{ + if (name.compare("DEVICE_CONST") == 0) { + return true; + } else { + return false; + } +} + +std::shared_ptr +DeviceConstResourceFactory::create(const std::string& name, int id) +{ + // constant memory resource, compiled by cuda compiler. umpire_internal_constant_memory + return std::make_shared(Platform::cuda, "DEVICE_CONST", id); +} + +} // end of namespace resource +} // end of namespace umpire diff --git a/src/umpire/resource/DeviceConstResourceFactory.hpp b/src/umpire/resource/DeviceConstResourceFactory.hpp new file mode 100644 index 000000000..b6c0214bc --- /dev/null +++ b/src/umpire/resource/DeviceConstResourceFactory.hpp @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#ifndef UMPIRE_DeviceConstResourceFactory_HPP +#define UMPIRE_DeviceConstResourceFactory_HPP + +#include "umpire/resource/MemoryResourceFactory.hpp" + +namespace umpire { +namespace resource { + + +/*! + * \brief Factory class for constructing MemoryResource objects that use GPU + * memory. + */ +class DeviceConstResourceFactory : + public MemoryResourceFactory +{ + bool isValidMemoryResourceFor(const std::string& name); + + std::shared_ptr create(const std::string& name, int id); +}; + +} // end of namespace resource +} // end of namespace umpire + +#endif // UMPIRE_DeviceResourceFactory_HPP diff --git a/src/umpire/resource/MemoryResourceTypes.hpp b/src/umpire/resource/MemoryResourceTypes.hpp index 42a3cd543..1bd7b4534 100644 --- a/src/umpire/resource/MemoryResourceTypes.hpp +++ b/src/umpire/resource/MemoryResourceTypes.hpp @@ -32,7 +32,8 @@ enum MemoryResourceType { Host, Device, UnifiedMemory, - PinnedMemory + PinnedMemory, + Device_Const }; } // end of namespace resource From e65c153991bd674c8e3e83c8fdb47e1b054149e1 Mon Sep 17 00:00:00 2001 From: znan Date: Mon, 16 Jul 2018 16:42:35 -0700 Subject: [PATCH 002/110] modify changed files, ready for test --- src/umpire/ResourceManager.cpp | 29 +++++++++++++++++++++++++++++ src/umpire/resource/CMakeLists.txt | 11 +++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index 0351d8ab2..9c289d079 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -162,6 +162,29 @@ ResourceManager::getAllocator(resource::MemoryResourceType resource_type) return Allocator(m_memory_resources[resource_type]); } +void +ResourceManager::registerAllocator(const std::string& name, Allocator allocator) +{ + if (isAllocator(name)) { + UMPIRE_ERROR("Allocator " << name << " is already registered."); + } + + m_allocators_by_name[name] = allocator.getAllocationStrategy(); +} + +Allocator +ResourceManager::getAllocator(int id) +{ + UMPIRE_LOG(Debug, "(\"" << id << "\")"); + + auto allocator = m_allocators_by_id.find(id); + if (allocator == m_allocators_by_id.end()) { + UMPIRE_ERROR("Allocator \"" << id << "\" not found."); + } + + return Allocator(m_allocators_by_id[id]); +} + Allocator ResourceManager::getAllocator(void* ptr) { @@ -169,6 +192,12 @@ ResourceManager::getAllocator(void* ptr) return Allocator(findAllocatorForPointer(ptr)); } +bool +ResourceManager::isAllocator(const std::string& name) +{ + return (m_allocators_by_name.find(name) != m_allocators_by_name.end()); +} + bool ResourceManager::hasAllocator(void* ptr) { diff --git a/src/umpire/resource/CMakeLists.txt b/src/umpire/resource/CMakeLists.txt index db7ba718e..cef26b7f7 100644 --- a/src/umpire/resource/CMakeLists.txt +++ b/src/umpire/resource/CMakeLists.txt @@ -60,9 +60,20 @@ blt_add_library( HEADERS_OUTPUT_SUBDIR umpire/resource DEPENDS_ON ${umpire_resource_depends}) +target_include_directories( + umpire_resource + PUBLIC + $ + $ + $) + install(TARGETS umpire_resource EXPORT umpire-targets RUNTIME DESTINATION lib LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) + +install(FILES + ${umpire_resource_headers} + DESTINATION include/umpire/resource) \ No newline at end of file From f68b07e2edb3f815e7bd60232d0f27b1c2c56ee5 Mon Sep 17 00:00:00 2001 From: znan Date: Thu, 26 Jul 2018 14:41:09 -0700 Subject: [PATCH 003/110] change to original position --- src/umpire/ResourceManager.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index 9c289d079..5b7d180a5 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -162,16 +162,6 @@ ResourceManager::getAllocator(resource::MemoryResourceType resource_type) return Allocator(m_memory_resources[resource_type]); } -void -ResourceManager::registerAllocator(const std::string& name, Allocator allocator) -{ - if (isAllocator(name)) { - UMPIRE_ERROR("Allocator " << name << " is already registered."); - } - - m_allocators_by_name[name] = allocator.getAllocationStrategy(); -} - Allocator ResourceManager::getAllocator(int id) { @@ -185,6 +175,17 @@ ResourceManager::getAllocator(int id) return Allocator(m_allocators_by_id[id]); } +void +ResourceManager::registerAllocator(const std::string& name, Allocator allocator) +{ + if (isAllocator(name)) { + UMPIRE_ERROR("Allocator " << name << " is already registered."); + } + + m_allocators_by_name[name] = allocator.getAllocationStrategy(); +} + + Allocator ResourceManager::getAllocator(void* ptr) { From dd8b24ba2855f5aebea013da24967893dba15818 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Sat, 4 Aug 2018 15:06:01 -0700 Subject: [PATCH 004/110] Adding more tutorial examples --- examples/CMakeLists.txt | 18 +++++++++++++ examples/tut_allocator.cpp | 37 +++++++++++++++++++++++++ examples/tut_dynamic_pool.cpp | 51 +++++++++++++++++++++++++++++++++++ examples/tut_resources.cpp | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 examples/tut_allocator.cpp create mode 100644 examples/tut_dynamic_pool.cpp create mode 100644 examples/tut_resources.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 33b0a6007..670fb6886 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -45,3 +45,21 @@ if (ENABLE_STATISTICS) SOURCES statistics.cpp DEPENDS_ON umpire) endif() + +blt_add_executable( + NAME tut_allocator + SOURCES tut_allocator.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_resources + SOURCES tut_resources.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_dynamic_pool + SOURCES tut_dynamic_pool.cpp + DEPENDS_ON + umpire) diff --git a/examples/tut_allocator.cpp b/examples/tut_allocator.cpp new file mode 100644 index 000000000..07b9c5029 --- /dev/null +++ b/examples/tut_allocator.cpp @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +int main(int argc, char* argv[]) { + + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + umpire::Allocator allocator = rm.getAllocator("HOST"); + + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + << allocator.getName() << " allocator..."; + + allocator.deallocate(data); + + std::cout << " dealocated." + + return 0; +} diff --git a/examples/tut_dynamic_pool.cpp b/examples/tut_dynamic_pool.cpp new file mode 100644 index 000000000..35470fe5e --- /dev/null +++ b/examples/tut_dynamic_pool.cpp @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +void allocate_and_deallocate_pool(const std::string& resource) +{ + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + auto allocator = rm.getAllocator(resource); + + auto pooled_allocator = + rm.makeAllocator(resource + "_pool", + allocator); + + double* data = static_cast( + pooled_allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + << pooled_allocator.getName() << " allocator..."; + + pooled_allocator.deallocate(data); + + std::cout << " dealocated." +} + +int main(int argc, char* argv[]) { + allocate_and_deallocate_pool("HOST"); + +#if defined(UMPIRE_ENABLE_CUDA) + allocate_and_deallocate_pool("DEVICE"); + allocate_and_deallocate_pool("UM"); + allocate_and_deallocate_pool("PINNED"); +#endif + + return 0; +} diff --git a/examples/tut_resources.cpp b/examples/tut_resources.cpp new file mode 100644 index 000000000..d94faba7b --- /dev/null +++ b/examples/tut_resources.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +void allocate_and_deallocate(const std::string& resource) +{ + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + umpire::Allocator allocator = rm.getAllocator(resource); + + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + << allocator.getName() << " allocator..."; + + allocator.deallocate(data); + + std::cout << " dealocated." +} + +int main(int argc, char* argv[]) { + allocate_and_deallocate("HOST"); + +#if defined(UMPIRE_ENABLE_CUDA) + allocate_and_deallocate("DEVICE"); + allocate_and_deallocate("UM"); + allocate_and_deallocate("PINNED"); +#endif + + return 0; +} From 1cc3e225783959e1dd03e7e2ada73e92c7e5beda Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Sat, 4 Aug 2018 19:59:28 -0700 Subject: [PATCH 005/110] Added copy tutorial file --- examples/CMakeLists.txt | 6 ++++ examples/tut_operations.cpp | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 examples/tut_operations.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 670fb6886..977f6f65f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -63,3 +63,9 @@ blt_add_executable( SOURCES tut_dynamic_pool.cpp DEPENDS_ON umpire) + +blt_add_executable( + NAME tut_operations + SOURCES tut_operations.cpp + DEPENDS_ON + umpire) diff --git a/examples/tut_operations.cpp b/examples/tut_operations.cpp new file mode 100644 index 000000000..901cb68be --- /dev/null +++ b/examples/tut_operations.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +void copy_data(double* source_data, size_t size, const std::string& destination) +{ + auto& rm = umpire::ResourceManager::getInstance(); + auto dest_allocator = rm.getAllocator(destination); + + double* dest_data = static_cast( + dest_allocator.allocate(size*sizeof(double))); + + rm.copy(dest_data, source_data); + + std::cout << "Copied source data (" << source_data << ") to destination " + << destination << " (" << dest_data << ")" << std::endl; + + dest_allocator.deallocate(dest_data); +} + +int main(int argc, char* argv[]) { + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + auto allocator = rm.getAllocator("HOST"); + + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + << allocator.getName() << " allocator." << std::endl; + + std::cout << "Filling with 0.0..."; + + for (size_t i = 0; i < SIZE; i++) { + data[i] = 0.0; + } + + std::cout << "done." << std::endl; + + copy_data(data, SIZE, "HOST"); +#if defined(UMPIRE_ENABLE_CUDA) + copy_data(data, SIZE, "DEVICE"); + copy_data(data, SIZE, "UM"); + copy_data(data, SIZE, "PINNED"); +#endif + + allocator.deallocate(data); + + return 0; +} From ae6f4920bd19199650f3da52d9cce43ac2d6f50d Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Sat, 4 Aug 2018 20:00:29 -0700 Subject: [PATCH 006/110] Adding new Sphinx tutorial sections --- docs/sphinx/advanced_configuration.rst | 9 ++++-- docs/sphinx/tutorial.rst | 25 ++++++++++++++- docs/sphinx/tutorial/allocators.rst | 24 ++++++++++++++ docs/sphinx/tutorial/dynamic_pool.rst | 5 +++ docs/sphinx/tutorial/operations.rst | 6 ++++ docs/sphinx/tutorial/resources.rst | 43 ++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 docs/sphinx/tutorial/allocators.rst create mode 100644 docs/sphinx/tutorial/dynamic_pool.rst create mode 100644 docs/sphinx/tutorial/operations.rst create mode 100644 docs/sphinx/tutorial/resources.rst diff --git a/docs/sphinx/advanced_configuration.rst b/docs/sphinx/advanced_configuration.rst index 88d507266..5775b1800 100644 --- a/docs/sphinx/advanced_configuration.rst +++ b/docs/sphinx/advanced_configuration.rst @@ -18,6 +18,7 @@ Here is a summary of the configuration options, their default value, and meaning Variable Default Meaning =========================== ======== =============================================================================== ``ENABLE_CUDA`` On Enable CUDA support + ``ENABLE_STATISTICS`` Off Enable collection of memory statistics ``ENABLE_TESTING`` On Build test executables ``ENABLE_BENCHMARKS`` On Build benchmark programs ``ENABLE_LOGGING`` On Enable Logging within Umpire @@ -28,8 +29,12 @@ Here is a summary of the configuration options, their default value, and meaning These arguments are explained in more detail below: * ``ENABLE_CUDA`` - This option enables support for GPUs. If CHAI is built without CUDA support, - then only the ``CPU`` execution space is available for use. + This option enables support for GPUs. If Umpire is built without CUDA support, + then only the ``HOST`` allocator is available for use. + +* ``ENABLE_STATISTICS`` + This option enables collection of memory statistics. If Umpire is built with + this option, the Conduit library will also be built. * ``ENABLE_TESTING`` This option controls whether or not test executables will be built. diff --git a/docs/sphinx/tutorial.rst b/docs/sphinx/tutorial.rst index 90f178eb7..8a94e4165 100644 --- a/docs/sphinx/tutorial.rst +++ b/docs/sphinx/tutorial.rst @@ -4,4 +4,27 @@ Umpire Tutorial =============== -Coming soon! +This section is a tutorial introduction to Umpire. We start with the most basic +memory allocation, and move through topics like allocating on different +resources, using allocation strategies to change how memory is allocated, using +operations to move and modify data, and even how to write your own allocation +strategies! + +These examples are all built as part of Umpire, and you can find the files in +the ``exmamples`` directory at the root of the Umpire repository. Feel free to +play around and modify these examples to experiment with all of Umpire's +functionality. + +The following tutorial examples assume a working knowledge of C++ and a general +understanding of how memory is laid out in modern heterogeneous computers. The +main thing to remember is that in many systems, memory on other execution +devices (like GPUs) might not be accessible from the CPU. If you try and access +this memory your program will error! Luckily, Umpire makes it easy to move data +around, and check where it is, as you will see in the following sections. + +.. toctree:: + :maxdepth: 1 + + tutorial/allocators.rst + tutorial/resources.rst + tutorial/dynamic_pool.rst diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst new file mode 100644 index 000000000..00eb4daa5 --- /dev/null +++ b/docs/sphinx/tutorial/allocators.rst @@ -0,0 +1,24 @@ +.. _allocators: + +========== +Allocators +========== + +The fundamental concept for accessing memory through Umpire is the +``Allocator``. An ``Allocator`` is a C++ object that can be used to allocate +and deallocate memory, as well as query a pointer to get some extra information +about it. + +All ``Allocator`` s are created and managed by Umpire's ``ResourceManager``. To +get an Allocator, you need to ask for one: + +.. literalinclude:: ../../../examples/tut_allocator.cpp + :lines 22-24 + +Once you have an ``Allocator`` you can use it to allocate and deallocate memory: + +.. literalinclude:: ../../../examples/tut_allocator.cpp + :lines 26-32 + +In the next section, we will see how to allocate memory using different +resources. diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst new file mode 100644 index 000000000..1b1fea08b --- /dev/null +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -0,0 +1,5 @@ +.. _dynamic_pool: + +============= +Dynamic Pools +============= diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst new file mode 100644 index 000000000..94ee0943e --- /dev/null +++ b/docs/sphinx/tutorial/operations.rst @@ -0,0 +1,6 @@ +.. _operations: + +========== +Operations +========== + diff --git a/docs/sphinx/tutorial/resources.rst b/docs/sphinx/tutorial/resources.rst new file mode 100644 index 000000000..758848008 --- /dev/null +++ b/docs/sphinx/tutorial/resources.rst @@ -0,0 +1,43 @@ +.. _resources: + +========= +Resources +========= + +Each computer system will have a number of distinct places in which the system +will allow you to allocate memory. In Umpire's world, these are +``MemoryResources``. A memory resource can correspond to a hardware resource, +but can also be used to identify memory with a particular characteristic, like +"pinned" memory in a GPU system. + +When you configure Umpire, it will create ``MemoryResource`` s according to +what is available on the system you are building for. For each resource, Umpire +will create a default ``Allocator`` that you can use. In the previous example, +we were actually using an ``Allocator`` created for the ``MemoryResource`` +corresponding to the CPU memory + +The easiest way to identify resources is by name. The "HOST" resource is always +available. In a modern NVIDIA GPU system, we also have resources that represent +global GPU memory ("DEVICE"), unified memory that can be accessed by the CPU or +GPU ("UM") and host memory that can be accessed by the GPU ("PINNED"); + +Umpire will create an ``Allocator`` for each of these resources, and you can +get them using the same ``getAllocator`` call you saw in the previous example: + +.. literalinclude:: ../../../examples/tut_resources.cpp + :lines 22-24 + +Note that every ``Allocator`` supports the same calls, no matter which resource +it is for, this means we can parametertize the ``getAllocator`` call, and run +the same code for all the resources available in the system: + +.. literalinclude:: ../../../examples/tut_resources.cpp + :lines 18-35 + +As you can see, we can call this function with any valid resource name: + +.. literalinclude:: ../../../examples/tut_resources.cpp + :lines 38-44 + +In the next example, we will learn how to move data between resources using +operations. From 23c88a3cc7a3140045b11371910f1bf6425d0daa Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Sat, 4 Aug 2018 20:07:59 -0700 Subject: [PATCH 007/110] Add contribution guide --- docs/sphinx/contribution_guide.rst | 102 +++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 docs/sphinx/contribution_guide.rst diff --git a/docs/sphinx/contribution_guide.rst b/docs/sphinx/contribution_guide.rst new file mode 100644 index 000000000..f47b5d99e --- /dev/null +++ b/docs/sphinx/contribution_guide.rst @@ -0,0 +1,102 @@ +.. _contribution_guide: + +================== +Contribution Guide +================== + +This document is intented for developers who want to add new features or +bugfixes to Umpire. It assumes you have some familiarity with git and GitHub. +It will discuss what a good pull request (PR) looks like, and the tests that +your PR must pass before it can be merged into Umpire. + +-------------- +Forking Umpire +-------------- + +If you aren't an Umpire deveolper at LLNL, then you won't have permission to +push new branches to the repository. First, you should create a `fork +`_. This will create a copy of the Umpire +repository that you own, and will ensure you can push your changes up to GitHub +and create pull requests. + +^^^^^^^^^^^^^^^^^^^^^^^^ +Developing a New Feature +^^^^^^^^^^^^^^^^^^^^^^^^ + +New features should be based on the ``develop`` branch. When you want to create +a new feature, first ensure you have an up-to-date copy of the ``develop`` +branch: + +.. code-block:: bash + + $ git checkout develop + $ git pull origin develop + +You can now create a new branch to develop your feature on: + +.. code-block:: bash + + $ git checkout -b feature/ + +Proceed to develop your feature on this branch, and add tests that will exercise +your new code. If you are creating new methods or classes, please add Doxygen +documentation. + +Once your feature is complete and your tests are passing, you can push your +branch to GitHub and create a PR. + +^^^^^^^^^^^^^^^^^^^^ +Developing a Bug Fix +^^^^^^^^^^^^^^^^^^^^ + +First, check if the change you want to make has been fixed in ``develop``. If +so, we suggest you either start using the ``develop`` branch, or temporarily +apply the fix to whichever version of Umpire you are using. + +If the bug is still unfixed, first make sure you have an up-to-date copy +of the develop branch: + +.. code-block:: bash + + $ git checkout develop + $ git pull origin develop + +Then create a new branch for your bugfix: + +.. code-block:: bash + + $ git checkout -b bugfix/ + +First, add a test that reproduces the bug you have found. Then develop your +bugfix as normal, and ensure to ``make test`` to check your changes actually +fix the bug. + +Once you are finished, you can push your branch to GitHub, then create a PR. + +^^^^^^^^^^^^^^^^^^^^^^^ +Creating a Pull Request +^^^^^^^^^^^^^^^^^^^^^^^ + +You can create a new PR `here`_. +Ensure that your PR base is the ``develop`` branch of Umpire. + +Add a descriptive title explaining the bug you fixed or the feature you have +added, and put a longer description of the changes you have made in the comment +box. + +Once your PR has been created, it will be run through our automated tests and +also be reviewed by Umpire team members. Providing the branch passes both the +tests and reviews, it will be merged into Umpire. + +^^^^^ +Tests +^^^^^ + +Umpire uses Bamboo for continuous integration tests. Our tests are automatically +run against every new pull request, and passing all tests is a requirement for +merging your PR. If you are developing a bugfix or a new feature, please add a +test that checks the correctness of your new code. Umpire is used on a wide +variety of systems with a number of configurations, and adding new tests helps +ensure that all features work as expected across these environments. + +Umpire's tests are all in the ``test`` directory and are split up by component. From b1a18a5495c47da6b50fc7cddc6f425415acc9b5 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 11:02:38 -0700 Subject: [PATCH 008/110] Try and get ReadTheDocs to build the Doxygen --- docs/doxygen/Doxyfile | 1254 ++++++++++++++++++++++++++ docs/doxygen/Doxyfile.in | 1255 +-------------------------- docs/sphinx/conf.py | 5 + docs/sphinx/tutorial/allocators.rst | 2 +- 4 files changed, 1261 insertions(+), 1255 deletions(-) create mode 100644 docs/doxygen/Doxyfile mode change 100644 => 120000 docs/doxygen/Doxyfile.in diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile new file mode 100644 index 000000000..8d52d206f --- /dev/null +++ b/docs/doxygen/Doxyfile @@ -0,0 +1,1254 @@ +############################################################################## +# Copyright (c) 2018, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory +# +# Created by David Beckingsale, david@llnl.gov +# LLNL-CODE-747640 +# +# All rights reserved. +# +# This file is part of Umpire. +# +# For details, see https://github.com/LLNL/Umpire +# Please also see the LICENSE file for MIT license. +############################################################################## +# +# Doxyfile 1.4.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = UMPIRE + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_BRIEF = "Umpire: resource management and provision" + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +#OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4097 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES +# SAMRAI NO + +# Not present in SAMRAI +BUILTIN_STL_SUPPORT = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = @top_srcdir@ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = @top_srcdir@ + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 +# SAMRAI = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is YES. + +#SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = dox.warnings + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @PROJECT_SOURCE_DIR@/src + +# Allow Markdown files to provide the Doxygen main page + +#USE_MDFILE_AS_MAINPAGE = mainpage.md + + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS += *.md \ + *.markdown \ + *.cpp \ + *.hpp \ + *.dox + +#SAMRAI = *.[ChIf] \ +#SAMRAI *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + + + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = @PROJECT_SOURCE_DIR@/src/tpl/simpool/* @PROJECT_SOURCE_DIR@/src/tpl/judy/* + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. +# +# NOTE: generating source pages is VERY time consuming. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +#HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +EXTENSION_MAPPING = f=FortranFree +# from sidre + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = YES + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. (used SAMRAI different from Kenny's) + +GENERATE_XML = YES + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +# Not used in SAMRAI + +USE_MATHJAX = YES + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = HAVE_SILO \ + HAVE_SUNDIALS \ + HAVE_HYPRE \ + HAVE_PETSC \ + HAVE_HDF5 + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = @SAMRAI_PERL@ + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES +# SAMRAI @HAVE_DOT@ + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +CALLER_GRAPH = NO +#SAMRAI not used. + + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +INTERACTIVE_SVG = YES +# SAMRAI not used + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = @DOT_PATH@ + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in deleted file mode 100644 index 424038d7d..000000000 --- a/docs/doxygen/Doxyfile.in +++ /dev/null @@ -1,1254 +0,0 @@ -############################################################################## -# Copyright (c) 2018, Lawrence Livermore National Security, LLC. -# Produced at the Lawrence Livermore National Laboratory -# -# Created by David Beckingsale, david@llnl.gov -# LLNL-CODE-747640 -# -# All rights reserved. -# -# This file is part of Umpire. -# -# For details, see https://github.com/LLNL/Umpire -# Please also see the LICENSE file for MIT license. -############################################################################## -# -# Doxyfile 1.4.2 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = UMPIRE - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_BRIEF = "Umpire: resource management and provision" - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -#OUTPUT_DIRECTORY = @dox_output_dir@asctoolkit-dox - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4097 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, -# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, -# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, -# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, -# Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = YES -# SAMRAI NO - -# Not present in SAMRAI -BUILTIN_STL_SUPPORT = YES - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = @top_srcdir@ - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = @top_srcdir@ - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 -# SAMRAI = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = YES - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is YES. - -#SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the progam writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = dox.warnings - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = @PROJECT_SOURCE_DIR@/src - -# Allow Markdown files to provide the Doxygen main page - -#USE_MDFILE_AS_MAINPAGE = mainpage.md - - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm - -FILE_PATTERNS += *.md \ - *.markdown \ - *.cpp \ - *.hpp \ - *.dox - -#SAMRAI = *.[ChIf] \ -#SAMRAI *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - - - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = @PROJECT_SOURCE_DIR@/src/tpl/simpool/* @PROJECT_SOURCE_DIR@/src/tpl/judy/* - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = YES - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. -# -# NOTE: generating source pages is VERY time consuming. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = NO - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -#HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = YES - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -EXTENSION_MAPPING = f=FortranFree -# from sidre - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = letter - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = YES - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. (used SAMRAI different from Kenny's) - -GENERATE_XML = YES - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -# Not used in SAMRAI - -USE_MATHJAX = YES - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = HAVE_SILO \ - HAVE_SUNDIALS \ - HAVE_HYPRE \ - HAVE_PETSC \ - HAVE_HDF5 - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = @dox_output_dir@asctoolkit.tag - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = @SAMRAI_PERL@ - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES -# SAMRAI @HAVE_DOT@ - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = NO - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = NO - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -CALLER_GRAPH = NO -#SAMRAI not used. - - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = NO - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = NO - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -INTERACTIVE_SVG = YES -# SAMRAI not used - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = @DOT_PATH@ - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in new file mode 120000 index 000000000..cef6e7b6b --- /dev/null +++ b/docs/doxygen/Doxyfile.in @@ -0,0 +1 @@ +Doxyfile \ No newline at end of file diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 8e876bde6..55cca77bc 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -34,6 +34,11 @@ # import sys # sys.path.insert(0, os.path.abspath('.')) +read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' + +if read_the_docs_build: + + subprocess.call('cd ../doxygen; doxygen', shell=True) # -- General configuration ------------------------------------------------ diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst index 00eb4daa5..c58ca64e8 100644 --- a/docs/sphinx/tutorial/allocators.rst +++ b/docs/sphinx/tutorial/allocators.rst @@ -12,7 +12,7 @@ about it. All ``Allocator`` s are created and managed by Umpire's ``ResourceManager``. To get an Allocator, you need to ask for one: -.. literalinclude:: ../../../examples/tut_allocator.cpp +.. literalinclude:: ../../../examples/tut_allocator.cpp :lines 22-24 Once you have an ``Allocator`` you can use it to allocate and deallocate memory: From 0b7224a841599b92ffd4f36bfbb7616e6e762274 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 11:13:59 -0700 Subject: [PATCH 009/110] Fix config --- docs/sphinx/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 55cca77bc..f2885d248 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -34,10 +34,10 @@ # import sys # sys.path.insert(0, os.path.abspath('.')) -read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' +import os, subprocess +read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' if read_the_docs_build: - subprocess.call('cd ../doxygen; doxygen', shell=True) # -- General configuration ------------------------------------------------ From b18c1e8ce93047cef9a9b4666b8660e385008d14 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 11:25:37 -0700 Subject: [PATCH 010/110] Update paths in Doxyfile --- docs/doxygen/Doxyfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 8d52d206f..44fa35be1 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -456,7 +456,7 @@ WARN_LOGFILE = dox.warnings # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @PROJECT_SOURCE_DIR@/src +INPUT = ../../src # Allow Markdown files to provide the Doxygen main page @@ -505,7 +505,7 @@ EXCLUDE_SYMLINKS = NO # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = @PROJECT_SOURCE_DIR@/src/tpl/simpool/* @PROJECT_SOURCE_DIR@/src/tpl/judy/* +EXCLUDE_PATTERNS = ../../src/umpire/tpl/simpool/* ../../src/umpire/tpl/judy/* # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see From e63582603dadaac1f22460d5048046225bcd8c19 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 11:33:57 -0700 Subject: [PATCH 011/110] Add html_extra_path --- docs/sphinx/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index f2885d248..752ec717e 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -39,6 +39,7 @@ read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' if read_the_docs_build: subprocess.call('cd ../doxygen; doxygen', shell=True) + html_extra_path = ['../doxygen/html'] # -- General configuration ------------------------------------------------ From 465ab6b1cf093e19fbd01c9cf2fae8fb6ba63b3e Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 12:14:53 -0700 Subject: [PATCH 012/110] Cleaning up constant memory files --- src/umpire/resource/CMakeLists.txt | 2 +- src/umpire/resource/ConstantMemoryResource.cu | 14 +------------- src/umpire/resource/ConstantMemoryResource.hpp | 10 +--------- src/umpire/resource/DeviceConstResourceFactory.cpp | 3 +-- src/umpire/resource/DeviceConstResourceFactory.hpp | 3 +-- 5 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/umpire/resource/CMakeLists.txt b/src/umpire/resource/CMakeLists.txt index c5c3626a4..183c655de 100644 --- a/src/umpire/resource/CMakeLists.txt +++ b/src/umpire/resource/CMakeLists.txt @@ -76,4 +76,4 @@ install(TARGETS install(FILES ${umpire_resource_headers} - DESTINATION include/umpire/resource) \ No newline at end of file + DESTINATION include/umpire/resource) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index bc50d7482..a5ed23788 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -12,10 +12,9 @@ // For details, see https://github.com/LLNL/Umpire // Please also see the LICENSE file for MIT license. ////////////////////////////////////////////////////////////////////////////// -// #ifndef UMPIRE_DefaultMemoryResource_INL -// #define UMPIRE_DefaultMemoryResource_INL #include "umpire/resource/ConstantMemoryResource.hpp" + #include "umpire/ResourceManager.hpp" #include "umpire/util/Macros.hpp" @@ -25,21 +24,16 @@ namespace umpire { namespace resource { -// template ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::string& name, int id) : MemoryResource(name, id), - // m_allocator(), m_current_size(0l), m_highwatermark(0l), m_platform(platform) { } -// template void* ConstantMemoryResource::allocate(size_t bytes) { - // void* ptr = m_allocator.allocate(bytes); - void* ptr = nullptr; cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); @@ -54,32 +48,27 @@ void* ConstantMemoryResource::allocate(size_t bytes) return ptr; } -// template void ConstantMemoryResource::deallocate(void* ptr) { UMPIRE_LOG(Debug, "(ptr=" << ptr << ")"); - // m_allocator.deallocate(ptr); util::AllocationRecord* record = ResourceManager::getInstance().deregisterAllocation(ptr); m_current_size -= record->m_size; delete record; } -// template long ConstantMemoryResource::getCurrentSize() { UMPIRE_LOG(Debug, "() returning " << m_current_size); return m_current_size; } -// template long ConstantMemoryResource::getHighWatermark() { UMPIRE_LOG(Debug, "() returning " << m_highwatermark); return m_highwatermark; } -// template Platform ConstantMemoryResource::getPlatform() { return m_platform; @@ -87,4 +76,3 @@ Platform ConstantMemoryResource::getPlatform() } // end of namespace resource } // end of namespace umpire -// #endif // UMPIRE_DefaultMemoryResource_INL diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp index 76f3811cb..9f1dce40c 100644 --- a/src/umpire/resource/ConstantMemoryResource.hpp +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -28,10 +28,6 @@ namespace umpire { namespace resource { - /*! - * \brief Concrete MemoryResource object that uses the template _allocator to - * allocate and deallocate memory. - */ class ConstantMemoryResource : public MemoryResource { @@ -47,8 +43,6 @@ class ConstantMemoryResource : Platform getPlatform(); protected: - // _allocator m_allocator; - long m_current_size; long m_highwatermark; @@ -58,6 +52,4 @@ class ConstantMemoryResource : } // end of namespace resource } // end of namespace umpire -// #include "umpire/resource/ConstantMemoryResource.inl" - -#endif // UMPIRE_DefaultMemoryResource_HPP +#endif // UMPIRE_ConstantMemoryResource_HPP diff --git a/src/umpire/resource/DeviceConstResourceFactory.cpp b/src/umpire/resource/DeviceConstResourceFactory.cpp index cf85bbca7..6970ed58c 100644 --- a/src/umpire/resource/DeviceConstResourceFactory.cpp +++ b/src/umpire/resource/DeviceConstResourceFactory.cpp @@ -33,8 +33,7 @@ DeviceConstResourceFactory::isValidMemoryResourceFor(const std::string& name) std::shared_ptr DeviceConstResourceFactory::create(const std::string& name, int id) { - // constant memory resource, compiled by cuda compiler. umpire_internal_constant_memory - return std::make_shared(Platform::cuda, "DEVICE_CONST", id); + return std::make_shared("DEVICE_CONST", id); } } // end of namespace resource diff --git a/src/umpire/resource/DeviceConstResourceFactory.hpp b/src/umpire/resource/DeviceConstResourceFactory.hpp index b6c0214bc..4eec2c7e4 100644 --- a/src/umpire/resource/DeviceConstResourceFactory.hpp +++ b/src/umpire/resource/DeviceConstResourceFactory.hpp @@ -20,7 +20,6 @@ namespace umpire { namespace resource { - /*! * \brief Factory class for constructing MemoryResource objects that use GPU * memory. @@ -36,4 +35,4 @@ class DeviceConstResourceFactory : } // end of namespace resource } // end of namespace umpire -#endif // UMPIRE_DeviceResourceFactory_HPP +#endif // UMPIRE_DeviceConstResourceFactory_HPP From c85acc2696aa4b412e5ca4f5235533cef4c85062 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 15:58:39 -0700 Subject: [PATCH 013/110] Fix literalincludes --- docs/sphinx/tutorial/allocators.rst | 4 ++-- docs/sphinx/tutorial/resources.rst | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst index c58ca64e8..0f3323ff5 100644 --- a/docs/sphinx/tutorial/allocators.rst +++ b/docs/sphinx/tutorial/allocators.rst @@ -13,12 +13,12 @@ All ``Allocator`` s are created and managed by Umpire's ``ResourceManager``. To get an Allocator, you need to ask for one: .. literalinclude:: ../../../examples/tut_allocator.cpp - :lines 22-24 + :lines: 22-24 Once you have an ``Allocator`` you can use it to allocate and deallocate memory: .. literalinclude:: ../../../examples/tut_allocator.cpp - :lines 26-32 + :lines: 26-32 In the next section, we will see how to allocate memory using different resources. diff --git a/docs/sphinx/tutorial/resources.rst b/docs/sphinx/tutorial/resources.rst index 758848008..d2b46328f 100644 --- a/docs/sphinx/tutorial/resources.rst +++ b/docs/sphinx/tutorial/resources.rst @@ -24,20 +24,20 @@ GPU ("UM") and host memory that can be accessed by the GPU ("PINNED"); Umpire will create an ``Allocator`` for each of these resources, and you can get them using the same ``getAllocator`` call you saw in the previous example: -.. literalinclude:: ../../../examples/tut_resources.cpp - :lines 22-24 +.. literalinclude:: ../../../examples/tut_resources.cpp + :lines: 22-24 Note that every ``Allocator`` supports the same calls, no matter which resource it is for, this means we can parametertize the ``getAllocator`` call, and run the same code for all the resources available in the system: .. literalinclude:: ../../../examples/tut_resources.cpp - :lines 18-35 + :lines: 18-35 As you can see, we can call this function with any valid resource name: .. literalinclude:: ../../../examples/tut_resources.cpp - :lines 38-44 + :lines: 38-44 In the next example, we will learn how to move data between resources using operations. From 9cf9b9446bfd060aa7fec6f7344f2b0f8894b6a4 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 16:28:27 -0700 Subject: [PATCH 014/110] Try using breathe for Doxygen --- docs/sphinx/conf.py | 10 ++++++++-- docs/sphinx/developer_guide.rst | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 docs/sphinx/developer_guide.rst diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 752ec717e..50e2c7abc 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -50,9 +50,15 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autodoc', +extensions = [ + 'sphinx.ext.autodoc', 'sphinx.ext.todo', - 'sphinx.ext.mathjax'] + 'sphinx.ext.mathjax' + 'breathe' +] + +breathe_projects = { 'umpire': "../doxygen/xml/" } +breathe_default_project = "umpire" # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs/sphinx/developer_guide.rst b/docs/sphinx/developer_guide.rst new file mode 100644 index 000000000..97a92cfb9 --- /dev/null +++ b/docs/sphinx/developer_guide.rst @@ -0,0 +1,8 @@ +.. developer_guide: + +=============== +Developer Guide +=============== + +.. doxygenindex:: + :project: umpire From 8ed4c9d8400df63bb4d86629644f163e4e45ff5c Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 16:30:35 -0700 Subject: [PATCH 015/110] Fix extensions list --- docs/sphinx/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 50e2c7abc..30f595128 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -39,7 +39,6 @@ read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' if read_the_docs_build: subprocess.call('cd ../doxygen; doxygen', shell=True) - html_extra_path = ['../doxygen/html'] # -- General configuration ------------------------------------------------ @@ -53,7 +52,7 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', - 'sphinx.ext.mathjax' + 'sphinx.ext.mathjax', 'breathe' ] From 1e358aea58b61de6d37c40ad6670f5d3b67821dc Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 6 Aug 2018 16:37:49 -0700 Subject: [PATCH 016/110] Add requirements.txt --- docs/sphinx/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/sphinx/requirements.txt diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt new file mode 100644 index 000000000..cd6467ed8 --- /dev/null +++ b/docs/sphinx/requirements.txt @@ -0,0 +1 @@ +breathe From 55a20f2ed3e1eea37319bc0386debc892f59cf38 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 09:40:27 -0700 Subject: [PATCH 017/110] Disable breathe and change Doxygen output dir --- docs/doxygen/Doxyfile | 8 ++++--- docs/doxygen/Doxyfile.in | 1 - docs/sphinx/concepts.rst | 17 -------------- docs/sphinx/conf.py | 11 +++++---- docs/sphinx/contribution_guide.rst | 2 +- docs/sphinx/index.rst | 2 +- docs/sphinx/tutorial.rst | 1 + docs/sphinx/tutorial/dynamic_pool.rst | 34 +++++++++++++++++++++++++++ docs/sphinx/tutorial/operations.rst | 6 +++++ 9 files changed, 55 insertions(+), 27 deletions(-) delete mode 120000 docs/doxygen/Doxyfile.in delete mode 100644 docs/sphinx/concepts.rst diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 44fa35be1..ab2e13f31 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -1,4 +1,4 @@ -############################################################################## +############################################################################# # Copyright (c) 2018, Lawrence Livermore National Security, LLC. # Produced at the Lawrence Livermore National Laboratory # @@ -505,7 +505,9 @@ EXCLUDE_SYMLINKS = NO # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = ../../src/umpire/tpl/simpool/* ../../src/umpire/tpl/judy/* +EXCLUDE_PATTERNS = */tpl/simpool/* \ + */tpl/judy/* \ + */tpl/conduit/* # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see @@ -644,7 +646,7 @@ GENERATE_HTML = YES # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. -HTML_OUTPUT = html +HTML_OUTPUT = html/docs/ # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in deleted file mode 120000 index cef6e7b6b..000000000 --- a/docs/doxygen/Doxyfile.in +++ /dev/null @@ -1 +0,0 @@ -Doxyfile \ No newline at end of file diff --git a/docs/sphinx/concepts.rst b/docs/sphinx/concepts.rst deleted file mode 100644 index d7da31e28..000000000 --- a/docs/sphinx/concepts.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _concepts: - -===================== -Features and Concepts -===================== - ----------- -Allocators ----------- - ---------------- -ResourceManager ---------------- - ----------- -Operations ----------- diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 30f595128..4219dcd70 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -52,16 +52,19 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', - 'sphinx.ext.mathjax', - 'breathe' + 'sphinx.ext.mathjax' +# 'breathe' ] -breathe_projects = { 'umpire': "../doxygen/xml/" } -breathe_default_project = "umpire" +#breathe_projects = { 'umpire': "../../build/docs/doxygen/xml/" } +#breathe_default_project = "umpire" # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] + +html_extra_path = ['../doxygen/html/'] + # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # diff --git a/docs/sphinx/contribution_guide.rst b/docs/sphinx/contribution_guide.rst index f47b5d99e..2f5f1fe7e 100644 --- a/docs/sphinx/contribution_guide.rst +++ b/docs/sphinx/contribution_guide.rst @@ -77,7 +77,7 @@ Once you are finished, you can push your branch to GitHub, then create a PR. Creating a Pull Request ^^^^^^^^^^^^^^^^^^^^^^^ -You can create a new PR `here`_. +You can create a new PR `here `_. Ensure that your PR base is the ``develop`` branch of Umpire. Add a descriptive title explaining the bug you fixed or the feature you have diff --git a/docs/sphinx/index.rst b/docs/sphinx/index.rst index c6ccc267e..21dca9960 100644 --- a/docs/sphinx/index.rst +++ b/docs/sphinx/index.rst @@ -23,7 +23,7 @@ and management of memory on next-generation hardware architectures. :caption: Reference advanced_configuration - concepts + features code_documentation .. toctree:: diff --git a/docs/sphinx/tutorial.rst b/docs/sphinx/tutorial.rst index 8a94e4165..cb63c15ff 100644 --- a/docs/sphinx/tutorial.rst +++ b/docs/sphinx/tutorial.rst @@ -28,3 +28,4 @@ around, and check where it is, as you will see in the following sections. tutorial/allocators.rst tutorial/resources.rst tutorial/dynamic_pool.rst + tutorial/introspection.rst diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index 1b1fea08b..6834d5012 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -3,3 +3,37 @@ ============= Dynamic Pools ============= + +Frequently allocating and deallocating memory can be quite costly, especially +when you are making large allocations or allocating on different memory +resources. To mitigate this, Umpire provides allocation strategies that can be +used to customize how data is obtained from the system. + +In this example, we will look at the ``DynamicPool`` strategy. This is a simple +pooling algorithm that can fulfill requests for allocations of any size. To +create a new ``Allocator`` using the ``DynamicPool`` strategy: + +.. literalinclude:: ../../../examples/tut_dynamic_pool.cpp + :lines: 26-28 + +We have to provide a new name for the Allocator, as well as the underlying +Allocator we wish to use to grab memory. + +Once you have an ``Allocator``, you can allocate and deallocate memory as +before, without needing to worry about the underlying algorithm used for the +allocations: + +.. literalinclude:: ../../../examples/tut_dynamic_pool.cpp + :lines: 30-36 + +Don't forget, these strategies can be created on top of any valid Allocator: + +.. literalinclude:: ../../../examples/tut_dynamic_pool.cpp + :lines: 42-48 + +Most Umpire users will make alloctations that use the GPU via the DynamicPool, +to help mitigate the cost of allocating memory on these devices. + +There are lots of different strategies that you can use, and we will look at +many of them in the rest of this tutorial. A complete list of strategies can be +found here. diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst index 94ee0943e..87b72e7ff 100644 --- a/docs/sphinx/tutorial/operations.rst +++ b/docs/sphinx/tutorial/operations.rst @@ -4,3 +4,9 @@ Operations ========== +Moving and modifying data in a heterogenous memory system can be annoying. You +have to keep track of the source and destination, and often use vendor-specific +APIs to perform the modifications. In Umpire, all data modification and +movement is wrapped up in a concept we call `Operations`. + + From ae06f28d9b3fb2063f26a17cc9c8df411c0f5edc Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:04:37 -0700 Subject: [PATCH 018/110] Switch to exhale --- docs/sphinx/conf.py | 30 ++++++++++++++++++++++++------ docs/sphinx/index.rst | 1 + docs/sphinx/requirements.txt | 1 + 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 4219dcd70..65f73a575 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -52,18 +52,36 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', - 'sphinx.ext.mathjax' -# 'breathe' + 'sphinx.ext.mathjax', + 'breathe', + 'exhale' ] #breathe_projects = { 'umpire': "../../build/docs/doxygen/xml/" } -#breathe_default_project = "umpire" +breathe_projects = { 'umpire': "../doxygen/xml/" } +breathe_default_project = "umpire" + +exhale_args = { + # These arguments are required + "containmentFolder": "./api/", + "rootFileName": "api.rst", + "rootFileTitle": "API", + "doxygenStripFromPath": "..", + # Suggested optional arguments + "createTreeView": True, + # TIP: if using the sphinx-bootstrap-theme, you need + # "treeViewIsBootstrap": True, + "exhaleExecutesDoxygen": False, +} -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +# Tell sphinx what the primary language being documented is. +primary_domain = 'cpp' +# Tell sphinx what the pygments highlight language should be. +highlight_language = 'cpp' -html_extra_path = ['../doxygen/html/'] +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: diff --git a/docs/sphinx/index.rst b/docs/sphinx/index.rst index 21dca9960..add07d362 100644 --- a/docs/sphinx/index.rst +++ b/docs/sphinx/index.rst @@ -25,6 +25,7 @@ and management of memory on next-generation hardware architectures. advanced_configuration features code_documentation + api/api .. toctree:: :maxdepth: 2 diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt index cd6467ed8..714405518 100644 --- a/docs/sphinx/requirements.txt +++ b/docs/sphinx/requirements.txt @@ -1 +1,2 @@ breathe +exhale From 62a78fd7b681ee3ff85f824d9159d2f9c57829b2 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:12:14 -0700 Subject: [PATCH 019/110] Disable exhale and check doxygen gets run --- docs/sphinx/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 65f73a575..11e038e7b 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -38,6 +38,7 @@ read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' if read_the_docs_build: + print 'Running on read the docs' subprocess.call('cd ../doxygen; doxygen', shell=True) # -- General configuration ------------------------------------------------ @@ -54,7 +55,7 @@ 'sphinx.ext.todo', 'sphinx.ext.mathjax', 'breathe', - 'exhale' + #'exhale' ] #breathe_projects = { 'umpire': "../../build/docs/doxygen/xml/" } From eaf3412640749a237b49c778ca843391212e7c9a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:17:09 -0700 Subject: [PATCH 020/110] Add Doxyfile.in --- docs/doxygen/Doxyfile | 2 +- docs/doxygen/Doxyfile.in | 1256 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 1257 insertions(+), 1 deletion(-) create mode 100644 docs/doxygen/Doxyfile.in diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index ab2e13f31..5097a90f3 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -646,7 +646,7 @@ GENERATE_HTML = YES # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. -HTML_OUTPUT = html/docs/ +HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in new file mode 100644 index 000000000..22d1d80ab --- /dev/null +++ b/docs/doxygen/Doxyfile.in @@ -0,0 +1,1256 @@ +############################################################################## +# Copyright (c) 2018, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory +# +# Created by David Beckingsale, david@llnl.gov +# LLNL-CODE-747640 +# +# All rights reserved. +# +# This file is part of Umpire. +# +# For details, see https://github.com/LLNL/Umpire +# Please also see the LICENSE file for MIT license. +############################################################################## +# +# Doxyfile 1.4.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = UMPIRE + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_BRIEF = "Umpire: resource management and provision" + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +#OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4097 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES +# SAMRAI NO + +# Not present in SAMRAI +BUILTIN_STL_SUPPORT = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = @top_srcdir@ + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = @top_srcdir@ + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 +# SAMRAI = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is YES. + +#SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = dox.warnings + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @PROJECT_SOURCE_DIR@/src + +# Allow Markdown files to provide the Doxygen main page + +#USE_MDFILE_AS_MAINPAGE = mainpage.md + + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS += *.md \ + *.markdown \ + *.cpp \ + *.hpp \ + *.dox + +#SAMRAI = *.[ChIf] \ +#SAMRAI *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + + + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = */tpl/simpool/* \ + */tpl/judy/* \ + */tpl/conduit/* + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. +# +# NOTE: generating source pages is VERY time consuming. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +#HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +EXTENSION_MAPPING = f=FortranFree +# from sidre + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = YES + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. (used SAMRAI different from Kenny's) + +GENERATE_XML = YES + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +# Not used in SAMRAI + +USE_MATHJAX = YES + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = HAVE_SILO \ + HAVE_SUNDIALS \ + HAVE_HYPRE \ + HAVE_PETSC \ + HAVE_HDF5 + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = @SAMRAI_PERL@ + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES +# SAMRAI @HAVE_DOT@ + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +CALLER_GRAPH = NO +#SAMRAI not used. + + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = NO + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +INTERACTIVE_SVG = YES +# SAMRAI not used + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = @DOT_PATH@ + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO From c93a16093fd9ae6a2945ff8cb1c7fd0a63f736ea Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:20:03 -0700 Subject: [PATCH 021/110] Re-enable exhale --- docs/sphinx/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 11e038e7b..8e401cd75 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -37,6 +37,7 @@ import os, subprocess read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' + if read_the_docs_build: print 'Running on read the docs' subprocess.call('cd ../doxygen; doxygen', shell=True) @@ -55,7 +56,7 @@ 'sphinx.ext.todo', 'sphinx.ext.mathjax', 'breathe', - #'exhale' + 'exhale' ] #breathe_projects = { 'umpire': "../../build/docs/doxygen/xml/" } From 3ece86d123be634e600015ea307ecf998610b596 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:41:21 -0700 Subject: [PATCH 022/110] Remove Doxygen listing from developer guide --- docs/sphinx/developer_guide.rst | 3 --- docs/sphinx/features/allocators.rst | 5 +++++ docs/sphinx/features/operations.rst | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 docs/sphinx/features/allocators.rst create mode 100644 docs/sphinx/features/operations.rst diff --git a/docs/sphinx/developer_guide.rst b/docs/sphinx/developer_guide.rst index 97a92cfb9..c648f8211 100644 --- a/docs/sphinx/developer_guide.rst +++ b/docs/sphinx/developer_guide.rst @@ -3,6 +3,3 @@ =============== Developer Guide =============== - -.. doxygenindex:: - :project: umpire diff --git a/docs/sphinx/features/allocators.rst b/docs/sphinx/features/allocators.rst new file mode 100644 index 000000000..3b6bd0f7f --- /dev/null +++ b/docs/sphinx/features/allocators.rst @@ -0,0 +1,5 @@ +========== +Allocators +========== + +.. doxygenclass:: umpire::Allocator diff --git a/docs/sphinx/features/operations.rst b/docs/sphinx/features/operations.rst new file mode 100644 index 000000000..6c16f02f5 --- /dev/null +++ b/docs/sphinx/features/operations.rst @@ -0,0 +1,6 @@ +========== +Operations +========== + +.. doxygennamespace:: umpire::op + From 11891c5206aca63a498657553a01b2a6eea468c8 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:41:48 -0700 Subject: [PATCH 023/110] Add feature file --- docs/sphinx/features.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/sphinx/features.rst diff --git a/docs/sphinx/features.rst b/docs/sphinx/features.rst new file mode 100644 index 000000000..8b7d8e16d --- /dev/null +++ b/docs/sphinx/features.rst @@ -0,0 +1,13 @@ +.. _features: + +======== +Features +======== + +.. toctree:: + :maxdepth: 1 + + features/allocators + features/strategies + features/operations + features/introspection From 8c305e45623f0243ebb43eae0553f33894707b10 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:52:48 -0700 Subject: [PATCH 024/110] Tweak doxygen options --- docs/doxygen/Doxyfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 5097a90f3..262230346 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -118,7 +118,7 @@ BUILTIN_STL_SUPPORT = YES # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. -FULL_PATH_NAMES = YES +FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is @@ -378,7 +378,7 @@ MAX_INITIALIZER_LINES = 30 # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. -SHOW_USED_FILES = YES +SHOW_USED_FILES = NO # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy @@ -640,7 +640,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. -GENERATE_HTML = YES +GENERATE_HTML = NO # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be From 90ab354760fcac5324fd54b8ebdb4bc4b72a9c58 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 10:57:53 -0700 Subject: [PATCH 025/110] Hide include files --- docs/doxygen/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 262230346..46f46b5b6 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -304,7 +304,7 @@ HIDE_SCOPE_NAMES = NO # will put a list of the files that are included by a file in the documentation # of that file. -SHOW_INCLUDE_FILES = YES +SHOW_INCLUDE_FILES NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. From 39269fdcec50bb09b15f6f1358803d42e0872a95 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 11:07:14 -0700 Subject: [PATCH 026/110] Set up STRIP_FROM_PATH --- docs/doxygen/Doxyfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 46f46b5b6..1037ed648 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -118,7 +118,7 @@ BUILTIN_STL_SUPPORT = YES # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. -FULL_PATH_NAMES = NO +FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is @@ -127,7 +127,8 @@ FULL_PATH_NAMES = NO # If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = @top_srcdir@ +STRIP_FROM_PATH = ../../src + # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells @@ -136,7 +137,7 @@ STRIP_FROM_PATH = @top_srcdir@ # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = @top_srcdir@ +STRIP_FROM_INC_PATH = ../../src # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems From dc84428dd84130519a243c217ebcadcf6fd33d1b Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 17:44:02 -0700 Subject: [PATCH 027/110] Moving tutorial examples --- docs/sphinx/features/allocators.rst | 2 +- docs/sphinx/features/introspection.rst | 5 ++ docs/sphinx/features/operations.rst | 2 + docs/sphinx/features/strategies.rst | 7 ++ docs/sphinx/index.rst | 11 ++- docs/sphinx/tutorial.rst | 1 + docs/sphinx/tutorial/allocators.rst | 4 +- docs/sphinx/tutorial/dynamic_pool.rst | 6 +- docs/sphinx/tutorial/introspection.rst | 5 ++ docs/sphinx/tutorial/operations.rst | 22 ++++++ examples/CMakeLists.txt | 2 + examples/tutorial/CMakeLists.txt | 38 +++++++++++ examples/{ => tutorial}/tut_allocator.cpp | 0 .../tut_copy.cpp} | 0 examples/{ => tutorial}/tut_dynamic_pool.cpp | 0 examples/tutorial/tut_move.cpp | 67 +++++++++++++++++++ examples/tutorial/tut_reallocate.cpp | 0 examples/{ => tutorial}/tut_resources.cpp | 0 18 files changed, 163 insertions(+), 9 deletions(-) create mode 100644 docs/sphinx/features/introspection.rst create mode 100644 docs/sphinx/features/strategies.rst create mode 100644 docs/sphinx/tutorial/introspection.rst create mode 100644 examples/tutorial/CMakeLists.txt rename examples/{ => tutorial}/tut_allocator.cpp (100%) rename examples/{tut_operations.cpp => tutorial/tut_copy.cpp} (100%) rename examples/{ => tutorial}/tut_dynamic_pool.cpp (100%) create mode 100644 examples/tutorial/tut_move.cpp create mode 100644 examples/tutorial/tut_reallocate.cpp rename examples/{ => tutorial}/tut_resources.cpp (100%) diff --git a/docs/sphinx/features/allocators.rst b/docs/sphinx/features/allocators.rst index 3b6bd0f7f..dd0f42328 100644 --- a/docs/sphinx/features/allocators.rst +++ b/docs/sphinx/features/allocators.rst @@ -2,4 +2,4 @@ Allocators ========== -.. doxygenclass:: umpire::Allocator +.. doxygenclass:: Allocator diff --git a/docs/sphinx/features/introspection.rst b/docs/sphinx/features/introspection.rst new file mode 100644 index 000000000..a85cf8700 --- /dev/null +++ b/docs/sphinx/features/introspection.rst @@ -0,0 +1,5 @@ +.. _introspection: + +============= +Introspection +============= diff --git a/docs/sphinx/features/operations.rst b/docs/sphinx/features/operations.rst index 6c16f02f5..c43005bff 100644 --- a/docs/sphinx/features/operations.rst +++ b/docs/sphinx/features/operations.rst @@ -1,3 +1,5 @@ +.. _operations: + ========== Operations ========== diff --git a/docs/sphinx/features/strategies.rst b/docs/sphinx/features/strategies.rst new file mode 100644 index 000000000..38c948f81 --- /dev/null +++ b/docs/sphinx/features/strategies.rst @@ -0,0 +1,7 @@ +.. _strategies: + +========== +Strategies +========== + +.. doxygennamespace:: umpire::strategy diff --git a/docs/sphinx/index.rst b/docs/sphinx/index.rst index add07d362..95a815dd2 100644 --- a/docs/sphinx/index.rst +++ b/docs/sphinx/index.rst @@ -2,14 +2,19 @@ Umpire ****** -Umpire is a resource management libray that allows the discovery, provision, -and management of memory on next-generation hardware architectures. +Umpire is a resource management library that allows the discovery, provision, +and management of memory on next-generation hardware architectures with NUMA +memory hierarchies. + +- Take a look at our Getting Started guide for all you need to get up and + running with Umpire. -- If you want to get and install Umpire, take a look at our getting started guide. - If you are looking for developer documentation on a particular function, check out the code documentation. + - Want to contribute? Take a look at our developer and contribution guides. +Any questions? File an issue on GitHub, or email umpire-dev@llnl.gov .. toctree:: :maxdepth: 2 diff --git a/docs/sphinx/tutorial.rst b/docs/sphinx/tutorial.rst index cb63c15ff..7ad62d590 100644 --- a/docs/sphinx/tutorial.rst +++ b/docs/sphinx/tutorial.rst @@ -27,5 +27,6 @@ around, and check where it is, as you will see in the following sections. tutorial/allocators.rst tutorial/resources.rst + tutorial/operations.rst tutorial/dynamic_pool.rst tutorial/introspection.rst diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst index 0f3323ff5..e414b0bca 100644 --- a/docs/sphinx/tutorial/allocators.rst +++ b/docs/sphinx/tutorial/allocators.rst @@ -12,12 +12,12 @@ about it. All ``Allocator`` s are created and managed by Umpire's ``ResourceManager``. To get an Allocator, you need to ask for one: -.. literalinclude:: ../../../examples/tut_allocator.cpp +.. literalinclude:: ../../../examples/tutorial/tut_allocator.cpp :lines: 22-24 Once you have an ``Allocator`` you can use it to allocate and deallocate memory: -.. literalinclude:: ../../../examples/tut_allocator.cpp +.. literalinclude:: ../../../examples/tutorial/tut_allocator.cpp :lines: 26-32 In the next section, we will see how to allocate memory using different diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index 6834d5012..826c5d20f 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -13,7 +13,7 @@ In this example, we will look at the ``DynamicPool`` strategy. This is a simple pooling algorithm that can fulfill requests for allocations of any size. To create a new ``Allocator`` using the ``DynamicPool`` strategy: -.. literalinclude:: ../../../examples/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp :lines: 26-28 We have to provide a new name for the Allocator, as well as the underlying @@ -23,12 +23,12 @@ Once you have an ``Allocator``, you can allocate and deallocate memory as before, without needing to worry about the underlying algorithm used for the allocations: -.. literalinclude:: ../../../examples/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp :lines: 30-36 Don't forget, these strategies can be created on top of any valid Allocator: -.. literalinclude:: ../../../examples/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp :lines: 42-48 Most Umpire users will make alloctations that use the GPU via the DynamicPool, diff --git a/docs/sphinx/tutorial/introspection.rst b/docs/sphinx/tutorial/introspection.rst new file mode 100644 index 000000000..a85cf8700 --- /dev/null +++ b/docs/sphinx/tutorial/introspection.rst @@ -0,0 +1,5 @@ +.. _introspection: + +============= +Introspection +============= diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst index 87b72e7ff..07a8dde24 100644 --- a/docs/sphinx/tutorial/operations.rst +++ b/docs/sphinx/tutorial/operations.rst @@ -9,4 +9,26 @@ have to keep track of the source and destination, and often use vendor-specific APIs to perform the modifications. In Umpire, all data modification and movement is wrapped up in a concept we call `Operations`. +---- +Copy +---- +Let's start by looking at how we copy data around. The +:class:`umpire::ResourceManager` provides an interface to copy that handles +figuring out where the source and destination pointers were allocated, and +selects the correct implementation to copy the data: + +.. literalinclude:: ../../../examples/tutorial/tut_copy.cpp + :lines: 23-26 + +This example allocates the destination data using any valid Allocator. + +---- +Move +---- + +If you want to move data to a new Allocator and deallocate the old copy, Umpire +provides a `move` operation. + +.. literalinclude:: ../../../examples/tutorial/tut_move.cpp + :lines: 23-26 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 977f6f65f..f7baa868c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -69,3 +69,5 @@ blt_add_executable( SOURCES tut_operations.cpp DEPENDS_ON umpire) + +add_subdirectory(tutorial) diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt new file mode 100644 index 000000000..3edfa7c1d --- /dev/null +++ b/examples/tutorial/CMakeLists.txt @@ -0,0 +1,38 @@ +############################################################################## +# Copyright (c) 2018, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory +# +# Created by David Beckingsale, david@llnl.gov +# LLNL-CODE-747640 +# +# All rights reserved. +# +# This file is part of Umpire. +# +# For details, see https://github.com/LLNL/Umpire +# Please also see the LICENSE file for MIT license. +############################################################################## + +blt_add_executable( + NAME tut_allocator + SOURCES tut_allocator.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_resources + SOURCES tut_resources.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_dynamic_pool + SOURCES tut_dynamic_pool.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_operations + SOURCES tut_operations.cpp + DEPENDS_ON + umpire) diff --git a/examples/tut_allocator.cpp b/examples/tutorial/tut_allocator.cpp similarity index 100% rename from examples/tut_allocator.cpp rename to examples/tutorial/tut_allocator.cpp diff --git a/examples/tut_operations.cpp b/examples/tutorial/tut_copy.cpp similarity index 100% rename from examples/tut_operations.cpp rename to examples/tutorial/tut_copy.cpp diff --git a/examples/tut_dynamic_pool.cpp b/examples/tutorial/tut_dynamic_pool.cpp similarity index 100% rename from examples/tut_dynamic_pool.cpp rename to examples/tutorial/tut_dynamic_pool.cpp diff --git a/examples/tutorial/tut_move.cpp b/examples/tutorial/tut_move.cpp new file mode 100644 index 000000000..c8cd68f67 --- /dev/null +++ b/examples/tutorial/tut_move.cpp @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +double* move_data(double* source_data, const std::string& destination) +{ + auto& rm = umpire::ResourceManager::getInstance(); + auto dest_allocator = rm.getAllocator(destination); + + double* dest_data = static_cast( + dest_allocator.allocate(size*sizeof(double))); + + std::cout << "Moved source data (" << source_data << ") to destination "; + + double* dest_data = static_cast( + rm.move(source_data, dest_allocator)); + + std::cout << destination << " (" << dest_data << ")" << std::endl; + + return dest_data; +} + +int main(int argc, char* argv[]) { + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + auto allocator = rm.getAllocator("HOST"); + + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + << allocator.getName() << " allocator." << std::endl; + + std::cout << "Filling with 0.0..."; + + for (size_t i = 0; i < SIZE; i++) { + data[i] = 0.0; + } + + std::cout << "done." << std::endl; + + data = move_data(data, "HOST"); +#if defined(UMPIRE_ENABLE_CUDA) + data = move_data(data, "DEVICE"); + data = move_data(data, "UM"); + data = move_data(data, "PINNED"); +#endif + + rm.deallocate(data); + + return 0; +} diff --git a/examples/tutorial/tut_reallocate.cpp b/examples/tutorial/tut_reallocate.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/examples/tut_resources.cpp b/examples/tutorial/tut_resources.cpp similarity index 100% rename from examples/tut_resources.cpp rename to examples/tutorial/tut_resources.cpp From 5d65bd2022929db9ca71f39be94d75a499011c26 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 17:51:11 -0700 Subject: [PATCH 028/110] Add travis.yml and build script --- .travis.yml | 21 +++++++++++++++++++++ scripts/travis/build_and_test.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 .travis.yml create mode 100755 scripts/travis/build_and_test.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..9c15cc625 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +services: docker +dist: trusty +language: cpp +env: + global: + - DO_BUILD=yes + - DO_TEST=yes +matrix: + include: + - compiler: gcc5 + env: + - COMPILER=g++ + - IMG=gcc-5 + - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On" + +script: +- docker run --rm --user='root' -v ${TRAVIS_BUILD_DIR}:/home/axom axom/compilers:$IMG chown -R axom /home/axom +- docker run --rm -v ${TRAVIS_BUILD_DIR}:/home/axom -e COMPILER -e DO_BUILD -e DO_TEST -e CMAKE_EXTRA_FLAGS axom/compilers:$IMG ./scripts/travis/build_and_test.sh + +after_success: +- if [[ "${CMAKE_EXTRA_FLAGS}" == *"ENABLE_COVERAGE"* ]] ; then bash <(curl -s https://codecov.io/bash) -a "-f" >& /dev/null; fi diff --git a/scripts/travis/build_and_test.sh b/scripts/travis/build_and_test.sh new file mode 100755 index 000000000..9b2ac8c83 --- /dev/null +++ b/scripts/travis/build_and_test.sh @@ -0,0 +1,26 @@ +#!/bin/bash +env +function or_die () { + "$@" + local status=$? + if [[ $status != 0 ]] ; then + echo ERROR $status command: $@ + exit $status + fi +} + +or_die mkdir travis-build +cd travis-build +if [[ "$DO_BUILD" == "yes" ]] ; then + or_die cmake -DCMAKE_CXX_COMPILER="${COMPILER}" ${CMAKE_EXTRA_FLAGS} ../ + if [[ ${CMAKE_EXTRA_FLAGS} == *COVERAGE* ]] ; then + or_die make -j 3 + else + or_die make -j 3 VERBOSE=1 + fi + if [[ "${DO_TEST}" == "yes" ]] ; then + or_die ctest -V + fi +fi + +exit 0 From 0f17c1a301e5070d2c4e58acc4833ad19d1ef096 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 17:53:12 -0700 Subject: [PATCH 029/110] Disable CUDA --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9c15cc625..ebed12673 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: env: - COMPILER=g++ - IMG=gcc-5 - - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On" + - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_CUDA=Off" script: - docker run --rm --user='root' -v ${TRAVIS_BUILD_DIR}:/home/axom axom/compilers:$IMG chown -R axom /home/axom From 733c5e63953ae630dcc5d3f6cc8f2f062c75cb59 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 7 Aug 2018 18:09:49 -0700 Subject: [PATCH 030/110] Add NVIDIA configuration --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index ebed12673..2b4edff20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,12 @@ matrix: - COMPILER=g++ - IMG=gcc-5 - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_CUDA=Off" + - compiler: nvcc + env: + - COMPILER=g++ + - IMG=nvcc-9 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=On" + - DO_TEST=no script: - docker run --rm --user='root' -v ${TRAVIS_BUILD_DIR}:/home/axom axom/compilers:$IMG chown -R axom /home/axom From cd81871ca0b47fcc97c62b82c7d7da3ab4fcea5d Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 09:15:41 -0700 Subject: [PATCH 031/110] Add clang-4 --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2b4edff20..30d4f7adb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,16 @@ env: - DO_TEST=yes matrix: include: - - compiler: gcc5 + - compiler: gcc-5 env: - COMPILER=g++ - IMG=gcc-5 - - CMAKE_EXTRA_FLAGS="-DENABLE_WARNINGS=On -DENABLE_CUDA=Off" + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - compiler: clang-4 + env: + - COMPILER=clang++ + - IMG=clang-4 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - compiler: nvcc env: - COMPILER=g++ From 7d8a85b88a6ad2a8f042c2177fae82f1c60f3c42 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 11:25:59 -0700 Subject: [PATCH 032/110] Support deallocting nullptr --- src/umpire/Allocator.cpp | 8 +- .../allocator_integration_tests.cpp | 301 +++++++----------- 2 files changed, 117 insertions(+), 192 deletions(-) diff --git a/src/umpire/Allocator.cpp b/src/umpire/Allocator.cpp index a4c27ba6c..ab3e7f9a6 100644 --- a/src/umpire/Allocator.cpp +++ b/src/umpire/Allocator.cpp @@ -43,12 +43,16 @@ Allocator::allocate(size_t bytes) void Allocator::deallocate(void* ptr) { - UMPIRE_ASSERT("Deallocate called with nullptr" && ptr); UMPIRE_LOG(Debug, "(" << ptr << ")"); + UMPIRE_RECORD_STATISTIC(getName(), "ptr", reinterpret_cast(ptr), "size", 0x0, "event", "deallocate"); - m_allocator->deallocate(ptr); + if (!ptr) { + return; + } else { + m_allocator->deallocate(ptr); + } } size_t diff --git a/tests/integration/allocator_integration_tests.cpp b/tests/integration/allocator_integration_tests.cpp index 9df4f5994..cd4155192 100644 --- a/tests/integration/allocator_integration_tests.cpp +++ b/tests/integration/allocator_integration_tests.cpp @@ -15,248 +15,123 @@ #include "gtest/gtest.h" #include "umpire/config.hpp" -#include "umpire/ResourceManager.hpp" +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" #include "umpire/resource/MemoryResourceTypes.hpp" -TEST(Allocator, HostAllocator) -{ - auto &rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator("HOST"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); - ASSERT_NE(nullptr, test_alloc); - allocator.deallocate(test_alloc); - - test_alloc = static_cast(allocator.allocate(0*sizeof(double))); - allocator.deallocate(test_alloc); -} - -TEST(Allocator, HostAllocatorType) -{ - auto &rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator(umpire::resource::Host); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); - - ASSERT_NE(nullptr, test_alloc); - - allocator.deallocate(test_alloc); -} - -TEST(Allocator, HostAllocatorReference) -{ - auto &rm = umpire::ResourceManager::getInstance(); - umpire::Allocator *p; - - p = new umpire::Allocator(rm.getAllocator("HOST")); - - double* test_alloc = static_cast(p->allocate(100*sizeof(double))); - - ASSERT_NE(nullptr, test_alloc); - - p->deallocate(test_alloc); - - delete p; -} - -TEST(Allocator, HostAllocatorSize) -{ - auto &rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator("HOST"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); - - ASSERT_EQ((100*sizeof(double)), allocator.getSize(test_alloc)); - - allocator.deallocate(test_alloc); - - ASSERT_ANY_THROW(allocator.getSize(test_alloc)); -} - -#if defined(UMPIRE_ENABLE_CUDA) -TEST(Allocator, DeviceAllocator) +class AllocatorTest : + public ::testing::TestWithParam< std::string > { - auto &rm = umpire::ResourceManager::getInstance(); + public: + virtual void SetUp() + { + auto& rm = umpire::ResourceManager::getInstance(); + m_allocator = new umpire::Allocator(rm.getAllocator(GetParam())); + } - umpire::Allocator allocator = rm.getAllocator("DEVICE"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); + virtual void TearDown() + { + delete m_allocator; + } - ASSERT_NE(nullptr, test_alloc); -} - -TEST(Allocator, DeviceAllocatorReference) -{ - auto &rm = umpire::ResourceManager::getInstance(); - umpire::Allocator *p; + umpire::Allocator* m_allocator; - p = new umpire::Allocator(rm.getAllocator("DEVICE")); + const size_t m_big = 16000; + const size_t m_small = 8; + const size_t m_nothing = 0; +}; - double* test_alloc = static_cast(p->allocate(100*sizeof(double))); - - ASSERT_NE(nullptr, test_alloc); - - p->deallocate(test_alloc); - - delete p; -} - -TEST(Allocator, DeviceAllocatorSize) +TEST_P(AllocatorTest, AllocateDeallocateBig) { - auto &rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator("DEVICE"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); + double* data = static_cast( + m_allocator->allocate(m_big*sizeof(double))); - ASSERT_EQ((100*sizeof(double)), allocator.getSize(test_alloc)); + ASSERT_NE(nullptr, data); - allocator.deallocate(test_alloc); - - ASSERT_ANY_THROW(allocator.getSize(test_alloc)); -} - -TEST(Allocator, UmAllocator) -{ - auto &rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator("UM"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); - - ASSERT_NE(nullptr, test_alloc); + m_allocator->deallocate(data); } -TEST(Allocator, UmAllocatorReference) +TEST_P(AllocatorTest, AllocateDeallocateSmall) { - auto &rm = umpire::ResourceManager::getInstance(); - umpire::Allocator *p; + double* data = static_cast( + m_allocator->allocate(m_small*sizeof(double))); - p = new umpire::Allocator(rm.getAllocator("UM")); + ASSERT_NE(nullptr, data); - double* test_alloc = static_cast(p->allocate(100*sizeof(double))); - - ASSERT_NE(nullptr, test_alloc); - - p->deallocate(test_alloc); - - delete p; + m_allocator->deallocate(data); } -TEST(Allocator, UmAllocatorSize) +TEST_P(AllocatorTest, AllocateDeallocateNothing) { - auto &rm = umpire::ResourceManager::getInstance(); + double* data = static_cast( + m_allocator->allocate(m_nothing*sizeof(double))); - umpire::Allocator allocator = rm.getAllocator("UM"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); + ASSERT_NE(nullptr, data); - ASSERT_EQ((100*sizeof(double)), allocator.getSize(test_alloc)); - - allocator.deallocate(test_alloc); - - ASSERT_ANY_THROW(allocator.getSize(test_alloc)); + m_allocator->deallocate(data); } -TEST(Allocator, PinnedAllocator) +TEST_P(AllocatorTest, DeallocateNullptr) { - auto &rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator("PINNED"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); + double* data = nullptr; - ASSERT_NE(nullptr, test_alloc); -} - -TEST(Allocator, PinnedAllocatorReference) -{ - auto &rm = umpire::ResourceManager::getInstance(); - umpire::Allocator *p; - - p = new umpire::Allocator(rm.getAllocator("PINNED")); - - double* test_alloc = static_cast(p->allocate(100*sizeof(double))); - - ASSERT_NE(nullptr, test_alloc); - - p->deallocate(test_alloc); + ASSERT_NO_THROW( + m_allocator->deallocate(data); + ); - delete p; + SUCCEED(); } -TEST(Allocator, PinnedAllocatorSize) +TEST_P(AllocatorTest, GetSize) { - auto &rm = umpire::ResourceManager::getInstance(); + const size_t size = m_big*sizeof(double); - umpire::Allocator allocator = rm.getAllocator("PINNED"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); + double* data = static_cast( + m_allocator->allocate(size)); - ASSERT_EQ((100*sizeof(double)), allocator.getSize(test_alloc)); + ASSERT_EQ(size, m_allocator->getSize(data)); - allocator.deallocate(test_alloc); + m_allocator->deallocate(data); - ASSERT_ANY_THROW(allocator.getSize(test_alloc)); + ASSERT_ANY_THROW(m_allocator->getSize(data)); } -#endif - -TEST(Allocator, Deallocate) +TEST_P(AllocatorTest, GetName) { - auto& rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator allocator = rm.getAllocator("HOST"); - double* test_alloc = static_cast(allocator.allocate(100*sizeof(double))); - - rm.deallocate(test_alloc); - - SUCCEED(); -} - -TEST(Allocator, DeallocateThrow) -{ - auto& rm = umpire::ResourceManager::getInstance(); - - double* ptr = new double[20]; - ASSERT_ANY_THROW(rm.deallocate(ptr)); + ASSERT_EQ(m_allocator->getName(), GetParam()); } -TEST(Allocator, Name) +TEST_P(AllocatorTest, GetById) { auto& rm = umpire::ResourceManager::getInstance(); - umpire::Allocator alloc = rm.getAllocator("HOST"); - - ASSERT_EQ(alloc.getName(), "HOST"); -} - -TEST(Allocator, Id) -{ - auto& rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator alloc = rm.getAllocator("HOST"); - int id = alloc.getId(); + int id = m_allocator->getId(); ASSERT_GE(id, 0); auto allocator_by_id = rm.getAllocator(id); - ASSERT_EQ(alloc.getAllocationStrategy(), allocator_by_id.getAllocationStrategy()); + ASSERT_EQ(m_allocator->getAllocationStrategy(), allocator_by_id.getAllocationStrategy()); ASSERT_THROW( rm.getAllocator(-25), umpire::util::Exception); } +const std::string allocator_strings[] = { + "HOST" #if defined(UMPIRE_ENABLE_CUDA) -TEST(Allocator, IdUnique) -{ - auto& rm = umpire::ResourceManager::getInstance(); - - umpire::Allocator host_alloc = rm.getAllocator("HOST"); - umpire::Allocator device_alloc = rm.getAllocator("DEVICE"); - - int host_id = host_alloc.getId(); - int device_id = device_alloc.getId(); - - ASSERT_NE(host_id, device_id); -} + , "DEVICE" + , "UM" + , "PINNED" #endif +}; + +INSTANTIATE_TEST_CASE_P( + Allocators, + AllocatorTest, + ::testing::ValuesIn(allocator_strings) +); TEST(Allocator, isRegistered) { @@ -279,7 +154,7 @@ TEST(Allocator, registerAllocator) rm.registerAllocator("HOST", rm.getAllocator("my_host_allocator_copy"))); } -TEST(DefaultAllocator, GetSet) +TEST(Allocator, GetSetDefault) { auto& rm = umpire::ResourceManager::getInstance(); @@ -291,3 +166,49 @@ TEST(DefaultAllocator, GetSet) rm.setDefaultAllocator(rm.getDefaultAllocator()); ); } + +class AllocatorByResourceTest : + public ::testing::TestWithParam< umpire::resource::MemoryResourceType > +{ + public: + virtual void SetUp() + { + auto& rm = umpire::ResourceManager::getInstance(); + m_allocator = new umpire::Allocator(rm.getAllocator(GetParam())); + } + + virtual void TearDown() + { + delete m_allocator; + } + + umpire::Allocator* m_allocator; + + const size_t m_big = 16000; + const size_t m_small = 8; + const size_t m_nothing = 0; +}; + +TEST_P(AllocatorByResourceTest, AllocateDeallocate) +{ + double* data = static_cast( + m_allocator->allocate(m_big*sizeof(double))); + + ASSERT_NE(nullptr, data); + + m_allocator->deallocate(data); +} + +const umpire::resource::MemoryResourceType resource_types[] = { + umpire::resource::Host +#if defined(UMPIRE_ENABLE_CUDA) + , umpire::resource::Device + , umpire::resource::UnifiedMemory + , umpire::resource::Pinned +#endif +}; + +INSTANTIATE_TEST_CASE_P( + Resources, + AllocatorByResourceTest, + ::testing::ValuesIn(resource_types)); From 2b5218095ed26098820eb84a255e9f9d3425d748 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 11:27:05 -0700 Subject: [PATCH 033/110] Add extra GCC and clang versions --- .travis.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.travis.yml b/.travis.yml index 30d4f7adb..52d78bcc5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,11 +12,36 @@ matrix: - COMPILER=g++ - IMG=gcc-5 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - compiler: gcc-6 + env: + - COMPILER=g++ + - IMG=gcc-6 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - compiler: gcc-7 + env: + - COMPILER=g++ + - IMG=gcc-7 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - compiler: gcc-8 + env: + - COMPILER=g++ + - IMG=gcc-8 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - compiler: clang-4 env: - COMPILER=clang++ - IMG=clang-4 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - compiler: clang-5 + env: + - COMPILER=clang++ + - IMG=clang-5 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - compiler: clang-6 + env: + - COMPILER=clang++ + - IMG=clang-6 + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - compiler: nvcc env: - COMPILER=g++ From 3f4abc268fe54e0a6954c48ad654bbb7ca8d47cf Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 11:46:12 -0700 Subject: [PATCH 034/110] Correct PinnedMemory resource type usage --- tests/integration/allocator_integration_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/allocator_integration_tests.cpp b/tests/integration/allocator_integration_tests.cpp index cd4155192..eda2432f4 100644 --- a/tests/integration/allocator_integration_tests.cpp +++ b/tests/integration/allocator_integration_tests.cpp @@ -204,7 +204,7 @@ const umpire::resource::MemoryResourceType resource_types[] = { #if defined(UMPIRE_ENABLE_CUDA) , umpire::resource::Device , umpire::resource::UnifiedMemory - , umpire::resource::Pinned + , umpire::resource::PinnedMemory #endif }; From 741a52b54a22e6375a835262bc9d80eacf79e1bc Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 11:48:56 -0700 Subject: [PATCH 035/110] Add log message when deallocating nullptr --- src/umpire/Allocator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/umpire/Allocator.cpp b/src/umpire/Allocator.cpp index ab3e7f9a6..392560c05 100644 --- a/src/umpire/Allocator.cpp +++ b/src/umpire/Allocator.cpp @@ -49,6 +49,7 @@ Allocator::deallocate(void* ptr) UMPIRE_RECORD_STATISTIC(getName(), "ptr", reinterpret_cast(ptr), "size", 0x0, "event", "deallocate"); if (!ptr) { + UMPIRE_LOG(Info, "Deallocating a null pointer"); return; } else { m_allocator->deallocate(ptr); From 62d78b470c71ce8253c3882fdcbebac477a79099 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 11:51:49 -0700 Subject: [PATCH 036/110] Try and correct .travis.yml --- .travis.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52d78bcc5..29cd589ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,40 +7,40 @@ env: - DO_TEST=yes matrix: include: - - compiler: gcc-5 + - compiler: gcc5 env: - COMPILER=g++ - IMG=gcc-5 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - - compiler: gcc-6 + - compiler: gcc6 env: - COMPILER=g++ - IMG=gcc-6 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - - compiler: gcc-7 + - compiler: gcc7 env: - COMPILER=g++ - IMG=gcc-7 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - - compiler: gcc-8 + - compiler: gcc8 env: - COMPILER=g++ - IMG=gcc-8 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - - compiler: clang-4 + - compiler: clang4 env: - - COMPILER=clang++ - - IMG=clang-4 + - COMPILER=clang++ + - IMG=clang-4 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - - compiler: clang-5 + - compiler: clang5 env: - - COMPILER=clang++ - - IMG=clang-5 + - COMPILER=clang++ + - IMG=clang-5 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - - compiler: clang-6 + - compiler: clang6 env: - - COMPILER=clang++ - - IMG=clang-6 + - COMPILER=clang++ + - IMG=clang-6 - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" - compiler: nvcc env: From 953f07792f4e5dd19ef9eb9a6f232613543d84e2 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 12:07:42 -0700 Subject: [PATCH 037/110] Run ctest with -V flag in test script --- scripts/bamboo/build_and_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bamboo/build_and_test.sh b/scripts/bamboo/build_and_test.sh index 255fe26b1..854b78e57 100755 --- a/scripts/bamboo/build_and_test.sh +++ b/scripts/bamboo/build_and_test.sh @@ -48,7 +48,7 @@ trycmd "make VERBOSE=1 -j" # echo "Testing..." if [[ $HOSTNAME == *manta* ]]; then - bsub -x -n 1 -G guests -Ip ctest -T Test + bsub -x -n 1 -G guests -Ip ctest -V -T Test else - srun -ppdebug -t 5 -N 1 ctest -T Test + srun -ppdebug -t 5 -N 1 ctest -V -T Test fi From 5cd4ea87b15489d86f9a790c2e4f5c6b878a858c Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 12:09:11 -0700 Subject: [PATCH 038/110] Switch to using --output-on-failure --- scripts/bamboo/build_and_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bamboo/build_and_test.sh b/scripts/bamboo/build_and_test.sh index 854b78e57..b14b3934e 100755 --- a/scripts/bamboo/build_and_test.sh +++ b/scripts/bamboo/build_and_test.sh @@ -48,7 +48,7 @@ trycmd "make VERBOSE=1 -j" # echo "Testing..." if [[ $HOSTNAME == *manta* ]]; then - bsub -x -n 1 -G guests -Ip ctest -V -T Test + bsub -x -n 1 -G guests -Ip ctest --output-on-failure -T Test else - srun -ppdebug -t 5 -N 1 ctest -V -T Test + srun -ppdebug -t 5 -N 1 ctest --output-on-failure -T Test fi From b23a66038d7497394854fd98b68bf7abb6cbd318 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 12:27:08 -0700 Subject: [PATCH 039/110] Modify test because CUDA doesn't support 0-byte allocation --- tests/integration/allocator_integration_tests.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/integration/allocator_integration_tests.cpp b/tests/integration/allocator_integration_tests.cpp index eda2432f4..835747db7 100644 --- a/tests/integration/allocator_integration_tests.cpp +++ b/tests/integration/allocator_integration_tests.cpp @@ -64,12 +64,17 @@ TEST_P(AllocatorTest, AllocateDeallocateSmall) TEST_P(AllocatorTest, AllocateDeallocateNothing) { - double* data = static_cast( - m_allocator->allocate(m_nothing*sizeof(double))); + // CUDA doesn't support allocating 0 bytes + if (m_allocator.getPlatform() == umpire::Platform::cuda) { + SUCCEED(); + } else { + double* data = static_cast( + m_allocator->allocate(m_nothing*sizeof(double))); - ASSERT_NE(nullptr, data); + ASSERT_NE(nullptr, data); - m_allocator->deallocate(data); + m_allocator->deallocate(data); + } } TEST_P(AllocatorTest, DeallocateNullptr) From 479a84bfb47c2f7db10d4144b0d9e40603802a1f Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 12:33:52 -0700 Subject: [PATCH 040/110] m_allocator is a pointer, duh --- tests/integration/allocator_integration_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/allocator_integration_tests.cpp b/tests/integration/allocator_integration_tests.cpp index 835747db7..1d0f4f4d9 100644 --- a/tests/integration/allocator_integration_tests.cpp +++ b/tests/integration/allocator_integration_tests.cpp @@ -65,7 +65,7 @@ TEST_P(AllocatorTest, AllocateDeallocateSmall) TEST_P(AllocatorTest, AllocateDeallocateNothing) { // CUDA doesn't support allocating 0 bytes - if (m_allocator.getPlatform() == umpire::Platform::cuda) { + if (m_allocator->getPlatform() == umpire::Platform::cuda) { SUCCEED(); } else { double* data = static_cast( From c486e0d4edcaedc993d31517a38f1fe795882cdb Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 12:43:44 -0700 Subject: [PATCH 041/110] Add Travis badge to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index cc7361fb9..2618d11ab 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Umpire v0.2.3 +[![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) + Umpire is a resource management library that allows the discovery, provision, and management of memory on next-generation architectures. From 4fc8d28f157ad5ab20acad375587f4f3b1607542 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 8 Aug 2018 13:06:40 -0700 Subject: [PATCH 042/110] Remove assert test This test is no longer relevant now that deallocating a nullptr is supported --- tests/integration/CMakeLists.txt | 17 ----------------- tests/integration/assert_tests.cpp | 28 ---------------------------- 2 files changed, 45 deletions(-) delete mode 100644 tests/integration/assert_tests.cpp diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt index 8f3a3b77c..99617527e 100644 --- a/tests/integration/CMakeLists.txt +++ b/tests/integration/CMakeLists.txt @@ -75,23 +75,6 @@ blt_add_test( NAME operation_tests COMMAND operation_tests) -if (ENABLE_ASSERTS) - blt_add_executable( - NAME assert_tests - SOURCES assert_tests.cpp - DEPENDS_ON umpire gtest - OUTPUT_DIR ${UMPIRE_TEST_OUTPUT_DIR}) - - target_include_directories( - assert_tests - PRIVATE - ${PROJECT_BINARY_DIR}/include) - - blt_add_test( - NAME assert_tests - COMMAND assert_tests) -endif () - blt_add_executable( NAME free_functions_integration_tests SOURCES free_functions_integration_tests.cpp diff --git a/tests/integration/assert_tests.cpp b/tests/integration/assert_tests.cpp deleted file mode 100644 index 183970db1..000000000 --- a/tests/integration/assert_tests.cpp +++ /dev/null @@ -1,28 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2018, Lawrence Livermore National Security, LLC. -// Produced at the Lawrence Livermore National Laboratory -// -// Created by David Beckingsale, david@llnl.gov -// LLNL-CODE-747640 -// -// All rights reserved. -// -// This file is part of Umpire. -// -// For details, see https://github.com/LLNL/Umpire -// Please also see the LICENSE file for MIT license. -////////////////////////////////////////////////////////////////////////////// -#include "gtest/gtest.h" - -#include "umpire/ResourceManager.hpp" -#include "umpire/resource/MemoryResourceTypes.hpp" - -TEST(AllocatorAssert, DeallocateDeath) -{ -#if !defined(NDEBUG) - ASSERT_DEATH(umpire::ResourceManager::getInstance().getAllocator("HOST").deallocate( nullptr ), ""); -#else - SUCCEED(); -#endif -} - From c89419cfbb66b90fa521db71815f5e983303e9d4 Mon Sep 17 00:00:00 2001 From: znan Date: Wed, 8 Aug 2018 17:11:03 -0700 Subject: [PATCH 043/110] add tpl/judy install --- src/umpire/tpl/judy/CMakeLists.txt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/umpire/tpl/judy/CMakeLists.txt b/src/umpire/tpl/judy/CMakeLists.txt index 400e78660..ad506580d 100644 --- a/src/umpire/tpl/judy/CMakeLists.txt +++ b/src/umpire/tpl/judy/CMakeLists.txt @@ -12,10 +12,19 @@ # For details, see https://github.com/LLNL/Umpire # Please also see the LICENSE file for MIT license. ############################################################################## +set (judy_sources + judy.c) + +set (judy_headers + judy.h + judyLArray.h + judyL2Array.h) + + blt_add_library( NAME umpire_tpl_judy - SOURCES judy.c - HEADERS judy.h judyLArray.h judyL2Array.h + SOURCES ${judy_sources} + HEADERS ${judy_headers} HEADERS_OUTPUT_SUBDIR umpire/tpl/judy) install(TARGETS @@ -26,5 +35,5 @@ install(TARGETS ARCHIVE DESTINATION lib) install(FILES - judy.h judyLArray.h + ${judy_headers} DESTINATION include/umpire/tpl/judy) From 134292c2e7aa5d4cf358047a11cdbd1e6fbc252b Mon Sep 17 00:00:00 2001 From: znan Date: Wed, 8 Aug 2018 18:03:16 -0700 Subject: [PATCH 044/110] add offset --- src/umpire/resource/ConstantMemoryResource.cu | 9 +++++++++ src/umpire/resource/ConstantMemoryResource.hpp | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index bc50d7482..a0658bbcd 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -33,6 +33,7 @@ ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::str m_highwatermark(0l), m_platform(platform) { + offset = 0; } // template @@ -43,6 +44,14 @@ void* ConstantMemoryResource::allocate(size_t bytes) void* ptr = nullptr; cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); + ptr += offset; + offset += bytes; + + if (offset > 1024 * 64) + { + UMPIRE_LOG(Debug, "ask bytes more than max constant memory size (64KB), current size is " << offset - bytes << "bytes"); + } + ResourceManager::getInstance().registerAllocation(ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); m_current_size += bytes; diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp index 76f3811cb..c42092966 100644 --- a/src/umpire/resource/ConstantMemoryResource.hpp +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -53,6 +53,8 @@ class ConstantMemoryResource : long m_highwatermark; Platform m_platform; + private: + size_t offset; }; } // end of namespace resource From 30596cf1f2e17b5ecf4813707aae0e8c7d98ae89 Mon Sep 17 00:00:00 2001 From: znan Date: Wed, 8 Aug 2018 18:31:59 -0700 Subject: [PATCH 045/110] debug add char type --- src/umpire/resource/ConstantMemoryResource.cu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index a0658bbcd..76c4e460e 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -44,7 +44,7 @@ void* ConstantMemoryResource::allocate(size_t bytes) void* ptr = nullptr; cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); - ptr += offset; + (char*)ptr += offset; offset += bytes; if (offset > 1024 * 64) @@ -60,7 +60,7 @@ void* ConstantMemoryResource::allocate(size_t bytes) UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ptr); - return ptr; + return (void*)ptr; } // template From 054c0aad2a65f8e35029617816e82877bc50a6a7 Mon Sep 17 00:00:00 2001 From: znan Date: Wed, 8 Aug 2018 18:39:45 -0700 Subject: [PATCH 046/110] debug add char type --- src/umpire/resource/ConstantMemoryResource.cu | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index 76c4e460e..b6af6125d 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -44,7 +44,7 @@ void* ConstantMemoryResource::allocate(size_t bytes) void* ptr = nullptr; cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); - (char*)ptr += offset; + char* new_ptr = (char*)ptr + offset; offset += bytes; if (offset > 1024 * 64) @@ -52,7 +52,7 @@ void* ConstantMemoryResource::allocate(size_t bytes) UMPIRE_LOG(Debug, "ask bytes more than max constant memory size (64KB), current size is " << offset - bytes << "bytes"); } - ResourceManager::getInstance().registerAllocation(ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); + ResourceManager::getInstance().registerAllocation((void*)new_ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); m_current_size += bytes; if (m_current_size > m_highwatermark) @@ -60,7 +60,7 @@ void* ConstantMemoryResource::allocate(size_t bytes) UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ptr); - return (void*)ptr; + return (void*)new_ptr; } // template From 0b7ffbd31debb3912482f58f8546235640cafefb Mon Sep 17 00:00:00 2001 From: znan Date: Wed, 8 Aug 2018 22:12:20 -0700 Subject: [PATCH 047/110] test for new constmemresrouce --- src/umpire/resource/ConstantMemoryResource.cu | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index b6af6125d..ebe501756 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -21,6 +21,7 @@ #include #include +#include namespace umpire { namespace resource { @@ -34,6 +35,7 @@ ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::str m_platform(platform) { offset = 0; + std::cout << "new ConstantMemoryResource" << std::endl; } // template From ee11424dd12d4e99afaadb5a88a1a68d01852139 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 9 Aug 2018 10:13:34 -0700 Subject: [PATCH 048/110] Update tutorial and examples --- docs/sphinx/tutorial/allocators.rst | 2 ++ docs/sphinx/tutorial/dynamic_pool.rst | 2 ++ docs/sphinx/tutorial/introspection.rst | 5 +++ docs/sphinx/tutorial/operations.rst | 20 ++++++++++++ docs/sphinx/tutorial/resources.rst | 2 ++ docs/sphinx/tutorial/typed_allocators.rst | 32 ++++++++++++++++++ examples/CMakeLists.txt | 24 -------------- examples/tutorial/CMakeLists.txt | 10 ++++-- examples/tutorial/tut_allocator.cpp | 6 ++-- examples/tutorial/tut_copy.cpp | 4 +-- examples/tutorial/tut_dynamic_pool.cpp | 8 +++-- examples/tutorial/tut_move.cpp | 5 +-- examples/tutorial/tut_resources.cpp | 4 +-- examples/tutorial/tut_typed_allocators.cpp | 38 ++++++++++++++++++++++ 14 files changed, 122 insertions(+), 40 deletions(-) create mode 100644 docs/sphinx/tutorial/typed_allocators.rst create mode 100644 examples/tutorial/tut_typed_allocators.cpp diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst index e414b0bca..d3abfcf31 100644 --- a/docs/sphinx/tutorial/allocators.rst +++ b/docs/sphinx/tutorial/allocators.rst @@ -22,3 +22,5 @@ Once you have an ``Allocator`` you can use it to allocate and deallocate memory: In the next section, we will see how to allocate memory using different resources. + +.. literalinclude:: ../../../examples/tutorial/tut_allocator.cpp diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index 826c5d20f..bf3a1bbb6 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -37,3 +37,5 @@ to help mitigate the cost of allocating memory on these devices. There are lots of different strategies that you can use, and we will look at many of them in the rest of this tutorial. A complete list of strategies can be found here. + +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp diff --git a/docs/sphinx/tutorial/introspection.rst b/docs/sphinx/tutorial/introspection.rst index a85cf8700..3f8f06b8e 100644 --- a/docs/sphinx/tutorial/introspection.rst +++ b/docs/sphinx/tutorial/introspection.rst @@ -3,3 +3,8 @@ ============= Introspection ============= + +When writing code to run on computers with a complex memory hierarchy, one of +the most difficult things can be keeping track of where each pointer has been +allocated. Umpire's instrospection capability keeps track of this information, +as well as other useful bits and pieces you might want to know. diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst index 07a8dde24..2bbdc9045 100644 --- a/docs/sphinx/tutorial/operations.rst +++ b/docs/sphinx/tutorial/operations.rst @@ -23,6 +23,8 @@ selects the correct implementation to copy the data: This example allocates the destination data using any valid Allocator. +.. literalinclude:: ../../../examples/tutorial/tut_copy.cpp + ---- Move ---- @@ -32,3 +34,21 @@ provides a `move` operation. .. literalinclude:: ../../../examples/tutorial/tut_move.cpp :lines: 23-26 + +.. literalinclude:: ../../../examples/tutorial/tut_move.cpp + +------ +Memset +------ + + + +---------- +Reallocate +---------- + + + +------------- +Memory Advice +------------- diff --git a/docs/sphinx/tutorial/resources.rst b/docs/sphinx/tutorial/resources.rst index d2b46328f..f29a73b5d 100644 --- a/docs/sphinx/tutorial/resources.rst +++ b/docs/sphinx/tutorial/resources.rst @@ -41,3 +41,5 @@ As you can see, we can call this function with any valid resource name: In the next example, we will learn how to move data between resources using operations. + +.. literalinclude:: ../../../examples/tut_resources.cpp diff --git a/docs/sphinx/tutorial/typed_allocators.rst b/docs/sphinx/tutorial/typed_allocators.rst new file mode 100644 index 000000000..1ad1da6c5 --- /dev/null +++ b/docs/sphinx/tutorial/typed_allocators.rst @@ -0,0 +1,32 @@ +.. _typed_allocators: + +---------------- +Typed Allocators +---------------- + +Sometimes, you might want to construct an allocator that allocates objects of a +specific type. Umpire provides a ``TypedAllocator`` for this purpose. It can +also be used with STL objects like ``std::vector``. + +A ``TypedAllocator`` is constructed from any existing Allocator, and provides +the same interface as the normal ``Allocator``. However, when you call +allocate, this argument is the number of objects you want to allocate, no the +total number of bytes: + +.. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp + :lines: 25-29 + +To use this TypedAllocator with an STL object std::vector, you need to pass the +type as a template parameter for the vector, and also pass the allocatro to the +vector when you construct it: + +.. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp + :lines: 32-33 + +One thing to remember is that whatever ``Allocator`` you use with an STL +object, it must be compatible with the inner workings of that object. For +example, if you try and use a "DEVICE"-based ``Allocator`` it will fail, since +the vector will try and construct each element. The CPU cannot access DEVICE +memory in most systems, thus causing a segfault. Be careful! + +.. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f7baa868c..864cdc35b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -46,28 +46,4 @@ if (ENABLE_STATISTICS) DEPENDS_ON umpire) endif() -blt_add_executable( - NAME tut_allocator - SOURCES tut_allocator.cpp - DEPENDS_ON - umpire) - -blt_add_executable( - NAME tut_resources - SOURCES tut_resources.cpp - DEPENDS_ON - umpire) - -blt_add_executable( - NAME tut_dynamic_pool - SOURCES tut_dynamic_pool.cpp - DEPENDS_ON - umpire) - -blt_add_executable( - NAME tut_operations - SOURCES tut_operations.cpp - DEPENDS_ON - umpire) - add_subdirectory(tutorial) diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt index 3edfa7c1d..83d09c8ee 100644 --- a/examples/tutorial/CMakeLists.txt +++ b/examples/tutorial/CMakeLists.txt @@ -32,7 +32,13 @@ blt_add_executable( umpire) blt_add_executable( - NAME tut_operations - SOURCES tut_operations.cpp + NAME tut_copy + SOURCES tut_copy.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_move + SOURCES tut_move.cpp DEPENDS_ON umpire) diff --git a/examples/tutorial/tut_allocator.cpp b/examples/tutorial/tut_allocator.cpp index 07b9c5029..d4cdc1480 100644 --- a/examples/tutorial/tut_allocator.cpp +++ b/examples/tutorial/tut_allocator.cpp @@ -15,7 +15,7 @@ #include "umpire/Allocator.hpp" #include "umpire/ResourceManager.hpp" -int main(int argc, char* argv[]) { +int main(int, char**) { constexpr size_t SIZE = 1024; @@ -26,12 +26,12 @@ int main(int argc, char* argv[]) { double* data = static_cast( allocator.allocate(SIZE*sizeof(double))); - std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " << allocator.getName() << " allocator..."; allocator.deallocate(data); - std::cout << " dealocated." + std::cout << " deallocated." << std::endl; return 0; } diff --git a/examples/tutorial/tut_copy.cpp b/examples/tutorial/tut_copy.cpp index 901cb68be..9bd6567f3 100644 --- a/examples/tutorial/tut_copy.cpp +++ b/examples/tutorial/tut_copy.cpp @@ -31,7 +31,7 @@ void copy_data(double* source_data, size_t size, const std::string& destination) dest_allocator.deallocate(dest_data); } -int main(int argc, char* argv[]) { +int main(int, char**) { constexpr size_t SIZE = 1024; auto& rm = umpire::ResourceManager::getInstance(); @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) { double* data = static_cast( allocator.allocate(SIZE*sizeof(double))); - std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " << allocator.getName() << " allocator." << std::endl; std::cout << "Filling with 0.0..."; diff --git a/examples/tutorial/tut_dynamic_pool.cpp b/examples/tutorial/tut_dynamic_pool.cpp index 35470fe5e..1462b751b 100644 --- a/examples/tutorial/tut_dynamic_pool.cpp +++ b/examples/tutorial/tut_dynamic_pool.cpp @@ -15,6 +15,8 @@ #include "umpire/Allocator.hpp" #include "umpire/ResourceManager.hpp" +#include "umpire/strategy/DynamicPool.hpp" + void allocate_and_deallocate_pool(const std::string& resource) { constexpr size_t SIZE = 1024; @@ -30,15 +32,15 @@ void allocate_and_deallocate_pool(const std::string& resource) double* data = static_cast( pooled_allocator.allocate(SIZE*sizeof(double))); - std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " << pooled_allocator.getName() << " allocator..."; pooled_allocator.deallocate(data); - std::cout << " dealocated." + std::cout << " deallocated." << std::endl; } -int main(int argc, char* argv[]) { +int main(int, char**) { allocate_and_deallocate_pool("HOST"); #if defined(UMPIRE_ENABLE_CUDA) diff --git a/examples/tutorial/tut_move.cpp b/examples/tutorial/tut_move.cpp index c8cd68f67..c5e8c6792 100644 --- a/examples/tutorial/tut_move.cpp +++ b/examples/tutorial/tut_move.cpp @@ -20,9 +20,6 @@ double* move_data(double* source_data, const std::string& destination) auto& rm = umpire::ResourceManager::getInstance(); auto dest_allocator = rm.getAllocator(destination); - double* dest_data = static_cast( - dest_allocator.allocate(size*sizeof(double))); - std::cout << "Moved source data (" << source_data << ") to destination "; double* dest_data = static_cast( @@ -43,7 +40,7 @@ int main(int argc, char* argv[]) { double* data = static_cast( allocator.allocate(SIZE*sizeof(double))); - std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " << allocator.getName() << " allocator." << std::endl; std::cout << "Filling with 0.0..."; diff --git a/examples/tutorial/tut_resources.cpp b/examples/tutorial/tut_resources.cpp index d94faba7b..06ecbeba0 100644 --- a/examples/tutorial/tut_resources.cpp +++ b/examples/tutorial/tut_resources.cpp @@ -26,12 +26,12 @@ void allocate_and_deallocate(const std::string& resource) double* data = static_cast( allocator.allocate(SIZE*sizeof(double))); - std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the" + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " << allocator.getName() << " allocator..."; allocator.deallocate(data); - std::cout << " dealocated." + std::cout << " deallocated." << std::endl; } int main(int argc, char* argv[]) { diff --git a/examples/tutorial/tut_typed_allocators.cpp b/examples/tutorial/tut_typed_allocators.cpp new file mode 100644 index 000000000..6c1b81de8 --- /dev/null +++ b/examples/tutorial/tut_typed_allocators.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/ResourceManager.hpp" +#include "umpire/Allocator.hpp" + +#include "umpire/TypedAllocator.hpp" + +int main(int, char**) { + auto& rm = umpire::ResourceManager::getInstance(); + auto alloc = rm.getAllocator("HOST"); + + // Create a TypedAllocator for doubles + umpire::TypedAllocator double_alloc(alloc); + + double* my_doubles = double_alloc.allocate(1024); + + double_alloc.deallocate(my_doubles); + + + std::vector< double, umpire::TypedAllocator > + my_vector(double_allocator); + + my_vector.resize(100); + + return 0; +} From 90769973ab43996c797c2573f12f461ac750e32f Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 9 Aug 2018 10:24:26 -0700 Subject: [PATCH 049/110] Update feature documentation --- docs/sphinx/features/allocators.rst | 4 +++- docs/sphinx/features/operations.rst | 3 +++ docs/sphinx/features/strategies.rst | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/features/allocators.rst b/docs/sphinx/features/allocators.rst index dd0f42328..595631e1e 100644 --- a/docs/sphinx/features/allocators.rst +++ b/docs/sphinx/features/allocators.rst @@ -2,4 +2,6 @@ Allocators ========== -.. doxygenclass:: Allocator +.. doxygenclass:: umpire::Allocator + +.. doxygenclass:: umpire::TypedAllocator diff --git a/docs/sphinx/features/operations.rst b/docs/sphinx/features/operations.rst index c43005bff..702c588fe 100644 --- a/docs/sphinx/features/operations.rst +++ b/docs/sphinx/features/operations.rst @@ -4,5 +4,8 @@ Operations ========== +Operations provide an abstract interface to modifying and moving data between +Umpire Allocators. + .. doxygennamespace:: umpire::op diff --git a/docs/sphinx/features/strategies.rst b/docs/sphinx/features/strategies.rst index 38c948f81..28a287ead 100644 --- a/docs/sphinx/features/strategies.rst +++ b/docs/sphinx/features/strategies.rst @@ -4,4 +4,22 @@ Strategies ========== +Strategies are used in Umpire to allow custom algorithms to be applied when +allocating memory. These strategies can do anything, from providing different +pooling methods to speed up allocations to applying different operations to +every alloctaion. + +Strategies can be composed to combine their functionality, allowing flexible +and reusable implementations of different components. + .. doxygennamespace:: umpire::strategy + +.. doxygenclass:: umpire::AllocationAdvisor + +.. doxygenclass:: umpire::DynamicPool + +.. doxygenclass:: umpire::FixedPool + +.. doxygenclass:: umpire::MonotonicAllocationStrategy + +.. doxygenclass:: umpire::SlotPool From 7cd2da7c33fe4f9dcf750808454e5257ae479eb7 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 9 Aug 2018 11:51:01 -0700 Subject: [PATCH 050/110] Updating tutorial docs --- docs/sphinx/features/strategies.rst | 10 ++--- docs/sphinx/tutorial/allocators.rst | 4 +- docs/sphinx/tutorial/dynamic_pool.rst | 12 +++--- docs/sphinx/tutorial/operations.rst | 28 +++++++++++--- docs/sphinx/tutorial/resources.rst | 8 ++-- examples/tutorial/tut_memset.cpp | 55 +++++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 examples/tutorial/tut_memset.cpp diff --git a/docs/sphinx/features/strategies.rst b/docs/sphinx/features/strategies.rst index 28a287ead..402ca55b6 100644 --- a/docs/sphinx/features/strategies.rst +++ b/docs/sphinx/features/strategies.rst @@ -14,12 +14,12 @@ and reusable implementations of different components. .. doxygennamespace:: umpire::strategy -.. doxygenclass:: umpire::AllocationAdvisor +.. doxygenclass:: umpire::strategy::AllocationAdvisor -.. doxygenclass:: umpire::DynamicPool +.. doxygenclass:: umpire::strategy::DynamicPool -.. doxygenclass:: umpire::FixedPool +.. doxygenclass:: umpire::strategy::FixedPool -.. doxygenclass:: umpire::MonotonicAllocationStrategy +.. doxygenclass:: umpire::strategy::MonotonicAllocationStrategy -.. doxygenclass:: umpire::SlotPool +.. doxygenclass:: umpire::strategy::SlotPool diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst index d3abfcf31..4f93b79d6 100644 --- a/docs/sphinx/tutorial/allocators.rst +++ b/docs/sphinx/tutorial/allocators.rst @@ -9,8 +9,8 @@ The fundamental concept for accessing memory through Umpire is the and deallocate memory, as well as query a pointer to get some extra information about it. -All ``Allocator`` s are created and managed by Umpire's ``ResourceManager``. To -get an Allocator, you need to ask for one: +All ``Allocator`` s are created and managed by Umpire's +:class:`umpire::ResourceManager`. To get an Allocator, you need to ask for one: .. literalinclude:: ../../../examples/tutorial/tut_allocator.cpp :lines: 22-24 diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index bf3a1bbb6..4d6cde038 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -9,9 +9,10 @@ when you are making large allocations or allocating on different memory resources. To mitigate this, Umpire provides allocation strategies that can be used to customize how data is obtained from the system. -In this example, we will look at the ``DynamicPool`` strategy. This is a simple -pooling algorithm that can fulfill requests for allocations of any size. To -create a new ``Allocator`` using the ``DynamicPool`` strategy: +In this example, we will look at the :class:`umpire::strategy::DynamicPool` +strategy. This is a simple pooling algorithm that can fulfill requests for +allocations of any size. To create a new ``Allocator`` using the +:class:`umpire::strategy::DynamicPool` strategy: .. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp :lines: 26-28 @@ -31,8 +32,9 @@ Don't forget, these strategies can be created on top of any valid Allocator: .. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp :lines: 42-48 -Most Umpire users will make alloctations that use the GPU via the DynamicPool, -to help mitigate the cost of allocating memory on these devices. +Most Umpire users will make alloctations that use the GPU via the +:class:`umpire::strategy::DynamicPool`, to help mitigate the cost of allocating +memory on these devices. There are lots of different strategies that you can use, and we will look at many of them in the rest of this tutorial. A complete list of strategies can be diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst index 2bbdc9045..dc8df5268 100644 --- a/docs/sphinx/tutorial/operations.rst +++ b/docs/sphinx/tutorial/operations.rst @@ -7,7 +7,9 @@ Operations Moving and modifying data in a heterogenous memory system can be annoying. You have to keep track of the source and destination, and often use vendor-specific APIs to perform the modifications. In Umpire, all data modification and -movement is wrapped up in a concept we call `Operations`. +movement is wrapped up in a concept we call `operations`. Full documentation +for all of these is available here: :namespace:`umpire::op`. The full code +listing for each example is include at the bottom of the page. ---- Copy @@ -23,7 +25,6 @@ selects the correct implementation to copy the data: This example allocates the destination data using any valid Allocator. -.. literalinclude:: ../../../examples/tutorial/tut_copy.cpp ---- Move @@ -33,22 +34,39 @@ If you want to move data to a new Allocator and deallocate the old copy, Umpire provides a `move` operation. .. literalinclude:: ../../../examples/tutorial/tut_move.cpp - :lines: 23-26 + :lines: 25-26 -.. literalinclude:: ../../../examples/tutorial/tut_move.cpp +The move operation combines an allocation, a copy, and a deallocate into one +function call, allowing you to move data without having to have the destination +data allocated. As always, this operation will work with any valid destination +Allocator. ------ Memset ------ +Setting a whole block of memory to a value (like 0) is a common operation, that +most people know as a memset. Umpire provides a memset implementation that can +be applied to any allocation, regardless of where it came from: +.. literalinclude:: ../../../examples/tutorial/tut_memset.cpp + :lines: 22 ---------- Reallocate ---------- - ------------- Memory Advice ------------- + + + +-------- +Listings +-------- + +.. literalinclude:: ../../../examples/tutorial/tut_copy.cpp + +.. literalinclude:: ../../../examples/tutorial/tut_move.cpp diff --git a/docs/sphinx/tutorial/resources.rst b/docs/sphinx/tutorial/resources.rst index f29a73b5d..0fc4a61aa 100644 --- a/docs/sphinx/tutorial/resources.rst +++ b/docs/sphinx/tutorial/resources.rst @@ -24,22 +24,22 @@ GPU ("UM") and host memory that can be accessed by the GPU ("PINNED"); Umpire will create an ``Allocator`` for each of these resources, and you can get them using the same ``getAllocator`` call you saw in the previous example: -.. literalinclude:: ../../../examples/tut_resources.cpp +.. literalinclude:: ../../../examples/tutorial/tut_resources.cpp :lines: 22-24 Note that every ``Allocator`` supports the same calls, no matter which resource it is for, this means we can parametertize the ``getAllocator`` call, and run the same code for all the resources available in the system: -.. literalinclude:: ../../../examples/tut_resources.cpp +.. literalinclude:: ../../../examples/tutorial/tut_resources.cpp :lines: 18-35 As you can see, we can call this function with any valid resource name: -.. literalinclude:: ../../../examples/tut_resources.cpp +.. literalinclude:: ../../../examples/tutorial/tut_resources.cpp :lines: 38-44 In the next example, we will learn how to move data between resources using operations. -.. literalinclude:: ../../../examples/tut_resources.cpp +.. literalinclude:: ../../../examples/tutorial/tut_resources.cpp diff --git a/examples/tutorial/tut_memset.cpp b/examples/tutorial/tut_memset.cpp new file mode 100644 index 000000000..a8e16452e --- /dev/null +++ b/examples/tutorial/tut_memset.cpp @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +void set_to_zero(double* source_data) +{ + auto& rm = umpire::ResourceManager::getInstance(); + + rm.memset(dest_data, 0); + + std::cout << "Set data from " << destination << " (" << dest_data << ") to 0." << std::endl; +} + +int main(int, char**) { + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + const std::string destinations[] = { + "HOST" +#if defined(UMPIRE_ENABLE_CUDA) + , "DEVCIE" + , "UM" + , "PINNED" +#endif + }; + + for (auto& destination : destinations) { + auto allocator = rm.getAllocator(destination); + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " + << allocator.getName() << " allocator." << std::endl; + + set_to_zero(data); + + allocator.deallocate(data); + } + + return 0; +} From f1827317c61bc2c3b60fdda47ce0c71bd927c4f9 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 9 Aug 2018 11:52:49 -0700 Subject: [PATCH 051/110] Only require CMake 3.8.2 when not using CUDA --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0e9c55e5..06c26b0b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,6 @@ # For details, see https://github.com/LLNL/Umpire # Please also see the LICENSE file for MIT license. ############################################################################## -cmake_minimum_required(VERSION 3.9) cmake_policy(SET CMP0048 NEW) cmake_policy(SET CMP0057 NEW) @@ -34,6 +33,14 @@ option(ENABLE_ASSERTS "Build Umpire with assert() enabled" On) set(ENABLE_GTEST_DEATH_TESTS ${ENABLE_ASSERTS} CACHE Bool "") option(ENABLE_STATISTICS "Track statistics for allocations and operations" Off) +if (ENABLE_CUDA) + cmake_minimum_required(VERSION 3.9) +else () + cmake_minimum_required(VERSION 3.8.2) +endif () + +message(STATUS "Using CMake version ${CMAKE_VERSION}") + ################################ # BLT ################################ From dbecffe80c70b9363824959bab9624620c1ea4e2 Mon Sep 17 00:00:00 2001 From: znan Date: Thu, 9 Aug 2018 15:04:09 -0700 Subject: [PATCH 052/110] remove unnecessary header --- src/umpire/resource/ConstantMemoryResource.cu | 1 - 1 file changed, 1 deletion(-) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index ebe501756..1edda7af1 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -21,7 +21,6 @@ #include #include -#include namespace umpire { namespace resource { From 406157e8c259eeb269961f9c97d05e895de6b62d Mon Sep 17 00:00:00 2001 From: znan Date: Thu, 9 Aug 2018 15:05:21 -0700 Subject: [PATCH 053/110] remove unnecessary test output --- src/umpire/resource/ConstantMemoryResource.cu | 1 - 1 file changed, 1 deletion(-) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index 1edda7af1..b6af6125d 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -34,7 +34,6 @@ ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::str m_platform(platform) { offset = 0; - std::cout << "new ConstantMemoryResource" << std::endl; } // template From 17c1031c354387edc50cbcfe1b0d5e5bcb899fa6 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 10 Aug 2018 09:57:58 -0700 Subject: [PATCH 054/110] Starting to make introspection optional... --- src/umpire/ResourceManager.hpp | 5 +- src/umpire/ResourceManager.inl | 30 +++++++++++ src/umpire/strategy/AllocationTracker.cpp | 66 +++++++++++++++++++++++ src/umpire/strategy/AllocationTracker.hpp | 54 +++++++++++++++++++ src/umpire/strategy/CMakeLists.txt | 8 ++- src/umpire/strategy/mixins/Inspector.cpp | 61 +++++++++++++++++++++ src/umpire/strategy/mixins/Inspector.hpp | 48 +++++++++++++++++ 7 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 src/umpire/strategy/AllocationTracker.cpp create mode 100644 src/umpire/strategy/AllocationTracker.hpp create mode 100644 src/umpire/strategy/mixins/Inspector.cpp create mode 100644 src/umpire/strategy/mixins/Inspector.hpp diff --git a/src/umpire/ResourceManager.hpp b/src/umpire/ResourceManager.hpp index 715634a49..1a8227dbb 100644 --- a/src/umpire/ResourceManager.hpp +++ b/src/umpire/ResourceManager.hpp @@ -94,10 +94,9 @@ class ResourceManager { * */ template - Allocator makeAllocator( - const std::string& name, - Args&&... args); + Allocator makeAllocator(const std::string& name, Args&&... args); /*! * \brief Register an Allocator with the ResourceManager. diff --git a/src/umpire/ResourceManager.inl b/src/umpire/ResourceManager.inl index b460ad9eb..ea1c0bb80 100644 --- a/src/umpire/ResourceManager.inl +++ b/src/umpire/ResourceManager.inl @@ -50,6 +50,36 @@ Allocator ResourceManager::makeAllocator( return Allocator(allocator); } +// template +// Allocator ResourceManager::makeAllocator( +// const std::string& name, +// Args&&... args) +// { +// std::shared_ptr allocator; +// +// try { +// UMPIRE_LOCK; +// +// UMPIRE_LOG(Debug, "(name=\"" << name << "\")"); +// +// if (isAllocator(name)) { +// UMPIRE_ERROR("Allocator with name " << name << " is already registered."); +// } +// +// allocator = std::make_shared(name, getNextId(), std::forward(args)...); +// +// m_allocators_by_name[name] = allocator; +// m_allocators_by_id[allocator->getId()] = allocator; +// UMPIRE_UNLOCK; +// } catch (...) { +// UMPIRE_UNLOCK; +// throw; +// } +// +// return Allocator(allocator); +// } + } // end of namespace umpire #endif // UMPIRE_ResourceManager_INL diff --git a/src/umpire/strategy/AllocationTracker.cpp b/src/umpire/strategy/AllocationTracker.cpp new file mode 100644 index 000000000..3182ff2a9 --- /dev/null +++ b/src/umpire/strategy/AllocationTracker.cpp @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/strategy/AllocationTracker.hpp" + +namespace umpire { +namespace strategy { + +AllocationTracker::AllocationTracker( + const std::string& name, + int id, + Allocator allocator) : +AllocationStrategy(name, id), +mixins::Inspector(), +m_allocator(allocator.getAllocationStrategy()) +{ +} + +void* +AllocationTracker::allocate(size_t bytes) +{ + void* ptr = m_allocator->allocate(bytes); + + registerAllocation(ptr, bytes, this->shared_from_this()); + + return ptr; +} + +void +AllocationTracker::deallocate(void* ptr) +{ + deregisterAllocation(ptr); + m_allocator->deallocate(ptr); +} + +long +AllocationTracker::getCurrentSize() +{ + return m_current_size; +} + +long +AllocationTracker::getHighWatermark() +{ + return m_high_watermark; +} + +Platform +AllocationTracker::getPlatform() +{ + return m_allocator->getPlatform(); +} + +} // end of namespace umpire +} // end of namespace strategy diff --git a/src/umpire/strategy/AllocationTracker.hpp b/src/umpire/strategy/AllocationTracker.hpp new file mode 100644 index 000000000..ed5ba594c --- /dev/null +++ b/src/umpire/strategy/AllocationTracker.hpp @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#ifndef UMPIRE_AllocationTracker_HPP +#define UMPIRE_AllocationTracker_HPP + +#include + +#include "umpire/strategy/AllocationStrategy.hpp" +#include "umpire/Allocator.hpp" +#include "umpire/strategy/mixins/Inspector.hpp" + +namespace umpire { +namespace strategy { + +class AllocationTracker : + public AllocationStrategy, + private mixins::Inspector +{ + public: + AllocationTracker( + const std::string& name, + int id, + Allocator allocator); + + void* allocate(size_t bytes); + + void deallocate(void* ptr); + + long getCurrentSize(); + long getHighWatermark(); + + Platform getPlatform(); + + private: + std::shared_ptr m_allocator; + +}; + +} // end of namespace umpire +} // end of namespace strategy + +#endif // UMPIRE_AllocationTracker_HPP diff --git a/src/umpire/strategy/CMakeLists.txt b/src/umpire/strategy/CMakeLists.txt index 9e1996821..eecc9eaa8 100644 --- a/src/umpire/strategy/CMakeLists.txt +++ b/src/umpire/strategy/CMakeLists.txt @@ -15,20 +15,24 @@ set (umpire_strategy_headers AllocationAdvisor.hpp AllocationStrategy.hpp + AllocationTracker.hpp MonotonicAllocationStrategy.hpp SlotPool.hpp ThreadSafeAllocator.hpp DynamicPool.hpp FixedPool.hpp - FixedPool.inl) + FixedPool.inl + mixins/Inspector.hpp) set (umpire_stategy_sources AllocationAdvisor.cpp AllocationStrategy.cpp + AllocationTracker.cpp MonotonicAllocationStrategy.cpp SlotPool.cpp ThreadSafeAllocator.cpp - DynamicPool.cpp) + DynamicPool.cpp + mixins/Inspector.cpp) set (umpire_strategy_depends umpire diff --git a/src/umpire/strategy/mixins/Inspector.cpp b/src/umpire/strategy/mixins/Inspector.cpp new file mode 100644 index 000000000..1a20213b9 --- /dev/null +++ b/src/umpire/strategy/mixins/Inspector.cpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/strategy/mixins/Inspector.hpp" + +#include "umpire/ResourceManager.hpp" + +namespace umpire { +namespace strategy { +namespace mixins { + +Inspector::Inspector() : + m_current_size(0), + m_high_watermark(0) +{ +} + + +void +Inspector::registerAllocation( + void* ptr, + size_t size, + std::shared_ptr strategy) +{ + m_current_size += size; + + if (m_current_size > m_high_watermark) { + m_high_watermark = m_current_size; + } + + auto record = new umpire::util::AllocationRecord{ + ptr, + size, + strategy}; + + ResourceManager::getInstance().registerAllocation(ptr, record); +} + +void +Inspector::deregisterAllocation(void* ptr) +{ + auto record = ResourceManager::getInstance().deregisterAllocation(ptr); + + m_current_size -= record->m_size; + delete record; +} + +} // end of namespace mixins +} // end of namespace strategy +} // end of namespace umpire diff --git a/src/umpire/strategy/mixins/Inspector.hpp b/src/umpire/strategy/mixins/Inspector.hpp new file mode 100644 index 000000000..e317574d0 --- /dev/null +++ b/src/umpire/strategy/mixins/Inspector.hpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#ifndef UMPIRE_Inspector_HPP +#define UMPIRE_Inspector_HPP + +#include + +namespace umpire { +namespace strategy { + +class AllocationStrategy; + +namespace mixins { + +class Inspector +{ + public: + Inspector(); + + void registerAllocation( + void* ptr, + size_t size, + std::shared_ptr strategy); + + void deregisterAllocation(void* ptr); + + protected: + long m_current_size; + long m_high_watermark; +}; + +} // end of namespace mixins +} // end of namespace strategy +} // end of namespace umpire + +#endif // UMPIRE_Inspector_HPP From a3cdf0dc74fcc23b60b7a34fc8add4f453542282 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 10 Aug 2018 10:12:26 -0700 Subject: [PATCH 055/110] Make the MemoryResource use the Inspector mixin --- src/umpire/resource/DefaultMemoryResource.hpp | 9 ++++----- src/umpire/resource/DefaultMemoryResource.inl | 18 ++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/umpire/resource/DefaultMemoryResource.hpp b/src/umpire/resource/DefaultMemoryResource.hpp index 19309d730..3f123b07b 100644 --- a/src/umpire/resource/DefaultMemoryResource.hpp +++ b/src/umpire/resource/DefaultMemoryResource.hpp @@ -20,17 +20,19 @@ #include "umpire/util/AllocationRecord.hpp" #include "umpire/util/Platform.hpp" +#include "umpire/strategy/mixins/Inspector.hpp" + namespace umpire { namespace resource { - /*! * \brief Concrete MemoryResource object that uses the template _allocator to * allocate and deallocate memory. */ template class DefaultMemoryResource : - public MemoryResource + public MemoryResource, + private umpire::strategy::mixins::Inspector { public: DefaultMemoryResource(Platform platform, const std::string& name, int id); @@ -46,9 +48,6 @@ class DefaultMemoryResource : protected: _allocator m_allocator; - long m_current_size; - long m_highwatermark; - Platform m_platform; }; diff --git a/src/umpire/resource/DefaultMemoryResource.inl b/src/umpire/resource/DefaultMemoryResource.inl index de693b822..e5f561b76 100644 --- a/src/umpire/resource/DefaultMemoryResource.inl +++ b/src/umpire/resource/DefaultMemoryResource.inl @@ -16,6 +16,7 @@ #define UMPIRE_DefaultMemoryResource_INL #include "umpire/resource/DefaultMemoryResource.hpp" + #include "umpire/ResourceManager.hpp" #include "umpire/util/Macros.hpp" @@ -28,9 +29,8 @@ namespace resource { template DefaultMemoryResource<_allocator>::DefaultMemoryResource(Platform platform, const std::string& name, int id) : MemoryResource(name, id), + umpire::strategy::mixins::Inspector(), m_allocator(), - m_current_size(0l), - m_highwatermark(0l), m_platform(platform) { } @@ -39,14 +39,10 @@ template void* DefaultMemoryResource<_allocator>::allocate(size_t bytes) { void* ptr = m_allocator.allocate(bytes); - ResourceManager::getInstance().registerAllocation(ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); - m_current_size += bytes; - if (m_current_size > m_highwatermark) - m_highwatermark = m_current_size; + registerAllocation(ptr, bytes, this->shared_from_this()); UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ptr); - UMPIRE_RECORD_STATISTIC(getName(), "ptr", reinterpret_cast(ptr), "size", bytes, "event", "allocate"); return ptr; @@ -60,9 +56,7 @@ void DefaultMemoryResource<_allocator>::deallocate(void* ptr) UMPIRE_RECORD_STATISTIC(getName(), "ptr", reinterpret_cast(ptr), "size", 0x0, "event", "deallocate"); m_allocator.deallocate(ptr); - util::AllocationRecord* record = ResourceManager::getInstance().deregisterAllocation(ptr); - m_current_size -= record->m_size; - delete record; + deregisterAllocation(ptr); } template @@ -75,8 +69,8 @@ long DefaultMemoryResource<_allocator>::getCurrentSize() template long DefaultMemoryResource<_allocator>::getHighWatermark() { - UMPIRE_LOG(Debug, "() returning " << m_highwatermark); - return m_highwatermark; + UMPIRE_LOG(Debug, "() returning " << m_high_watermark); + return m_high_watermark; } template From bd62adefb6dce7b2d3f6bed540b7df8248aeaf7f Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 10 Aug 2018 10:26:08 -0700 Subject: [PATCH 056/110] Update to use AllocationTracker for introspection --- src/umpire/ResourceManager.hpp | 2 +- src/umpire/ResourceManager.inl | 26 +++++++++++++++--- src/umpire/strategy/AllocationAdvisor.cpp | 14 ++-------- src/umpire/strategy/AllocationAdvisor.hpp | 3 --- src/umpire/strategy/DynamicPool.cpp | 15 ++--------- src/umpire/strategy/FixedPool.inl | 3 --- .../strategy/MonotonicAllocationStrategy.cpp | 5 ---- src/umpire/strategy/ThreadSafeAllocator.cpp | 27 ++----------------- src/umpire/strategy/ThreadSafeAllocator.hpp | 3 --- 9 files changed, 30 insertions(+), 68 deletions(-) diff --git a/src/umpire/ResourceManager.hpp b/src/umpire/ResourceManager.hpp index 1a8227dbb..7f8b30ef1 100644 --- a/src/umpire/ResourceManager.hpp +++ b/src/umpire/ResourceManager.hpp @@ -94,7 +94,7 @@ class ResourceManager { * */ template Allocator makeAllocator(const std::string& name, Args&&... args); diff --git a/src/umpire/ResourceManager.inl b/src/umpire/ResourceManager.inl index ea1c0bb80..fc793018c 100644 --- a/src/umpire/ResourceManager.inl +++ b/src/umpire/ResourceManager.inl @@ -17,17 +17,22 @@ #include "umpire/ResourceManager.hpp" +#include + #include "umpire/util/Macros.hpp" +#include "umpire/strategy/AllocationTracker.hpp" namespace umpire { template Allocator ResourceManager::makeAllocator( const std::string& name, Args&&... args) { std::shared_ptr allocator; + try { UMPIRE_LOCK; @@ -37,10 +42,25 @@ Allocator ResourceManager::makeAllocator( UMPIRE_ERROR("Allocator with name " << name << " is already registered."); } - allocator = std::make_shared(name, getNextId(), std::forward(args)...); + if (!introspection) { + allocator = std::make_shared(name, getNextId(), std::forward(args)...); + + m_allocators_by_name[name] = allocator; + m_allocators_by_id[allocator->getId()] = allocator; + } else { + std::stringstream base_name; + base_name << name << "_base"; + + + auto base_allocator = std::make_shared(base_name.str(), getNextId(), std::forward(args)...); + + allocator = std::make_shared(name, getNextId(), Allocator(base_allocator)); + + m_allocators_by_name[name] = allocator; + m_allocators_by_id[allocator->getId()] = allocator; + + } - m_allocators_by_name[name] = allocator; - m_allocators_by_id[allocator->getId()] = allocator; UMPIRE_UNLOCK; } catch (...) { UMPIRE_UNLOCK; diff --git a/src/umpire/strategy/AllocationAdvisor.cpp b/src/umpire/strategy/AllocationAdvisor.cpp index df0663609..97f1bd7d1 100644 --- a/src/umpire/strategy/AllocationAdvisor.cpp +++ b/src/umpire/strategy/AllocationAdvisor.cpp @@ -42,8 +42,6 @@ AllocationAdvisor::AllocationAdvisor( const std::string& advice_operation, Allocator accessing_allocator) : AllocationStrategy(name, id), - m_current_size(0), - m_highwatermark(0), m_allocator(allocator.getAllocationStrategy()), m_device(0) { @@ -74,31 +72,23 @@ void* AllocationAdvisor::allocate(size_t bytes) m_device, bytes); - ResourceManager::getInstance().registerAllocation(ptr, alloc_record); - - m_current_size += bytes; - if (m_current_size > m_highwatermark) - m_highwatermark = m_current_size; - return ptr; } void AllocationAdvisor::deallocate(void* ptr) { m_allocator->deallocate(ptr); - m_current_size -= ResourceManager::getInstance().getSize(ptr); - ResourceManager::getInstance().deregisterAllocation(ptr); } long AllocationAdvisor::getCurrentSize() { - return m_current_size; + return 0; } long AllocationAdvisor::getHighWatermark() { - return m_highwatermark; + return 0; } Platform AllocationAdvisor::getPlatform() diff --git a/src/umpire/strategy/AllocationAdvisor.hpp b/src/umpire/strategy/AllocationAdvisor.hpp index c11b83ff9..c76a551b1 100644 --- a/src/umpire/strategy/AllocationAdvisor.hpp +++ b/src/umpire/strategy/AllocationAdvisor.hpp @@ -51,9 +51,6 @@ class AllocationAdvisor : private: std::shared_ptr m_advice_operation; - long m_current_size; - long m_highwatermark; - std::shared_ptr m_allocator; int m_device; diff --git a/src/umpire/strategy/DynamicPool.cpp b/src/umpire/strategy/DynamicPool.cpp index 961c13975..022195ec7 100644 --- a/src/umpire/strategy/DynamicPool.cpp +++ b/src/umpire/strategy/DynamicPool.cpp @@ -29,8 +29,6 @@ DynamicPool::DynamicPool( const std::size_t min_alloc_size) : AllocationStrategy(name, id), dpa(nullptr), - m_current_size(0), - m_highwatermark(0), m_allocator(allocator.getAllocationStrategy()) { dpa = new DynamicSizePool<>(m_allocator, min_initial_alloc_size, min_alloc_size); @@ -41,12 +39,6 @@ DynamicPool::allocate(size_t bytes) { UMPIRE_LOG(Debug, "(bytes=" << bytes << ")"); void* ptr = dpa->allocate(bytes); - ResourceManager::getInstance().registerAllocation(ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); - - m_current_size += bytes; - if (m_current_size > m_highwatermark) - m_highwatermark = m_current_size; - return ptr; } @@ -55,23 +47,20 @@ DynamicPool::deallocate(void* ptr) { UMPIRE_LOG(Debug, "(ptr=" << ptr << ")"); dpa->deallocate(ptr); - m_current_size -= ResourceManager::getInstance().getSize(ptr); - - ResourceManager::getInstance().deregisterAllocation(ptr); } long DynamicPool::getCurrentSize() { UMPIRE_LOG(Debug, "() returning " << m_current_size); - return m_current_size; + return 0; } long DynamicPool::getHighWatermark() { UMPIRE_LOG(Debug, "() returning " << m_highwatermark); - return m_highwatermark; + return 0; } long diff --git a/src/umpire/strategy/FixedPool.inl b/src/umpire/strategy/FixedPool.inl index 2a14dca0c..24153d779 100644 --- a/src/umpire/strategy/FixedPool.inl +++ b/src/umpire/strategy/FixedPool.inl @@ -107,8 +107,6 @@ FixedPool::allocate(size_t bytes) { m_num_blocks++; } - ResourceManager::getInstance().registerAllocation(ptr, new util::AllocationRecord{ptr, sizeof(T), this->shared_from_this()}); - return ptr; } @@ -134,7 +132,6 @@ FixedPool::deallocate(void* ptr) { curr->avail[indexI] ^= 1 << indexB; curr->numAvail++; m_num_blocks--; - ResourceManager::getInstance().deregisterAllocation(ptr); return; } diff --git a/src/umpire/strategy/MonotonicAllocationStrategy.cpp b/src/umpire/strategy/MonotonicAllocationStrategy.cpp index 8d318fbc7..175985a13 100644 --- a/src/umpire/strategy/MonotonicAllocationStrategy.cpp +++ b/src/umpire/strategy/MonotonicAllocationStrategy.cpp @@ -46,8 +46,6 @@ MonotonicAllocationStrategy::allocate(size_t bytes) UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ret); - ResourceManager::getInstance().registerAllocation(ret, new util::AllocationRecord{ret, bytes, this->shared_from_this()}); - return ret; } @@ -55,9 +53,6 @@ void MonotonicAllocationStrategy::deallocate(void* ptr) { UMPIRE_LOG(Info, "() doesn't do anything"); - // no op - - ResourceManager::getInstance().deregisterAllocation(ptr); } long diff --git a/src/umpire/strategy/ThreadSafeAllocator.cpp b/src/umpire/strategy/ThreadSafeAllocator.cpp index 02dabb4ce..a639b0a87 100644 --- a/src/umpire/strategy/ThreadSafeAllocator.cpp +++ b/src/umpire/strategy/ThreadSafeAllocator.cpp @@ -25,8 +25,6 @@ ThreadSafeAllocator::ThreadSafeAllocator( int id, Allocator allocator) : AllocationStrategy(name, id), - m_current_size(0), - m_highwatermark(0), m_allocator(allocator.getAllocationStrategy()), m_mutex(new std::mutex()) { @@ -42,20 +40,12 @@ ThreadSafeAllocator::allocate(size_t bytes) ret = m_allocator->allocate(bytes); - m_current_size += bytes; - if (m_current_size > m_highwatermark) - m_highwatermark = m_current_size; - - UMPIRE_UNLOCK; } catch (...) { UMPIRE_UNLOCK; throw; } - ResourceManager::getInstance().registerAllocation(ret, - new util::AllocationRecord{ret, bytes, this->shared_from_this()}); - return ret; } @@ -72,31 +62,18 @@ ThreadSafeAllocator::deallocate(void* ptr) UMPIRE_UNLOCK; throw; } - - util::AllocationRecord* record = ResourceManager::getInstance().deregisterAllocation(ptr); - m_current_size -= record->m_size; - - delete record; } long ThreadSafeAllocator::getCurrentSize() { - long size; - - size = m_current_size; - - return size; + return 0; } long ThreadSafeAllocator::getHighWatermark() { - long size; - - size = m_highwatermark; - - return size; + return 0; } diff --git a/src/umpire/strategy/ThreadSafeAllocator.hpp b/src/umpire/strategy/ThreadSafeAllocator.hpp index 6a6a3a896..64620ecad 100644 --- a/src/umpire/strategy/ThreadSafeAllocator.hpp +++ b/src/umpire/strategy/ThreadSafeAllocator.hpp @@ -41,9 +41,6 @@ class ThreadSafeAllocator : Platform getPlatform(); protected: - long m_current_size; - long m_highwatermark; - std::shared_ptr m_allocator; std::mutex* m_mutex; From 463f2ad209a7f1bb698484532bea6235583949a5 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 10 Aug 2018 15:31:45 -0700 Subject: [PATCH 057/110] Update tutorial --- docs/sphinx/features/operations.rst | 2 +- docs/sphinx/features/strategies.rst | 10 ++-- docs/sphinx/tutorial.rst | 1 + docs/sphinx/tutorial/operations.rst | 35 +++++++++---- examples/tutorial/tut_reallocate.cpp | 52 +++++++++++++++++++ src/umpire/strategy/AllocationStrategy.hpp | 58 ++++++++++++++++++++-- 6 files changed, 141 insertions(+), 17 deletions(-) diff --git a/docs/sphinx/features/operations.rst b/docs/sphinx/features/operations.rst index 702c588fe..fc32d7636 100644 --- a/docs/sphinx/features/operations.rst +++ b/docs/sphinx/features/operations.rst @@ -5,7 +5,7 @@ Operations ========== Operations provide an abstract interface to modifying and moving data between -Umpire Allocators. +Umpire :class:`umpire::Allocator`s. .. doxygennamespace:: umpire::op diff --git a/docs/sphinx/features/strategies.rst b/docs/sphinx/features/strategies.rst index 402ca55b6..d101a9310 100644 --- a/docs/sphinx/features/strategies.rst +++ b/docs/sphinx/features/strategies.rst @@ -7,12 +7,14 @@ Strategies Strategies are used in Umpire to allow custom algorithms to be applied when allocating memory. These strategies can do anything, from providing different pooling methods to speed up allocations to applying different operations to -every alloctaion. +every alloctaion. Strategies can be composed to combine their functionality, +allowing flexible and reusable implementations of different components. -Strategies can be composed to combine their functionality, allowing flexible -and reusable implementations of different components. +.. doxygenclass:: umpire::strategy::AllocationStrategy -.. doxygennamespace:: umpire::strategy +------------------- +Provided Strategies +------------------- .. doxygenclass:: umpire::strategy::AllocationAdvisor diff --git a/docs/sphinx/tutorial.rst b/docs/sphinx/tutorial.rst index 7ad62d590..3ae6dbeb3 100644 --- a/docs/sphinx/tutorial.rst +++ b/docs/sphinx/tutorial.rst @@ -30,3 +30,4 @@ around, and check where it is, as you will see in the following sections. tutorial/operations.rst tutorial/dynamic_pool.rst tutorial/introspection.rst + tutorial/typed_allocators.rst diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst index dc8df5268..d25d0b223 100644 --- a/docs/sphinx/tutorial/operations.rst +++ b/docs/sphinx/tutorial/operations.rst @@ -8,8 +8,8 @@ Moving and modifying data in a heterogenous memory system can be annoying. You have to keep track of the source and destination, and often use vendor-specific APIs to perform the modifications. In Umpire, all data modification and movement is wrapped up in a concept we call `operations`. Full documentation -for all of these is available here: :namespace:`umpire::op`. The full code -listing for each example is include at the bottom of the page. +for all of these is available `here <../features/operations.html>`_. The full +code listing for each example is include at the bottom of the page. ---- Copy @@ -31,7 +31,7 @@ Move ---- If you want to move data to a new Allocator and deallocate the old copy, Umpire -provides a `move` operation. +provides a :func:`umpire::ResourceManager::move` operation. .. literalinclude:: ../../../examples/tutorial/tut_move.cpp :lines: 25-26 @@ -46,8 +46,9 @@ Memset ------ Setting a whole block of memory to a value (like 0) is a common operation, that -most people know as a memset. Umpire provides a memset implementation that can -be applied to any allocation, regardless of where it came from: +most people know as a memset. Umpire provides a +:func:`umpire::ResourceManager::memset` implementation that can be applied to +any allocation, regardless of where it came from: .. literalinclude:: ../../../examples/tutorial/tut_memset.cpp :lines: 22 @@ -56,17 +57,33 @@ be applied to any allocation, regardless of where it came from: Reallocate ---------- +Reallocating CPU memory is easy, there is a function designed specifically to +do it: ``realloc``. When the original allocation was made in a different memory +however, you can be out of luck. Umpire provides a +:func:`umpire::ResourceManager::reallocate` operation: -------------- -Memory Advice -------------- - +.. literalinclude:: ../../../examples/tutorial/tut_reallocate.cpp + :lines: 44 +This method returns a pointer to the reallocated data. Like all operations, +this can be used regardless of the Allocator used for the source data. -------- Listings -------- +Copy Example Listing + .. literalinclude:: ../../../examples/tutorial/tut_copy.cpp +Move Example Listing + .. literalinclude:: ../../../examples/tutorial/tut_move.cpp + +Memset Example Listing + +.. literalinclude:: ../../../examples/tutorial/tut_memset.cpp + +Reallocate Example Listing + +.. literalinclude:: ../../../examples/tutorial/tut_reallocate.cpp diff --git a/examples/tutorial/tut_reallocate.cpp b/examples/tutorial/tut_reallocate.cpp index e69de29bb..0b340fb9e 100644 --- a/examples/tutorial/tut_reallocate.cpp +++ b/examples/tutorial/tut_reallocate.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +int main(int, char**) { + constexpr size_t SIZE = 1024; + constexpr size_t REALLOCATED_SIZE = 256; + + auto& rm = umpire::ResourceManager::getInstance(); + + const std::string destinations[] = { + "HOST" +#if defined(UMPIRE_ENABLE_CUDA) + , "DEVCIE" + , "UM" + , "PINNED" +#endif + }; + + for (auto& destination : destinations) { + auto allocator = rm.getAllocator(destination); + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " + << allocator.getName() << " allocator." << std::endl; + + std::cout << "Reallocating data (" << data << ") to size " + << REALLOCATED_SIZE << "..."; + + data = rm.reallocate(data, REALLOCATED_SIZE); + + std::cout << "done. Reallocated data (" << << ")" << std::endl; + + allocator.deallocate(data); + } + + return 0; +} diff --git a/src/umpire/strategy/AllocationStrategy.hpp b/src/umpire/strategy/AllocationStrategy.hpp index 58936ae0b..ccdcb60fc 100644 --- a/src/umpire/strategy/AllocationStrategy.hpp +++ b/src/umpire/strategy/AllocationStrategy.hpp @@ -25,13 +25,22 @@ namespace umpire { namespace strategy { /*! - * \brief Allocator provides a unified interface to all Umpire classes that can - * be used to allocate and free data. + * \brief AllocationStrategy provides a unified interface to all classes that + * can be used to allocate and free data. */ class AllocationStrategy : public std::enable_shared_from_this { public: + /*! + * \brief Construct a new AllocationStrategy object. + * + * All AllocationStrategy objects must will have a unique name and id. This + * uniqueness is enforced by the ResourceManager. + * + * \param name The name of this AllocationStrategy object. + * \param id The id of this AllocationStrategy object. + */ AllocationStrategy(const std::string& name, int id); /*! @@ -39,7 +48,7 @@ class AllocationStrategy : * * \param bytes Number of bytes to allocate. * - * \return Pointer to start of allocation. + * \return Pointer to start of allocated bytes. */ virtual void* allocate(size_t bytes) = 0; @@ -50,14 +59,57 @@ class AllocationStrategy : */ virtual void deallocate(void* ptr) = 0; + /*! + * \brief Get current (total) size of the allocated memory. + * + * This is the total size of all allocation currently 'live' that have been + * made by this AllocationStrategy object. + * + * \return Current total size of allocations. + */ virtual long getCurrentSize() = 0; + + /*! + * \brief Get the high watermark of the total allocated size. + * + * This is equivalent to the highest observed value of getCurrentSize. + * \return High watermark allocation size. + */ virtual long getHighWatermark() = 0; + + /*! + * \brief Get the current amount of memory allocated by this allocator. + * + * Note that this can be larger than getCurrentSize(), particularly if the + * AllocationStrategy implements some kind of pooling. + * + * \return The total size of all the memory this object has allocated. + */ virtual long getActualSize(); + /*! + * \brief Get the platform associated with this AllocationStrategy. + * + * The Platform distinguishes the appropriate place to execute operations + * on memory allocated by this AllocationStrategy. + * + * \return The platform associated with this AllocationStrategy. + */ virtual Platform getPlatform() = 0; + /*! + * \brief Get the name of this AllocationStrategy. + * + * \return The name of this AllocationStrategy. + */ std::string getName(); + + /*! + * \brief Get the id of this AllocationStrategy. + * + * \return The id of this AllocationStrategy. + */ int getId(); protected: From 4234f3a947a95d867a2d327eba1082c7e4290417 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 10 Aug 2018 16:02:40 -0700 Subject: [PATCH 058/110] Fix TypedAllocator tutorial and example --- docs/sphinx/tutorial/dynamic_pool.rst | 8 ++++---- docs/sphinx/tutorial/typed_allocators.rst | 16 ++++++++-------- ...ed_allocators.cpp => tut_typed_allocator.cpp} | 0 3 files changed, 12 insertions(+), 12 deletions(-) rename examples/tutorial/{tut_typed_allocators.cpp => tut_typed_allocator.cpp} (100%) diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index 4d6cde038..a89167172 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -15,7 +15,7 @@ allocations of any size. To create a new ``Allocator`` using the :class:`umpire::strategy::DynamicPool` strategy: .. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp - :lines: 26-28 + :lines: 26-30 We have to provide a new name for the Allocator, as well as the underlying Allocator we wish to use to grab memory. @@ -36,8 +36,8 @@ Most Umpire users will make alloctations that use the GPU via the :class:`umpire::strategy::DynamicPool`, to help mitigate the cost of allocating memory on these devices. -There are lots of different strategies that you can use, and we will look at -many of them in the rest of this tutorial. A complete list of strategies can be -found here. +There are lots of different strategies that you can use, we will look at some +of them in this tutorial. A complete list of strategies can be found `here +<../features/operations.html>`_. .. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp diff --git a/docs/sphinx/tutorial/typed_allocators.rst b/docs/sphinx/tutorial/typed_allocators.rst index 1ad1da6c5..f0dced646 100644 --- a/docs/sphinx/tutorial/typed_allocators.rst +++ b/docs/sphinx/tutorial/typed_allocators.rst @@ -5,19 +5,19 @@ Typed Allocators ---------------- Sometimes, you might want to construct an allocator that allocates objects of a -specific type. Umpire provides a ``TypedAllocator`` for this purpose. It can -also be used with STL objects like ``std::vector``. +specific type. Umpire provides a :class:`umpire::TypedAllocator` for this +purpose. It can also be used with STL objects like ``std::vector``. -A ``TypedAllocator`` is constructed from any existing Allocator, and provides -the same interface as the normal ``Allocator``. However, when you call -allocate, this argument is the number of objects you want to allocate, no the -total number of bytes: +A :class:`umpire::TypedAllocator` is constructed from any existing Allocator, +and provides the same interface as the normal ``Allocator``. However, when you +call allocate, this argument is the number of objects you want to allocate, no +the total number of bytes: .. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp :lines: 25-29 -To use this TypedAllocator with an STL object std::vector, you need to pass the -type as a template parameter for the vector, and also pass the allocatro to the +To use this allocator with an STL object like a vector, you need to pass the +type as a template parameter for the vector, and also pass the allocator to the vector when you construct it: .. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp diff --git a/examples/tutorial/tut_typed_allocators.cpp b/examples/tutorial/tut_typed_allocator.cpp similarity index 100% rename from examples/tutorial/tut_typed_allocators.cpp rename to examples/tutorial/tut_typed_allocator.cpp From 3209fce2ddd896f1e81e5c55600d5d11b1ca013f Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 10 Aug 2018 16:17:50 -0700 Subject: [PATCH 059/110] Add introspection tutorial --- docs/sphinx/tutorial.rst | 6 +-- docs/sphinx/tutorial/introspection.rst | 27 +++++++++++++ examples/tutorial/CMakeLists.txt | 24 +++++++++++ examples/tutorial/tut_introspection.cpp | 54 +++++++++++++++++++++++++ src/umpire/CMakeLists.txt | 1 - 5 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 examples/tutorial/tut_introspection.cpp diff --git a/docs/sphinx/tutorial.rst b/docs/sphinx/tutorial.rst index 3ae6dbeb3..4fee7971e 100644 --- a/docs/sphinx/tutorial.rst +++ b/docs/sphinx/tutorial.rst @@ -7,11 +7,11 @@ Umpire Tutorial This section is a tutorial introduction to Umpire. We start with the most basic memory allocation, and move through topics like allocating on different resources, using allocation strategies to change how memory is allocated, using -operations to move and modify data, and even how to write your own allocation -strategies! +operations to move and modify data, and how to use Umpire introspection +capability to find out information about Allocators and allocations. These examples are all built as part of Umpire, and you can find the files in -the ``exmamples`` directory at the root of the Umpire repository. Feel free to +the ``examples`` directory at the root of the Umpire repository. Feel free to play around and modify these examples to experiment with all of Umpire's functionality. diff --git a/docs/sphinx/tutorial/introspection.rst b/docs/sphinx/tutorial/introspection.rst index 3f8f06b8e..4110e21f5 100644 --- a/docs/sphinx/tutorial/introspection.rst +++ b/docs/sphinx/tutorial/introspection.rst @@ -8,3 +8,30 @@ When writing code to run on computers with a complex memory hierarchy, one of the most difficult things can be keeping track of where each pointer has been allocated. Umpire's instrospection capability keeps track of this information, as well as other useful bits and pieces you might want to know. + +The :class:`umpire::ResourceManager` can be used to find the allocator +associated with an address: + +.. literalinclude:: ../../../examples/tutorial/tut_introspection.cpp + :lines: 40 + +Once you have this, it's easy to query things like the name of the Allocator: + +.. literalinclude:: ../../../examples/tutorial/tut_introspection.cpp + :lines: 43 + +You can also find out the associated :class:`umpire::Platform`, which can help +you decide where to operate on this data: + +.. literalinclude:: ../../../examples/tutorial/tut_introspection.cpp + :lines: 45 + +You can also find out how big the allocation is, in case you forgot: + +.. literalinclude:: ../../../examples/tutorial/tut_introspection.cpp + :lines: 48 + +Remember that these functions will work on any allocation made using an +Allocator or :class:`umpire::TypedAllocator`. + +.. literalinclude:: ../../../examples/tutorial/tut_introspection.cpp diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt index 83d09c8ee..57a738519 100644 --- a/examples/tutorial/CMakeLists.txt +++ b/examples/tutorial/CMakeLists.txt @@ -42,3 +42,27 @@ blt_add_executable( SOURCES tut_move.cpp DEPENDS_ON umpire) + +blt_add_executable( + NAME tut_memset + SOURCES tut_memset.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_reallocate + SOURCES tut_reallocate.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_typed_allocator + SOURCES tut_realtyped_allocator.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_introspection + SOURCES tut_introspection.cpp + DEPENDS_ON + umpire) diff --git a/examples/tutorial/tut_introspection.cpp b/examples/tutorial/tut_introspection.cpp new file mode 100644 index 000000000..e2ce01bf1 --- /dev/null +++ b/examples/tutorial/tut_introspection.cpp @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +int main(int, char**) { + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + const std::string destinations[] = { + "HOST" +#if defined(UMPIRE_ENABLE_CUDA) + , "DEVCIE" + , "UM" + , "PINNED" +#endif + }; + + for (auto& destination : destinations) { + auto allocator = rm.getAllocator(destination); + double* data = static_cast( + allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " + << allocator.getName() << " allocator." << std::endl; + + auto found_allocator = rm.getAllocator(data); + + std::cout << "According to the ResourceManager, the Allocator used is " + << found_allocator.getName() + << ", which has the Platform " + << found_allocator.getPlatform() << std::endl; + + std::cout << "The size of the allocation is << " + << found_allocator.getSize(data) << std::endl; + + allocator.deallocate(data); + } + + return 0; +} diff --git a/src/umpire/CMakeLists.txt b/src/umpire/CMakeLists.txt index ef3ed1f91..6f52308ce 100644 --- a/src/umpire/CMakeLists.txt +++ b/src/umpire/CMakeLists.txt @@ -47,7 +47,6 @@ if (ENABLE_FORTRAN) Fortran_FORMAT FREE) endif () - blt_add_library( NAME umpire HEADERS ${umpire_headers} From 098a1cc1cfd4059c72e14f4efca75ab4337e00f8 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 16 Aug 2018 15:54:41 -0700 Subject: [PATCH 060/110] Fix warning for unused arg and test linkage --- src/umpire/strategy/MonotonicAllocationStrategy.cpp | 2 +- tests/unit/resource/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/umpire/strategy/MonotonicAllocationStrategy.cpp b/src/umpire/strategy/MonotonicAllocationStrategy.cpp index 175985a13..35cc6ab01 100644 --- a/src/umpire/strategy/MonotonicAllocationStrategy.cpp +++ b/src/umpire/strategy/MonotonicAllocationStrategy.cpp @@ -50,7 +50,7 @@ MonotonicAllocationStrategy::allocate(size_t bytes) } void -MonotonicAllocationStrategy::deallocate(void* ptr) +MonotonicAllocationStrategy::deallocate(void* UMPIRE_UNUSED_ARG(ptr)) { UMPIRE_LOG(Info, "() doesn't do anything"); } diff --git a/tests/unit/resource/CMakeLists.txt b/tests/unit/resource/CMakeLists.txt index 58e54930c..94661bea3 100644 --- a/tests/unit/resource/CMakeLists.txt +++ b/tests/unit/resource/CMakeLists.txt @@ -15,7 +15,7 @@ blt_add_executable( NAME resource_tests SOURCES resource_tests.cpp - DEPENDS_ON umpire_resource umpire_util umpire gtest gmock) + DEPENDS_ON umpire umpire_resource umpire_util umpire gtest gmock) blt_add_test( NAME resource_tests From de0eafad16f52b746816a3f978a80fb73816a6b4 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 16 Aug 2018 16:48:13 -0700 Subject: [PATCH 061/110] Add code of conduct --- CODE_OF_CONDUCT.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..cbb24651c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at umpire-dev@llnl.gov. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ From 55c293490f4c5d19c82215994afc8679a8f1dece Mon Sep 17 00:00:00 2001 From: Chong Peng Date: Sun, 19 Aug 2018 14:31:44 -0400 Subject: [PATCH 062/110] typo in strategy example --- examples/strategy_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/strategy_example.cpp b/examples/strategy_example.cpp index ef07cb285..a3d3817da 100644 --- a/examples/strategy_example.cpp +++ b/examples/strategy_example.cpp @@ -60,7 +60,7 @@ int main(int, char**) * Allocator getAllocator(const std::string& name); // name of allocator * */ - alloc = rm.getAllocator("POOL"); + alloc = rm.getAllocator("host_slot_pool"); void* test = alloc.allocate(100); alloc.deallocate(test); From f83491836d29ab8e0aa5b5a2fa8269fa77fcec2e Mon Sep 17 00:00:00 2001 From: Chong Peng Date: Sun, 19 Aug 2018 14:33:41 -0400 Subject: [PATCH 063/110] judyL2Array.atOrBefore function is not const, it modifies member _success, need to lock, this seems to fix issue #8 --- src/umpire/util/AllocationMap.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/umpire/util/AllocationMap.cpp b/src/umpire/util/AllocationMap.cpp index d9f241287..f3d394785 100644 --- a/src/umpire/util/AllocationMap.cpp +++ b/src/umpire/util/AllocationMap.cpp @@ -87,7 +87,18 @@ AllocationMap::remove(void* ptr) AllocationRecord* AllocationMap::findRecord(void* ptr) { - auto record = m_records.atOrBefore(reinterpret_cast(ptr)); + + AddressPair record; + + try { + UMPIRE_LOCK; + record = m_records.atOrBefore(reinterpret_cast(ptr)); + UMPIRE_UNLOCK; + } + catch (...){ + UMPIRE_UNLOCK; + throw; + } if (record.value) { void* parent_ptr = reinterpret_cast(record.key); From 36df95f63acf19040e0492d29b054fd420b1ea92 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 20 Aug 2018 09:12:37 -0700 Subject: [PATCH 064/110] Quick fixes to advanced_configuration --- docs/sphinx/advanced_configuration.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/advanced_configuration.rst b/docs/sphinx/advanced_configuration.rst index 5775b1800..47ea3f53f 100644 --- a/docs/sphinx/advanced_configuration.rst +++ b/docs/sphinx/advanced_configuration.rst @@ -40,14 +40,13 @@ These arguments are explained in more detail below: This option controls whether or not test executables will be built. * ``ENABLE_BENCHMARKS`` - This option will build the benchmark programs used to test ``ManagedArray`` - performance. + This option will build the benchmark programs used to test performance. * ``ENABLE_LOGGING`` This option enables usage of Logging services for Umpire * ``ENABLE_SLIC`` - This option enables usage of Logging services provided by SLIC. + This option enables usage of logging services provided by SLIC. * ``ENABLE_ASSERTS`` Enable assert() within Umpire From 17af4c86118a7cf7c1fcfbd85b91673d67727bc2 Mon Sep 17 00:00:00 2001 From: Chong Peng Date: Wed, 22 Aug 2018 09:32:00 -0400 Subject: [PATCH 065/110] needs to lock the entire findRecord function to prevent modification from oother thread at the same time --- src/umpire/util/AllocationMap.cpp | 36 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/umpire/util/AllocationMap.cpp b/src/umpire/util/AllocationMap.cpp index f3d394785..7c4f8f356 100644 --- a/src/umpire/util/AllocationMap.cpp +++ b/src/umpire/util/AllocationMap.cpp @@ -88,11 +88,25 @@ AllocationRecord* AllocationMap::findRecord(void* ptr) { - AddressPair record; + AllocationRecord* alloc_record; try { UMPIRE_LOCK; - record = m_records.atOrBefore(reinterpret_cast(ptr)); + auto record = m_records.atOrBefore(reinterpret_cast(ptr)); + if (record.value) { + void* parent_ptr = reinterpret_cast(record.key); + alloc_record = + reinterpret_cast(record.value->back()); + + if (alloc_record && + ((static_cast(parent_ptr) + alloc_record->m_size) + > static_cast(ptr))) { + + UMPIRE_LOG(Debug, "Found " << ptr << " at " << parent_ptr + << " with size " << alloc_record->m_size); + + } + } UMPIRE_UNLOCK; } catch (...){ @@ -100,23 +114,7 @@ AllocationMap::findRecord(void* ptr) throw; } - if (record.value) { - void* parent_ptr = reinterpret_cast(record.key); - auto alloc_record = - reinterpret_cast(record.value->back()); - - if (alloc_record && - ((static_cast(parent_ptr) + alloc_record->m_size) - > static_cast(ptr))) { - - UMPIRE_LOG(Debug, "Found " << ptr << " at " << parent_ptr - << " with size " << alloc_record->m_size); - - return alloc_record; - } - } - - return nullptr; + return alloc_record; } AllocationRecord* From 839d70a19eb2b2bc8d5b93407886432702d393cf Mon Sep 17 00:00:00 2001 From: Chong Peng Date: Wed, 22 Aug 2018 10:43:27 -0400 Subject: [PATCH 066/110] initialize pointer as nullptr --- src/umpire/util/AllocationMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umpire/util/AllocationMap.cpp b/src/umpire/util/AllocationMap.cpp index 7c4f8f356..2b9ce27f1 100644 --- a/src/umpire/util/AllocationMap.cpp +++ b/src/umpire/util/AllocationMap.cpp @@ -88,7 +88,7 @@ AllocationRecord* AllocationMap::findRecord(void* ptr) { - AllocationRecord* alloc_record; + Entry alloc_record = nullptr; try { UMPIRE_LOCK; From 1dfb5ca1dc2bd89ca37af7b02c7107d64d7e8222 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 22 Aug 2018 15:45:30 -0700 Subject: [PATCH 067/110] Add doxygen for TypedAllocator --- src/umpire/TypedAllocator.hpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/umpire/TypedAllocator.hpp b/src/umpire/TypedAllocator.hpp index 6df984f39..4692d3a0f 100644 --- a/src/umpire/TypedAllocator.hpp +++ b/src/umpire/TypedAllocator.hpp @@ -19,15 +19,42 @@ namespace umpire { +/*! + * \brief Allocator for objects of type T + * + * This class is an adaptor that allows using an Allocator to allocate objects + * of type T. You can use this class as an allocator for STL containers like + * std::vector. + */ template class TypedAllocator { public: typedef T value_type; + /*! + * + * \brief Construct a new TypedAllocator that will use allocator to allocate + * data + * + * \param allocator Allocator to use for allocating memory. + */ TypedAllocator(Allocator allocator); + /* + * \brief Allocate size objects of type T. + * + * \param size The number of objects to allocate. + * + * \return Pointer to the start of the allocated memory. + */ T* allocate(size_t size); + /*! + * \brief Deallocate ptr, the passed size is ignored. + * + * \param ptr Pointer to deallocate + * \param size Size of allocation (ignored). + */ void deallocate(T* ptr, size_t size); private: From d6716017f9a0a0dee5c8cdee083b0224457fd34e Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 22 Aug 2018 15:45:59 -0700 Subject: [PATCH 068/110] Fixes from PR review by Marty --- docs/sphinx/features/introspection.rst | 1 + docs/sphinx/tutorial.rst | 13 +++-- docs/sphinx/tutorial/dynamic_pool.rst | 26 +++++++-- examples/tutorial/CMakeLists.txt | 10 +++- ...ynamic_pool.cpp => tut_dynamic_pool_1.cpp} | 0 examples/tutorial/tut_dynamic_pool_2.cpp | 57 +++++++++++++++++++ 6 files changed, 95 insertions(+), 12 deletions(-) rename examples/tutorial/{tut_dynamic_pool.cpp => tut_dynamic_pool_1.cpp} (100%) create mode 100644 examples/tutorial/tut_dynamic_pool_2.cpp diff --git a/docs/sphinx/features/introspection.rst b/docs/sphinx/features/introspection.rst index a85cf8700..bfe817420 100644 --- a/docs/sphinx/features/introspection.rst +++ b/docs/sphinx/features/introspection.rst @@ -3,3 +3,4 @@ ============= Introspection ============= + diff --git a/docs/sphinx/tutorial.rst b/docs/sphinx/tutorial.rst index 4fee7971e..8a0e62ca0 100644 --- a/docs/sphinx/tutorial.rst +++ b/docs/sphinx/tutorial.rst @@ -11,16 +11,17 @@ operations to move and modify data, and how to use Umpire introspection capability to find out information about Allocators and allocations. These examples are all built as part of Umpire, and you can find the files in -the ``examples`` directory at the root of the Umpire repository. Feel free to -play around and modify these examples to experiment with all of Umpire's -functionality. +the `examples `_ +directory at the root of the Umpire repository. Feel free to play around and +modify these examples to experiment with all of Umpire's functionality. The following tutorial examples assume a working knowledge of C++ and a general understanding of how memory is laid out in modern heterogeneous computers. The main thing to remember is that in many systems, memory on other execution -devices (like GPUs) might not be accessible from the CPU. If you try and access -this memory your program will error! Luckily, Umpire makes it easy to move data -around, and check where it is, as you will see in the following sections. +devices (like GPUs) might not be directly accessible from the CPU. If you try +and access this memory your program will error! Luckily, Umpire makes it easy +to move data around, and check where it is, as you will see in the following +sections. .. toctree:: :maxdepth: 1 diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index a89167172..873212247 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -14,7 +14,7 @@ strategy. This is a simple pooling algorithm that can fulfill requests for allocations of any size. To create a new ``Allocator`` using the :class:`umpire::strategy::DynamicPool` strategy: -.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_1.cpp :lines: 26-30 We have to provide a new name for the Allocator, as well as the underlying @@ -24,20 +24,38 @@ Once you have an ``Allocator``, you can allocate and deallocate memory as before, without needing to worry about the underlying algorithm used for the allocations: -.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_1.cpp :lines: 30-36 Don't forget, these strategies can be created on top of any valid Allocator: -.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_1.cpp :lines: 42-48 Most Umpire users will make alloctations that use the GPU via the :class:`umpire::strategy::DynamicPool`, to help mitigate the cost of allocating memory on these devices. +You can tune the way that :class:`umpire::strategy::DynamicPool` allocates +memory using two parameters: the initial size, and the minimum size. The +initial size controls how large the first underly allocation made will be, +regardless of the requested size. The minimum size controls the minimum size of +any future underlying allocations. These two parameters can be passed when +constructing a pool: + +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_2.cpp + :lines: 31-35 + +Depending on where you are allocating data, you might want to use different +sizes. It's easy to construct multiple pools with different configurations: + +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_2.cpp + :lines: 49-54 + There are lots of different strategies that you can use, we will look at some of them in this tutorial. A complete list of strategies can be found `here <../features/operations.html>`_. -.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool.cpp +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_1.cpp + +.. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_2.cpp diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt index 57a738519..4a863dec9 100644 --- a/examples/tutorial/CMakeLists.txt +++ b/examples/tutorial/CMakeLists.txt @@ -26,8 +26,14 @@ blt_add_executable( umpire) blt_add_executable( - NAME tut_dynamic_pool - SOURCES tut_dynamic_pool.cpp + NAME tut_dynamic_pool_1 + SOURCES tut_dynamic_pool_1.cpp + DEPENDS_ON + umpire) + +blt_add_executable( + NAME tut_dynamic_pool_2 + SOURCES tut_dynamic_pool_2.cpp DEPENDS_ON umpire) diff --git a/examples/tutorial/tut_dynamic_pool.cpp b/examples/tutorial/tut_dynamic_pool_1.cpp similarity index 100% rename from examples/tutorial/tut_dynamic_pool.cpp rename to examples/tutorial/tut_dynamic_pool_1.cpp diff --git a/examples/tutorial/tut_dynamic_pool_2.cpp b/examples/tutorial/tut_dynamic_pool_2.cpp new file mode 100644 index 000000000..0f4002926 --- /dev/null +++ b/examples/tutorial/tut_dynamic_pool_2.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2018, Lawrence Livermore National Security, LLC. +// Produced at the Lawrence Livermore National Laboratory +// +// Created by David Beckingsale, david@llnl.gov +// LLNL-CODE-747640 +// +// All rights reserved. +// +// This file is part of Umpire. +// +// For details, see https://github.com/LLNL/Umpire +// Please also see the LICENSE file for MIT license. +////////////////////////////////////////////////////////////////////////////// +#include "umpire/Allocator.hpp" +#include "umpire/ResourceManager.hpp" + +#include "umpire/strategy/DynamicPool.hpp" + +void allocate_and_deallocate_pool( + const std::string& resource, + std::size_t initial_size, + std::size_t min_block_size) +{ + constexpr size_t SIZE = 1024; + + auto& rm = umpire::ResourceManager::getInstance(); + + auto allocator = rm.getAllocator(resource); + + auto pooled_allocator = + rm.makeAllocator(resource + "_pool", + allocator + initial_size, + min_block_size); + + double* data = static_cast( + pooled_allocator.allocate(SIZE*sizeof(double))); + + std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " + << pooled_allocator.getName() << " allocator..."; + + pooled_allocator.deallocate(data); + + std::cout << " deallocated." << std::endl; +} + +int main(int, char**) { + allocate_and_deallocate_pool("HOST", 65536, 512); +#if defined(UMPIRE_ENABLE_CUDA) + allocate_and_deallocate_pool("DEVICE", (1024*1024*1024), (1024*1024)); + allocate_and_deallocate_pool("UM", (1024*64), 1024); + allocate_and_deallocate_pool("PINNED", (1024*16), 1024); +#endif + + return 0; +} From 5bbc3ec5dd4c2e087de767eb65ffcfbb6ae78ffa Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 22 Aug 2018 15:56:53 -0700 Subject: [PATCH 069/110] Add doxygen to strategies --- src/umpire/strategy/AllocationAdvisor.hpp | 14 ++++++++++++++ src/umpire/strategy/DynamicPool.hpp | 23 ++++++++++++++++++++++- src/umpire/strategy/FixedPool.hpp | 7 +++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/umpire/strategy/AllocationAdvisor.hpp b/src/umpire/strategy/AllocationAdvisor.hpp index c11b83ff9..c1493d116 100644 --- a/src/umpire/strategy/AllocationAdvisor.hpp +++ b/src/umpire/strategy/AllocationAdvisor.hpp @@ -24,6 +24,20 @@ namespace umpire { namespace strategy { +/*! + * + * \brief Applies the given MemoryOperation to every allocation. + * + * This AllocationStrategy is designed to be used with the following + * operations: + * + * - op::CudaAdviseAccessedByOperation + * - op::CudaAdvisePreferredLocationOperation + * - op::CudaAdviseReadMostlyOperation + * + * Using this AllocationStrategy when combined with a pool like DynamicPool is + * a good way to mitigate the overhead of applying the memory advice. + */ class AllocationAdvisor : public AllocationStrategy { diff --git a/src/umpire/strategy/DynamicPool.hpp b/src/umpire/strategy/DynamicPool.hpp index 4034891d6..77b82e9d5 100644 --- a/src/umpire/strategy/DynamicPool.hpp +++ b/src/umpire/strategy/DynamicPool.hpp @@ -27,9 +27,30 @@ namespace umpire { namespace strategy { -class DynamicPool : public AllocationStrategy +/*! + * \brief Simple dynamic pool for allocations + * + * This AllocationStrategy uses Simpool to provide pooling for allocations of + * any size. The behavior of the pool can be controlled by two parameters: the + * initial allocation size, and the minimum allocation size. + * + * The initial size controls how large the first piece of memory allocated is, + * and the minimum size controls the lower bound on all future chunk + * allocations. + */ +class DynamicPool : + public AllocationStrategy { public: + /*! + * \brief Construct a new DynamicPool. + * + * \param name Name of this instance of the DynamicPool. + * \param id Id of this instance of the DynamicPool. + * \param min_initial_alloc_size The minimum size of the first allocation + * the pool will make. + * \param min_alloc_size The minimum size of all future allocations. + */ DynamicPool( const std::string& name, int id, diff --git a/src/umpire/strategy/FixedPool.hpp b/src/umpire/strategy/FixedPool.hpp index caa49a62e..f25bcdb4a 100644 --- a/src/umpire/strategy/FixedPool.hpp +++ b/src/umpire/strategy/FixedPool.hpp @@ -27,6 +27,13 @@ namespace umpire { namespace strategy { +/*! + * \brief Pool for fixed size allocations + * + * This AllocationStrategy provides an efficient pool for fixed size + * allocations of size T. Pools of NP objects of type T are constructed, and + * used to quickly allocate and deallocate objects. + */ template class FixedPool : public AllocationStrategy From 9f94b4e70f704aab3f50c4ff0ee5cf3009463ea9 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 23 Aug 2018 13:56:23 -0700 Subject: [PATCH 070/110] Error if over-allocating constant memory --- src/umpire/resource/ConstantMemoryResource.cu | 7 +++---- src/umpire/resource/ConstantMemoryResource.hpp | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index 31f596663..c9b4996d6 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -2,7 +2,6 @@ // Copyright (c) 2018, Lawrence Livermore National Security, LLC. // Produced at the Lawrence Livermore National Laboratory // -// Created by Zifan Nan, nan1@llnl.gov // LLNL-CODE-747640 // // All rights reserved. @@ -28,9 +27,9 @@ ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::str MemoryResource(name, id), m_current_size(0l), m_highwatermark(0l), - m_platform(platform) + m_platform(platform), + m_offset(0) { - offset = 0; } void* ConstantMemoryResource::allocate(size_t bytes) @@ -43,7 +42,7 @@ void* ConstantMemoryResource::allocate(size_t bytes) if (offset > 1024 * 64) { - UMPIRE_LOG(Debug, "ask bytes more than max constant memory size (64KB), current size is " << offset - bytes << "bytes"); + UMPIRE_ERROR("Max total size of constant allocations is 64KB, current size is " << offset - bytes << "bytes"); } ResourceManager::getInstance().registerAllocation((void*)new_ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp index e771615cf..97a75bce6 100644 --- a/src/umpire/resource/ConstantMemoryResource.hpp +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -2,7 +2,6 @@ // Copyright (c) 2018, Lawrence Livermore National Security, LLC. // Produced at the Lawrence Livermore National Laboratory // -// Created by Zifan Nan, nan1@llnl.gov // LLNL-CODE-747640 // // All rights reserved. @@ -42,13 +41,13 @@ class ConstantMemoryResource : Platform getPlatform(); - protected: + private: long m_current_size; long m_highwatermark; Platform m_platform; - private: - size_t offset; + + size_t m_offset; }; } // end of namespace resource From 5b634cd912ade5ac1fee0c59949e4ec8a5440ab6 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 23 Aug 2018 15:49:33 -0700 Subject: [PATCH 071/110] Fixup errors in constructor for ConstantMemoryResource --- examples/device_const_mem_real_case.cu | 2 +- src/umpire/resource/ConstantMemoryResource.cu | 12 ++++++------ src/umpire/resource/ConstantMemoryResource.hpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/device_const_mem_real_case.cu b/examples/device_const_mem_real_case.cu index 039ffd439..fa030ab25 100644 --- a/examples/device_const_mem_real_case.cu +++ b/examples/device_const_mem_real_case.cu @@ -146,4 +146,4 @@ int main(int, char**) dev_const_alloc.deallocate(d_d); return 0; -} \ No newline at end of file +} diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index c9b4996d6..50969e0f9 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -23,11 +23,11 @@ namespace umpire { namespace resource { -ConstantMemoryResource::ConstantMemoryResource(Platform platform, const std::string& name, int id) : +ConstantMemoryResource::ConstantMemoryResource(const std::string& name, int id) : MemoryResource(name, id), m_current_size(0l), m_highwatermark(0l), - m_platform(platform), + m_platform(Platform::cuda), m_offset(0) { } @@ -37,12 +37,12 @@ void* ConstantMemoryResource::allocate(size_t bytes) void* ptr = nullptr; cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); - char* new_ptr = (char*)ptr + offset; - offset += bytes; + char* new_ptr = (char*)ptr + m_offset; + m_offset += bytes; - if (offset > 1024 * 64) + if (m_offset > 1024 * 64) { - UMPIRE_ERROR("Max total size of constant allocations is 64KB, current size is " << offset - bytes << "bytes"); + UMPIRE_ERROR("Max total size of constant allocations is 64KB, current size is " << m_offset - bytes << "bytes"); } ResourceManager::getInstance().registerAllocation((void*)new_ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp index 97a75bce6..411625fab 100644 --- a/src/umpire/resource/ConstantMemoryResource.hpp +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -31,7 +31,7 @@ class ConstantMemoryResource : public MemoryResource { public: - ConstantMemoryResource(Platform platform, const std::string& name, int id); + ConstantMemoryResource(const std::string& name, int id); void* allocate(size_t bytes); void deallocate(void* ptr); From bd56bb7b8023eb3d52ac15054797b9e0d720b1dd Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 23 Aug 2018 16:12:55 -0700 Subject: [PATCH 072/110] Fixup deallocations and tests of ConstantMemroy --- src/umpire/ResourceManager.cpp | 5 ++-- src/umpire/resource/ConstantMemoryResource.cu | 26 +++++++++++++------ .../resource/ConstantMemoryResource.hpp | 1 + src/umpire/resource/MemoryResourceTypes.hpp | 2 +- .../allocator_integration_tests.cpp | 6 +++-- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index d2d989696..d8452b009 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -93,8 +93,7 @@ ResourceManager::initialize() m_memory_resources[resource::Device] = registry.makeMemoryResource("DEVICE", getNextId()); m_memory_resources[resource::UnifiedMemory] = registry.makeMemoryResource("UM", getNextId()); m_memory_resources[resource::PinnedMemory] = registry.makeMemoryResource("PINNED", getNextId()); - // constant memory - m_memory_resources[resource::Device_Const] = registry.makeMemoryResource("DEVICE_CONST", getNextId()); + m_memory_resources[resource::DeviceConst] = registry.makeMemoryResource("DEVICE_CONST", getNextId()); #endif /* @@ -127,7 +126,7 @@ ResourceManager::initialize() m_allocators_by_id[pinned_allocator->getId()] = pinned_allocator; // constant memory - auto device_const_allocator = m_memory_resources[resource::Device_Const]; + auto device_const_allocator = m_memory_resources[resource::DeviceConst]; m_allocators_by_name["DEVICE_CONST"] = device_const_allocator; m_allocators_by_id[device_const_allocator->getId()] = device_const_allocator; #endif diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index 50969e0f9..2e973f42a 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -28,32 +28,34 @@ ConstantMemoryResource::ConstantMemoryResource(const std::string& name, int id) m_current_size(0l), m_highwatermark(0l), m_platform(Platform::cuda), - m_offset(0) + m_offset(0), + m_ptr(nullptr) { + cudaError_t error = ::cudaGetSymbolAddress((void**)&m_ptr, umpire_internal_device_constant_memory); } void* ConstantMemoryResource::allocate(size_t bytes) { - void* ptr = nullptr; - cudaError_t error = ::cudaGetSymbolAddress((void**)&ptr, umpire_internal_device_constant_memory); - - char* new_ptr = (char*)ptr + m_offset; + char* ptr = static_cast(m_ptr) + m_offset; m_offset += bytes; + void* ret = static_cast(ptr); + if (m_offset > 1024 * 64) { UMPIRE_ERROR("Max total size of constant allocations is 64KB, current size is " << m_offset - bytes << "bytes"); } - ResourceManager::getInstance().registerAllocation((void*)new_ptr, new util::AllocationRecord{ptr, bytes, this->shared_from_this()}); + ResourceManager::getInstance().registerAllocation( + ret, new util::AllocationRecord{ret, bytes, this->shared_from_this()}); m_current_size += bytes; if (m_current_size > m_highwatermark) m_highwatermark = m_current_size; - UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ptr); + UMPIRE_LOG(Debug, "(bytes=" << bytes << ") returning " << ret); - return (void*)new_ptr; + return ret; } void ConstantMemoryResource::deallocate(void* ptr) @@ -62,6 +64,14 @@ void ConstantMemoryResource::deallocate(void* ptr) util::AllocationRecord* record = ResourceManager::getInstance().deregisterAllocation(ptr); m_current_size -= record->m_size; + + if ( (static_cast(m_ptr) + (m_offset - record->m_size)) + == static_cast(ptr)) { + m_offset -= record->m_size; + } else { + UMPIRE_ERROR("ConstantMemory deallocations must be in reverse order"); + } + delete record; } diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp index 411625fab..51d36940e 100644 --- a/src/umpire/resource/ConstantMemoryResource.hpp +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -48,6 +48,7 @@ class ConstantMemoryResource : Platform m_platform; size_t m_offset; + void* m_ptr; }; } // end of namespace resource diff --git a/src/umpire/resource/MemoryResourceTypes.hpp b/src/umpire/resource/MemoryResourceTypes.hpp index 1bd7b4534..aa3895f78 100644 --- a/src/umpire/resource/MemoryResourceTypes.hpp +++ b/src/umpire/resource/MemoryResourceTypes.hpp @@ -33,7 +33,7 @@ enum MemoryResourceType { Device, UnifiedMemory, PinnedMemory, - Device_Const + DeviceConst }; } // end of namespace resource diff --git a/tests/integration/allocator_integration_tests.cpp b/tests/integration/allocator_integration_tests.cpp index 1d0f4f4d9..a8a333353 100644 --- a/tests/integration/allocator_integration_tests.cpp +++ b/tests/integration/allocator_integration_tests.cpp @@ -37,7 +37,7 @@ class AllocatorTest : umpire::Allocator* m_allocator; - const size_t m_big = 16000; + const size_t m_big = 64; const size_t m_small = 8; const size_t m_nothing = 0; }; @@ -129,6 +129,7 @@ const std::string allocator_strings[] = { , "DEVICE" , "UM" , "PINNED" + , "DEVICE_CONST" #endif }; @@ -189,7 +190,7 @@ class AllocatorByResourceTest : umpire::Allocator* m_allocator; - const size_t m_big = 16000; + const size_t m_big = 64; const size_t m_small = 8; const size_t m_nothing = 0; }; @@ -210,6 +211,7 @@ const umpire::resource::MemoryResourceType resource_types[] = { , umpire::resource::Device , umpire::resource::UnifiedMemory , umpire::resource::PinnedMemory + , umpire::resource::DeviceConst #endif }; From 827efecd9f5701c46a63a18485029b1572ce9b35 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 23 Aug 2018 16:21:40 -0700 Subject: [PATCH 073/110] Remove long constant memory example --- examples/CMakeLists.txt | 6 - examples/device_const_mem_real_case.cu | 149 ------------------------- 2 files changed, 155 deletions(-) delete mode 100644 examples/device_const_mem_real_case.cu diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d0f699057..33b0a6007 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -39,12 +39,6 @@ blt_add_executable( DEPENDS_ON umpire) -blt_add_executable( - NAME device_const_test_case - SOURCES device_const_mem_real_case.cu - DEPENDS_ON - umpire) - if (ENABLE_STATISTICS) blt_add_executable( NAME statistics_example diff --git a/examples/device_const_mem_real_case.cu b/examples/device_const_mem_real_case.cu deleted file mode 100644 index fa030ab25..000000000 --- a/examples/device_const_mem_real_case.cu +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include -#include -#include - -#include "umpire/ResourceManager.hpp" -#include - -__global__ void add_constant_kernel(const double *a, double *d, double *c, int size) -{ - const int i = blockDim.x * blockIdx.x + threadIdx.x; - if (i < size) - { - c[i] = a[i] + d[i]; - } -} - -__global__ void add_kernel(const double *a, const double *b, double *c, int size) -{ - const int i = blockDim.x * blockIdx.x + threadIdx.x; - if (i < size) - c[i] = a[i] + b[i]; -} - -void check_error(void) -{ - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) - { - std::cerr << "Error: " << cudaGetErrorString(err) << std::endl; - exit(err); - } -} - -int main(int, char**) -{ - // auto& rm = umpire::ResourceManager::getInstance(); - - const int size = 1024 * 8; - - auto& rm = umpire::ResourceManager::getInstance(); - - std::cout << "Available allocators: "; - for (auto s : rm.getAvailableAllocators()){ - std::cout << s << " "; - } - std::cout << std::endl; - - // double *a = (double*)malloc(sizeof(double) * size); - // double *b = (double*)malloc(sizeof(double) * size); - // double *sum = (double*)malloc(sizeof(double) * size); - - auto host_alloc = rm.getAllocator("HOST"); - double *sum = static_cast(host_alloc.allocate(size*sizeof(double))); - double *a = static_cast(host_alloc.allocate(size*sizeof(double))); - double *b = static_cast(host_alloc.allocate(size*sizeof(double))); - std::cout << "Host memory allocation finished\n"; - - // double *d_a; - // double *d_b; - // double *d_sum; - - auto dev_alloc = rm.getAllocator("DEVICE"); - double *d_sum = static_cast(dev_alloc.allocate(size*sizeof(double))); - double *d_a = static_cast(dev_alloc.allocate(size*sizeof(double))); - double *d_b = static_cast(dev_alloc.allocate(size*sizeof(double))); - std::cout << "Device memory allocation finished\n"; - - - auto dev_const_alloc = rm.getAllocator("DEVICE_CONST"); - double *d_d = static_cast(dev_const_alloc.allocate(size*sizeof(double))); - std::cout << "Device constant memory allocation finished\n"; - - - - for (int i=0; i(i); - b[i] = a[i]; - sum[i] = 1; - } - - // cudaMemcpy(d_a, a, size*sizeof(double), cudaMemcpyHostToDevice); - rm.copy(d_a, a, size*sizeof(double)); - check_error(); - - // cudaMemcpy(d_b, b, size*sizeof(double), cudaMemcpyHostToDevice); - rm.copy(d_b, b, size*sizeof(double)); - check_error(); - - // cudaMemcpy(d_d, b, size*sizeof(double), cudaMemcpyHostToDevice); - rm.copy(d_d, b, size*sizeof(double)); - check_error(); - - std::cout << "Memory copy finished\n"; - -// ----------------add kernel------------------------- - add_kernel<<<256, 1024>>>(d_a, d_b, d_sum, size); - check_error(); - - // cudaMemcpy(sum, d_sum, size*sizeof(double), cudaMemcpyDeviceToHost); - rm.copy(sum, d_sum, size*sizeof(double)); - check_error(); - - int final_sum = 0; - for (int i=0; i>>(d_a, d_d, d_sum, size); - check_error(); - - // cudaMemcpy(sum, d_sum, size*sizeof(double), cudaMemcpyDeviceToHost); - rm.copy(sum, d_sum, size*sizeof(double)); - check_error(); - - int final_sum_const = 0; - for (int i=0; i Date: Mon, 27 Aug 2018 09:49:30 -0400 Subject: [PATCH 074/110] typo --- src/umpire/Allocator.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umpire/Allocator.hpp b/src/umpire/Allocator.hpp index 3ab04f0ec..fd1e4674a 100644 --- a/src/umpire/Allocator.hpp +++ b/src/umpire/Allocator.hpp @@ -51,7 +51,7 @@ class Allocator { * * The memory will be allocated as determined by the AllocationStrategy * used by this Allocator. Note that this method does not guarantee new - * memory pages being requested from thet underlying memory system, as the + * memory pages being requested from the underlying memory system, as the * associated AllocationStrategy could have already allocated sufficient * memory, or re-use existing allocations that were not returned to the * system. From e73e1be0f82a766873280a094c03ae955b73e469 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 08:30:05 -0700 Subject: [PATCH 075/110] Fixup compilation bugs --- docs/doxygen/Doxyfile | 11 ++++++----- docs/doxygen/Doxyfile.in | 11 ++++++----- examples/tutorial/CMakeLists.txt | 2 +- examples/tutorial/tut_dynamic_pool_2.cpp | 2 +- examples/tutorial/tut_introspection.cpp | 2 +- examples/tutorial/tut_memset.cpp | 15 ++++----------- examples/tutorial/tut_reallocate.cpp | 6 +++--- examples/tutorial/tut_typed_allocator.cpp | 8 +++----- src/umpire/Allocator.hpp | 7 ++----- 9 files changed, 27 insertions(+), 37 deletions(-) diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 1037ed648..eb7a23c55 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -1028,11 +1028,12 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = HAVE_SILO \ - HAVE_SUNDIALS \ - HAVE_HYPRE \ - HAVE_PETSC \ - HAVE_HDF5 +PREDEFINED = UMPIRE_ENABLE_CUDA \ + UMPIRE_ENABLE_SLIC \ + UMPIRE_ENABLE_LOGGING \ + UMPIRE_ENABLE_ASSERTS \ + UMPIRE_ENABLE_STATISTICS \ + DOXYGEN_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 22d1d80ab..af62e8d67 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -1027,11 +1027,12 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = HAVE_SILO \ - HAVE_SUNDIALS \ - HAVE_HYPRE \ - HAVE_PETSC \ - HAVE_HDF5 +PREDEFINED = UMPIRE_ENABLE_CUDA \ + UMPIRE_ENABLE_SLIC \ + UMPIRE_ENABLE_LOGGING \ + UMPIRE_ENABLE_ASSERTS \ + UMPIRE_ENABLE_STATISTICS \ + DOXYGEN_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt index 4a863dec9..0ccbf312b 100644 --- a/examples/tutorial/CMakeLists.txt +++ b/examples/tutorial/CMakeLists.txt @@ -63,7 +63,7 @@ blt_add_executable( blt_add_executable( NAME tut_typed_allocator - SOURCES tut_realtyped_allocator.cpp + SOURCES tut_typed_allocator.cpp DEPENDS_ON umpire) diff --git a/examples/tutorial/tut_dynamic_pool_2.cpp b/examples/tutorial/tut_dynamic_pool_2.cpp index 0f4002926..26a5f3454 100644 --- a/examples/tutorial/tut_dynamic_pool_2.cpp +++ b/examples/tutorial/tut_dynamic_pool_2.cpp @@ -30,7 +30,7 @@ void allocate_and_deallocate_pool( auto pooled_allocator = rm.makeAllocator(resource + "_pool", - allocator + allocator, initial_size, min_block_size); diff --git a/examples/tutorial/tut_introspection.cpp b/examples/tutorial/tut_introspection.cpp index e2ce01bf1..87d934be6 100644 --- a/examples/tutorial/tut_introspection.cpp +++ b/examples/tutorial/tut_introspection.cpp @@ -42,7 +42,7 @@ int main(int, char**) { std::cout << "According to the ResourceManager, the Allocator used is " << found_allocator.getName() << ", which has the Platform " - << found_allocator.getPlatform() << std::endl; + << static_cast(found_allocator.getPlatform()) << std::endl; std::cout << "The size of the allocation is << " << found_allocator.getSize(data) << std::endl; diff --git a/examples/tutorial/tut_memset.cpp b/examples/tutorial/tut_memset.cpp index a8e16452e..ba084e8d8 100644 --- a/examples/tutorial/tut_memset.cpp +++ b/examples/tutorial/tut_memset.cpp @@ -15,15 +15,6 @@ #include "umpire/Allocator.hpp" #include "umpire/ResourceManager.hpp" -void set_to_zero(double* source_data) -{ - auto& rm = umpire::ResourceManager::getInstance(); - - rm.memset(dest_data, 0); - - std::cout << "Set data from " << destination << " (" << dest_data << ") to 0." << std::endl; -} - int main(int, char**) { constexpr size_t SIZE = 1024; @@ -32,7 +23,7 @@ int main(int, char**) { const std::string destinations[] = { "HOST" #if defined(UMPIRE_ENABLE_CUDA) - , "DEVCIE" + , "DEVICE" , "UM" , "PINNED" #endif @@ -46,7 +37,9 @@ int main(int, char**) { std::cout << "Allocated " << (SIZE*sizeof(double)) << " bytes using the " << allocator.getName() << " allocator." << std::endl; - set_to_zero(data); + rm.memset(data, 0); + + std::cout << "Set data from " << destination << " (" << data << ") to 0." << std::endl; allocator.deallocate(data); } diff --git a/examples/tutorial/tut_reallocate.cpp b/examples/tutorial/tut_reallocate.cpp index 0b340fb9e..fe063cf6e 100644 --- a/examples/tutorial/tut_reallocate.cpp +++ b/examples/tutorial/tut_reallocate.cpp @@ -24,7 +24,7 @@ int main(int, char**) { const std::string destinations[] = { "HOST" #if defined(UMPIRE_ENABLE_CUDA) - , "DEVCIE" + , "DEVICE" , "UM" , "PINNED" #endif @@ -41,9 +41,9 @@ int main(int, char**) { std::cout << "Reallocating data (" << data << ") to size " << REALLOCATED_SIZE << "..."; - data = rm.reallocate(data, REALLOCATED_SIZE); + data = static_cast(rm.reallocate(data, REALLOCATED_SIZE)); - std::cout << "done. Reallocated data (" << << ")" << std::endl; + std::cout << "done. Reallocated data (" << data << ")" << std::endl; allocator.deallocate(data); } diff --git a/examples/tutorial/tut_typed_allocator.cpp b/examples/tutorial/tut_typed_allocator.cpp index 6c1b81de8..1a9dc6284 100644 --- a/examples/tutorial/tut_typed_allocator.cpp +++ b/examples/tutorial/tut_typed_allocator.cpp @@ -21,13 +21,11 @@ int main(int, char**) { auto& rm = umpire::ResourceManager::getInstance(); auto alloc = rm.getAllocator("HOST"); - // Create a TypedAllocator for doubles - umpire::TypedAllocator double_alloc(alloc); + umpire::TypedAllocator double_allocator(alloc); - double* my_doubles = double_alloc.allocate(1024); - - double_alloc.deallocate(my_doubles); + double* my_doubles = double_allocator.allocate(1024); + double_allocator.deallocate(my_doubles, 1024); std::vector< double, umpire::TypedAllocator > my_vector(double_allocator); diff --git a/src/umpire/Allocator.hpp b/src/umpire/Allocator.hpp index fd1e4674a..3f074e2cc 100644 --- a/src/umpire/Allocator.hpp +++ b/src/umpire/Allocator.hpp @@ -29,17 +29,14 @@ namespace umpire { class ResourceManager; /*! - * \brief Allocator provides a unified interface to all Umpire classes that can - * be used to allocate and free data. + * \brief Provides a unified interface to allocate and free data. * * An Allocator encapsulates all the details of how and where allocations will * be made, and can also be used to introspect the memory resource. Allocator * objects do not return typed allocations, so the pointer returned from the * allocate method must be cast to the relevant type. * - * \code - * - * float* my_floats = static_cast(allocator.allocate(100*sizeof(float)); + * \see TypedAllocator */ class Allocator { friend class ResourceManager; From 28dde20be8ccfb7dfb4db230037f9b85b3277e3a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 08:42:45 -0700 Subject: [PATCH 076/110] Update links to point at Doxygen documentation --- docs/sphinx/features.rst | 1 - docs/sphinx/features/allocators.rst | 3 +++ docs/sphinx/features/introspection.rst | 6 ----- docs/sphinx/features/operations.rst | 5 +++- docs/sphinx/tutorial/allocators.rst | 10 +++---- docs/sphinx/tutorial/dynamic_pool.rst | 4 +-- docs/sphinx/tutorial/operations.rst | 2 +- docs/sphinx/tutorial/resources.rst | 33 ++++++++++++----------- docs/sphinx/tutorial/typed_allocators.rst | 16 +++++------ 9 files changed, 41 insertions(+), 39 deletions(-) delete mode 100644 docs/sphinx/features/introspection.rst diff --git a/docs/sphinx/features.rst b/docs/sphinx/features.rst index 8b7d8e16d..cb40b933c 100644 --- a/docs/sphinx/features.rst +++ b/docs/sphinx/features.rst @@ -10,4 +10,3 @@ Features features/allocators features/strategies features/operations - features/introspection diff --git a/docs/sphinx/features/allocators.rst b/docs/sphinx/features/allocators.rst index 595631e1e..66c3d5754 100644 --- a/docs/sphinx/features/allocators.rst +++ b/docs/sphinx/features/allocators.rst @@ -2,6 +2,9 @@ Allocators ========== +Allocators are the fundamental object used to allocate and deallocate memory +using Umpire. + .. doxygenclass:: umpire::Allocator .. doxygenclass:: umpire::TypedAllocator diff --git a/docs/sphinx/features/introspection.rst b/docs/sphinx/features/introspection.rst deleted file mode 100644 index bfe817420..000000000 --- a/docs/sphinx/features/introspection.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. _introspection: - -============= -Introspection -============= - diff --git a/docs/sphinx/features/operations.rst b/docs/sphinx/features/operations.rst index fc32d7636..7de4fff45 100644 --- a/docs/sphinx/features/operations.rst +++ b/docs/sphinx/features/operations.rst @@ -7,5 +7,8 @@ Operations Operations provide an abstract interface to modifying and moving data between Umpire :class:`umpire::Allocator`s. -.. doxygennamespace:: umpire::op +------------------- +Provided Operations +------------------- +.. doxygennamespace:: umpire::op diff --git a/docs/sphinx/tutorial/allocators.rst b/docs/sphinx/tutorial/allocators.rst index 4f93b79d6..f8968509a 100644 --- a/docs/sphinx/tutorial/allocators.rst +++ b/docs/sphinx/tutorial/allocators.rst @@ -5,17 +5,17 @@ Allocators ========== The fundamental concept for accessing memory through Umpire is the -``Allocator``. An ``Allocator`` is a C++ object that can be used to allocate -and deallocate memory, as well as query a pointer to get some extra information -about it. +:class:`umpire::Allocator`. An :class:`umpire::Allocator` is a C++ object that +can be used to allocate and deallocate memory, as well as query a pointer to +get some extra information about it. -All ``Allocator`` s are created and managed by Umpire's +All :class:`umpire::Allocator` s are created and managed by Umpire's :class:`umpire::ResourceManager`. To get an Allocator, you need to ask for one: .. literalinclude:: ../../../examples/tutorial/tut_allocator.cpp :lines: 22-24 -Once you have an ``Allocator`` you can use it to allocate and deallocate memory: +Once you have an :class:`umpire::Allocator` you can use it to allocate and deallocate memory: .. literalinclude:: ../../../examples/tutorial/tut_allocator.cpp :lines: 26-32 diff --git a/docs/sphinx/tutorial/dynamic_pool.rst b/docs/sphinx/tutorial/dynamic_pool.rst index 873212247..18551d5e7 100644 --- a/docs/sphinx/tutorial/dynamic_pool.rst +++ b/docs/sphinx/tutorial/dynamic_pool.rst @@ -25,12 +25,12 @@ before, without needing to worry about the underlying algorithm used for the allocations: .. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_1.cpp - :lines: 30-36 + :lines: 32-38 Don't forget, these strategies can be created on top of any valid Allocator: .. literalinclude:: ../../../examples/tutorial/tut_dynamic_pool_1.cpp - :lines: 42-48 + :lines: 46-50 Most Umpire users will make alloctations that use the GPU via the :class:`umpire::strategy::DynamicPool`, to help mitigate the cost of allocating diff --git a/docs/sphinx/tutorial/operations.rst b/docs/sphinx/tutorial/operations.rst index d25d0b223..951ad28f9 100644 --- a/docs/sphinx/tutorial/operations.rst +++ b/docs/sphinx/tutorial/operations.rst @@ -51,7 +51,7 @@ most people know as a memset. Umpire provides a any allocation, regardless of where it came from: .. literalinclude:: ../../../examples/tutorial/tut_memset.cpp - :lines: 22 + :lines: 40 ---------- Reallocate diff --git a/docs/sphinx/tutorial/resources.rst b/docs/sphinx/tutorial/resources.rst index 0fc4a61aa..78881bfac 100644 --- a/docs/sphinx/tutorial/resources.rst +++ b/docs/sphinx/tutorial/resources.rst @@ -5,31 +5,34 @@ Resources ========= Each computer system will have a number of distinct places in which the system -will allow you to allocate memory. In Umpire's world, these are -``MemoryResources``. A memory resource can correspond to a hardware resource, -but can also be used to identify memory with a particular characteristic, like -"pinned" memory in a GPU system. - -When you configure Umpire, it will create ``MemoryResource`` s according to -what is available on the system you are building for. For each resource, Umpire -will create a default ``Allocator`` that you can use. In the previous example, -we were actually using an ``Allocator`` created for the ``MemoryResource`` -corresponding to the CPU memory +will allow you to allocate memory. In Umpire's world, these are `memory +resources`. A memory resource can correspond to a hardware resource, but can +also be used to identify memory with a particular characteristic, like "pinned" +memory in a GPU system. + +When you configure Umpire, it will create +:class:`umpire::resource::MemoryResource` s according to what is available on +the system you are building for. For each resource, Umpire will create a +default :class:`umpire::Allocator` that you can use. In the previous example, +we were actually using an :class:`umpire::Allocator` created for the memory +resource corresponding to the CPU memory The easiest way to identify resources is by name. The "HOST" resource is always available. In a modern NVIDIA GPU system, we also have resources that represent global GPU memory ("DEVICE"), unified memory that can be accessed by the CPU or GPU ("UM") and host memory that can be accessed by the GPU ("PINNED"); -Umpire will create an ``Allocator`` for each of these resources, and you can -get them using the same ``getAllocator`` call you saw in the previous example: +Umpire will create an :class:`umpire::Allocator` for each of these resources, +and you can get them using the same +:func:`umpire::ResourceManager::getAllocator` call you saw in the previous +example: .. literalinclude:: ../../../examples/tutorial/tut_resources.cpp :lines: 22-24 -Note that every ``Allocator`` supports the same calls, no matter which resource -it is for, this means we can parametertize the ``getAllocator`` call, and run -the same code for all the resources available in the system: +Note that every allocator supports the same calls, no matter which resource it +is for, this means we can run the same code for all the resources available in +the system: .. literalinclude:: ../../../examples/tutorial/tut_resources.cpp :lines: 18-35 diff --git a/docs/sphinx/tutorial/typed_allocators.rst b/docs/sphinx/tutorial/typed_allocators.rst index f0dced646..b7aee540f 100644 --- a/docs/sphinx/tutorial/typed_allocators.rst +++ b/docs/sphinx/tutorial/typed_allocators.rst @@ -9,9 +9,9 @@ specific type. Umpire provides a :class:`umpire::TypedAllocator` for this purpose. It can also be used with STL objects like ``std::vector``. A :class:`umpire::TypedAllocator` is constructed from any existing Allocator, -and provides the same interface as the normal ``Allocator``. However, when you -call allocate, this argument is the number of objects you want to allocate, no -the total number of bytes: +and provides the same interface as the normal :class:`umpire::Allocator`. +However, when you call allocate, this argument is the number of objects you +want to allocate, no the total number of bytes: .. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp :lines: 25-29 @@ -23,10 +23,10 @@ vector when you construct it: .. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp :lines: 32-33 -One thing to remember is that whatever ``Allocator`` you use with an STL -object, it must be compatible with the inner workings of that object. For -example, if you try and use a "DEVICE"-based ``Allocator`` it will fail, since -the vector will try and construct each element. The CPU cannot access DEVICE -memory in most systems, thus causing a segfault. Be careful! +One thing to remember is that whatever allocator you use with an STL object, it +must be compatible with the inner workings of that object. For example, if you +try and use a "DEVICE"-based allocator it will fail, since the vector will try +and construct each element. The CPU cannot access DEVICE memory in most +systems, thus causing a segfault. Be careful! .. literalinclude:: ../../../examples/tutorial/tut_typed_allocator.cpp From f84d72764d6639f43418bd92a45ac085a6dafe27 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 09:05:13 -0700 Subject: [PATCH 077/110] Fix unused arg warnings for argc and argv --- examples/tutorial/tut_move.cpp | 2 +- examples/tutorial/tut_resources.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/tutorial/tut_move.cpp b/examples/tutorial/tut_move.cpp index c5e8c6792..0bb451070 100644 --- a/examples/tutorial/tut_move.cpp +++ b/examples/tutorial/tut_move.cpp @@ -30,7 +30,7 @@ double* move_data(double* source_data, const std::string& destination) return dest_data; } -int main(int argc, char* argv[]) { +int main(int, char**) { constexpr size_t SIZE = 1024; auto& rm = umpire::ResourceManager::getInstance(); diff --git a/examples/tutorial/tut_resources.cpp b/examples/tutorial/tut_resources.cpp index 06ecbeba0..8c1f749f7 100644 --- a/examples/tutorial/tut_resources.cpp +++ b/examples/tutorial/tut_resources.cpp @@ -34,7 +34,7 @@ void allocate_and_deallocate(const std::string& resource) std::cout << " deallocated." << std::endl; } -int main(int argc, char* argv[]) { +int main(int, char**) { allocate_and_deallocate("HOST"); #if defined(UMPIRE_ENABLE_CUDA) From b0b61bb84448e25a37d3d57bdcfd2ed01205928d Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 09:19:25 -0700 Subject: [PATCH 078/110] Let getActualSize work with AllocationTracker --- src/umpire/strategy/AllocationTracker.cpp | 6 ++++++ src/umpire/strategy/AllocationTracker.hpp | 1 + tests/integration/strategy_tests.cpp | 7 ++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/umpire/strategy/AllocationTracker.cpp b/src/umpire/strategy/AllocationTracker.cpp index 3182ff2a9..7fc908238 100644 --- a/src/umpire/strategy/AllocationTracker.cpp +++ b/src/umpire/strategy/AllocationTracker.cpp @@ -56,6 +56,12 @@ AllocationTracker::getHighWatermark() return m_high_watermark; } +long +AllocationTracker::getActualSize() +{ + return m_allocator->getActualSize(); +} + Platform AllocationTracker::getPlatform() { diff --git a/src/umpire/strategy/AllocationTracker.hpp b/src/umpire/strategy/AllocationTracker.hpp index ed5ba594c..b588a672f 100644 --- a/src/umpire/strategy/AllocationTracker.hpp +++ b/src/umpire/strategy/AllocationTracker.hpp @@ -40,6 +40,7 @@ class AllocationTracker : long getCurrentSize(); long getHighWatermark(); + long getActualSize(); Platform getPlatform(); diff --git a/tests/integration/strategy_tests.cpp b/tests/integration/strategy_tests.cpp index db7ac4c2d..b2d44106c 100644 --- a/tests/integration/strategy_tests.cpp +++ b/tests/integration/strategy_tests.cpp @@ -251,11 +251,12 @@ TEST(FixedPool, Host) auto allocator = rm.makeAllocator>( "host_fixed_pool", rm.getAllocator("HOST")); - void* alloc = allocator.allocate(100); + void* alloc = allocator.allocate(sizeof(data)); - ASSERT_GE(allocator.getCurrentSize(), sizeof(data)*64); + ASSERT_GE(allocator.getCurrentSize(), sizeof(data)); + ASSERT_GE(allocator.getActualSize(), sizeof(data)*64); ASSERT_EQ(allocator.getSize(alloc), sizeof(data)); - ASSERT_GE(allocator.getHighWatermark(), sizeof(data)*64); + ASSERT_GE(allocator.getHighWatermark(), sizeof(data)); ASSERT_EQ(allocator.getName(), "host_fixed_pool"); } From 5e260c650096391441a09f08b1defde09f2984fc Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 09:19:30 -0700 Subject: [PATCH 079/110] Remove commented code --- src/umpire/ResourceManager.inl | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/umpire/ResourceManager.inl b/src/umpire/ResourceManager.inl index fc793018c..f450481c1 100644 --- a/src/umpire/ResourceManager.inl +++ b/src/umpire/ResourceManager.inl @@ -70,36 +70,6 @@ Allocator ResourceManager::makeAllocator( return Allocator(allocator); } -// template -// Allocator ResourceManager::makeAllocator( -// const std::string& name, -// Args&&... args) -// { -// std::shared_ptr allocator; -// -// try { -// UMPIRE_LOCK; -// -// UMPIRE_LOG(Debug, "(name=\"" << name << "\")"); -// -// if (isAllocator(name)) { -// UMPIRE_ERROR("Allocator with name " << name << " is already registered."); -// } -// -// allocator = std::make_shared(name, getNextId(), std::forward(args)...); -// -// m_allocators_by_name[name] = allocator; -// m_allocators_by_id[allocator->getId()] = allocator; -// UMPIRE_UNLOCK; -// } catch (...) { -// UMPIRE_UNLOCK; -// throw; -// } -// -// return Allocator(allocator); -// } - } // end of namespace umpire #endif // UMPIRE_ResourceManager_INL From 4563089434829bf7e12b0caeb5bce59fbb212769 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 09:44:11 -0700 Subject: [PATCH 080/110] Show default sizes for DynamicPool --- examples/tutorial/tut_dynamic_pool_2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/tutorial/tut_dynamic_pool_2.cpp b/examples/tutorial/tut_dynamic_pool_2.cpp index 26a5f3454..262aa1719 100644 --- a/examples/tutorial/tut_dynamic_pool_2.cpp +++ b/examples/tutorial/tut_dynamic_pool_2.cpp @@ -31,8 +31,8 @@ void allocate_and_deallocate_pool( auto pooled_allocator = rm.makeAllocator(resource + "_pool", allocator, - initial_size, - min_block_size); + initial_size, /* default = 512Mb*/ + min_block_size /* default = 1Mb */); double* data = static_cast( pooled_allocator.allocate(SIZE*sizeof(double))); From 7562e2e14eed9dc456b0808265e86ae1f2126867 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 10:39:36 -0700 Subject: [PATCH 081/110] Fixup comments --- src/umpire/ResourceManager.cpp | 1 - src/umpire/resource/ConstantMemoryResource.cu | 1 + src/umpire/resource/ConstantMemoryResource.hpp | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index d8452b009..ea03874a4 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -71,7 +71,6 @@ ResourceManager::ResourceManager() : registry.registerMemoryResource( std::make_shared()); - // constant memory registry.registerMemoryResource( std::make_shared()); #endif diff --git a/src/umpire/resource/ConstantMemoryResource.cu b/src/umpire/resource/ConstantMemoryResource.cu index 2e973f42a..d5e10d212 100644 --- a/src/umpire/resource/ConstantMemoryResource.cu +++ b/src/umpire/resource/ConstantMemoryResource.cu @@ -2,6 +2,7 @@ // Copyright (c) 2018, Lawrence Livermore National Security, LLC. // Produced at the Lawrence Livermore National Laboratory // +// Created by David Beckingsale, david@llnl.gov // LLNL-CODE-747640 // // All rights reserved. diff --git a/src/umpire/resource/ConstantMemoryResource.hpp b/src/umpire/resource/ConstantMemoryResource.hpp index 51d36940e..6e2c06039 100644 --- a/src/umpire/resource/ConstantMemoryResource.hpp +++ b/src/umpire/resource/ConstantMemoryResource.hpp @@ -2,6 +2,7 @@ // Copyright (c) 2018, Lawrence Livermore National Security, LLC. // Produced at the Lawrence Livermore National Laboratory // +// Created by David Beckingsale, david@llnl.gov // LLNL-CODE-747640 // // All rights reserved. From 8cc09f5a1d954c3a82938df946ce54d51e973ad6 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 11:15:58 -0700 Subject: [PATCH 082/110] Remove one more comment --- src/umpire/resource/DeviceConstResourceFactory.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/umpire/resource/DeviceConstResourceFactory.cpp b/src/umpire/resource/DeviceConstResourceFactory.cpp index 6970ed58c..68258e5bd 100644 --- a/src/umpire/resource/DeviceConstResourceFactory.cpp +++ b/src/umpire/resource/DeviceConstResourceFactory.cpp @@ -15,7 +15,6 @@ #include "umpire/resource/DeviceConstResourceFactory.hpp" #include "umpire/resource/ConstantMemoryResource.hpp" -// #include "umpire/alloc/CudaConstMemAllocator.hpp" namespace umpire { namespace resource { From 0ae7906f9c5924c4e2825e0e52c9d9a2b61384f8 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 12:07:00 -0700 Subject: [PATCH 083/110] More code cleanup --- src/umpire/ResourceManager.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/umpire/ResourceManager.cpp b/src/umpire/ResourceManager.cpp index ea03874a4..12188abbf 100644 --- a/src/umpire/ResourceManager.cpp +++ b/src/umpire/ResourceManager.cpp @@ -105,13 +105,6 @@ ResourceManager::initialize() m_default_allocator = host_allocator; #if defined(UMPIRE_ENABLE_CUDA) - /* - * strategy::AllocationStrategyRegistry& strategy_registry = - * strategy::AllocationStrategyRegistry::getInstance(); - * - * m_allocators_by_name["DEVICE"] = strategy_registry.makeAllocationStrategy("POOL", {}, {m_memory_resources["DEVICE"]}); - */ - auto device_allocator = m_memory_resources[resource::Device]; m_allocators_by_name["DEVICE"] = device_allocator; m_allocators_by_id[device_allocator->getId()] = device_allocator; @@ -124,7 +117,6 @@ ResourceManager::initialize() m_allocators_by_name["PINNED"] = pinned_allocator; m_allocators_by_id[pinned_allocator->getId()] = pinned_allocator; - // constant memory auto device_const_allocator = m_memory_resources[resource::DeviceConst]; m_allocators_by_name["DEVICE_CONST"] = device_const_allocator; m_allocators_by_id[device_const_allocator->getId()] = device_const_allocator; @@ -207,7 +199,6 @@ ResourceManager::registerAllocator(const std::string& name, Allocator allocator) m_allocators_by_name[name] = allocator.getAllocationStrategy(); } - Allocator ResourceManager::getAllocator(void* ptr) { From ad97deee9246075cfc09b01c256622e2b2491b6a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 13:29:53 -0700 Subject: [PATCH 084/110] Fix unused arg warning --- src/umpire/resource/DeviceConstResourceFactory.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/umpire/resource/DeviceConstResourceFactory.cpp b/src/umpire/resource/DeviceConstResourceFactory.cpp index 68258e5bd..0737e24ff 100644 --- a/src/umpire/resource/DeviceConstResourceFactory.cpp +++ b/src/umpire/resource/DeviceConstResourceFactory.cpp @@ -16,6 +16,8 @@ #include "umpire/resource/ConstantMemoryResource.hpp" +#include "umpire/util/Macros.hpp" + namespace umpire { namespace resource { @@ -30,7 +32,7 @@ DeviceConstResourceFactory::isValidMemoryResourceFor(const std::string& name) } std::shared_ptr -DeviceConstResourceFactory::create(const std::string& name, int id) +DeviceConstResourceFactory::create(const std::string& UMPIRE_UNUSED_ARG(name), int id) { return std::make_shared("DEVICE_CONST", id); } From c43b649b2cbe85e2349dd07b29fc9118a59cb8f4 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 15:14:55 -0700 Subject: [PATCH 085/110] Add ReadTheDocs badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2618d11ab..5450dc39d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Umpire v0.2.3 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) +[![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) Umpire is a resource management library that allows the discovery, provision, and management of memory on next-generation architectures. From 31a33871cad5728d95eab6c315d95e56cf3c3ace Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 15:49:03 -0700 Subject: [PATCH 086/110] Enable code coverage for codecov --- .travis.yml | 2 +- CMakeLists.txt | 2 ++ cmake/SetupCompilerFlags.cmake | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 cmake/SetupCompilerFlags.cmake diff --git a/.travis.yml b/.travis.yml index 29cd589ad..2682a86a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: env: - COMPILER=g++ - IMG=gcc-5 - - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off" + - CMAKE_EXTRA_FLAGS="-DENABLE_CUDA=Off -DENABLE_COVERAGE=On" - compiler: gcc6 env: - COMPILER=g++ diff --git a/CMakeLists.txt b/CMakeLists.txt index 06c26b0b4..c878eca62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ option(ENABLE_SLIC "Build Umpire with SLIC logging" Off) option(ENABLE_ASSERTS "Build Umpire with assert() enabled" On) set(ENABLE_GTEST_DEATH_TESTS ${ENABLE_ASSERTS} CACHE Bool "") option(ENABLE_STATISTICS "Track statistics for allocations and operations" Off) +option(ENABLE_COVERAGE "Enable code coverage (with GCC)" Off) if (ENABLE_CUDA) cmake_minimum_required(VERSION 3.9) @@ -65,6 +66,7 @@ if (NOT BLT_LOADED) endif() +include(cmake/SetupCompilerFlags.cmake) include(cmake/SetupUmpireThirdParty.cmake) configure_file( diff --git a/cmake/SetupCompilerFlags.cmake b/cmake/SetupCompilerFlags.cmake new file mode 100644 index 000000000..d6eaacb00 --- /dev/null +++ b/cmake/SetupCompilerFlags.cmake @@ -0,0 +1,5 @@ +if (ENABLE_COVERAGE) + message(INFO "Coverage analysis enabled") + set(CMAKE_CXX_FLAGS "-coverage ${CMAKE_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "-coverage ${CMAKE_EXE_LINKER_FLAGS}") +endif () From 77b757029090ccc1433ae84f00db968d453a1f64 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 15:55:58 -0700 Subject: [PATCH 087/110] Disable performance test when coverage is enabled --- tests/unit/util/CMakeLists.txt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/unit/util/CMakeLists.txt b/tests/unit/util/CMakeLists.txt index 305b3fbf4..740cad2c1 100644 --- a/tests/unit/util/CMakeLists.txt +++ b/tests/unit/util/CMakeLists.txt @@ -32,12 +32,15 @@ blt_add_test( NAME allocation_map_tests COMMAND allocation_map_tests) -blt_add_executable( - NAME allocation_map_performance_tests - SOURCES allocation_map_performance_tests.cpp - DEPENDS_ON umpire_util gtest - OUTPUT_DIR ${UMPIRE_TEST_OUTPUT_DIR}) +# This test can fail when coverage is enabled +if (NOT ENABLE_COVERAGE) + blt_add_executable( + NAME allocation_map_performance_tests + SOURCES allocation_map_performance_tests.cpp + DEPENDS_ON umpire_util gtest + OUTPUT_DIR ${UMPIRE_TEST_OUTPUT_DIR}) -blt_add_test( - NAME allocation_map_performance_tests - COMMAND allocation_map_performance_tests) + blt_add_test( + NAME allocation_map_performance_tests + COMMAND allocation_map_performance_tests) +endif () From 426c22795bc04b8bc33d4dc1b6b02e82aa8575eb Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 27 Aug 2018 16:08:06 -0700 Subject: [PATCH 088/110] Add badge for codecov --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5450dc39d..f2a230893 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) +[![codecov](https://codecov.io/gh/LLNL/Umpire/branch/develop/graph/badge.svg)](https://codecov.io/gh/LLNL/Umpire) Umpire is a resource management library that allows the discovery, provision, and management of memory on next-generation architectures. From aaa594a2335542521eec4a60e74be813c932dc1a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 28 Aug 2018 12:23:26 -0700 Subject: [PATCH 089/110] Add CodeCov YAML file to ignore TPLs and tests --- codecov.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..ff41987ad --- /dev/null +++ b/codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "src/umpire/tpl" + - "test" From 94f428ded623f6e20015ef812c3307b6441cb238 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 29 Aug 2018 12:46:41 -0700 Subject: [PATCH 090/110] Disable performance test (for now) --- tests/unit/util/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/util/CMakeLists.txt b/tests/unit/util/CMakeLists.txt index 740cad2c1..4c4a15038 100644 --- a/tests/unit/util/CMakeLists.txt +++ b/tests/unit/util/CMakeLists.txt @@ -32,8 +32,8 @@ blt_add_test( NAME allocation_map_tests COMMAND allocation_map_tests) -# This test can fail when coverage is enabled -if (NOT ENABLE_COVERAGE) +# TODO: Make this test a relative performance test +if (False) blt_add_executable( NAME allocation_map_performance_tests SOURCES allocation_map_performance_tests.cpp From 3fde3c32d8ce55923e983932c10a8e99cc0271a7 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 29 Aug 2018 13:24:42 -0700 Subject: [PATCH 091/110] Update codecov to check simpool coverage --- codecov.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index ff41987ad..a6c66018c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,4 @@ ignore: - - "src/umpire/tpl" + - "src/umpire/tpl/conduit" + - "src/umpire/tpl/judy" - "test" From 9a9480cf48ebc6374aa3916909a012f334647af2 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 29 Aug 2018 14:25:07 -0700 Subject: [PATCH 092/110] Correctly install 'mixin' headers --- src/umpire/strategy/CMakeLists.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/umpire/strategy/CMakeLists.txt b/src/umpire/strategy/CMakeLists.txt index eecc9eaa8..fa0c93206 100644 --- a/src/umpire/strategy/CMakeLists.txt +++ b/src/umpire/strategy/CMakeLists.txt @@ -21,7 +21,9 @@ set (umpire_strategy_headers ThreadSafeAllocator.hpp DynamicPool.hpp FixedPool.hpp - FixedPool.inl + FixedPool.inl) + +set (umpire_strategy_mixin_headers mixins/Inspector.hpp) set (umpire_stategy_sources @@ -40,8 +42,8 @@ set (umpire_strategy_depends umpire_tpl_simpool) blt_add_library( - NAME umpire_strategy - HEADERS ${umpire_strategy_headers} + NAME umpire_strategy + HEADERS ${umpire_strategy_headers} ${umpire_strategy_mixin_headers} SOURCES ${umpire_stategy_sources} HEADERS_OUTPUT_SUBDIR umpire/strategy DEPENDS_ON ${umpire_strategy_depends}) @@ -63,3 +65,7 @@ install(TARGETS install(FILES ${umpire_strategy_headers} DESTINATION include/umpire/strategy) + +install(FILES + ${umpire_strategy_mixin_headers} + DESTINATION include/umpire/strategy/mixins) From 9eebc37b111da8639feaa3ccfd3b49cdf72b024a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 29 Aug 2018 14:39:10 -0700 Subject: [PATCH 093/110] Add link to documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2a230893..fd2393321 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For more advanced configuration you can use standard CMake variables. # Documentation -Both user and code documentation is available. +Both user and code documentation is available [here](http://umpire.readthedocs.io/). # Authors From a275d190522ac014f388bb9ba90afbb3ed7cd956 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 11 Sep 2018 14:33:06 +0100 Subject: [PATCH 094/110] Add Umpire logo --- share/umpire/logo/umpire-logo.svg | 115 ++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 share/umpire/logo/umpire-logo.svg diff --git a/share/umpire/logo/umpire-logo.svg b/share/umpire/logo/umpire-logo.svg new file mode 100644 index 000000000..576758aa2 --- /dev/null +++ b/share/umpire/logo/umpire-logo.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From cfdf6ddf6e680872c803f4fb3315602a8d0d5c81 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 11 Sep 2018 14:40:49 +0100 Subject: [PATCH 095/110] Add logo to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd2393321..bebae6609 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire v0.2.3 +# Umpire Umpire v0.2.3 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) From af4a31c1c52258dab0a988ec7a686b0b2f430710 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 11 Sep 2018 14:42:16 +0100 Subject: [PATCH 096/110] Change logo size --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bebae6609..4d258dd87 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire Umpire v0.2.3 +# Umpire Umpire v0.2.3 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) From ef2a6abbe4b45c629c8f0f41e55aa44026db41e6 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 11 Sep 2018 14:52:08 +0100 Subject: [PATCH 097/110] Add update logo --- share/umpire/logo/umpire-logo.svg | 124 +++++++++++++++--------------- 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/share/umpire/logo/umpire-logo.svg b/share/umpire/logo/umpire-logo.svg index 576758aa2..bd2b029a9 100644 --- a/share/umpire/logo/umpire-logo.svg +++ b/share/umpire/logo/umpire-logo.svg @@ -1,7 +1,7 @@ + viewBox="0 0 213.3 204" style="enable-background:new 0 0 213.3 204;" xml:space="preserve"> @@ -35,81 +35,79 @@ .st1{fill:#010101;} - + C64.2,118.1,62.9,118.7,61.8,117.5z M89.2,51c1,5,3.2,9,6.3,11.7c1.2,1,0.4,2.4-0.4,2.4s-8.3,0-8.3,0c-7.4,0-10.8-1.2-13.9-4.7 + c-0.6-0.7-0.8-1.9,0.5-3c3.9-3.2,8.4-5.9,13.2-8C88,48.8,88.9,49.4,89.2,51z M68.6,64.1c1.3,1.5,2.7,2.7,4.2,3.7 + c0.7,0.5,1.1,1.2-0.5,1.2c-2.4,0-5.7,0-6.5,0c-1.4,0-1.5-1.3-1.1-1.9c0.6-0.9,1.2-1.7,1.8-2.6C67.3,63.5,68.1,63.5,68.6,64.1z + M40,74.8c1.1,0.8,3.2,1.1,4.4,1.6c0.7,0.3,0.1,4.5,0,5.3c-0.2,1.3-0.3,2.5-0.4,3.8c0,0.4-0.6,1.2-1.3,1.2c-1.3,0-3.2,0-3.8,0 + c-0.9,0-1.1-1-1.1-1.5c0.2-2.2,0.4-4.3,0.7-6.5C38.7,78.3,39.6,74.5,40,74.8z M43.9,93.7c0,0.9,0.1,1.9,0.2,2.8 + c0.1,0.8-0.1,3.1-0.5,3.2c-1.4,0.3-3,0.1-4.1,0c-0.4,0-1.3-0.7-1.3-1.1c-0.2-1.7-0.3-3.4-0.4-5.1c0-0.5,0.4-1.1,1-1.1 + c1.3,0,3.5,0,4.1,0C43.7,92.5,43.9,93.3,43.9,93.7z M18.4,64.6c0-3.7,3-6.7,6.6-6.7c0,0,10.9,0,11.6,0c0.7,0,1.5,1.2,1.3,1.8 + c-1,2.4-1.8,4.8-2.5,7.3C35,68.2,33.6,69,32.8,69c-1.6,0-2.8,1.3-2.8,2.9c0,1.6,1.3,2.4,2.9,2.4c0.4,0,0.6,0.6,0.5,1.4 + c-0.6,3.1-1,6.3-1.2,9.6c0,0.5-0.6,1.5-1.4,1.5c-3.1,0-10.2,0-10.8,0c-0.7,0-1.4-0.8-1.4-1.6S18.4,64.6,18.4,64.6z M25,121.3 + c-3.6,0-6.6-3-6.6-6.7c0,0,0-19.6,0-20.4c0-0.8,0.8-1.6,1.7-1.6c0.7,0,7.1,0,10.2,0c1.2,0,1.7,0.6,1.7,2c0.1,2.9,0.4,5.8,0.8,8.6 + c0.1,0.9-0.3,1.3-0.7,1.4c-1.3,0.3-2.3,1.4-2.3,2.8c0,1.6,1.3,2.9,2.8,2.9c0.8,0,1.6,0.5,1.9,1.6c0.4,2.1,0.8,4.3,1.4,6.5 + c0.2,1-0.1,3-1.4,3C33.4,121.3,25,121.3,25,121.3z M79.7,185.4c-0.2-0.5-2.3-4.6-4.9-9.8c-0.3-0.6,0.2-1.7,1.1-1.7 + c4.6,0,7.3-0.5,10.8,0.7c1.2,0.4,1.1-0.2,2,2.4l2.8,11.5c0.2,0.7,0.2,1.5-1,1.5c-0.9,0-3.5,0-3.5,0 + C83.3,189.9,81.9,189.7,79.7,185.4z M126.1,195.7c5.4,0,8.8-1.2,12.2-7.7c0.3-0.6,3.3-6.5,6.6-13.1c0.5-1.1,1.8-2.7,2.7-2.9 + c1.4-0.3,2.4-0.7,3.6-0.9c3.8-0.8,7.3-3.3,8.8-7c1-2.4,2.8-6.6,4.9-11.6c0.6-1.4,1.7-2.2,2.3-2.2l0.6,0.1c1.6,0,2.8-1,2.8-2.6 + c0-1.1-0.6-2-1.5-2.5c-0.5-0.3-0.9-1-0.6-1.7c1.6-4.2,3.3-8.7,4.7-13.1c0.4-1.1,1.6-3.4,4-3.4c2.4,0,10.7,0,10.7,0 + c6.8,0,12.3-5.6,12.3-12.5c0,0,0-19.1,0-20.2c0-1,0.9-1.9,1.6-1.9c0.7,0,0.7,0,0.7,0c1.6,0,2.8-1.3,2.8-2.9c0-1.6-1.3-2.9-2.8-2.9 + c0,0-0.5,0-1,0s-1.3-0.8-1.3-1.7s0-20.4,0-20.4c0-6.9-5.5-12.5-12.3-12.5c0,0-12.9,0-14.5,0c-1.6,0-2.6-1.3-3-1.9 + c-2.6-4.7-5.7-9.1-9.2-13.1c-0.3-0.3-0.5-1.2-0.6-1.9c-0.1-1-0.6-2-1.5-2.7l-12.8-11c-0.9-0.8-2-1.1-3.1-1 + c-1.5,0.1-1.8,0.4-3.1-0.4c-6.2-3.3-12.8-5.8-19.8-7.2c-0.9-0.2-1.7-0.7-2.4-1.4c-0.8-0.9-1.9-1.4-3.2-1.4H98.1 + c-1.3,0-2.4,0.6-3.2,1.4c-0.7,0.7-1.5,1.2-2.4,1.4c-7,1.4-13.6,3.9-19.8,7.2c-1.3,0.7-1.6,0.5-3.1,0.4c-1.1-0.1-2.2,0.2-3.1,1 + l-12.8,11c-0.8,0.7-1.3,1.7-1.5,2.7c-0.1,0.7-0.3,1.6-0.6,1.9c-3.5,4-6.6,8.4-9.2,13.1c-0.4,0.6-1.4,1.9-3,1.9s-14.5,0-14.5,0 + c-6.8,0-12.3,5.6-12.3,12.5c0,0,0,19.5,0,20.4s-0.7,1.7-1.3,1.7s-1,0-1,0c-1.6,0-2.8,1.3-2.8,2.9c0,1.6,1.3,2.9,2.8,2.9 + c0,0,0,0,0.7,0c0.7,0,1.6,0.9,1.6,1.9c0,1,0,20.2,0,20.2c0,6.9,5.5,12.5,12.3,12.5c0,0,8.2,0,10.7,0c2.4,0,3.6,2.2,4,3.4 + c1.5,4.5,3.1,8.9,4.7,13.1c0.3,0.7-0.1,1.4-0.6,1.7c-0.9,0.5-1.5,1.4-1.5,2.5c0,1.6,1.3,2.6,2.9,2.6l0.4,0.1c0.5,0,1.8,0.6,2.4,2 + c2.1,5.1,3.9,9.2,4.9,11.6c1.6,3.7,5.2,6.3,9,7.1c1.1,0.3,2.1,1.2,3.5,1.5c0.9,0.2,2.1,1.2,2.6,2.3c3.3,6.6,6.3,12.5,6.6,13.1 + c3.3,6.5,6.7,7.7,12.2,7.7H126.1z M99.5,189.9c-1.4,0-2.1-0.8-2.3-1.7c-0.2-0.7-1.9-7.7-2.6-11c-0.2-0.9,0.5-1.6,1.8-1.5 + c3.1,0.1,6.5,0.1,10.1,0.1c3.6,0,7-0.1,10.1-0.1c1.3,0,2,0.6,1.8,1.5c-0.8,3.2-2.5,10.3-2.6,11c-0.2,0.9-0.9,1.7-2.3,1.7H99.5z + M150.5,74.8c3.9-0.2,3.6,1,4.1,1.5c2,2,3.7,3.6,6.6,4.2c0.9,0.2,1.6,0.7,1.7,1.6c0.4,2.8,0.6,5.6,0.6,8.6c0,1.9-0.1,3.7-0.2,5.5 + c-0.1,0.9-0.9,2.1-1.7,2.5c-2.2,0.9-4.2,2.3-5.7,4.3c-0.4,0.5-1.6,1.5-3.1,1.5H60.4c-1.5,0-2.8-1.1-3.1-1.5c-1.5-2-3.6-3.5-5.7-4.3 + c-0.9-0.4-1.7-1.6-1.7-2.5c-0.2-1.8-0.2-3.6-0.2-5.5c0-2.9,0.2-5.8,0.6-8.6c0.1-0.9,0.8-1.4,1.7-1.6c2.9-0.6,4.3-2.1,6.4-4 + c0.5-0.5-0.4-1.8,4.3-1.6H150.5z M106.5,144.4c-4.4,0-8.7-0.8-13-2.3c-1.9-0.7-2.3-2.3-2.1-3.8l0.9-6.6c1.2-8.9,6.2-13.8,14.2-13.8 + s13,4.9,14.2,13.8l0.9,6.6c0.2,1.6-0.2,3.2-2.1,3.8C115.2,143.6,110.8,144.4,106.5,144.4z M119.3,114.2c0.9,0,7.4,0,7.4,0 + c10,0,13.1,2.1,17.5,8.6c0.8,1.1,0.9,3-0.1,4.1c-4,4.4-8.7,8.2-13.8,11.3c-1.2,0.7-2.5-0.2-2.7-1.6l-0.7-5c-1-6.9-4-12.3-8.5-15.6 + C117.6,115.2,118.4,114.2,119.3,114.2z M147.2,119c-2.2-3.1-4.3-5.5-7-7.2c-0.9-0.6-1.2-1.5,1-1.5c3.9,0,9.6,0,10.9,0 + c1.9,0,2,1.4,1.7,2.1c-1.1,2.3-2.3,4.6-3.6,6.8C149.1,120.8,147.9,120,147.2,119z M106.5,60.6c-8.6,0-11.2-7.2-11.9-11.9 + c-0.1-0.8,0.5-2.1,1.6-2.4c3.4-0.7,6.8-1.2,10.2-1.2s6.8,0.4,10.2,1.2c1.1,0.3,1.7,1.6,1.6,2.4C117.6,53.4,115.1,60.6,106.5,60.6z + M126.3,49.4c4.8,2.1,9.3,4.8,13.2,8c1.3,1.1,1.1,2.3,0.5,3c-3.1,3.5-6.4,4.7-13.9,4.7c0,0-7.5,0-8.3,0c-0.8,0-1.6-1.4-0.4-2.4 + c3.1-2.6,5.3-6.6,6.3-11.7C124,49.4,124.9,48.8,126.3,49.4z M146.4,64.5c0.6,0.8,1.2,1.7,1.8,2.6c0.4,0.6,0.2,1.9-1.1,1.9 + c-0.8,0-4.1,0-6.5,0c-1.6,0-1.3-0.8-0.5-1.2c1.6-1,2.9-2.2,4.2-3.7C144.8,63.5,145.7,63.5,146.4,64.5z M174.3,78.8 + c0.3,2.1,0.6,4.3,0.7,6.5c0,0.5-0.2,1.5-1.1,1.5c-0.6,0-2.5,0-3.8,0c-0.7,0-1.3-0.8-1.3-1.2c-0.1-1.3-0.2-2.5-0.4-3.8 + c-0.1-0.8-0.4-4.4,0.3-4.6c1.2-0.4,2.5-0.4,3.9-0.4C173.1,76.7,174.3,78.3,174.3,78.8z M170.1,92.5c0.6,0,2.8,0,4.1,0 + c0.7,0,1,0.6,1,1.1c-0.1,1.7-0.2,3.4-0.4,5.1c0,0.4-1,1.9-1.4,1.8c-1.5-0.4-2.8-0.3-4.3-0.6c-0.5-0.1-0.4-2.5-0.3-3.3 + c0.1-0.9,0.1-1.9,0.2-2.8C169,93.3,169.2,92.5,170.1,92.5z M194.5,85.1c0,0.8-0.7,1.6-1.4,1.6c-0.6,0-7.8,0-10.8,0 + c-0.8,0-1.4-1-1.4-1.5c-0.2-3.2-0.6-6.4-1.2-9.6c-0.1-0.8,0-1.3,0.4-1.3c1.6,0,3-0.9,3-2.5c0-1.6-1.3-2.9-2.8-2.9 + c-0.8,0-2.2-0.8-2.6-1.9c-0.7-2.5-1.6-5-2.5-7.3c-0.2-0.6,0.5-1.8,1.3-1.8s11.6,0,11.6,0c3.6,0,6.6,3,6.6,6.7 + C194.5,64.6,194.5,84.4,194.5,85.1z M178.2,121.3c-1.3,0-1.7-2-1.4-3c0.6-2.3,1.1-4.5,1.4-6.5c0.3-1,1.1-1.6,1.9-1.6 + c1.6,0,2.8-1.3,2.8-2.9c0-1.4-1-2.6-2.3-2.8c-0.4-0.1-0.8-0.5-0.7-1.4c0.4-2.8,0.7-5.7,0.8-8.6c0.1-1.4,0.5-2,1.7-2 + c3.1,0,9.5,0,10.2,0c0.9,0,1.7,0.8,1.7,1.6c0,0.8,0,20.4,0,20.4c0,3.7-3,6.7-6.6,6.7C187.9,121.3,179.6,121.3,178.2,121.3z + M126.1,189.9c0,0-2.7,0-3.5,0c-1.2,0-1.2-0.8-1-1.5l2.8-11.5c0.3-0.9,0.9-1.9,2.2-2c4.1-0.3,7.5-1.5,10.9-1.3 + c1.2,0.1,1.2,0.8,0.8,1.8c-2.4,5.3-4.7,9.4-4.9,9.8C131,189.7,129.6,189.9,126.1,189.9z"/> - + c0.3-1,1.2-1.6,1.9-1.6c1.6,0,2.9-1.3,2.9-2.9C183.8,105.9,182.8,104.7,181.5,104.5z"/> - + c-0.3,1.1-1.8,1.9-2.6,1.9c-1.6,0-2.9,1.3-2.9,2.9C29.1,73.1,30.4,74.4,32,74.4z"/> From b34d7fd1b82031467b5dc142354d4cb93471adb5 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 11 Sep 2018 15:03:39 +0100 Subject: [PATCH 098/110] Switch to PNG logo --- README.md | 2 +- share/umpire/logo/umpire-logo.png | Bin 0 -> 61582 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 share/umpire/logo/umpire-logo.png diff --git a/README.md b/README.md index 4d258dd87..ee16d4213 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire Umpire v0.2.3 +# Umpire Umpire v0.2.3 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) diff --git a/share/umpire/logo/umpire-logo.png b/share/umpire/logo/umpire-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0de751097ebbd2b8263a48dd3563166956c266cf GIT binary patch literal 61582 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�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 YIgVIs?THOe)4`vfj Date: Tue, 11 Sep 2018 15:04:45 +0100 Subject: [PATCH 099/110] Bump size --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ee16d4213..560b7fe64 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire Umpire v0.2.3 +# Umpire Umpire v0.2.3 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) From d3cacb49b3e03d291ba240c1a218b2094548d41b Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Tue, 11 Sep 2018 16:56:04 +0100 Subject: [PATCH 100/110] Fix logo URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 560b7fe64..d897ebebf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire Umpire v0.2.3 +# Umpire Umpire v0.2.3 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) From e206ec2140b0de22fbb4152cbfe510d5b78042c6 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Mon, 17 Sep 2018 19:33:22 +0000 Subject: [PATCH 101/110] Add Gitter badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d897ebebf..db8ac940b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) -[![codecov](https://codecov.io/gh/LLNL/Umpire/branch/develop/graph/badge.svg)](https://codecov.io/gh/LLNL/Umpire) +[![codecov](https://codecov.io/gh/LLNL/Umpire/branch/develop/graph/badge.svg)](https://codecov.io/gh/LLNL/Umpire) [![Join the chat at https://gitter.im/LLNL/Umpire](https://badges.gitter.im/LLNL/Umpire.svg)](https://gitter.im/LLNL/Umpire?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Umpire is a resource management library that allows the discovery, provision, and management of memory on next-generation architectures. From 48f5df05bc18d07f7dbe33fea392d5c9ecf94645 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 18 Oct 2018 13:19:29 -0700 Subject: [PATCH 102/110] Add target_compile_options to judy --- src/umpire/tpl/judy/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/umpire/tpl/judy/CMakeLists.txt b/src/umpire/tpl/judy/CMakeLists.txt index ad506580d..204491725 100644 --- a/src/umpire/tpl/judy/CMakeLists.txt +++ b/src/umpire/tpl/judy/CMakeLists.txt @@ -27,6 +27,11 @@ blt_add_library( HEADERS ${judy_headers} HEADERS_OUTPUT_SUBDIR umpire/tpl/judy) +target_compile_options( + umpire_tpl_judy + PRIVATE + -O0) + install(TARGETS umpire_tpl_judy EXPORT umpire-targets From dff7a927e65ec2809db47ca28ba73af02b4fa410 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 18 Oct 2018 14:07:27 -0700 Subject: [PATCH 103/110] Print map contents when a record is not found. --- src/umpire/util/AllocationMap.cpp | 23 +++++++++++++++++++++++ src/umpire/util/AllocationMap.hpp | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/src/umpire/util/AllocationMap.cpp b/src/umpire/util/AllocationMap.cpp index 2b9ce27f1..36859ea85 100644 --- a/src/umpire/util/AllocationMap.cpp +++ b/src/umpire/util/AllocationMap.cpp @@ -127,6 +127,7 @@ AllocationMap::find(void* ptr) if (alloc_record) { return alloc_record; } else { + printAll(); UMPIRE_ERROR("Allocation not mapped: " << ptr); } } @@ -139,5 +140,27 @@ AllocationMap::contains(void* ptr) return (findRecord(ptr) != nullptr); } +void +AllocationMap::printAll() +{ + std::cout << "🔍 Printing allocation map contents..." << std::endl; + + for (auto record = m_records.begin(); m_records.success(); record=m_records.next()){ + auto addr = record.key; + auto vec = *record.value; + + std::cout << reinterpret_cast(addr) << " : {" << std::endl; + for (auto const& records : vec) { + AllocationRecord* tmp = reinterpret_cast(records); + std::cout << " " << tmp->m_size << + " [ " << reinterpret_cast(addr) << + " -- " << reinterpret_cast(addr+tmp->m_size) << + " ] " << std::endl; + } + std::cout << "}" << std::endl; + } + std::cout << "done." << std::endl; +} + } // end of namespace util } // end of namespace umpire diff --git a/src/umpire/util/AllocationMap.hpp b/src/umpire/util/AllocationMap.hpp index 2ba715c3f..cde65e14c 100644 --- a/src/umpire/util/AllocationMap.hpp +++ b/src/umpire/util/AllocationMap.hpp @@ -50,6 +50,10 @@ class AllocationMap void reset(); + + void + printAll(); + private: AllocationRecord* findRecord(void* ptr); From 75e5cdd7b371cd87a205ec52f6e4a8d6965b9b9a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 18 Oct 2018 17:12:57 -0700 Subject: [PATCH 104/110] Set Os flag for judy and util, and remove judy include from .hpp files --- src/umpire/tpl/judy/CMakeLists.txt | 2 +- src/umpire/util/AllocationMap.cpp | 20 +++++++++++++++----- src/umpire/util/AllocationMap.hpp | 9 +++------ src/umpire/util/CMakeLists.txt | 5 +++++ tests/unit/util/allocation_map_tests.cpp | 16 ++++++++++++++++ 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/umpire/tpl/judy/CMakeLists.txt b/src/umpire/tpl/judy/CMakeLists.txt index 204491725..0ee975dea 100644 --- a/src/umpire/tpl/judy/CMakeLists.txt +++ b/src/umpire/tpl/judy/CMakeLists.txt @@ -30,7 +30,7 @@ blt_add_library( target_compile_options( umpire_tpl_judy PRIVATE - -O0) + -Os) install(TARGETS umpire_tpl_judy diff --git a/src/umpire/util/AllocationMap.cpp b/src/umpire/util/AllocationMap.cpp index 36859ea85..bb1fde477 100644 --- a/src/umpire/util/AllocationMap.cpp +++ b/src/umpire/util/AllocationMap.cpp @@ -16,10 +16,20 @@ #include "umpire/util/Macros.hpp" +#include "umpire/tpl/judy/judyL2Array.h" + +namespace { + using AddressPair = judyL2Array::cpair; + using EntryVector = judyL2Array::vector; + using Entry = umpire::util::AllocationRecord*; +} + namespace umpire { namespace util { + AllocationMap::AllocationMap() : + m_records(new judyL2Array()), m_mutex(new std::mutex()) { } @@ -36,7 +46,7 @@ AllocationMap::insert(void* ptr, AllocationRecord* alloc_record) UMPIRE_LOG(Debug, "Inserting " << ptr); - m_records.insert( + m_records->insert( reinterpret_cast(ptr), reinterpret_cast(alloc_record)); @@ -59,7 +69,7 @@ AllocationMap::remove(void* ptr) EntryVector* record_vector = const_cast( - m_records.find(reinterpret_cast(ptr))); + m_records->find(reinterpret_cast(ptr))); if (record_vector) { if (record_vector->size() > 0) { @@ -68,7 +78,7 @@ AllocationMap::remove(void* ptr) record_vector->pop_back(); if (record_vector->empty()) { - m_records.removeEntry(reinterpret_cast(ptr)); + m_records->removeEntry(reinterpret_cast(ptr)); } } } else { @@ -92,7 +102,7 @@ AllocationMap::findRecord(void* ptr) try { UMPIRE_LOCK; - auto record = m_records.atOrBefore(reinterpret_cast(ptr)); + auto record = m_records->atOrBefore(reinterpret_cast(ptr)); if (record.value) { void* parent_ptr = reinterpret_cast(record.key); alloc_record = @@ -145,7 +155,7 @@ AllocationMap::printAll() { std::cout << "🔍 Printing allocation map contents..." << std::endl; - for (auto record = m_records.begin(); m_records.success(); record=m_records.next()){ + for (auto record = m_records->begin(); m_records->success(); record=m_records->next()){ auto addr = record.key; auto vec = *record.value; diff --git a/src/umpire/util/AllocationMap.hpp b/src/umpire/util/AllocationMap.hpp index cde65e14c..e808cccf6 100644 --- a/src/umpire/util/AllocationMap.hpp +++ b/src/umpire/util/AllocationMap.hpp @@ -20,7 +20,8 @@ #include #include -#include "umpire/tpl/judy/judyL2Array.h" +template< typename JudyKey, typename JudyValue > +class judyL2Array; namespace umpire { namespace util { @@ -28,9 +29,6 @@ namespace util { class AllocationMap { public: - using AddressPair = judyL2Array::cpair; - using EntryVector = judyL2Array::vector; - using Entry = AllocationRecord*; AllocationMap(); ~AllocationMap(); @@ -50,14 +48,13 @@ class AllocationMap void reset(); - void printAll(); private: AllocationRecord* findRecord(void* ptr); - judyL2Array m_records; + judyL2Array* m_records; std::mutex* m_mutex; }; diff --git a/src/umpire/util/CMakeLists.txt b/src/umpire/util/CMakeLists.txt index cbdead318..64d051407 100644 --- a/src/umpire/util/CMakeLists.txt +++ b/src/umpire/util/CMakeLists.txt @@ -62,6 +62,11 @@ blt_add_library( DEPENDS_ON ${umpire_util_depends} ) +target_compile_options( + umpire_util + PRIVATE + -Os) + target_include_directories( umpire_util PUBLIC diff --git a/tests/unit/util/allocation_map_tests.cpp b/tests/unit/util/allocation_map_tests.cpp index 62f322258..ae4e6834b 100644 --- a/tests/unit/util/allocation_map_tests.cpp +++ b/tests/unit/util/allocation_map_tests.cpp @@ -155,3 +155,19 @@ TEST_F(AllocationMapTest, FindMultiple) ASSERT_EQ(actual_record, record); } + +TEST_F(AllocationMapTest, PrintAll) +{ + umpire::util::AllocationRecord* next_record = + new umpire::util::AllocationRecord{data, 1, nullptr}; + + auto extra_data = new double[10]; + umpire::util::AllocationRecord* extra_record = + new umpire::util::AllocationRecord{extra_data, 10, nullptr}; + + map.insert(data, record); + map.insert(data, next_record); + map.insert(extra_data, extra_record); + + map.printAll(); +} From 4ab2b01e2336e2ec7e10fba50ddcdad5a6a11644 Mon Sep 17 00:00:00 2001 From: Marty McFadden Date: Fri, 19 Oct 2018 11:40:40 -0700 Subject: [PATCH 105/110] Only disable optimization of judy array for clang compiler --- src/umpire/tpl/judy/CMakeLists.txt | 10 ++++++---- src/umpire/util/CMakeLists.txt | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/umpire/tpl/judy/CMakeLists.txt b/src/umpire/tpl/judy/CMakeLists.txt index 0ee975dea..f0efdb8fb 100644 --- a/src/umpire/tpl/judy/CMakeLists.txt +++ b/src/umpire/tpl/judy/CMakeLists.txt @@ -27,10 +27,12 @@ blt_add_library( HEADERS ${judy_headers} HEADERS_OUTPUT_SUBDIR umpire/tpl/judy) -target_compile_options( - umpire_tpl_judy - PRIVATE - -Os) +if (CMAKE_CXX_COMPILER_ID MATCHES Clang) + target_compile_options( + umpire_tpl_judy + PRIVATE + -Os) +endif() install(TARGETS umpire_tpl_judy diff --git a/src/umpire/util/CMakeLists.txt b/src/umpire/util/CMakeLists.txt index 64d051407..ba073f32d 100644 --- a/src/umpire/util/CMakeLists.txt +++ b/src/umpire/util/CMakeLists.txt @@ -62,10 +62,12 @@ blt_add_library( DEPENDS_ON ${umpire_util_depends} ) -target_compile_options( - umpire_util - PRIVATE - -Os) +if (CMAKE_CXX_COMPILER_ID MATCHES Clang) + target_compile_options( + umpire_util + PRIVATE + -Os) +endif() target_include_directories( umpire_util From 6a6af17337ac498ee3cb719efe11bc92e3ba90ca Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Fri, 19 Oct 2018 14:55:52 -0700 Subject: [PATCH 106/110] Guard printAll with !defined(NDEBUG) This ensures that the map is only printed in Debug builds. --- src/umpire/util/AllocationMap.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/umpire/util/AllocationMap.cpp b/src/umpire/util/AllocationMap.cpp index bb1fde477..03b8d0a50 100644 --- a/src/umpire/util/AllocationMap.cpp +++ b/src/umpire/util/AllocationMap.cpp @@ -84,7 +84,7 @@ AllocationMap::remove(void* ptr) } else { UMPIRE_ERROR("Cannot remove " << ptr ); } - + UMPIRE_UNLOCK; } catch (...) { UMPIRE_UNLOCK; @@ -137,7 +137,10 @@ AllocationMap::find(void* ptr) if (alloc_record) { return alloc_record; } else { +#if !defined(NDEBUG) + // use this from a debugger to dump the contents of the AllocationMap printAll(); +#endif UMPIRE_ERROR("Allocation not mapped: " << ptr); } } @@ -162,13 +165,13 @@ AllocationMap::printAll() std::cout << reinterpret_cast(addr) << " : {" << std::endl; for (auto const& records : vec) { AllocationRecord* tmp = reinterpret_cast(records); - std::cout << " " << tmp->m_size << + std::cout << " " << tmp->m_size << " [ " << reinterpret_cast(addr) << " -- " << reinterpret_cast(addr+tmp->m_size) << " ] " << std::endl; } std::cout << "}" << std::endl; - } + } std::cout << "done." << std::endl; } From 02eba7e60ca0d2f7cd689364ffd092a3befc3bc0 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 22 Oct 2018 13:53:36 -0700 Subject: [PATCH 107/110] Add defaulted virtual destructors to classes with virtual functions --- src/umpire/op/MemoryOperation.hpp | 2 ++ src/umpire/resource/MemoryResource.hpp | 2 ++ src/umpire/resource/MemoryResourceFactory.hpp | 2 ++ src/umpire/strategy/AllocationStrategy.hpp | 4 +++- src/umpire/util/Exception.hpp | 2 ++ 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/umpire/op/MemoryOperation.hpp b/src/umpire/op/MemoryOperation.hpp index 279eda157..cd28cc29c 100644 --- a/src/umpire/op/MemoryOperation.hpp +++ b/src/umpire/op/MemoryOperation.hpp @@ -31,6 +31,8 @@ namespace op { */ class MemoryOperation { public: + virtual ~MemoryOperation() = default; + /*! * \brief Transfrom length bytes of memory from src_ptr to dst_ptr. * diff --git a/src/umpire/resource/MemoryResource.hpp b/src/umpire/resource/MemoryResource.hpp index 896013a87..6018b56a0 100644 --- a/src/umpire/resource/MemoryResource.hpp +++ b/src/umpire/resource/MemoryResource.hpp @@ -40,6 +40,8 @@ class MemoryResource : */ MemoryResource(const std::string& name, int id); + virtual ~MemoryResource() = default; + /*! * \brief Allocate bytes of memory. * diff --git a/src/umpire/resource/MemoryResourceFactory.hpp b/src/umpire/resource/MemoryResourceFactory.hpp index f82431e38..8901d94ec 100644 --- a/src/umpire/resource/MemoryResourceFactory.hpp +++ b/src/umpire/resource/MemoryResourceFactory.hpp @@ -33,6 +33,8 @@ namespace resource { */ class MemoryResourceFactory { public: + virtual ~MemoryResourceFactory() = default; + /* * \brief Check whether the MemoryResource constructed by this factory is * valid for the given name diff --git a/src/umpire/strategy/AllocationStrategy.hpp b/src/umpire/strategy/AllocationStrategy.hpp index ccdcb60fc..c1fa3a1ac 100644 --- a/src/umpire/strategy/AllocationStrategy.hpp +++ b/src/umpire/strategy/AllocationStrategy.hpp @@ -43,6 +43,8 @@ class AllocationStrategy : */ AllocationStrategy(const std::string& name, int id); + virtual ~AllocationStrategy() = default; + /*! * \brief Allocate bytes of memory. * @@ -74,7 +76,7 @@ class AllocationStrategy : * * This is equivalent to the highest observed value of getCurrentSize. * \return High watermark allocation size. - */ + */ virtual long getHighWatermark() = 0; /*! diff --git a/src/umpire/util/Exception.hpp b/src/umpire/util/Exception.hpp index 1db76376c..da8ae16b5 100644 --- a/src/umpire/util/Exception.hpp +++ b/src/umpire/util/Exception.hpp @@ -27,6 +27,8 @@ class Exception : public std::exception { const std::string &file, int line); + virtual ~Exception() = default; + std::string message() const; virtual const char* what() const throw(); From 0336a19eb3ce08c124815a648d6ddf94416543c8 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 22 Oct 2018 16:19:00 -0700 Subject: [PATCH 108/110] Add bug report issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..49524b176 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** + +A clear and concise description of what the bug is: + +**To Reproduce** + +Steps to reproduce the behavior: + +**Expected behavior** + +A clear and concise description of what you expected to happen: + +**Compilers & Libraries (please complete the following information):** + - Compiler & version: [e.g. GCC 4.9.3]: + - CUDA version (if applicable): + +**Additional context** + +Add any other context about the problem here. From beaf0f9068ae4da583ceb3d25b9397c37a16bc5d Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Mon, 22 Oct 2018 16:20:33 -0700 Subject: [PATCH 109/110] Add feature request issue template --- .github/ISSUE_TEMPLATE/feature_request.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..4790454fb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or information about the feature request here. From 4bc7a2ea46d8049853d84c3848b1f89103098f71 Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Wed, 24 Oct 2018 09:09:23 -0700 Subject: [PATCH 110/110] Update version number and add missing license headers --- CMakeLists.txt | 2 +- README.md | 2 +- cmake/SetupCompilerFlags.cmake | 14 ++++++++++++++ docs/sphinx/conf.py | 2 +- docs/sphinx/requirements.txt | 14 ++++++++++++++ scripts/make_release_tarball.sh | 2 +- scripts/travis/build_and_test.sh | 15 +++++++++++++++ 7 files changed, 47 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c878eca62..28d542304 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ cmake_policy(SET CMP0057 NEW) project(Umpire LANGUAGES CXX C - VERSION 0.2.3) + VERSION 0.2.4) set(ENABLE_OPENMP On CACHE Bool "") set(ENABLE_CUDA On CACHE Bool "") diff --git a/README.md b/README.md index db8ac940b..c2617f150 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Umpire Umpire v0.2.3 +# Umpire Umpire v0.2.4 [![Build Status](https://travis-ci.com/LLNL/Umpire.svg?branch=develop)](https://travis-ci.com/LLNL/Umpire) [![Documentation Status](https://readthedocs.org/projects/umpire/badge/?version=develop)](https://umpire.readthedocs.io/en/develop/?badge=develop) diff --git a/cmake/SetupCompilerFlags.cmake b/cmake/SetupCompilerFlags.cmake index d6eaacb00..5d3d2736b 100644 --- a/cmake/SetupCompilerFlags.cmake +++ b/cmake/SetupCompilerFlags.cmake @@ -1,3 +1,17 @@ +############################################################################## +# Copyright (c) 2018, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory +# +# Created by David Beckingsale, david@llnl.gov +# LLNL-CODE-747640 +# +# All rights reserved. +# +# This file is part of Umpire. +# +# For details, see https://github.com/LLNL/Umpire +# Please also see the LICENSE file for MIT license. +############################################################################## if (ENABLE_COVERAGE) message(INFO "Coverage analysis enabled") set(CMAKE_CXX_FLAGS "-coverage ${CMAKE_CXX_FLAGS}") diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py index 163a1d4af..0a98309c2 100644 --- a/docs/sphinx/conf.py +++ b/docs/sphinx/conf.py @@ -106,7 +106,7 @@ # The short X.Y version. version = u'0.2' # The full version, including alpha/beta/rc tags. -release = u'0.2.3' +release = u'0.2.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt index 714405518..ed51decc3 100644 --- a/docs/sphinx/requirements.txt +++ b/docs/sphinx/requirements.txt @@ -1,2 +1,16 @@ +############################################################################## +# Copyright (c) 2018, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory +# +# Created by David Beckingsale, david@llnl.gov +# LLNL-CODE-747640 +# +# All rights reserved. +# +# This file is part of Umpire. +# +# For details, see https://github.com/LLNL/Umpire +# Please also see the LICENSE file for MIT license. +############################################################################## breathe exhale diff --git a/scripts/make_release_tarball.sh b/scripts/make_release_tarball.sh index 3a6acb023..19f1b5427 100755 --- a/scripts/make_release_tarball.sh +++ b/scripts/make_release_tarball.sh @@ -15,7 +15,7 @@ ############################################################################## TAR_CMD=gtar -VERSION=0.2.3 +VERSION=0.2.4 git archive --prefix=umpire-${VERSION}/ -o umpire-${VERSION}.tar HEAD 2> /dev/null diff --git a/scripts/travis/build_and_test.sh b/scripts/travis/build_and_test.sh index 9b2ac8c83..1be3b835c 100755 --- a/scripts/travis/build_and_test.sh +++ b/scripts/travis/build_and_test.sh @@ -1,4 +1,19 @@ #!/bin/bash +############################################################################## +# Copyright (c) 2018, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory +# +# Created by David Beckingsale, david@llnl.gov +# LLNL-CODE-747640 +# +# All rights reserved. +# +# This file is part of Umpire. +# +# For details, see https://github.com/LLNL/Umpire +# Please also see the LICENSE file for MIT license. +############################################################################## + env function or_die () { "$@"