1 #ifndef UTOPIA_DATAIO_FACTORY_HH
2 #define UTOPIA_DATAIO_FACTORY_HH
7 #include <unordered_map>
11 #include <boost/graph/adjacency_list.hpp>
12 #include <boost/graph/adjacency_matrix.hpp>
13 #include <boost/graph/graph_traits.hpp>
14 #include <boost/graph/properties.hpp>
16 #include <boost/hana/ext/std/tuple.hpp>
17 #include <boost/hana/integral_constant.hpp>
18 #include <boost/hana/remove_at.hpp>
19 #include <boost/hana/transform.hpp>
22 #include "../../core/logging.hh"
23 #include "../../core/type_traits.hh"
24 #include "../cfg_utils.hh"
103 template <
class Model, TypeTag typetag = TypeTag::plain >
107 static std::unordered_map<
109 std::function< std::string(std::string,
Model&) > >
129 template <
class Func,
class AttributeHandle >
133 using AttrType = std::decay_t< AttributeHandle >;
136 if constexpr (std::is_same_v< AttrType, Nothing >)
140 else if constexpr (Utopia::Utils::has_static_size_v< AttrType >)
145 std::decay_t< std::tuple_element_t< 0, AttrType > >;
151 Utils::is_string_v< Nametype >,
152 "Error, first entry of Dataset_attribute must be a string "
153 "naming the attribute");
157 std::string name = get< 0 >(attr);
158 auto pos = name.find(
'$');
160 if (pos != std::string::npos)
162 auto path_builder =
_modifiers[name.substr(pos + 1)];
163 std::string new_path = name.substr(0, pos);
165 writer = [attr, path_builder, new_path](
auto&& hdfobject,
167 hdfobject->add_attribute(path_builder(new_path, m),
173 writer = [attr](
auto&& hdfobject,
auto &&) ->
void {
174 hdfobject->add_attribute(get< 0 >(attr),
182 Utils::is_callable_v< AttrType >,
183 "Error, if the given attribute argument is not a tuple/pair "
184 "and not 'Nothing', it has to be a function");
205 auto pos = dataset_descriptor.
path.find(
'$');
208 if (pos != std::string::npos)
215 std::string new_path = dataset_descriptor.
path.substr(0, pos);
218 [dataset_descriptor, path_builder, new_path](
220 auto&& model) -> std::shared_ptr< HDFDataset > {
221 return group->open_dataset(
222 path_builder(new_path, model),
232 [dataset_descriptor](
233 std::shared_ptr< HDFGroup >&
group,
234 Model&) -> std::shared_ptr< HDFDataset > {
236 return group->open_dataset(
237 dataset_descriptor.
path,
243 return dataset_builder;
259 template <
class SourceGetter,
class Getter >
266 std::invoke_result_t< std::decay_t< SourceGetter >,
Model& > >;
270 writer = [&getter, &get_source](
271 std::shared_ptr< HDFDataset >&
dataset,
274 auto& graph = get_source(m);
277 typename GraphType::vertex_iterator v, v_end;
278 boost::tie(v, v_end) = boost::vertices(graph);
280 dataset->write(v, v_end, [&getter, &graph](
auto&& vd) {
281 return getter(graph[vd]);
287 writer = [&getter, &get_source](
288 std::shared_ptr< HDFDataset >&
dataset,
290 auto& graph = get_source(m);
293 typename GraphType::edge_iterator v, v_end;
294 boost::tie(v, v_end) = boost::edges(graph);
296 dataset->write(v, v_end, [&getter, &graph](
auto&& vd) {
297 return getter(graph[vd]);
302 not std::is_same_v< std::decay_t< Getter >,
303 std::function<
void() > >)
306 writer = [&getter, &get_source](
307 std::shared_ptr< HDFDataset >&
dataset,
309 auto& graph = get_source(m);
312 typename GraphType::vertex_iterator v, v_end;
313 boost::tie(v, v_end) = boost::vertices(graph);
314 dataset->write(v, v_end, [&getter, &graph](
auto&& vd) {
315 return getter(graph, vd);
320 not std::is_same_v< std::decay_t< Getter >,
321 std::function<
void() > >)
323 writer = [&getter, &get_source](
324 std::shared_ptr< HDFDataset >&
dataset,
326 auto& graph = get_source(m);
329 typename GraphType::edge_iterator v, v_end;
330 boost::tie(v, v_end) = boost::edges(graph);
332 dataset->write(v, v_end, [&getter, &graph](
auto&& vd) {
333 return getter(graph, vd);
340 else if constexpr (std::is_same_v< std::decay_t< Getter >,
341 std::function<
void() > > and
344 writer = [&get_source](
345 std::shared_ptr< HDFDataset >&
dataset,
347 auto& graph = get_source(m);
349 auto [v, v_end] = boost::vertices(graph);
350 dataset->write(v, v_end, [&](
auto&& vd) {
351 return boost::get(boost::vertex_index_t(), graph, vd);
356 else if constexpr (std::is_same_v< std::decay_t< Getter >,
357 std::function<
void() > > and
361 [get_source](std::shared_ptr< HDFDataset >&
dataset,
363 auto& graph = get_source(m);
365 auto [e, e_end] = boost::edges(graph);
367 dataset->write(e, e_end, [&](
auto&& ed) {
368 return boost::get(boost::vertex_index_t(),
370 boost::source(ed, graph));
373 dataset->write(e, e_end, [&](
auto&& ed) {
374 return boost::get(boost::vertex_index_t(),
376 boost::target(ed, graph));
383 throw std::invalid_argument(
"Unknown ObjectType.");
448 template <
class SourceGetter,
450 class Group_attribute =
Nothing,
451 class Dataset_attribute =
Nothing >
452 std::pair< std::string,
453 std::shared_ptr< Default::DefaultWriteTask< Model > > >
457 std::string basegroup_path,
460 SourceGetter&& get_source,
462 Group_attribute&& group_attribute =
Nothing{},
463 Dataset_attribute&& dataset_attribute =
Nothing{})
467 std::decay_t< decltype(get_source(std::declval< Model& >())) >;
473 "Error, the argument 'get_source' must return a container "
474 "type or graph, i.e., "
475 "a type with an iterator");
479 Default::DefaultBuilder< Model > dataset_builder =
483 Default::DefaultAttributeWriterGroup< Model > >(
484 std::forward< Group_attribute >(group_attribute));
487 Default::DefaultAttributeWriterDataset< Model > >(
488 std::forward< Dataset_attribute >(dataset_attribute));
490 Default::DefaultDataWriter< Model > datawriter;
497 "Error in WriteTask factory:, a graph cannot be written "
498 "with TypeTag::plain, see documentation of TypeTag enum");
505 std::forward< Getter >(getter));
510 datawriter = [getter, get_source](
511 std::shared_ptr< HDFDataset >& dataset,
514 get_source(m).begin(), get_source(m).end(), getter);
519 return std::make_pair(
521 std::make_shared< Default::DefaultWriteTask< Model > >(
524 [basegroup_path](std::shared_ptr< HDFGroup > parent) {
525 return parent->open_group(basegroup_path);
532 group_attribute_writer,
534 dataset_attribute_writer));
552 std::pair< std::string,
553 std::shared_ptr< Default::DefaultWriteTask< Model > > >
561 return std::make_pair(
564 group_builder, writer, dataset_builder, group_attr, dset_attr));
574 template <
typename Model, TypeTag typetag >
575 std::unordered_map< std::string,
576 std::function< std::string(std::string,
Model&) > >
578 std::unordered_map< std::string,
579 std::function< std::string(std::string,
Model&) > >{
581 [](std::string path,
Model& m) {
597 template <
class Model >
611 template <
typename ArgTpl >
612 std::pair< std::string,
613 std::shared_ptr< Default::DefaultWriteTask< Model > > >
617 if (typetag ==
"plain")
621 return std::apply(factory, std::forward< ArgTpl >(arg_tpl));
623 else if (typetag ==
"edge_property")
627 return std::apply(factory, std::forward< ArgTpl >(arg_tpl));
629 else if (typetag ==
"vertex_descriptor")
633 return std::apply(factory, std::forward< ArgTpl >(arg_tpl));
635 else if (typetag ==
"vertex_property")
639 return std::apply(factory, std::forward< ArgTpl >(arg_tpl));
645 return std::apply(factory, std::forward< ArgTpl >(arg_tpl));
673 template <
typename... Args >
676 const std::tuple< Args... >& args,
678 Default::default_deciders<Model>,
680 Default::default_triggers<Model>)
683 const auto _log = spdlog::get(
"data_mngr");
685 if constexpr (
sizeof...(Args) == 0)
687 _log->info(
"Empty argument tuple for DataManager factory, "
688 "building default ...");
695 std::map< std::string, Config > tasknodes;
696 for (
auto&& node : conf[
"tasks"])
698 _log->info(
"Name of current task: {}",
699 node.first.as< std::string >());
701 tasknodes[node.first.as< std::string >()] = node.second;
708 std::shared_ptr< Default::DefaultWriteTask< Model > > >
719 [&](
const auto& arg_tpl) {
721 std::string name =
"";
722 std::string name_in_tpl = get< 0 >(arg_tpl);
723 auto tasknode_iter = tasknodes.find(name_in_tpl);
726 if (tasknode_iter != tasknodes.end())
728 name = tasknode_iter->first;
733 throw std::invalid_argument(
734 "A task with name '" + name_in_tpl +
735 "' was not found in the config!");
739 std::string typetag =
"";
740 if (not tasknode_iter->second[
"typetag"])
746 get_as< std::string >(
"typetag", tasknode_iter->second);
752 boost::hana::remove_at(arg_tpl,
753 boost::hana::size_t< 0 >{}),
755 return boost::hana::type_c<
756 std::decay_t< decltype(t) > >;
759 constexpr
bool is_all_callable =
760 decltype(boost::hana::unpack(
762 boost::hana::template_<
766 if constexpr (is_all_callable)
768 _log->info(
"Building write task '{}' via factory ...",
777 auto config_args = std::make_tuple(
781 get_as< std::string >(
"basegroup_path",
782 tasknode_iter->second),
785 get_as< std::string >(
"dataset_path",
786 tasknode_iter->second),
787 (tasknode_iter->second[
"capacity"]
788 ? get_as< std::vector< hsize_t > >(
789 "capacity", tasknode_iter->second)
790 : std::vector< hsize_t >{}),
791 (tasknode_iter->second[
"chunksize"]
792 ? get_as< std::vector< hsize_t > >(
793 "chunksize", tasknode_iter->second)
794 : std::vector< hsize_t >{}),
795 (tasknode_iter->second[
"compression"]
796 ? get_as< int >(
"compression",
797 tasknode_iter->second)
802 auto full_arg_tpl = std::tuple_cat(
804 boost::hana::remove_at(arg_tpl,
805 boost::hana::size_t< 0 >{}));
807 _log->info(
"Building write task '{}' via factory ...",
814 _log->info(
"Forwarding arguments to DataManager constructor ...");
Factory function which produces a Datamanager of type Default::DefaultDataManager<Model> from a confi...
Definition: factory.hh:599
std::pair< std::string, std::shared_ptr< Default::DefaultWriteTask< Model > > > _call_taskfactory(std::string typetag, ArgTpl &&arg_tpl)
Function which calls the taskfactory with argument tuples, and takes care of using the correct type-t...
Definition: factory.hh:614
auto operator()(const Config &conf, const std::tuple< Args... > &args, const Default::DefaultDecidermap< Model > &deciderfactories=Default::default_deciders< Model >, const Default::DefaultTriggermap< Model > &triggerfactories=Default::default_triggers< Model >)
Builds a new datamanager from a config file and a tuple of tuples of arguments.
Definition: factory.hh:675
Manage different tasks of writing out data from a source in a uniform yet flexible way....
Definition: data_manager.hh:131
Functor for building a writetask from arguments.
Definition: factory.hh:105
std::pair< std::string, std::shared_ptr< Default::DefaultWriteTask< Model > > > operator()(std::string name, std::string basegroup_path, DatasetDescriptor dataset_descriptor, SourceGetter &&get_source, Getter &&getter, Group_attribute &&group_attribute=Nothing{}, Dataset_attribute &&dataset_attribute=Nothing{})
Basic factory function producing Default::DefaultWriteTask<Model> intstances, for writing out data....
Definition: factory.hh:454
Func _make_attribute_writer(AttributeHandle &&attr)
Function which produces functions for writing attributes to a dataset or group, and which are used by...
Definition: factory.hh:131
std::pair< std::string, std::shared_ptr< Default::DefaultWriteTask< Model > > > operator()(std::string name, Default::DefaultBaseGroupBuilder group_builder, Default::DefaultDataWriter< Model > writer, Default::DefaultBuilder< Model > dataset_builder, Default::DefaultAttributeWriterGroup< Model > group_attr, Default::DefaultAttributeWriterDataset< Model > dset_attr)
Thin wrapper around the writetask constructor which allows to construct a writetask via the factory b...
Definition: factory.hh:554
Default::DefaultBuilder< Model > _make_dataset_builder(DatasetDescriptor dataset_descriptor)
Function producing a dataset builder function of type Default::DefaultBuilder<Model>,...
Definition: factory.hh:201
Default::DefaultDataWriter< Model > _adapt_graph_writer(SourceGetter &&get_source, Getter &&getter)
Function which adapts getter functions for the correct graph accessor type, i.e., vertex_descriptor e...
Definition: factory.hh:261
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
OutputIt transform(const Utopia::ExecPolicy policy, InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op)
Apply a unary operator to a range and store the result in a new range.
Definition: parallel.hh:368
void for_each(const Utopia::ExecPolicy policy, InputIt first, InputIt last, UnaryFunction f)
Apply a function to a range.
Definition: parallel.hh:346
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
std::function< void(std::shared_ptr< HDFDataset > &, Model &) > DefaultAttributeWriterDataset
Type of the default attribute writer for datasets.
Definition: defaults.hh:54
std::function< std::shared_ptr< HDFGroup >(std::shared_ptr< HDFGroup > &&) > DefaultBaseGroupBuilder
Type of the default group builder.
Definition: defaults.hh:34
std::unordered_map< std::string, std::function< std::shared_ptr< Decider< Model > >() > > DefaultDecidermap
Definition: defaults.hh:406
std::function< std::shared_ptr< HDFDataset >(std::shared_ptr< HDFGroup > &, Model &) > DefaultBuilder
Type of the default dataset builder.
Definition: defaults.hh:44
std::function< void(std::shared_ptr< HDFGroup > &, Model &) > DefaultAttributeWriterGroup
Type of the default attribute writer for groups.
Definition: defaults.hh:49
DefaultDecidermap< Model > DefaultTriggermap
Definition: defaults.hh:454
std::function< void(std::shared_ptr< HDFDataset > &, Model &) > DefaultDataWriter
Type of the default data writer.
Definition: defaults.hh:39
static std::unordered_map< std::string, std::function< std::string(std::string, Model &) > > _modifiers
Initialization of the modifier map.
Definition: factory.hh:110
TypeTag
TypeTag enumerates the kind of access which is used to write data. It became necessary after integrat...
Definition: factory.hh:84
boost::adjacency_list< EdgeContainer, VertexContainer, boost::bidirectionalS, Vertex, Edge > GraphType
The type of the graph.
Definition: CopyMeGraph.hh:146
constexpr bool is_graph_v
Shorthand for is_graph<T>::value.
Definition: type_traits.hh:418
constexpr bool is_container_v
Shorthand for 'is_container::value.
Definition: type_traits.hh:181
Metafunction for use with boost hana, check if all T are callable types.
Definition: utils.hh:39
Descriptor for a dataset. Contains: path: string giving the path of the dataset in its group or file ...
Definition: factory.hh:65
std::vector< hsize_t > dataset_chunksize
Definition: factory.hh:68
std::string path
Definition: factory.hh:66
int dataset_compression
Definition: factory.hh:69
std::vector< hsize_t > dataset_capacity
Definition: factory.hh:67
Functor representing what is considered the most widely used execution process for writing data.
Definition: defaults.hh:84
Encapsulate a task for writing data to a destination. Containes a callable 'writer' responisible for ...
Definition: write_task.hh:50
Represent a type that does nothing and represents nothing, hence can be used in metaprogramming whene...
Definition: type_traits.hh:742