NEML2 2.0.0
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Parser.h
1// Copyright 2024, UChicago Argonne, LLC
2// All Rights Reserved
3// Software Name: NEML2 -- the New Engineering material Model Library, version 2
4// By: Argonne National Laboratory
5// OPEN SOURCE LICENSE (MIT)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23// THE SOFTWARE.
24#pragma once
25
26#include <filesystem>
27
28#include "neml2/misc/string_utils.h"
29#include "neml2/misc/defaults.h"
30
31namespace neml2
32{
36class EnumSelection;
38
44class Parser
45{
46public:
47 Parser() = default;
48
49 Parser(const Parser &) = default;
50 Parser(Parser &&) noexcept = default;
51 Parser & operator=(const Parser &) = default;
52 Parser & operator=(Parser &&) noexcept = default;
53 virtual ~Parser() = default;
54
56 static const std::vector<std::string> sections;
57
66 virtual OptionCollection parse(const std::filesystem::path & filename,
67 const std::string & additional_input = "") const = 0;
68};
69
70namespace utils
71{
72template <typename T>
73std::string
74parse_failure_message(const std::string & raw_str)
75{
76 if constexpr (std::is_same_v<T, bool>)
77 return "Failed to parse '" + raw_str +
78 "' as a boolean. Only 'true' and 'false' (case-sensitive) are recognized.";
79
80 if constexpr (std::is_same_v<T, TensorShape>)
81 return "Failed to parse '" + raw_str +
82 "' as a tensor shape. Tensor shapes must be of the form "
83 "'(d1,d2,...,dn)': It must begin with '(' and end with ')', d1, d2, "
84 "... must be integers, and there must be no white spaces.";
85
86 return "Failed to parse '" + raw_str + "' as a " + utils::demangle(typeid(T).name());
87}
88
89template <typename T>
90bool
91parse_(T & val, const std::string & raw_str)
92{
93 std::stringstream ss(trim(raw_str));
94 ss >> val;
95 return !ss.fail();
96}
97
98template <typename T>
99T
100parse(const std::string & raw_str)
101{
102 T val;
103 auto success = parse_(val, raw_str);
104 if (!success)
106 return val;
107}
108
109template <typename T>
110bool
111parse_vector_(std::vector<T> & vals, const std::string & raw_str)
112{
113 auto tokens = split(raw_str, " \t\n\v\f\r");
114 if constexpr (std::is_same_v<T, Device>)
115 vals.resize(tokens.size(), kCPU);
116 else
117 vals.resize(tokens.size());
118 for (size_t i = 0; i < tokens.size(); i++)
119 {
120 auto success = parse_<T>(vals[i], tokens[i]);
121 if (!success)
122 return false;
123 }
124 return true;
125}
126
127template <typename T>
128std::vector<T>
129parse_vector(const std::string & raw_str)
130{
131 std::vector<T> vals;
132 auto success = parse_vector_(vals, raw_str);
133 if (!success)
134 throw ParserException("Failed to parse '" + raw_str + "' as a vector of " +
135 utils::demangle(typeid(T).name()));
136 return vals;
137}
138
139template <typename T>
140bool
141parse_vector_vector_(std::vector<std::vector<T>> & vals, const std::string & raw_str)
142{
143 auto token_vecs = split(raw_str, ";");
144 vals.resize(token_vecs.size());
145 for (size_t i = 0; i < token_vecs.size(); i++)
146 {
147 auto success = parse_vector_<T>(vals[i], token_vecs[i]);
148 if (!success)
149 return false;
150 }
151 return true;
152}
153
154template <typename T>
155std::vector<std::vector<T>>
156parse_vector_vector(const std::string & raw_str)
157{
158 std::vector<std::vector<T>> vals;
159 auto success = parse_vector_vector_(vals, raw_str);
160 if (!success)
161 throw ParserException("Failed to parse '" + raw_str + "' as a vector of vector of " +
162 utils::demangle(typeid(T).name()));
163 return vals;
164}
165
166// template specializations for special option types
167template <>
168bool parse_<bool>(bool &, const std::string & raw_str);
170template <>
171bool parse_vector_<bool>(std::vector<bool> &, const std::string & raw_str);
172template <>
173bool parse_<TensorShape>(TensorShape &, const std::string & raw_str);
174template <>
175bool parse_<VariableName>(VariableName &, const std::string & raw_str);
176template <>
177Device parse<Device>(const std::string & raw_str);
178template <>
179bool parse_<Device>(Device &, const std::string & raw_str);
180} // namespace utils
181} // namespace neml2
Selection of an enum value from a list of candidates.
Definition EnumSelection.h:41
The accessor containing all the information needed to access an item in a LabeledAxis.
Definition LabeledAxisAccessor.h:56
Selection of multiple enum value from a list of candidates.
Definition MultiEnumSelection.h:41
A data structure that holds options of multiple objects.
Definition OptionCollection.h:38
Definition errors.h:64
virtual OptionCollection parse(const std::filesystem::path &filename, const std::string &additional_input="") const =0
Deserialize a file.
static const std::vector< std::string > sections
Known top-level sections in the input file.
Definition Parser.h:56
Parser()=default
Parser(const Parser &)=default
Parser(Parser &&) noexcept=default
Definition Parser.cxx:35
Device parse(const std::string &raw_str)
Definition Parser.cxx:108
std::string trim(const std::string &str, const std::string &white_space)
Definition string_utils.cxx:73
std::string parse_failure_message(const std::string &raw_str)
Definition Parser.h:74
bool parse_vector_vector_(std::vector< std::vector< T > > &vals, const std::string &raw_str)
Definition Parser.h:141
bool parse_vector_(std::vector< bool > &vals, const std::string &raw_str)
Definition Parser.cxx:62
std::string demangle(const char *name)
Demangle a piece of cxx abi type information.
Definition string_utils.cxx:32
std::vector< T > parse_vector(const std::string &raw_str)
Definition Parser.h:129
std::vector< std::vector< T > > parse_vector_vector(const std::string &raw_str)
Definition Parser.h:156
std::vector< std::string > split(const std::string &str, const std::string &delims)
Definition string_utils.cxx:52
bool parse_(bool &val, const std::string &raw_str)
Definition Parser.cxx:38
Definition DiagnosticsInterface.cxx:30
c10::Device Device
Definition types.h:66
c10::SmallVector< Size, 8 > TensorShape
Definition types.h:71
std::string name(ElasticConstant p)
Definition ElasticityConverter.cxx:30
LabeledAxisAccessor VariableName
Definition LabeledAxisAccessor.h:185
constexpr auto kCPU
Definition types.h:56