Loading...
Searching...
No Matches
GpuBuffer.hpp
/*
Copyright 2024 SINTEF AS
This file is part of the Open Porous Media project (OPM).
OPM 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 3 of the License, or
(at your option) any later version.
OPM 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 OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_GPUBUFFER_HEADER_HPP
#define OPM_GPUBUFFER_HEADER_HPP
#include <dune/common/fvector.hh>
#include <dune/istl/bvector.hh>
#include <exception>
#include <fmt/core.h>
#include <opm/common/ErrorMacros.hpp>
#include <opm/simulators/linalg/gpuistl/detail/safe_conversion.hpp>
#include <opm/simulators/linalg/gpuistl/GpuView.hpp>
#include <vector>
#include <string>
#include <cuda_runtime.h>
namespace Opm::gpuistl
{
template <typename T>
class GpuBuffer
{
public:
using field_type = T;
using size_type = size_t;
using value_type = T;
GpuBuffer(const GpuBuffer<T>& other);
explicit GpuBuffer(const std::vector<T>& data);
GpuBuffer() = default;
explicit GpuBuffer(const size_t numberOfElements);
GpuBuffer(const T* dataOnHost, const size_t numberOfElements);
virtual ~GpuBuffer();
T* data();
const T* data() const;
template <int BlockDimension>
void copyFromHost(const Dune::BlockVector<Dune::FieldVector<T, BlockDimension>>& bvector)
{
// TODO: [perf] vector.size() can be replaced by bvector.N() * BlockDimension
if (m_numberOfElements != bvector.size()) {
OPM_THROW(std::runtime_error,
fmt::format("Given incompatible vector size. GpuBuffer has size {}, \n"
"however, BlockVector has N() = {}, and size = {}.",
m_numberOfElements,
bvector.N(),
bvector.size()));
}
const auto dataPointer = static_cast<const T*>(&(bvector[0][0]));
copyFromHost(dataPointer, m_numberOfElements);
}
template <int BlockDimension>
void copyToHost(Dune::BlockVector<Dune::FieldVector<T, BlockDimension>>& bvector) const
{
// TODO: [perf] vector.size() can be replaced by bvector.N() * BlockDimension
if (m_numberOfElements != bvector.size()) {
OPM_THROW(std::runtime_error,
fmt::format("Given incompatible vector size. GpuBuffer has size {},\n however, the BlockVector "
"has has N() = {}, and size() = {}.",
m_numberOfElements,
bvector.N(),
bvector.size()));
}
const auto dataPointer = static_cast<T*>(&(bvector[0][0]));
copyToHost(dataPointer, m_numberOfElements);
}
void copyFromHost(const T* dataPointer, size_t numberOfElements);
void copyToHost(T* dataPointer, size_t numberOfElements) const;
void copyFromHost(const std::vector<T>& data);
void copyToHost(std::vector<T>& data) const;
size_type size() const;
void resize(size_t);
std::vector<T> asStdVector() const;
private:
T* m_dataOnDevice = nullptr;
size_t m_numberOfElements = 0;
void assertSameSize(const GpuBuffer<T>& other) const;
void assertSameSize(size_t size) const;
void assertHasElements() const;
};
template <class T>
GpuView<T> make_view(GpuBuffer<T>&);
template <class T>
GpuView<const T> make_view(const GpuBuffer<T>&);
} // namespace Opm::gpuistl
#endif
Opm::gpuistl::GpuView
The GpuView class is provides a view of some data allocated on the GPU Essenstially is only stores a ...
Definition GpuView.hpp:53