diff --git a/src/particles/elements/mixin/named.H b/src/particles/elements/mixin/named.H index 5d75028e9..b42a5f7f9 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,50 @@ 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) { + 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) { + 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 +82,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 +95,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