diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e4b45b541a4f6d14a18cd315c0ce4f6eb7a4cea0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.19) + +option(INCLUDE_CUDA "GPU build in mode" OFF) + +project(memory-holder-test) + +enable_language(CXX) +set(CMAKE_CXX_STANDARD 11) + +if(INCLUDE_CUDA) + if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + message(FATAL_ERROR " + CMake will not pass any architecture flags to the compiler + because the CUDA architecture is not set. You should specify + an architecture: set -DCMAKE_CUDA_ARCHITECTURES=<N>.") + endif(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + + enable_language(CUDA) + include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) + add_definitions(-DINCLUDE_CUDA) +endif(INCLUDE_CUDA) + +add_subdirectory(Lib) + +set(SOURCES + main.cpp +) + +add_executable(test ${SOURCES}) +target_include_directories(test PUBLIC ${memory_processing_SOURCE_DIR}/include ./Lib/) +target_link_libraries(test memproc memory-holder) \ No newline at end of file diff --git a/Lib/CMakeLists.txt b/Lib/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a7d9b42b0ca6b72f864b50a6cf8df14a20cabd6d --- /dev/null +++ b/Lib/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.19) + +option(INCLUDE_CUDA "GPU build in mode" OFF) + +project(memory-holder) + +enable_language(CXX) +set(CMAKE_CXX_STANDARD 11) + +include(FetchContent) +FetchContent_Declare( + memory_processing + GIT_REPOSITORY http://tesla.parallel.ru/Lizzzka007/memory_processing.git + GIT_TAG main +) +FetchContent_MakeAvailable(memory_processing) +FetchContent_GetProperties(memory_processing) + +if(INCLUDE_CUDA) + if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + message(FATAL_ERROR " + CMake will not pass any architecture flags to the compiler + because the CUDA architecture is not set. You should specify + an architecture: set -DCMAKE_CUDA_ARCHITECTURES=<N>.") + endif(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + + enable_language(CUDA) + include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) + add_definitions(-DINCLUDE_CUDA) +endif(INCLUDE_CUDA) + +set(SOURCES + memory-holder.cpp +) + +set(HEADER + memory-holder.h +) + +add_library(memory-holder ${SOURCES} ${HEADER}) +target_include_directories(memory-holder PUBLIC ${memory_processing_SOURCE_DIR}/include) +target_link_libraries(memory-holder memproc) \ No newline at end of file diff --git a/Lib/memory-holder.cpp b/Lib/memory-holder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef12ee1d2ac30bcab8c0c34a01b220f4bb231b69 --- /dev/null +++ b/Lib/memory-holder.cpp @@ -0,0 +1,204 @@ +#include "memory-holder.h" +#include "MemoryProcessing.h" +#ifdef INCLUDE_CUDA +#include "MemoryProcessing.cuh" +#endif + +#include <algorithm> + +template< MemType mem > +buffer<mem>::buffer() +{ + ptr = nullptr; + allocated_size = 0; + scalar_size = 0; + is_free = true; + id = -1; +} + +template< MemType mem > +buffer<mem>::~buffer() +{ + memproc::dealloc<mem>((void *&)ptr, allocated_size); +} + +template< MemType mem > +bool buffer<mem>::is_available() const +{ + return is_free; +} + +template< MemType mem > +void buffer<mem>::reallocate(const size_t required_size) +{ + memproc::realloc<mem>((void *&)ptr, allocated_size, required_size); +} + +template< MemType mem > +buffer<mem>::buffer(const size_t required_size) +{ + reallocate(required_size); + scalar_size = 0; + is_free = false; +} + +template< MemType mem > +bool size_comparator(const buffer<mem>& obj, const size_t required_size) +{ + if(obj.get_status() == false) + return false; + + return obj.get_size() <= required_size; +} + +template bool size_comparator(const buffer<MemType::CPU>& obj, const size_t required_size); +template bool size_comparator(const buffer<MemType::GPU>& obj, const size_t required_size); + +template< MemType mem > +void* buffer<mem>::get_ptr() const +{ + return ptr; +} + +template< MemType mem > +bool buffer<mem>::get_status() const +{ + return is_free; +} + +template< MemType mem > +size_t buffer<mem>::get_size() const +{ + return allocated_size; +} + +template< MemType mem > +buffer<mem>& buffer<mem>::operator=(buffer<mem>& other) +{ + if (this == &other) + return *this; + + std::swap(ptr, other.ptr); + std::swap(allocated_size, other.allocated_size); // exchange resources between *this and other + std::swap(scalar_size, other.scalar_size); + std::swap(is_free, other.is_free); + std::swap(id, other.id); + return *this; +} + +template< MemType mem > +void buffer<mem>::set_status(const bool status) +{ + is_free = status; +} + +template< MemType mem > +void buffer<mem>::set_id(const int idx) +{ + id = idx; +} + +template class buffer<MemType::CPU>; +template class buffer<MemType::GPU>; + +memory_pipline::memory_pipline() +{ + gpu_buff = std::vector<buffer<MemType::GPU> > (); + cpu_buff = std::vector<buffer<MemType::CPU> > (); +} + +memory_pipline::~memory_pipline() +{ + gpu_buff.clear(); + cpu_buff.clear(); +} + +template< MemType mem > +std::vector<buffer<mem> >& memory_pipline::get_memtyped_vector() +{ + return cpu_buff; +} + +template<> +std::vector<buffer<MemType::GPU> >& memory_pipline::get_memtyped_vector() +{ + return gpu_buff; +} + +// template std::vector<buffer<MemType::CPU> >& memory_pipline::get_memtyped_vector(); +// template std::vector<buffer<MemType::GPU> >& memory_pipline::get_memtyped_vector(); + +template< MemType mem > +int memory_pipline::get_buffer(const size_t required_size, void * ptr) +{ + typename std::vector<buffer<mem>>::iterator available_buf_it; + available_buf_it = std::lower_bound (get_memtyped_vector<mem>().begin(), get_memtyped_vector<mem>().end(), required_size, size_comparator<mem>); + if(available_buf_it != get_memtyped_vector<mem>().end()) + { + ptr = available_buf_it->get_ptr(); + int id = std::distance(get_memtyped_vector<mem>().begin(), available_buf_it); + return id; + } + else + { + get_memtyped_vector<mem>().push_back(buffer<mem>(required_size)); + ptr = get_memtyped_vector<mem>().back().get_ptr(); + int id = get_memtyped_vector<mem>().size() - 1; + return id; + } +} + +template int memory_pipline::get_buffer<MemType::CPU>(const size_t required_size, void * ptr); +template int memory_pipline::get_buffer<MemType::GPU>(const size_t required_size, void * ptr); + +template< MemType mem > +void memory_pipline::set_available(const int id) +{ + get_memtyped_vector<mem>()[id].set_status(true); +} + +template void memory_pipline::set_available<MemType::CPU>(const int id); +template void memory_pipline::set_available<MemType::GPU>(const int id); + +memory_faucet::memory_faucet(){} + +memory_pipline* memory_faucet::get_faucet() +{ + if(mem_pipe == nullptr) + { + mem_pipe = new memory_pipline(); + } + return mem_pipe; +} + +memory_pipline* memory_faucet::mem_pipe = nullptr; + +template< MemType mem > +memBuf<mem>::memBuf(const size_t required_size) +{ + memory_pipline* mem_pipe = memory_faucet::get_faucet(); + id = mem_pipe->get_buffer<mem>(required_size, buf); + size = required_size; +} + +template< MemType mem > +memBuf<mem>::~memBuf() +{ + memory_pipline* mem_pipe = memory_faucet::get_faucet(); + mem_pipe->set_available<mem>(id); +} + +template< MemType mem > +void* memBuf<mem>::ptr() +{ + return buf; +} + +template< MemType mem > +int memBuf<mem>::get_size() +{ + return size; +} + +template class memBuf<MemType::CPU>; +template class memBuf<MemType::GPU>; \ No newline at end of file diff --git a/Lib/memory-holder.h b/Lib/memory-holder.h new file mode 100644 index 0000000000000000000000000000000000000000..0e1dd457c8e9b0b5e41aef59410c39aeaa2c60a1 --- /dev/null +++ b/Lib/memory-holder.h @@ -0,0 +1,83 @@ +#pragma once +#include <cstdlib> +#include <vector> +#include "TemplateParameters.h" + +enum class buf_choose_policy +{ + naiv, + sorted_vec, + unsorted_vec +}; + +template< MemType mem > +class buffer +{ +private: + void *ptr; + size_t allocated_size; + size_t scalar_size; + bool is_free; + int id; + +public: + buffer(); + ~buffer(); + buffer(const size_t required_size); + + bool is_available() const; + void* get_ptr() const; + bool get_status() const; + size_t get_size() const; + buffer<mem>& operator=(buffer<mem>& other); + void reallocate(const size_t required_size); + void set_status(const bool status); + void set_id(const int id); +}; + +class memory_pipline +{ +private: + std::vector<buffer<MemType::GPU> > gpu_buff; + std::vector<buffer<MemType::CPU> > cpu_buff; +public: + memory_pipline(); + ~memory_pipline(); + + template< MemType mem > + int get_buffer(const size_t required_size, void * ptr); + + template< MemType mem > + std::vector<buffer<mem> >& get_memtyped_vector(); + + template< MemType mem > + void set_available(const int id); +}; + +class memory_faucet +{ +private: + memory_faucet(); + memory_faucet(const memory_faucet&) = delete; + memory_faucet& operator=(const memory_faucet&) = delete; + + static memory_pipline* mem_pipe; + +public: + static memory_pipline* get_faucet(); +}; + +template< MemType mem > +class memBuf +{ +private: + void* buf; + int id; + size_t size; + +public: + memBuf(const size_t required_size); + ~memBuf(); + void* ptr(); + int get_size(); +}; \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f87bbb2fe8c09ea464c09e12470e9b41079b3f1d --- /dev/null +++ b/main.cpp @@ -0,0 +1,7 @@ +#include "memory-holder.h" + +int main(void) +{ + const size_t required_size = sizeof(float) * 100; + memBuf<MemType::CPU> Buf(required_size); +} \ No newline at end of file