52#if defined(OpenPFC_ENABLE_CUDA)
53#include <cuda_runtime.h>
68template <
typename BackendTag,
typename T>
struct DataBuffer;
76template <
typename T>
struct DataBuffer<backend::CpuTag, T> {
78 std::vector<T> m_data;
121 T *data() {
return m_data.data(); }
127 const T *
data()
const {
return m_data.data(); }
133 size_t size()
const {
return m_data.size(); }
139 bool empty()
const {
return m_data.empty(); }
173 const std::vector<T> &
as_vector()
const {
return m_data; }
181 if (
src.size() != m_data.size()) {
182 throw std::runtime_error(
"Size mismatch in copy_from_host: expected " +
183 std::to_string(m_data.size()) +
", got " +
184 std::to_string(
src.size()));
186 std::copy(
src.begin(),
src.end(), m_data.begin());
193 std::vector<T>
to_host()
const {
return m_data; }
202#if defined(OpenPFC_ENABLE_CUDA)
209template <
typename T>
struct DataBuffer<backend::
CudaTag, T> {
211 T *m_device_ptr =
nullptr;
220 explicit DataBuffer(
size_t size) : m_size(size) {
224 throw std::runtime_error(
"CUDA allocation failed: " +
233 DataBuffer() =
default;
239 if (m_device_ptr !=
nullptr) {
240 cudaFree(m_device_ptr);
247 DataBuffer(
const DataBuffer &) =
delete;
252 DataBuffer &operator=(
const DataBuffer &) =
delete;
257 DataBuffer(DataBuffer &&other) noexcept
258 : m_device_ptr(other.m_device_ptr), m_size(other.m_size) {
259 other.m_device_ptr =
nullptr;
266 DataBuffer &operator=(DataBuffer &&other)
noexcept {
267 if (
this != &other) {
268 if (m_device_ptr !=
nullptr) {
269 cudaFree(m_device_ptr);
271 m_device_ptr = other.m_device_ptr;
273 other.m_device_ptr =
nullptr;
283 T *data() {
return m_device_ptr; }
289 const T *data()
const {
return m_device_ptr; }
295 size_t size()
const {
return m_size; }
301 bool empty()
const {
return m_size == 0; }
310 void copy_from_host(
const std::vector<T> &src) {
311 if (src.size() != m_size) {
312 throw std::runtime_error(
"Size mismatch in copy_from_host: expected " +
313 std::to_string(m_size) +
", got " +
314 std::to_string(src.size()));
317 cudaError_t err = cudaMemcpy(m_device_ptr, src.data(), m_size *
sizeof(T),
318 cudaMemcpyHostToDevice);
319 if (err != cudaSuccess) {
320 throw std::runtime_error(
"CUDA copy failed: " +
321 std::string(cudaGetErrorString(err)));
331 std::vector<T> to_host()
const {
332 std::vector<T> result(m_size);
334 cudaError_t err = cudaMemcpy(result.data(), m_device_ptr, m_size *
sizeof(T),
335 cudaMemcpyDeviceToHost);
336 if (err != cudaSuccess) {
337 throw std::runtime_error(
"CUDA copy failed: " +
338 std::string(cudaGetErrorString(err)));
349 void resize(
size_t new_size) {
350 if (m_device_ptr !=
nullptr) {
351 cudaFree(m_device_ptr);
352 m_device_ptr =
nullptr;
356 cudaError_t err = cudaMalloc(&m_device_ptr, new_size *
sizeof(T));
357 if (err != cudaSuccess) {
358 throw std::runtime_error(
"CUDA allocation failed: " +
359 std::string(cudaGetErrorString(err)));
366#if defined(OpenPFC_ENABLE_HIP)
373template <
typename T>
struct DataBuffer<backend::HipTag, T> {
375 T *m_device_ptr =
nullptr;
384 explicit DataBuffer(
size_t size) : m_size(size) {
386 hipError_t err = hipMalloc(&m_device_ptr, size *
sizeof(T));
387 if (err != hipSuccess) {
388 throw std::runtime_error(
"HIP allocation failed: " +
389 std::string(hipGetErrorString(err)));
397 DataBuffer() =
default;
403 if (m_device_ptr !=
nullptr) {
404 hipFree(m_device_ptr);
411 DataBuffer(
const DataBuffer &) =
delete;
416 DataBuffer &operator=(
const DataBuffer &) =
delete;
421 DataBuffer(DataBuffer &&other) noexcept
422 : m_device_ptr(other.m_device_ptr), m_size(other.m_size) {
423 other.m_device_ptr =
nullptr;
430 DataBuffer &operator=(DataBuffer &&other)
noexcept {
431 if (
this != &other) {
432 if (m_device_ptr !=
nullptr) {
433 hipFree(m_device_ptr);
435 m_device_ptr = other.m_device_ptr;
436 m_size = other.m_size;
437 other.m_device_ptr =
nullptr;
447 T *data() {
return m_device_ptr; }
453 const T *data()
const {
return m_device_ptr; }
459 size_t size()
const {
return m_size; }
465 bool empty()
const {
return m_size == 0; }
474 void copy_from_host(
const std::vector<T> &src) {
475 if (src.size() != m_size) {
476 throw std::runtime_error(
"Size mismatch in copy_from_host: expected " +
477 std::to_string(m_size) +
", got " +
478 std::to_string(src.size()));
481 hipError_t err = hipMemcpy(m_device_ptr, src.data(), m_size *
sizeof(T),
482 hipMemcpyHostToDevice);
483 if (err != hipSuccess) {
484 throw std::runtime_error(
"HIP copy failed: " +
485 std::string(hipGetErrorString(err)));
495 std::vector<T> to_host()
const {
496 std::vector<T> result(m_size);
498 hipError_t err = hipMemcpy(result.data(), m_device_ptr, m_size *
sizeof(T),
499 hipMemcpyDeviceToHost);
500 if (err != hipSuccess) {
501 throw std::runtime_error(
"HIP copy failed: " +
502 std::string(hipGetErrorString(err)));
513 void resize(
size_t new_size) {
514 if (m_device_ptr !=
nullptr) {
515 hipFree(m_device_ptr);
516 m_device_ptr =
nullptr;
520 hipError_t err = hipMalloc(&m_device_ptr, new_size *
sizeof(T));
521 if (err != hipSuccess) {
522 throw std::runtime_error(
"HIP allocation failed: " +
523 std::string(hipGetErrorString(err)));
DataBuffer(size_t size)
Constructs a CPU buffer with the given size.
Definition databuffer.hpp:85
DataBuffer & operator=(const DataBuffer &)=default
Copy assignment.
DataBuffer(const DataBuffer &)=default
Copy constructor.
void resize(size_t new_size)
Resize the buffer.
Definition databuffer.hpp:199
DataBuffer(DataBuffer &&) noexcept=default
Move constructor.
DataBuffer()=default
Default constructor (empty buffer)
std::vector< T > to_host() const
Copy data to host vector.
Definition databuffer.hpp:193
bool empty() const
Returns true if buffer is empty.
Definition databuffer.hpp:139
void copy_from_host(const std::vector< T > &src)
Copy data from host vector.
Definition databuffer.hpp:180
const T & operator[](size_t i) const
Const element access operator (CPU only)
Definition databuffer.hpp:153
size_t size() const
Returns the number of elements.
Definition databuffer.hpp:133
const std::vector< T > & as_vector() const
Get underlying std::vector const reference (for Model compatibility)
Definition databuffer.hpp:173
T & operator[](size_t i)
Element access operator (CPU only)
Definition databuffer.hpp:146
std::vector< T > & as_vector()
Get underlying std::vector reference (for Model compatibility)
Definition databuffer.hpp:167
const T * data() const
Returns const pointer to underlying data.
Definition databuffer.hpp:127
Backend-agnostic memory buffer.
Definition databuffer.hpp:68
Represents the global simulation domain (the "world").
Definition world.hpp:91
const Int3 m_size
Grid dimensions: {nx, ny, nz}.
Definition world.hpp:94