Skip to content

Commit d282c8d

Browse files
committed
Add io.define_derived_variable(name, expression, type) function to Python API.
1 parent 26486ae commit d282c8d

File tree

13 files changed

+342
-45
lines changed

13 files changed

+342
-45
lines changed

bindings/Python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Python_add_library(adios2_py MODULE
33
py11ADIOS.cpp
44
py11IO.cpp
55
py11Variable.cpp
6+
py11VariableDerived.cpp
67
py11Attribute.cpp
78
py11Engine.cpp
89
py11Operator.cpp

bindings/Python/py11IO.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,23 @@ Variable IO::DefineVariable(const std::string &name, const pybind11::object &val
146146
return Variable(variable);
147147
}
148148

149+
VariableDerived IO::DefineDerivedVariable(const std::string &name, const std::string &exp_string,
150+
const DerivedVarType varType)
151+
{
152+
helper::CheckForNullptr(m_IO,
153+
"for variable " + name + ", in call to IO::DefineDerivedVariable");
154+
155+
#ifdef ADIOS2_HAVE_DERIVED_VARIABLE
156+
adios2::core::VariableDerived *dv = &m_IO->DefineDerivedVariable(name, exp_string, varType);
157+
adios2::py11::VariableDerived vd(dv);
158+
#else
159+
adios2::py11::VariableDerived vd;
160+
throw std::invalid_argument("ERROR: Derived Variables are not supported in this adios2 build "
161+
", in call to DefineDerivedVariable\n");
162+
#endif
163+
return vd;
164+
}
165+
149166
Variable IO::InquireVariable(const std::string &name)
150167
{
151168
helper::CheckForNullptr(m_IO, "for variable " + name + ", in call to IO::InquireVariable");

bindings/Python/py11IO.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "py11Attribute.h"
2020
#include "py11Engine.h"
2121
#include "py11Variable.h"
22+
#include "py11VariableDerived.h"
2223
#include "py11types.h"
2324

2425
namespace adios2
@@ -62,6 +63,10 @@ class IO
6263
const Dims &shape, const Dims &start, const Dims &count,
6364
const bool isConstantDims);
6465

66+
VariableDerived
67+
DefineDerivedVariable(const std::string &name, const std::string &expression,
68+
const DerivedVarType varType = DerivedVarType::MetadataOnly);
69+
6570
Variable InquireVariable(const std::string &name);
6671

6772
Attribute DefineAttribute(const std::string &name, const pybind11::array &array,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Distributed under the OSI-approved Apache License, Version 2.0. See
3+
* accompanying file Copyright.txt for details.
4+
*
5+
* py11Variable.cpp
6+
*/
7+
8+
#include "py11VariableDerived.h"
9+
10+
#include "adios2/helper/adiosFunctions.h"
11+
12+
namespace adios2
13+
{
14+
namespace py11
15+
{
16+
17+
#ifdef ADIOS2_HAVE_DERIVED_VARIABLE
18+
VariableDerived::VariableDerived(core::VariableDerived *v) : m_VariableDerived(v) {}
19+
20+
VariableDerived::operator bool() const noexcept
21+
{
22+
return (m_VariableDerived == nullptr) ? false : true;
23+
}
24+
25+
std::string VariableDerived::Name() const
26+
{
27+
helper::CheckForNullptr(m_VariableDerived, "in call to VariableDerived::Name");
28+
return m_VariableDerived->m_Name;
29+
}
30+
31+
DerivedVarType VariableDerived::Type() const
32+
{
33+
helper::CheckForNullptr(m_VariableDerived, "in call to VariableDerived::Type");
34+
return m_VariableDerived->GetDerivedType();
35+
}
36+
37+
#else
38+
39+
VariableDerived::operator bool() const noexcept { return false; }
40+
41+
std::string VariableDerived::Name() const
42+
{
43+
return "DerivedVariables are not supported in this ADIOS2 build";
44+
}
45+
46+
DerivedVarType VariableDerived::Type() const { return DerivedVarType::ExpressionString; }
47+
48+
#endif
49+
50+
} // end namespace py11
51+
} // end namespace adios2
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Distributed under the OSI-approved Apache License, Version 2.0. See
3+
* accompanying file Copyright.txt for details.
4+
*
5+
* py11VariableDerived.h
6+
*
7+
*/
8+
9+
#ifndef ADIOS2_BINDINGS_PYTHON_VARIABLEDERIVED_H_
10+
#define ADIOS2_BINDINGS_PYTHON_VARIABLEDERIVED_H_
11+
12+
#include "adios2/common/ADIOSConfig.h"
13+
14+
#ifdef ADIOS2_HAVE_DERIVED_VARIABLE
15+
#include "adios2/core/VariableDerived.h"
16+
#else
17+
#include "adios2/common/ADIOSTypes.h"
18+
#endif
19+
20+
namespace adios2
21+
{
22+
namespace py11
23+
{
24+
25+
class IO;
26+
class Engine;
27+
28+
class VariableDerived
29+
{
30+
friend class IO;
31+
friend class Engine;
32+
33+
public:
34+
VariableDerived() = default;
35+
36+
~VariableDerived() = default;
37+
38+
explicit operator bool() const noexcept;
39+
40+
std::string Name() const;
41+
42+
DerivedVarType Type() const;
43+
44+
private:
45+
#ifdef ADIOS2_HAVE_DERIVED_VARIABLE
46+
VariableDerived(adios2::core::VariableDerived *v);
47+
adios2::core::VariableDerived *m_VariableDerived = nullptr;
48+
#endif
49+
};
50+
51+
} // end namespace py11
52+
} // end namespace adios2
53+
54+
#endif /* ADIOS2_BINDINGS_PYTHON_VARIABLEDERIVED_H_ */

bindings/Python/py11glue.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "py11Operator.h"
2929
#include "py11Query.h"
3030
#include "py11Variable.h"
31+
#include "py11VariableDerived.h"
3132

3233
#if ADIOS2_USE_MPI
3334

@@ -124,6 +125,12 @@ PYBIND11_MODULE(ADIOS2_PYTHON_MODULE_NAME, m)
124125
.value("OtherError", adios2::StepStatus::OtherError)
125126
.export_values();
126127

128+
pybind11::enum_<adios2::DerivedVarType>(m, "DerivedVarType")
129+
.value("MetadataOnly", adios2::DerivedVarType::MetadataOnly)
130+
.value("ExpressionString", adios2::DerivedVarType::ExpressionString)
131+
.value("StoreData", adios2::DerivedVarType::StoreData)
132+
.export_values();
133+
127134
pybind11::class_<adios2::py11::ADIOS>(m, "ADIOS")
128135
// Python 2
129136
.def("__nonzero__",
@@ -218,6 +225,14 @@ PYBIND11_MODULE(ADIOS2_PYTHON_MODULE_NAME, m)
218225
adios2::py11::IO::DefineVariable,
219226
pybind11::return_value_policy::move, pybind11::arg("name"))
220227

228+
.def("DefineDerivedVariable",
229+
(adios2::py11::VariableDerived(adios2::py11::IO::*)(
230+
const std::string &, const std::string &, const adios2::DerivedVarType)) &
231+
adios2::py11::IO::DefineDerivedVariable,
232+
pybind11::return_value_policy::move, pybind11::arg("name"),
233+
pybind11::arg("expression"),
234+
pybind11::arg("vartype") = adios2::DerivedVarType::MetadataOnly)
235+
221236
.def("InquireVariable", &adios2::py11::IO::InquireVariable,
222237
pybind11::return_value_policy::move)
223238

@@ -379,6 +394,22 @@ PYBIND11_MODULE(ADIOS2_PYTHON_MODULE_NAME, m)
379394
.def("Operations", &adios2::py11::Variable::Operations)
380395
.def("RemoveOperations", &adios2::py11::Variable::RemoveOperations);
381396

397+
pybind11::class_<adios2::py11::VariableDerived>(m, "VariableDerived")
398+
// Python 2
399+
.def("__nonzero__",
400+
[](const adios2::py11::VariableDerived &vd) {
401+
const bool opBool = vd ? true : false;
402+
return opBool;
403+
})
404+
// Python 3
405+
.def("__bool__",
406+
[](const adios2::py11::VariableDerived &vd) {
407+
const bool opBool = vd ? true : false;
408+
return opBool;
409+
})
410+
.def("Name", &adios2::py11::VariableDerived::Name)
411+
.def("Type", &adios2::py11::VariableDerived::Type);
412+
382413
pybind11::class_<adios2::py11::Attribute>(m, "Attribute")
383414
// Python 2
384415
.def("__nonzero__",

python/adios2/derived_variable.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""License:
2+
Distributed under the OSI-approved Apache License, Version 2.0. See
3+
accompanying file Copyright.txt for details.
4+
"""
5+
6+
7+
class DerivedVariable:
8+
"""High level representation of the DerivedVariable class in the adios2.bindings"""
9+
10+
def __init__(self, implementation):
11+
self.impl = implementation
12+
13+
@property
14+
def impl(self):
15+
"""Bindings implementation of the class"""
16+
return self._impl
17+
18+
@impl.setter
19+
def impl(self, implementation):
20+
self._impl = implementation
21+
22+
def __eq__(self, other):
23+
if isinstance(other, DerivedVariable):
24+
return self.name() == other.name()
25+
return False
26+
27+
def type(self):
28+
"""
29+
Type of the DerivedVariable
30+
31+
Returns:
32+
str: Type of the DerivedVariable.
33+
"""
34+
return self.impl.Type()
35+
36+
def name(self):
37+
"""
38+
Name of the DerivedVariable
39+
40+
Returns:
41+
str: Name of the DerivedVariable.
42+
"""
43+
return self.impl.Name()

python/adios2/io.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
from adios2.attribute import Attribute
88
from adios2.variable import Variable
9+
from adios2.derived_variable import DerivedVariable
910
from adios2.engine import Engine
1011

1112

@@ -242,6 +243,31 @@ def remove_all_variables(self):
242243
"""
243244
self.impl.RemoveAllVariables()
244245

246+
def define_derived_variable(self, name, expression, etype=None):
247+
"""
248+
Define a derived variable with an expression
249+
250+
Parameters
251+
name
252+
name as it appears in variable list in the output
253+
254+
expression
255+
expression string using other variable names, operators and functions
256+
257+
type
258+
DerivedVarType.MetadataOnly : store only the metadata of the derived variable
259+
DerivedVarType.ExpressionString : store only the definition, nothing else
260+
DerivedVarType.StoreData : store as a complete variable (data and metadata)
261+
"""
262+
var_impl = None
263+
264+
if etype is None:
265+
var_impl = self.impl.DefineDerivedVariable(name, expression)
266+
else:
267+
var_impl = self.impl.DefineDerivedVariable(name, expression, etype)
268+
269+
return DerivedVariable(var_impl)
270+
245271
def open(self, name, mode, comm=None):
246272
"""
247273
Open an engine

python/adios2/variable.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
class Variable:
8-
"""High level representation of the Attribute class in the adios2.bindings"""
8+
"""High level representation of the Variable class in the adios2.bindings"""
99

1010
def __init__(self, implementation):
1111
self.impl = implementation

source/adios2/common/ADIOSTypes.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,13 @@
3333
namespace adios2
3434
{
3535

36-
#ifdef ADIOS2_HAVE_DERIVED_VARIABLE
3736
/** Type of derived variables */
3837
enum class DerivedVarType
3938
{
4039
MetadataOnly, ///< Store only the metadata (default)
4140
ExpressionString, ///< Store only the expression string
4241
StoreData ///< Store data and metadata
4342
};
44-
#endif
4543

4644
/** Memory space for the user provided buffers */
4745
enum class MemorySpace

0 commit comments

Comments
 (0)