From 8a8ea86baa9181b24706cbd930da51c21f83bd3a Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 24 Sep 2024 16:29:37 -0700 Subject: [PATCH] `Named` Mixing Class: 40 -> 8 Bytes Make smaller, because we will always copy the whole class to GPU, even though we do not access the name member on it. --- src/particles/elements/mixin/named.H | 62 ++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/particles/elements/mixin/named.H b/src/particles/elements/mixin/named.H index 5d75028e9..e801792e2 100644 --- a/src/particles/elements/mixin/named.H +++ b/src/particles/elements/mixin/named.H @@ -13,8 +13,11 @@ #include "particles/ImpactXParticleContainer.H" #include +#include +#include #include +#include #include @@ -28,13 +31,54 @@ namespace impactx::elements * * @param name a user defined and not necessarily unique name of the element */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Named ( std::optional name ) - : m_name(name) { + if (name.has_value()) { + m_name = new char[name->size() + 1]; + std::strcpy(m_name, name->c_str()); + } } + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + ~Named () { + AMREX_IF_ON_HOST(( + delete[] m_name; + m_name = nullptr; + )) + } + + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + Named (Named const & other) { + AMREX_IF_ON_HOST(( + if (other.has_name()) { + m_name = new char[std::strlen(other.m_name) + 1]; + std::strcpy(m_name, other.m_name); + } + )) + } + + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + Named& operator=(Named const & other) { + AMREX_IF_ON_HOST(( + if (&other != this) { + if (other.has_name()) { + m_name = new char[std::strlen(other.m_name) + 1]; + std::strcpy(m_name, other.m_name); + } + } + )) + return *this; + } + + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + Named (Named&&) noexcept = default; + + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + Named& operator=(Named && other) noexcept = default; + /** Return the user provided name of the element * * @return user defined and not necessarily unique name @@ -42,7 +86,10 @@ namespace impactx::elements AMREX_FORCE_INLINE std::string name () const { - return m_name.value(); + if (!has_name()) { + throw std::runtime_error("Name not set on element!"); + } + return std::string(m_name); } /** Return true if the user provided a name for this element @@ -52,10 +99,17 @@ namespace impactx::elements AMREX_FORCE_INLINE bool has_name () const { - return m_name.has_value(); + return m_name != nullptr; } - std::optional m_name; //! a user defined and not necessarily unique name of the element + // Implementation note: + // This is used as a mixin class in elements that are copied to GPU. GPU compilers copy + // a whole element by its sizeof(T). + // To save on this copy operation at kernel start, this is implemented + // as a simple C pointer (8 bytes), contrary to a std::string (32 bytes) or + // a std::optional (40 bytes). m_name points to host-side memory and + // must not be dereferenced (used) on GPU. + char * m_name = nullptr; //! a user defined and not necessarily unique name of the element }; } // namespace impactx::elements