Ginkgo Generated from branch based on main. Ginkgo version 1.10.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
yaml_config.hpp
1// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#ifndef GKO_PUBLIC_EXTENSIONS_CONFIG_JSON_CONFIG_HPP_
6#define GKO_PUBLIC_EXTENSIONS_CONFIG_JSON_CONFIG_HPP_
7
8#include <iostream>
9#include <stdexcept>
10#include <string>
11
12#include <yaml-cpp/yaml.h>
13
14#include <ginkgo/core/config/property_tree.hpp>
15
16
17namespace gko {
18namespace ext {
19namespace config {
20
21
26inline gko::config::pnode parse_yaml(const YAML::Node& input)
27{
28 auto parse_array = [](const auto& arr) {
29 gko::config::pnode::array_type nodes;
30 for (const auto& it : arr) {
31 nodes.emplace_back(parse_yaml(it));
32 }
33 return gko::config::pnode{nodes};
34 };
35 auto parse_map = [](const auto& map) {
36 gko::config::pnode::map_type nodes;
37 // use [] to get override behavior
38 for (const auto& yaml_item : map) {
39 std::string key = yaml_item.first.template as<std::string>();
40 // yaml-cpp keeps the alias without resolving it when parsing.
41 // We resolve them here.
42 if (key == "<<") {
43 auto node = parse_yaml(yaml_item.second);
44 if (node.get_tag() == gko::config::pnode::tag_t::array) {
45 for (const auto& arr : node.get_array()) {
46 if (arr.get_tag() != gko::config::pnode::tag_t::map) {
47 throw std::runtime_error(
48 "YAML only accepts merge key << to merge item "
49 "from map not " +
50 YAML::Dump(yaml_item.second));
51 }
52 for (const auto& item : arr.get_map()) {
53 nodes[item.first] = item.second;
54 }
55 }
56 } else if (node.get_tag() == gko::config::pnode::tag_t::map) {
57 for (const auto& item : node.get_map()) {
58 nodes[item.first] = item.second;
59 }
60 } else {
61 throw std::runtime_error("can not handle this alias: " +
62 YAML::Dump(yaml_item.second));
63 }
64 } else {
65 nodes[key] = parse_yaml(yaml_item.second);
66 }
67 }
68 return gko::config::pnode{nodes};
69 };
70 // yaml-cpp does not have type check
71 auto parse_data = [](const auto& data) {
72 if (std::int64_t value;
73 YAML::convert<std::int64_t>::decode(data, value)) {
74 return gko::config::pnode{value};
75 }
76 if (bool value; YAML::convert<bool>::decode(data, value)) {
77 return gko::config::pnode{value};
78 }
79 if (double value; YAML::convert<double>::decode(data, value)) {
80 return gko::config::pnode{value};
81 }
82 if (std::string value;
83 YAML::convert<std::string>::decode(data, value)) {
84 return gko::config::pnode{value};
85 }
86 std::string content = YAML::Dump(data);
87 throw std::runtime_error(
88 "property_tree can not handle the node with content: " + content);
89 };
90
91 if (input.IsSequence()) {
92 return parse_array(input);
93 }
94 if (input.IsMap()) {
95 return parse_map(input);
96 }
97 return parse_data(input);
98}
99
100
125inline gko::config::pnode parse_yaml_file(std::string filename)
126{
127 return parse_yaml(YAML::LoadFile(filename));
128}
129
130
131} // namespace config
132} // namespace ext
133} // namespace gko
134
135
136#endif // GKO_PUBLIC_EXTENSIONS_CONFIG_JSON_CONFIG_HPP_
The Ginkgo namespace.
Definition abstract_factory.hpp:20
std::decay_t< T > * as(U *obj)
Performs polymorphic type conversion.
Definition utils_helper.hpp:307