Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 : #ifdef MOOSE_LIBTORCH_ENABLED
10 :
11 : #include "CovarianceFunctionBase.h"
12 : #include "LibtorchUtils.h"
13 :
14 : namespace
15 : {
16 :
17 : torch::Tensor
18 524 : makeScalarHyperParameter(const Real value)
19 : {
20 524 : return torch::tensor(value, torch::TensorOptions().dtype(at::kDouble));
21 : }
22 :
23 : torch::Tensor
24 290 : makeVectorHyperParameter(const std::vector<Real> & value)
25 : {
26 290 : return LibtorchUtils::vectorToTensorCopy(value, {long(value.size())});
27 : }
28 :
29 : torch::Tensor &
30 814 : insertHyperParameter(std::unordered_map<std::string, torch::Tensor> & hyperparameters,
31 : std::unordered_set<std::string> & tunable_hp,
32 : const std::string & prefixed_name,
33 : torch::Tensor tensor,
34 : const bool is_tunable)
35 : {
36 814 : if (is_tunable)
37 : tunable_hp.insert(prefixed_name);
38 814 : return hyperparameters.emplace(prefixed_name, std::move(tensor)).first->second;
39 : }
40 :
41 : } // namespace
42 :
43 : bool
44 1900000 : CovarianceFunctionBase::isScalarHyperParameter(const torch::Tensor & tensor)
45 : {
46 1900000 : return tensor.dim() == 0;
47 : }
48 :
49 : bool
50 769561 : CovarianceFunctionBase::isVectorHyperParameter(const torch::Tensor & tensor)
51 : {
52 769561 : return tensor.dim() == 1;
53 : }
54 :
55 : InputParameters
56 532 : CovarianceFunctionBase::validParams()
57 : {
58 532 : InputParameters params = MooseObject::validParams();
59 1064 : params.addParam<std::vector<UserObjectName>>(
60 : "covariance_functions", {}, "Covariance functions that this covariance function depends on.");
61 1064 : params.addParam<unsigned int>(
62 1064 : "num_outputs", 1, "The number of outputs expected for this covariance function.");
63 532 : params.addClassDescription("Base class for covariance functions");
64 532 : params.registerBase("CovarianceFunctionBase");
65 532 : params.registerSystemAttributeName("CovarianceFunction");
66 532 : return params;
67 0 : }
68 :
69 266 : CovarianceFunctionBase::CovarianceFunctionBase(const InputParameters & parameters)
70 : : MooseObject(parameters),
71 : CovarianceInterface(parameters),
72 532 : _num_outputs(getParam<unsigned int>("num_outputs")),
73 1064 : _dependent_covariance_names(getParam<std::vector<UserObjectName>>("covariance_functions"))
74 :
75 : {
76 : // Fetch the dependent covariance functions
77 290 : for (const auto & name : _dependent_covariance_names)
78 : {
79 24 : _covariance_functions.push_back(getCovarianceFunctionByName(name));
80 24 : _dependent_covariance_types.push_back(_covariance_functions.back()->type());
81 : }
82 266 : }
83 :
84 : bool
85 0 : CovarianceFunctionBase::computedKdhyper(torch::Tensor & /*dKdhp*/,
86 : const torch::Tensor & /*x*/,
87 : const std::string & /*hyper_param_name*/,
88 : unsigned int /*ind*/) const
89 : {
90 0 : mooseError("Hyperparameter tuning not set up for this covariance function. Please define "
91 : "computedKdhyper() to compute gradient.");
92 : }
93 :
94 : torch::Tensor &
95 524 : CovarianceFunctionBase::addRealHyperParameter(const std::string & name,
96 : const Real value,
97 : const bool is_tunable)
98 : {
99 524 : const auto prefixed_name = _name + ":" + name;
100 1048 : return insertHyperParameter(
101 1048 : _hyperparameters, _tunable_hp, prefixed_name, makeScalarHyperParameter(value), is_tunable);
102 : }
103 :
104 : torch::Tensor &
105 290 : CovarianceFunctionBase::addVectorRealHyperParameter(const std::string & name,
106 : const std::vector<Real> & value,
107 : const bool is_tunable)
108 : {
109 290 : const auto prefixed_name = _name + ":" + name;
110 580 : return insertHyperParameter(
111 580 : _hyperparameters, _tunable_hp, prefixed_name, makeVectorHyperParameter(value), is_tunable);
112 : }
113 :
114 : bool
115 368 : CovarianceFunctionBase::isTunable(const std::string & name) const
116 : {
117 : // First, we check if the dependent covariances have the parameter
118 384 : for (const auto dependent_covar : _covariance_functions)
119 32 : if (dependent_covar->isTunable(name))
120 : return true;
121 :
122 352 : if (_tunable_hp.find(name) != _tunable_hp.end())
123 : return true;
124 16 : else if (_hyperparameters.find(name) != _hyperparameters.end())
125 0 : mooseError("We found hyperparameter ", name, " but it was not declared tunable!");
126 :
127 : return false;
128 : }
129 :
130 : void
131 376443 : CovarianceFunctionBase::loadHyperParamMap(const HyperParameterMap & map)
132 : {
133 : // First, load the hyperparameters of the dependent covariance functions
134 384467 : for (const auto dependent_covar : _covariance_functions)
135 8024 : dependent_covar->loadHyperParamMap(map);
136 :
137 : // Then we load the hyperparameters of this object
138 1521788 : for (auto & iter : _hyperparameters)
139 : {
140 1145345 : const auto map_iter = map.find(iter.first);
141 1145345 : if (map_iter == map.end())
142 : continue;
143 :
144 1529812 : if (!isScalarHyperParameter(map_iter->second) && !isVectorHyperParameter(map_iter->second))
145 0 : mooseError(
146 0 : "Unsupported hyperparameter rank ", map_iter->second.dim(), " for ", iter.first, ".");
147 :
148 2290690 : iter.second = map_iter->second.clone();
149 : }
150 376443 : }
151 :
152 : void
153 419 : CovarianceFunctionBase::buildHyperParamMap(HyperParameterMap & map) const
154 : {
155 : // First, add the hyperparameters of the dependent covariance functions
156 435 : for (const auto dependent_covar : _covariance_functions)
157 16 : dependent_covar->buildHyperParamMap(map);
158 :
159 : // At the end we just append the hyperparameters this object owns
160 1700 : for (const auto & iter : _hyperparameters)
161 1281 : if (!isScalarHyperParameter(iter.second) && !isVectorHyperParameter(iter.second))
162 0 : mooseError("Unsupported hyperparameter rank ", iter.second.dim(), " for ", iter.first, ".");
163 : else
164 2562 : map[iter.first] = iter.second.clone();
165 419 : }
166 :
167 : bool
168 368 : CovarianceFunctionBase::getTuningData(const std::string & name,
169 : unsigned int & size,
170 : Real & min,
171 : Real & max) const
172 : {
173 : // First, check the dependent covariances
174 384 : for (const auto dependent_covar : _covariance_functions)
175 32 : if (dependent_covar->getTuningData(name, size, min, max))
176 : return true;
177 :
178 352 : min = 1e-9;
179 352 : max = 1e9;
180 :
181 : const auto tensor_value = _hyperparameters.find(name);
182 352 : if (tensor_value == _hyperparameters.end())
183 : {
184 16 : size = 0;
185 16 : return false;
186 : }
187 :
188 336 : if (isScalarHyperParameter(tensor_value->second))
189 : {
190 160 : size = 1;
191 160 : return true;
192 : }
193 :
194 176 : if (isVectorHyperParameter(tensor_value->second))
195 : {
196 176 : size = tensor_value->second.numel();
197 176 : return true;
198 : }
199 :
200 0 : mooseError("Unsupported hyperparameter rank ", tensor_value->second.dim(), " for ", name, ".");
201 : }
202 :
203 : void
204 264 : CovarianceFunctionBase::dependentCovarianceTypes(
205 : std::map<UserObjectName, std::string> & name_type_map) const
206 : {
207 288 : for (const auto dependent_covar : _covariance_functions)
208 : {
209 24 : dependent_covar->dependentCovarianceTypes(name_type_map);
210 24 : name_type_map.insert(std::make_pair(dependent_covar->name(), dependent_covar->type()));
211 : }
212 264 : }
213 :
214 : #endif
|