Skip to content

Commit

Permalink
Merge pull request ComputationalRadiationPhysics#1094 from Flamefire/…
Browse files Browse the repository at this point in the history
…BufferCTOR

[WIP] cuSTL Host/DeviceBuffers: Contructors (Pointers)
  • Loading branch information
Heiko Burau committed Jan 12, 2016
2 parents 645a83c + ac7f373 commit c17cbf9
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 53 deletions.
8 changes: 5 additions & 3 deletions src/libPMacc/include/cuSTL/container/CartBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ class CartBuffer : public
BOOST_STATIC_CONSTEXPR int dim = T_dim;
typedef cursor::BufferCursor<Type, T_dim> Cursor;
typedef typename Allocator::tag memoryTag;
typedef math::Size_t<T_dim> SizeType;
typedef math::Size_t<T_dim-1> PitchType;
public:
Type* dataPointer;
int* refCount;
math::Size_t<T_dim> _size;
math::Size_t<T_dim-1> pitch;
SizeType _size;
PitchType pitch;
HDINLINE void init();
HDINLINE void exit();
HDINLINE CartBuffer() : refCount(NULL) {}
Expand All @@ -93,7 +95,7 @@ class CartBuffer : public
HDINLINE CartBuffer(size_t x, size_t y, size_t z);
/* the copy constructor just increments the reference counter but does not copy memory */
HDINLINE CartBuffer(const CartBuffer& other);
/* the move constructor has currently the same behavior as the copy constructor */
/* the move constructor */
HDINLINE CartBuffer(BOOST_RV_REF(CartBuffer) other);
HDINLINE ~CartBuffer();

Expand Down
56 changes: 43 additions & 13 deletions src/libPMacc/include/cuSTL/container/DeviceBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,52 +43,82 @@ namespace container
/** typedef version of a CartBuffer for a GPU.
* Additional feature: Able to copy data from a HostBuffer
* \tparam Type type of a single datum
* \tparam dim Dimension of the container
* \tparam T_dim Dimension of the container
*/
template<typename Type, int dim>
template<typename Type, int T_dim>
class DeviceBuffer
: public CartBuffer<Type, dim, allocator::DeviceMemAllocator<Type, dim>,
copier::D2DCopier<dim>,
: public CartBuffer<Type, T_dim, allocator::DeviceMemAllocator<Type, T_dim>,
copier::D2DCopier<T_dim>,
assigner::DeviceMemAssigner<> >
{
private:
typedef CartBuffer<Type, dim, allocator::DeviceMemAllocator<Type, dim>,
copier::D2DCopier<dim>,
typedef CartBuffer<Type, T_dim, allocator::DeviceMemAllocator<Type, T_dim>,
copier::D2DCopier<T_dim>,
assigner::DeviceMemAssigner<> > Base;
typedef DeviceBuffer<Type, dim> This;

///\todo: make protected
public:
protected:
HDINLINE DeviceBuffer() {}

BOOST_COPYABLE_AND_MOVABLE(This)
BOOST_COPYABLE_AND_MOVABLE(DeviceBuffer)
public:
typedef typename Base::PitchType PitchType;

/* constructors
*
* \param _size size of the container
*
* \param x,y,z convenient wrapper
*
*/
HDINLINE DeviceBuffer(const math::Size_t<dim>& _size) : Base(_size) {}
HDINLINE DeviceBuffer(const math::Size_t<T_dim>& size) : Base(size) {}
HDINLINE DeviceBuffer(size_t x) : Base(x) {}
HDINLINE DeviceBuffer(size_t x, size_t y) : Base(x, y) {}
HDINLINE DeviceBuffer(size_t x, size_t y, size_t z) : Base(x, y, z) {}
HDINLINE DeviceBuffer(const Base& base) : Base(base) {}
/**
* Creates a device buffer from a pointer with a size. Assumes dense layout (no padding)
*
* @param ptr Pointer to the first element
* @param size Size of the buffer
* @param ownMemory Set to false if the memory is only a reference and managed outside of this class
* Ignored for device side creation!y
* @param pitch Pitch in bytes (number of bytes in the lower dimensions)
*/
HDINLINE DeviceBuffer(Type* ptr, const math::Size_t<T_dim>& size, bool ownMemory, PitchType pitch = PitchType::create(0))
{
this->dataPointer = ptr;
this->_size = size;
if(T_dim >= 2)
this->pitch[0] = (pitch[0]) ? pitch[0] : size.x() * sizeof(Type);
if(T_dim == 3)
this->pitch[1] = (pitch[1]) ? pitch[1] : this->pitch[0] * size.y();
#ifndef __CUDA_ARCH__
this->refCount = new int;
*this->refCount = (ownMemory) ? 1 : 2;
#endif
}
HDINLINE DeviceBuffer(BOOST_RV_REF(DeviceBuffer) obj): Base(boost::move(static_cast<Base&>(obj))) {}

HDINLINE DeviceBuffer&
operator=(BOOST_RV_REF(DeviceBuffer) rhs)
{
Base::operator=(boost::move(static_cast<Base&>(rhs)));
return *this;
}

template<typename HBuffer>
HINLINE
DeviceBuffer& operator=(const HBuffer& rhs)
{
BOOST_STATIC_ASSERT((boost::is_same<typename HBuffer::memoryTag, allocator::tag::host>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename HBuffer::type, Type>::value));
BOOST_STATIC_ASSERT(dim == HBuffer::dim);
BOOST_STATIC_ASSERT(T_dim == HBuffer::dim);
if(rhs.size() != this->size())
throw std::invalid_argument(static_cast<std::stringstream&>(
std::stringstream() << "Assignment: Sizes of buffers do not match: "
<< this->size() << " <-> " << rhs.size() << std::endl).str());

cudaWrapper::Memcopy<dim>()(this->dataPointer, this->pitch, rhs.getDataPointer(), rhs.getPitch(),
cudaWrapper::Memcopy<T_dim>()(this->dataPointer, this->pitch, rhs.getDataPointer(), rhs.getPitch(),
this->_size, cudaWrapper::flags::Memcopy::hostToDevice);

return *this;
Expand Down
60 changes: 45 additions & 15 deletions src/libPMacc/include/cuSTL/container/HostBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,47 +41,77 @@ namespace container
/** typedef version of a CartBuffer for a CPU.
* Additional feature: Able to copy data from a DeviceBuffer
* \tparam Type type of a single datum
* \tparam dim Dimension of the container
* \tparam T_dim Dimension of the container
*/
template<typename Type, int dim>
template<typename Type, int T_dim>
class HostBuffer
: public CartBuffer<Type, dim, allocator::HostMemAllocator<Type, dim>,
copier::H2HCopier<dim>,
: public CartBuffer<Type, T_dim, allocator::HostMemAllocator<Type, T_dim>,
copier::H2HCopier<T_dim>,
assigner::HostMemAssigner<> >
{
private:
typedef CartBuffer<Type, dim, allocator::HostMemAllocator<Type, dim>,
copier::H2HCopier<dim>,
typedef CartBuffer<Type, T_dim, allocator::HostMemAllocator<Type, T_dim>,
copier::H2HCopier<T_dim>,
assigner::HostMemAssigner<> > Base;
///\todo: make protected
public:
/* makes this class able to emulate a r-value reference */
BOOST_COPYABLE_AND_MOVABLE(HostBuffer)
protected:
HostBuffer() {}
public:
typedef typename Base::PitchType PitchType;

/* constructors
*
* \param _size size of the container
*
* \param x,y,z convenient wrapper
*
*/
HostBuffer(const math::Size_t<dim>& _size) : Base(_size) {}
HostBuffer(size_t x) : Base(x) {}
HostBuffer(size_t x, size_t y) : Base(x, y) {}
HostBuffer(size_t x, size_t y, size_t z) : Base(x, y, z) {}
HostBuffer(const Base& base) : Base(base) {}
HINLINE HostBuffer(const math::Size_t<T_dim>& size) : Base(size) {}
HINLINE HostBuffer(size_t x) : Base(x) {}
HINLINE HostBuffer(size_t x, size_t y) : Base(x, y) {}
HINLINE HostBuffer(size_t x, size_t y, size_t z) : Base(x, y, z) {}
/**
* Creates a host buffer from a pointer with a size. Assumes dense layout (no padding)
*
* @param ptr Pointer to the first element
* @param size Size of the buffer
* @param ownMemory Set to false if the memory is only a reference and managed outside of this class
* @param pitch Pitch in bytes (number of bytes in the lower dimensions)
*/
HINLINE HostBuffer(Type* ptr, const math::Size_t<T_dim>& size, bool ownMemory, PitchType pitch = PitchType::create(0))
{
this->dataPointer = ptr;
this->_size = size;
if(T_dim >= 2)
this->pitch[0] = (pitch[0]) ? pitch[0] : size.x() * sizeof(Type);
if(T_dim == 3)
this->pitch[1] = (pitch[1]) ? pitch[1] : this->pitch[0] * size.y();
this->refCount = new int;
*this->refCount = (ownMemory) ? 1 : 2;
}
HINLINE HostBuffer(const Base& base) : Base(base) {}
HINLINE HostBuffer(BOOST_RV_REF(HostBuffer) obj): Base(boost::move(static_cast<Base&>(obj))) {}

HINLINE HostBuffer&
operator=(BOOST_RV_REF(HostBuffer) rhs)
{
Base::operator=(boost::move(static_cast<Base&>(rhs)));
return *this;
}

template<typename DBuffer>
HostBuffer& operator=(const DBuffer& rhs)
{
BOOST_STATIC_ASSERT((boost::is_same<typename DBuffer::memoryTag, allocator::tag::device>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename DBuffer::type, Type>::value));
BOOST_STATIC_ASSERT(DBuffer::dim == dim);
BOOST_STATIC_ASSERT(DBuffer::dim == T_dim);
if(rhs.size() != this->size())
throw std::invalid_argument(static_cast<std::stringstream&>(
std::stringstream() << "Assignment: Sizes of buffers do not match: "
<< this->size() << " <-> " << rhs.size() << std::endl).str());

cudaWrapper::Memcopy<dim>()(this->dataPointer, this->pitch, rhs.getDataPointer(), rhs.getPitch(),
cudaWrapper::Memcopy<T_dim>()(this->dataPointer, this->pitch, rhs.getDataPointer(), rhs.getPitch(),
this->_size, cudaWrapper::flags::Memcopy::deviceToHost);

return *this;
Expand Down
22 changes: 8 additions & 14 deletions src/libPMacc/include/memory/buffers/DeviceBuffer.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Copyright 2013-2016 Heiko Burau, Rene Widera, Benjamin Worpitz
* Alexander Grund
*
* This file is part of libPMacc.
*
Expand Down Expand Up @@ -77,31 +78,24 @@ namespace PMacc
};


#define COMMA ,

HINLINE
container::CartBuffer<TYPE, DIM, allocator::DeviceMemAllocator<TYPE, DIM>,
copier::D2DCopier<DIM>,
assigner::DeviceMemAssigner<> >
cartBuffer() const
{
container::DeviceBuffer<TYPE, DIM> result;
cudaPitchedPtr cudaData = this->getCudaPitched();
result.dataPointer = (TYPE*)cudaData.ptr;
result._size = (math::Size_t<DIM>)this->getDataSpace();
if(DIM == 2) result.pitch[0] = cudaData.pitch;
if(DIM == 3)
math::Size_t<DIM - 1> pitch;
if(DIM >= 2)
{
result.pitch[0] = cudaData.pitch;
result.pitch[1] = cudaData.pitch * this->getPhysicalMemorySize()[1];
assert(this->getPhysicalMemorySize()[0] == cudaData.pitch);
pitch[0] = this->getPhysicalMemorySize()[0];
}
#ifndef __CUDA_ARCH__
result.refCount = new int;
#endif
*result.refCount = 2;
if(DIM == 3)
pitch[1] = pitch[0] * this->getPhysicalMemorySize()[1];
container::DeviceBuffer<TYPE, DIM> result((TYPE*)cudaData.ptr, this->getDataSpace(), false, pitch);
return result;
}
#undef COMMA


/**
Expand Down
13 changes: 5 additions & 8 deletions src/libPMacc/include/memory/buffers/HostBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,12 @@ namespace PMacc
container::HostBuffer<TYPE, DIM>
cartBuffer()
{
container::HostBuffer<TYPE, DIM> result;
result.dataPointer = this->getBasePointer();
result._size = math::Size_t<DIM>(this->getDataSpace());
math::Size_t<DIM - 1> pitch;
if(DIM >= 2)
result.pitch[0] = result._size.x() * sizeof(TYPE);
if(DIM >= 3)
result.pitch[1] = result.pitch[0] * result._size.y();
result.refCount = new int;
*result.refCount = 2;
pitch[0] = this->getPhysicalMemorySize()[0];
if(DIM == 3)
pitch[1] = pitch[0] * this->getPhysicalMemorySize()[1];
container::HostBuffer<TYPE, DIM> result(this->getBasePointer(), this->getDataSpace(), false, pitch);
return result;
}

Expand Down

0 comments on commit c17cbf9

Please sign in to comment.