From b0330a36f72a6073f99a4e315a906fc3c2232e87 Mon Sep 17 00:00:00 2001 From: Russell Standish Date: Sat, 7 Dec 2024 09:29:55 +1100 Subject: [PATCH] WIP for getting model components in the right memory space. Still have an issue with Ouroboros-SYCL not being able to allocate more than 16 bytes at a time. --- classdesc | 2 +- graphcode | 2 +- include/ecolab.h | 110 ++++++++++++++++++++++------------------- models/ecolab_model.cc | 14 ++++-- models/ecolab_model.h | 6 +-- 5 files changed, 74 insertions(+), 60 deletions(-) diff --git a/classdesc b/classdesc index 392d56c..c2be4af 160000 --- a/classdesc +++ b/classdesc @@ -1 +1 @@ -Subproject commit 392d56c6e560c9d5ed49287701edb1a100b75687 +Subproject commit c2be4afd64d9652ac76b67dd33be383085b79203 diff --git a/graphcode b/graphcode index 33a2f47..db52ce5 160000 --- a/graphcode +++ b/graphcode @@ -1 +1 @@ -Subproject commit 33a2f47f38981960401756b92929b619760ee99f +Subproject commit db52ce5a8ee572ec964b876021821ba01a4861a5 diff --git a/include/ecolab.h b/include/ecolab.h index fffbb1e..8412a50 100644 --- a/include/ecolab.h +++ b/include/ecolab.h @@ -133,36 +133,40 @@ namespace ecolab using MemAllocator=Ouro::MultiOuroPQ; MemAllocator* memAlloc=nullptr; const sycl::stream* out=nullptr; - template class Allocator + template class CellAllocator { public: Ouro::SyclDesc<1>*const* desc=nullptr; MemAllocator*const* memAlloc; + const sycl::stream* out=nullptr; template friend class Allocator; - Allocator()=default; - Allocator(Ouro::SyclDesc<1>* const& desc, MemAllocator*const& memAlloc): - desc(&desc), memAlloc(&memAlloc) { + CellAllocator()=default; + CellAllocator(Ouro::SyclDesc<1>* const& desc, MemAllocator*const& memAlloc, const sycl::stream* out): + desc(&desc), memAlloc(&memAlloc), out(out) { } - template Allocator(const Allocator& x): + template CellAllocator(const CellAllocator& x): desc(x.desc) {} T* allocate(size_t sz) { - if (memAlloc && *memAlloc && desc && *desc) - return reinterpret_cast((*memAlloc)->malloc(**desc,sz*sizeof(T))); - else - return nullptr; // TODO raise an error?? + if (memAlloc && *memAlloc && desc && *desc) { + auto r=reinterpret_cast((*memAlloc)->malloc(**desc,sz*sizeof(T))); + if (out) (*out)<<"allocated "<free(**desc,p); } - bool operator==(const Allocator& x) const {return desc==x.desc && memAlloc==x.memAlloc;} + bool operator==(const CellAllocator& x) const {return desc==x.desc && memAlloc==x.memAlloc;} }; - template Allocator allocator() const { - return Allocator(desc,memAlloc); + template CellAllocator allocator() const { + return CellAllocator(desc,memAlloc,out); } #else - template using Allocator=std::allocator; - template Allocator allocator() const {return Allocator();} + template using CellAllocator=std::allocator; + template CellAllocator allocator() const {return CellAllocator();} #endif }; @@ -187,31 +191,15 @@ namespace ecolab #endif }; - // This class exists, because we need a default constructor, and - // usm_allocator needs to be initialised with a device context -#ifdef SYCL_LANGUAGE_VERSION - template - struct CellAllocator: public sycl::usm_allocator - { - CellAllocator(): sycl::usm_allocator(syclQ()) {} - template constexpr CellAllocator(const CellAllocator& x) noexcept: - sycl::usm_allocator(x) {} - template struct rebind {using other=CellAllocator;}; - }; -#else - template struct CellAllocator: std::allocator - { - CellAllocator()=default; - template constexpr CellAllocator(const CellAllocator& x) noexcept: - std::allocator(x) {} - template struct rebind {using other=CellAllocator;}; - }; -#endif - - template struct EcolabGraph: - public Exclude, public graphcode::Graph + public Exclude, public graphcode::Graph { +#ifdef SYCL_LANGUAGE_VERSION + EcolabGraph(): graphcode::Graph + (graphcode::Allocator(syclQ(),sycl::usm::alloc::shared), + graphcode::Allocator(syclQ(),sycl::usm::alloc::shared), + graphcode::Allocator>(syclQ(),sycl::usm::alloc::shared)) {} +#endif /// apply a functional to all local cells of this processor in parallel /// @param f template @@ -227,6 +215,7 @@ namespace ecolab h.parallel_for(sycl::nd_range<1>(range*workGroupSize, workGroupSize), [=,this](auto i) { auto idx=i.get_global_linear_id(); if (idxsize()) { + out<<"idx="<get()<<" as "<<(*this)[idx]->template as()<template as(); Ouro::SyclDesc<> desc(i,{}); cell.desc=&desc; @@ -251,15 +240,37 @@ namespace ecolab namespace classdesc { - template struct is_smart_ptr>: public true_type {}; + template struct is_smart_ptr>: public true_type {}; + template struct is_char: public false_type {}; + template <> struct is_char: public true_type {}; + template <> struct is_char: public true_type {}; + +#ifdef SYCL_LANGUAGE_VERSION + /// classdesc support for stringifying usm_alloc + namespace { + template <> EnumKey enum_keysData< ::sycl::usm::alloc >::keysData[]= + { + {"host",int(::sycl::usm::alloc::host)}, + {"device",int(::sycl::usm::alloc::device)}, + {"shared",int(::sycl::usm::alloc::shared)}, + {"unknown",int(::sycl::usm::alloc::unknown)} + }; + template <> EnumKeys< ::sycl::usm::alloc > enum_keysData< ::sycl::usm::alloc >::keys(enum_keysData< ::sycl::usm::alloc >::keysData,sizeof(enum_keysData< ::sycl::usm::alloc >::keysData)/sizeof(enum_keysData< ::sycl::usm::alloc >::keysData[0])); + template <> int enumKey< ::sycl::usm::alloc >(const std::string& x){return int(enum_keysData< ::sycl::usm::alloc >::keys(x));} + template <> std::string enumKey< ::sycl::usm::alloc >(int x){return enum_keysData< ::sycl::usm::alloc >::keys(x);} + } +#endif + } -namespace classdesc_access +namespace std { template - struct access_pack>: public classdesc::NullDescriptor {}; - template - struct access_unpack>: public classdesc::NullDescriptor {}; + typename classdesc::enable_if< + classdesc::Not::type>>, + std::ostream&>::T + operator<<(std::ostream& o, T* p) + {return o<neighbours.push_back(makeId(i,j-1)); o->neighbours.push_back(makeId(i,j+1)); } + rebuildPtrLists(); } void SpatialModel::generate(unsigned niter) @@ -552,12 +553,19 @@ void SpatialModel::makeConsistent() forAll([=,this](EcolabCell& c) { if (nsp>c.density.size()) { - array> tmp(nsp,0,c.allocator()); + array> tmp(nsp,0,c.allocator()); asg_v(tmp.data(),c.density.size(),c.density); + //(*c.out)<<"tmp.size:"<as()->density.size()<as(); + //cout< struct EcolabPoint: public Exclude { Float salt; /* random no. used for migration */ - array> density{this->template allocator()}; + array> density{this->template allocator()}; void generate(unsigned niter, const ModelData&); void condense(const array& mask, size_t mask_true); array mutate(const array&); @@ -82,8 +82,8 @@ struct EcolabPoint: public Exclude // for the panmictic model, we need to use std::allocator struct AllocatorBase { - template using Allocator=std::allocator; - template Allocator allocator() const {return Allocator();} + template using CellAllocator=std::allocator; + template CellAllocator allocator() const {return CellAllocator();} }; struct PanmicticModel: public ModelData, public EcolabPoint, public ecolab::Model