/* Copyright (C) 2012 fmaj7b5.info This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef FM7b5_DEVICE_MEMORY_CUH #define FM7b5_DEVICE_MEMORY_CUH #include #include #include #include #include "MDView.cuh" namespace FM7b5 { namespace memory { //! Linear 1-D memory template class Linear { public: typedef T value_type; typedef typename std::add_pointer::type pointer_type; typedef typename std::add_const::type const_pointer_type; typedef typename std::add_reference::type reference_type; Linear(const size_t count = 0) : m_count(count) { m_extent = sizeof(value_type); md_data = static_cast(allocate(m_extent * count)); } ~Linear() { deallocate(md_data); } void* allocate(const size_t byte) { void* p(nullptr); cudaError_t status; status = cudaMalloc(&p, byte); if (status != cudaSuccess) { throw std::bad_alloc(cudaGetErrorString(status)); } return p; } void deallocate(void* p) { cudaFree(p); } void copy_from(const void* const src, const size_t byte) { cudaMemcpy(md_data, src, byte, cudaMemcpyHostToDevice); } void copy_to(void* const dst, const size_t byte) { cudaMemcpy(dst, md_data, byte, cudaMemcpyDeviceToHost); } size_t size() const { return m_extent * m_count; } size_t count() const { return m_count; } pointer_type data() const { return md_data; } MDView ref() const { return MDView(md_data, &m_extent); } protected: size_t m_extent; size_t m_count; pointer_type md_data; }; //! Linear 2-D memory template class LinearPitch { public: typedef T value_type; typedef typename std::add_pointer::type pointer_type; typedef typename std::add_const::type const_pointer_type; typedef typename std::add_reference::type reference_type; LinearPitch(const size_t width, const size_t height) : m_width(width), m_height(height) { md_data = static_cast(allocate(width, height, &m_extent[0])); m_extent[1] = sizeof(value_type); } ~LinearPitch() { deallocate(md_data); } void* allocate(const size_t width, const size_t height, size_t* pitch) { void* p(nullptr); cudaError_t status; status = cudaMallocPitch(&p, pitch, sizeof(value_type) * width, height); if (status != cudaSuccess) { throw std::bad_alloc(cudaGetErrorString(status)); } return p; } void deallocate(void* p) { cudaFree(p); } void copy_from(const void* const src, const size_t width, const size_t height, size_t spitch = 0) { if (spitch < 1) { spitch = width; } cudaMemcpy2D(md_data, pitch(), src, spitch, width, height, cudaMemcpyHostToDevice); } void copy_to(void* const dst, const size_t width, const size_t height, size_t dpitch = 0) { if (dpitch < 1) { dpitch = width; } cudaMemcpy2D(dst, dpitch, md_data, pitch(), width, height, cudaMemcpyDeviceToHost); } size_t size() const { return m_extent[1] * m_height; } size_t width() const { return m_width; } size_t height() const { return m_height; } size_t pitch() const { return m_extent[0]; } pointer_type data() const { return md_data; } MDView ref() const { return MDView(md_data, m_extent); } protected: size_t m_width; size_t m_height; size_t m_extent[2]; pointer_type md_data; }; } } #endif /* FM7b5_DEVICE_MEMORY_CUH */