Ginkgo  Generated from pipelines/1757323510 branch based on develop. Ginkgo version 1.10.0
A numerical linear algebra library targeting many-core architectures
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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 
17 namespace gko {
18 namespace ext {
19 namespace config {
20 
21 
26 inline 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 
125 inline 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_
gko::config::pnode
pnode describes a tree of properties.
Definition: property_tree.hpp:28
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20