Skip to content

Commit

Permalink
Named Mixing Class: 40 -> 8 Bytes
Browse files Browse the repository at this point in the history
Make smaller, because we will always copy the whole
class to GPU, even though we do not access the name
member on it.
  • Loading branch information
ax3l committed Sep 24, 2024
1 parent 32d2036 commit 8a8ea86
Showing 1 changed file with 58 additions and 4 deletions.
62 changes: 58 additions & 4 deletions src/particles/elements/mixin/named.H
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
#include "particles/ImpactXParticleContainer.H"

#include <AMReX_Extension.H>
#include <AMReX_GpuQualifiers.H>

#include <cstring>
#include <optional>
#include <stdexcept>
#include <string>


Expand All @@ -28,21 +31,65 @@ 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<std::string> 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
*/
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
Expand All @@ -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<std::string> 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<std::string> (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
Expand Down

0 comments on commit 8a8ea86

Please sign in to comment.