Skip to content

Commit

Permalink
Merge pull request #2827 from pnorbert/mutable-attributes-bp4
Browse files Browse the repository at this point in the history
Mutable Attributes: Allow redefining attributes. BP4 stream reading will provide the late…
  • Loading branch information
pnorbert authored Aug 19, 2021
2 parents 43dbaf9 + 4205973 commit feb8fa8
Show file tree
Hide file tree
Showing 17 changed files with 401 additions and 72 deletions.
4 changes: 2 additions & 2 deletions bindings/CXX11/adios2/cxx11/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation)
#define declare_template_instantiation(T) \
template Attribute<T> IO::DefineAttribute( \
const std::string &, const T *, const size_t, const std::string &, \
const std::string); \
const std::string, const bool); \
\
template Attribute<T> IO::DefineAttribute(const std::string &, const T &, \
const std::string &, \
const std::string); \
const std::string, const bool); \
\
template Attribute<T> IO::InquireAttribute<T>( \
const std::string &, const std::string &, const std::string);
Expand Down
12 changes: 8 additions & 4 deletions bindings/CXX11/adios2/cxx11/IO.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class IO
* @param separator default is "/", hierarchy between variable name and
* attribute, e.g. variableName/attribute1, variableName::attribute1. Not
* used if variableName is empty.
* @param allowModification true allows redefining existing attribute
* @return object reference to internal Attribute in IO
* @exception std::invalid_argument if Attribute with unique name (in IO or
* Variable) is already defined
Expand All @@ -180,7 +181,8 @@ class IO
Attribute<T> DefineAttribute(const std::string &name, const T *data,
const size_t size,
const std::string &variableName = "",
const std::string separator = "/");
const std::string separator = "/",
const bool allowModification = false);

/**
* @brief Define single value attribute
Expand All @@ -192,14 +194,16 @@ class IO
* @param separator default is "/", hierarchy between variable name and
* attribute, e.g. variableName/attribute1, variableName::attribute1. Not
* used if variableName is empty.
* @param allowModification true allows redefining existing attribute
* @return object reference to internal Attribute in IO
* @exception std::invalid_argument if Attribute with unique name (in IO or
* Variable) is already defined
*/
template <class T>
Attribute<T> DefineAttribute(const std::string &name, const T &value,
const std::string &variableName = "",
const std::string separator = "/");
const std::string separator = "/",
const bool allowModification = false);

/**
* @brief Retrieve an existing attribute
Expand Down Expand Up @@ -386,11 +390,11 @@ ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation)
#define declare_template_instantiation(T) \
extern template Attribute<T> IO::DefineAttribute( \
const std::string &, const T *, const size_t, const std::string &, \
const std::string); \
const std::string, const bool); \
\
extern template Attribute<T> IO::DefineAttribute( \
const std::string &, const T &, const std::string &, \
const std::string); \
const std::string, const bool); \
\
extern template Attribute<T> IO::InquireAttribute<T>( \
const std::string &, const std::string &, const std::string);
Expand Down
19 changes: 10 additions & 9 deletions bindings/CXX11/adios2/cxx11/IO.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -38,31 +38,32 @@ Variable<T> IO::InquireVariable(const std::string &name)
}

template <class T>
Attribute<T> IO::DefineAttribute(const std::string &name, const T *data,
const size_t size,
const std::string &variableName,
const std::string separator)
Attribute<T>
IO::DefineAttribute(const std::string &name, const T *data, const size_t size,
const std::string &variableName,
const std::string separator, const bool allowModification)
{
using IOType = typename TypeInfo<T>::IOType;
helper::CheckForNullptr(m_IO, "for attribute name " + name +
" and variable name " + variableName +
", in call to IO::DefineAttribute");
return Attribute<T>(
&m_IO->DefineAttribute(name, reinterpret_cast<const IOType *>(data),
size, variableName, separator));
return Attribute<T>(&m_IO->DefineAttribute(
name, reinterpret_cast<const IOType *>(data), size, variableName,
separator, allowModification));
}

template <class T>
Attribute<T> IO::DefineAttribute(const std::string &name, const T &value,
const std::string &variableName,
const std::string separator)
const std::string separator,
const bool allowModification)
{
using IOType = typename TypeInfo<T>::IOType;
helper::CheckForNullptr(m_IO, "for attribute name " + name +
", in call to IO::DefineAttribute");
return Attribute<T>(
&m_IO->DefineAttribute(name, reinterpret_cast<const IOType &>(value),
variableName, separator));
variableName, separator, allowModification));
}

template <class T>
Expand Down
18 changes: 16 additions & 2 deletions source/adios2/core/Attribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,33 @@ class Attribute : public AttributeBase
* @param name
* @param data
* @param elements
* @param allowModifications
*/
Attribute<T>(const std::string &name, const T *data, const size_t elements);
Attribute<T>(const std::string &name, const T *data, const size_t elements,
const bool allowModification);

/**
* Single value constructor
* @param name
* @param data
* @param elements
* @param allowModifications
*/
Attribute<T>(const std::string &name, const T &data);
Attribute<T>(const std::string &name, const T &data,
const bool allowModification);

~Attribute<T>() = default;

/**
* Modification of an existing attribute (array)
*/
void Modify(const T *data, const size_t elements);

/**
* Modification of an existing attribute (single value)
*/
void Modify(const T &data);

private:
std::string DoGetInfoValue() const noexcept override;
};
Expand Down
62 changes: 55 additions & 7 deletions source/adios2/core/Attribute.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,75 @@ template <typename T>
Attribute<T>::Attribute(const Attribute<T> &other)
: AttributeBase(other), m_DataArray(other.m_DataArray)
{
Pad<T>::Zero(m_DataSingleValue);
m_DataSingleValue = other.m_DataSingleValue;
if (other.m_IsSingleValue)
{
m_DataArray.clear();
Pad<T>::Zero(m_DataSingleValue);
m_DataSingleValue = other.m_DataSingleValue;
}
else
{
m_DataArray = other.m_DataArray;
Pad<T>::Zero(m_DataSingleValue);
}
}

template <typename T>
Attribute<T>::Attribute(const std::string &name, const T *array,
const size_t elements)
: AttributeBase(name, helper::GetDataType<T>(), elements)
const size_t elements, const bool allowModification)
: AttributeBase(name, helper::GetDataType<T>(), elements, allowModification)
{
Pad<T>::Zero(m_DataSingleValue);
m_DataArray = std::vector<T>(array, array + elements);
Pad<T>::Zero(m_DataSingleValue);
}

template <typename T>
Attribute<T>::Attribute(const std::string &name, const T &value)
: AttributeBase(name, helper::GetDataType<T>())
Attribute<T>::Attribute(const std::string &name, const T &value,
const bool allowModification)
: AttributeBase(name, helper::GetDataType<T>(), allowModification)
{
m_DataArray.clear();
Pad<T>::Zero(m_DataSingleValue);
m_DataSingleValue = value;
}

template <typename T>
void Attribute<T>::Modify(const T *data, const size_t elements)
{
if (m_AllowModification)
{
m_DataArray = std::vector<T>(data, data + elements);
Pad<T>::Zero(m_DataSingleValue);
this->m_IsSingleValue = false;
this->m_Elements = elements;
}
else
{
throw std::invalid_argument(
"ERROR: Trying to modify attribute " + this->m_Name +
" which has been defined as non-modifiable\n");
}
}

template <typename T>
void Attribute<T>::Modify(const T &data)
{
if (m_AllowModification)
{
m_DataArray.clear();
Pad<T>::Zero(m_DataSingleValue);
m_DataSingleValue = data;
this->m_IsSingleValue = true;
this->m_Elements = 1;
}
else
{
throw std::invalid_argument(
"ERROR: Trying to modify attribute " + this->m_Name +
" which has been defined as non-modifiable\n");
}
}

template <typename T>
std::string Attribute<T>::DoGetInfoValue() const noexcept
{
Expand Down
13 changes: 9 additions & 4 deletions source/adios2/core/AttributeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ namespace adios2
namespace core
{

AttributeBase::AttributeBase(const std::string &name, const DataType type)
: m_Name(name), m_Type(type), m_Elements(1), m_IsSingleValue(true)
AttributeBase::AttributeBase(const std::string &name, const DataType type,
const bool allowModification)
: m_Name(name), m_Type(type), m_Elements(1), m_IsSingleValue(true),
m_AllowModification(allowModification)
{
}

AttributeBase::AttributeBase(const std::string &name, const DataType type,
const size_t elements)
: m_Name(name), m_Type(type), m_Elements(elements), m_IsSingleValue(false)
const size_t elements,
const bool allowModification)
: m_Name(name), m_Type(type), m_Elements(elements), m_IsSingleValue(false),
m_AllowModification(allowModification)
{
}

Expand All @@ -32,6 +36,7 @@ Params AttributeBase::GetInfo() const noexcept
info["Type"] = ToString(m_Type);
info["Elements"] = std::to_string(m_Elements);
info["Value"] = this->DoGetInfoValue();
info["Modifiable"] = std::to_string(m_AllowModification);
return info;
}

Expand Down
10 changes: 6 additions & 4 deletions source/adios2/core/AttributeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ class AttributeBase
public:
const std::string m_Name;
const DataType m_Type;
const size_t m_Elements;
const bool m_IsSingleValue;
size_t m_Elements;
bool m_IsSingleValue;
const bool m_AllowModification;

/**
* Single value constructor used by Attribute<T> derived class
* @param name
* @param type
*/
AttributeBase(const std::string &name, const DataType type);
AttributeBase(const std::string &name, const DataType type,
const bool allowModification);

/**
* Array constructor used by Attribute<T> derived class
Expand All @@ -46,7 +48,7 @@ class AttributeBase
* @param elements
*/
AttributeBase(const std::string &name, const DataType type,
const size_t elements);
const size_t elements, const bool allowModification);

virtual ~AttributeBase() = default;

Expand Down
2 changes: 2 additions & 0 deletions source/adios2/core/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ void Engine::Init() {}
void Engine::InitParameters() {}
void Engine::InitTransports() {}

void Engine::NotifyEngineAttribute(std::string name, DataType type) noexcept {}

// DoPut*
#define declare_type(T) \
void Engine::DoPut(Variable<T> &, typename Variable<T>::Span &, \
Expand Down
5 changes: 5 additions & 0 deletions source/adios2/core/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,11 @@ class Engine
return nullptr;
}

/** Notify the engine when a new attribute is defined. Called from IO.tcc
*/
virtual void NotifyEngineAttribute(std::string name,
DataType type) noexcept;

protected:
/** from ADIOS class passed to Engine created with Open
* if no communicator is passed */
Expand Down
4 changes: 2 additions & 2 deletions source/adios2/core/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,10 +842,10 @@ ADIOS2_FOREACH_STDTYPE_1ARG(define_template_instantiation)
#define declare_template_instantiation(T) \
template Attribute<T> &IO::DefineAttribute<T>( \
const std::string &, const T *, const size_t, const std::string &, \
const std::string); \
const std::string, const bool); \
template Attribute<T> &IO::DefineAttribute<T>( \
const std::string &, const T &, const std::string &, \
const std::string); \
const std::string, const bool); \
template Attribute<T> *IO::InquireAttribute<T>( \
const std::string &, const std::string &, const std::string) noexcept;

Expand Down
14 changes: 10 additions & 4 deletions source/adios2/core/IO.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ class IO
* @param array pointer to user data
* @param elements number of data elements
* @param variableName optionally associates the attribute to a Variable
* @param allowModification true allows redefining/modifying existing
* attribute
* @return reference to internal Attribute
* @exception std::invalid_argument if Attribute with unique name is already
* defined
Expand All @@ -205,20 +207,24 @@ class IO
Attribute<T> &DefineAttribute(const std::string &name, const T *array,
const size_t elements,
const std::string &variableName = "",
const std::string separator = "/");
const std::string separator = "/",
const bool allowModification = false);

/**
* @brief Define single value attribute
* @param name must be unique for the IO object
* @param value single data value
* @param allowModification true allows redefining/modifying existing
* attribute
* @return reference to internal Attribute
* @exception std::invalid_argument if Attribute with unique name is already
* defined
*/
template <class T>
Attribute<T> &DefineAttribute(const std::string &name, const T &value,
const std::string &variableName = "",
const std::string separator = "/");
const std::string separator = "/",
const bool allowModification = false);

/**
* @brief Removes an existing Variable in current IO object.
Expand Down Expand Up @@ -534,10 +540,10 @@ ADIOS2_FOREACH_STDTYPE_1ARG(declare_template_instantiation)
#define declare_template_instantiation(T) \
extern template Attribute<T> &IO::DefineAttribute<T>( \
const std::string &, const T *, const size_t, const std::string &, \
const std::string); \
const std::string, const bool); \
extern template Attribute<T> &IO::DefineAttribute<T>( \
const std::string &, const T &, const std::string &, \
const std::string); \
const std::string, const bool); \
extern template Attribute<T> *IO::InquireAttribute<T>( \
const std::string &, const std::string &, const std::string) noexcept;

Expand Down
Loading

0 comments on commit feb8fa8

Please sign in to comment.