#pragma once #include "common.hpp" namespace kel { namespace lbm { namespace encode { template struct Sycl { }; } namespace impl { template struct struct_has_only_equal_dimension_array{}; } } } namespace saw { template class data, Keys>...>, kel::lbm::encode::Sycl> final { public: static constexpr data*...>; private: /** * @todo Check by static assert that the members all have the same dimensions. Alternatively * Do it here by specializing. */ StorageT members_; kel::lbm::sycl::queue* q_; public: data(): members_{}, q_{nullptr} {} data(StorageT members__, kel::lbm::sycl::queue& q__): members_{members__}, q_{&q__} {} ~data(){ SAW_ASSERT(q_){ return; } std::visit([this](auto arg){ if(not arg){ return; } sycl::free(arg,*q_); arg = nullptr; },members_); } template auto* get_ptr(){ return std::get::value(members_); } template auto& get(){ auto ptr = get_ptr(); SAW_ASSERT(ptr); return *ptr; } }; namespace kel { namespace lbm { namespace impl { template struct sycl_malloc_struct_helper; template struct sycl_malloc_struct_helper, Encode> final { template static saw::error_or allocate_on_device_member(typename data>::StorageT& storage, sycl::queue& q){ if constexpr (i < sizeof...(Members)){ using M = typename saw::parameter_pack_type::type; auto& ptr = std::get(storage); ptr = sycl::malloc_device(,q); return allocate_on_device_member(storage,q); } return saw::make_void(); } static saw::error_or allocate_on_device(data>& sycl_data, sycl::queue& q){ typename data>::StorageT storage; auto eov = allocate_on_device_member<0u>(storage,q); sycl_data = {storage, q}; return eov; } }; } class device final { private: sycl::queue q_; SAW_FORBID_COPY(device); SAW_FORBID_MOVE(device); public: device() = default; ~device() = default; template saw::error_or allocate_on_device(data>& sycl_data){ auto eov = sycl_malloc_struct_helper::allocate_on_device(sycl_data, q_); if(eov.is_error()){ return eov; } sycl_data.set_queue(q_); } }; } }