Page MenuHomec4science

lm_python_components.hh
No OneTemporary

File Metadata

Created
Fri, Oct 4, 05:58

lm_python_components.hh

#ifndef __LM_PYTHON_COMPONENTS_HH__
#define __LM_PYTHON_COMPONENTS_HH__
/* -------------------------------------------------------------------------- */
#include <pybind11/eigen.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
/* -------------------------------------------------------------------------- */
#include "component_libmultiscale.hh"
/* -------------------------------------------------------------------------- */
namespace py = pybind11;
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template <typename indexes> struct ApplyFromVector;
template <int... n> struct ApplyFromVector<std::integer_sequence<int, n...>> {
template <typename V> static decltype(auto) from_vector(V &&v) {
auto it = v.begin();
return std::forward_as_tuple(it[n]...);
}
template <typename V, typename F> static void apply(F &&f, V &&vec) {
std::vector<InputConnection> _input;
for (auto &&[k, v] : vec) {
try {
auto &vec = py::cast<LMObject &>(v);
_input.push_back(InputConnection(py::cast<std::string>(k)) = vec);
continue;
} catch (std::exception &e) {
}
try {
_input.push_back(InputConnection(py::cast<std::string>(k)) =
py::cast<OutputContainer>(v));
continue;
} catch (std::exception &e) {
}
auto vec = py::cast<ContainerArray<Real>::EigenArray>(v);
ContainerArray<Real> out;
out = std::forward<ContainerArray<Real>::EigenArray>(vec);
_input.push_back(InputConnection(py::cast<std::string>(k)) =
std::forward<ContainerArray<Real>>(out));
}
std::apply(f,
from_vector(std::forward<std::vector<InputConnection>>(_input)));
}
};
template <int N, typename V, typename F> void apply_from_vector(F &&f, V &v) {
ApplyFromVector<std::make_integer_sequence<int, N>>::apply(f, v);
}
template <int N> struct call_compute_impl {
template <typename F, typename V> static void doit(F &&f, V &&v) {
int sz = v.size();
if (sz == N)
apply_from_vector<N>(f, std::forward<V>(v));
else
call_compute_impl<N - 1>::doit(std::forward<F>(f), std::forward<V>(v));
}
};
template <> struct call_compute_impl<0> {
template <typename F, typename V> static void doit(F &&f, V &&) { f(); }
};
template <typename F, typename V> void call_compute(F &&f, V &&v) {
call_compute_impl<6>::doit(f, v);
}
/* -------------------------------------------------------------------------- */
inline void declare_components(py::module &m) {
py::class_<LMObject, std::shared_ptr<LMObject>>(m, "LMObject");
py::class_<OutputContainer, std::shared_ptr<OutputContainer>>(
m, "OutputContainer")
.def("castContainer",
[](OutputContainer &self) -> decltype(auto) {
return self.get<ContainerInterface &>();
},
py::return_value_policy::reference);
py::class_<Component, LMObject, std::shared_ptr<Component>>(
m, "Component", py::multiple_inheritance())
.def("setCommGroup", &Component::setCommGroup<Real>)
.def("evalOutput",
[&](Component &self, const std::string output_name)
-> decltype(auto) { return self.evalOutput(output_name).get(); },
py::arg("name") = "", py::return_value_policy::reference)
.def_property_readonly("inputs",
[m](Component &self) {
return m.attr("prologue").attr("LMInputs")(self);
})
.def("setInput", [m](Component &self, const std::string &name,
Component &input) { self.connect(name, input); })
.def("compute", [](Component &self) { self.compute(); })
.def("compute",
[](Component &self, py::kwargs kwargs) {
call_compute([&](auto &&... a) { self.compute(a...); }, kwargs);
})
.def("compute",
[](Component &self, OutputContainer arg) {
self.compute(std::forward<OutputContainer>(arg));
})
.def("compute",
[](Component &self, LMObject &obj) { self.compute(obj); });
py::class_<Parsable, std::shared_ptr<Parsable>>(m, "Parsable")
.def("getPossibleKeywords", &Parsable::getPossibleKeywords)
.def("getParam", &Parsable::getParam<py::object>)
.def("setParam",
[](Parsable &self, const std::string &keyword, py::object &val) {
self.setParam<py::object>(keyword, val);
})
.def_property_readonly("params", [m](Parsable &self) {
return m.attr("prologue").attr("LMParameters")(self);
});
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif //__LM_PYTHON_COMPONENTS_HH__

Event Timeline