https://mooseframework.inl.gov
CovarianceFunctionBase.C
Go to the documentation of this file.
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 makeScalarHyperParameter(const Real value)
19 {
20  return torch::tensor(value, torch::TensorOptions().dtype(at::kDouble));
21 }
22 
23 torch::Tensor
24 makeVectorHyperParameter(const std::vector<Real> & value)
25 {
26  return LibtorchUtils::vectorToTensorCopy(value, {long(value.size())});
27 }
28 
29 torch::Tensor &
30 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  if (is_tunable)
37  tunable_hp.insert(prefixed_name);
38  return hyperparameters.emplace(prefixed_name, std::move(tensor)).first->second;
39 }
40 
41 } // namespace
42 
43 bool
45 {
46  return tensor.dim() == 0;
47 }
48 
49 bool
51 {
52  return tensor.dim() == 1;
53 }
54 
57 {
59  params.addParam<std::vector<UserObjectName>>(
60  "covariance_functions", {}, "Covariance functions that this covariance function depends on.");
61  params.addParam<unsigned int>(
62  "num_outputs", 1, "The number of outputs expected for this covariance function.");
63  params.addClassDescription("Base class for covariance functions");
64  params.registerBase("CovarianceFunctionBase");
65  params.registerSystemAttributeName("CovarianceFunction");
66  return params;
67 }
68 
70  : MooseObject(parameters),
71  CovarianceInterface(parameters),
72  _num_outputs(getParam<unsigned int>("num_outputs")),
73  _dependent_covariance_names(getParam<std::vector<UserObjectName>>("covariance_functions"))
74 
75 {
76  // Fetch the dependent covariance functions
77  for (const auto & name : _dependent_covariance_names)
78  {
80  _dependent_covariance_types.push_back(_covariance_functions.back()->type());
81  }
82 }
83 
84 bool
85 CovarianceFunctionBase::computedKdhyper(torch::Tensor & /*dKdhp*/,
86  const torch::Tensor & /*x*/,
87  const std::string & /*hyper_param_name*/,
88  unsigned int /*ind*/) const
89 {
90  mooseError("Hyperparameter tuning not set up for this covariance function. Please define "
91  "computedKdhyper() to compute gradient.");
92 }
93 
94 torch::Tensor &
96  const Real value,
97  const bool is_tunable)
98 {
99  const auto prefixed_name = _name + ":" + name;
100  return insertHyperParameter(
101  _hyperparameters, _tunable_hp, prefixed_name, makeScalarHyperParameter(value), is_tunable);
102 }
103 
104 torch::Tensor &
106  const std::vector<Real> & value,
107  const bool is_tunable)
108 {
109  const auto prefixed_name = _name + ":" + name;
110  return insertHyperParameter(
111  _hyperparameters, _tunable_hp, prefixed_name, makeVectorHyperParameter(value), is_tunable);
112 }
113 
114 bool
115 CovarianceFunctionBase::isTunable(const std::string & name) const
116 {
117  // First, we check if the dependent covariances have the parameter
118  for (const auto dependent_covar : _covariance_functions)
119  if (dependent_covar->isTunable(name))
120  return true;
121 
122  if (_tunable_hp.find(name) != _tunable_hp.end())
123  return true;
124  else if (_hyperparameters.find(name) != _hyperparameters.end())
125  mooseError("We found hyperparameter ", name, " but it was not declared tunable!");
126 
127  return false;
128 }
129 
130 void
132 {
133  // First, load the hyperparameters of the dependent covariance functions
134  for (const auto dependent_covar : _covariance_functions)
135  dependent_covar->loadHyperParamMap(map);
136 
137  // Then we load the hyperparameters of this object
138  for (auto & iter : _hyperparameters)
139  {
140  const auto map_iter = map.find(iter.first);
141  if (map_iter == map.end())
142  continue;
143 
144  if (!isScalarHyperParameter(map_iter->second) && !isVectorHyperParameter(map_iter->second))
145  mooseError(
146  "Unsupported hyperparameter rank ", map_iter->second.dim(), " for ", iter.first, ".");
147 
148  iter.second = map_iter->second.clone();
149  }
150 }
151 
152 void
154 {
155  // First, add the hyperparameters of the dependent covariance functions
156  for (const auto dependent_covar : _covariance_functions)
157  dependent_covar->buildHyperParamMap(map);
158 
159  // At the end we just append the hyperparameters this object owns
160  for (const auto & iter : _hyperparameters)
161  if (!isScalarHyperParameter(iter.second) && !isVectorHyperParameter(iter.second))
162  mooseError("Unsupported hyperparameter rank ", iter.second.dim(), " for ", iter.first, ".");
163  else
164  map[iter.first] = iter.second.clone();
165 }
166 
167 bool
169  unsigned int & size,
170  Real & min,
171  Real & max) const
172 {
173  // First, check the dependent covariances
174  for (const auto dependent_covar : _covariance_functions)
175  if (dependent_covar->getTuningData(name, size, min, max))
176  return true;
177 
178  min = 1e-9;
179  max = 1e9;
180 
181  const auto tensor_value = _hyperparameters.find(name);
182  if (tensor_value == _hyperparameters.end())
183  {
184  size = 0;
185  return false;
186  }
187 
188  if (isScalarHyperParameter(tensor_value->second))
189  {
190  size = 1;
191  return true;
192  }
193 
194  if (isVectorHyperParameter(tensor_value->second))
195  {
196  size = tensor_value->second.numel();
197  return true;
198  }
199 
200  mooseError("Unsupported hyperparameter rank ", tensor_value->second.dim(), " for ", name, ".");
201 }
202 
203 void
205  std::map<UserObjectName, std::string> & name_type_map) const
206 {
207  for (const auto dependent_covar : _covariance_functions)
208  {
209  dependent_covar->dependentCovarianceTypes(name_type_map);
210  name_type_map.insert(std::make_pair(dependent_covar->name(), dependent_covar->type()));
211  }
212 }
213 
214 #endif
HyperParameterMap _hyperparameters
Map of hyperparameters stored as rank-0 or rank-1 tensors.
std::vector< std::string > _dependent_covariance_types
The types of the dependent covariance functions.
std::unordered_set< std::string > _tunable_hp
list of tunable hyper-parameters
const std::string & _name
static bool isVectorHyperParameter(const torch::Tensor &tensor)
Return true if a hyperparameter tensor stores a vector of values.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::unordered_map< std::string, torch::Tensor > HyperParameterMap
torch::Tensor vectorToTensorCopy(const std::vector< DataType > &vector, c10::IntArrayRef sizes)
static bool isScalarHyperParameter(const torch::Tensor &tensor)
Return true if a hyperparameter tensor stores one scalar value.
std::vector< CovarianceFunctionBase * > _covariance_functions
Vector of pointers to the dependent covariance functions.
void registerSystemAttributeName(const std::string &value)
static InputParameters validParams()
CovarianceFunctionBase(const InputParameters &parameters)
void buildHyperParamMap(HyperParameterMap &map) const
Populates the input maps with the owned hyperparameters.
auto max(const L &left, const R &right)
void registerBase(const std::string &value)
const std::string & name() const
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const std::string name
Definition: Setup.h:21
void loadHyperParamMap(const HyperParameterMap &map)
Load some hyperparameters into the local map contained in this object.
torch::Tensor & addRealHyperParameter(const std::string &name, const Real value, const bool is_tunable)
Register a scalar hyperparameter to this covariance function.
void dependentCovarianceTypes(std::map< UserObjectName, std::string > &name_type_map) const
Populate a map with the names and types of the dependent covariance functions.
virtual bool computedKdhyper(torch::Tensor &dKdhp, const torch::Tensor &x, const std::string &hyper_param_name, unsigned int ind) const
Redirect dK/dhp for hyperparameter "hp".
const std::vector< UserObjectName > _dependent_covariance_names
The names of the dependent covariance functions.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
torch::Tensor & addVectorRealHyperParameter(const std::string &name, const std::vector< Real > &value, const bool is_tunable)
Register a vector hyperparameter to this covariance function.
static InputParameters validParams()
auto min(const L &left, const R &right)
void ErrorVector unsigned int
virtual bool getTuningData(const std::string &name, unsigned int &size, Real &min, Real &max) const
Get the default minimum and maximum and size of a hyperparameter.
virtual bool isTunable(const std::string &name) const
Check if a given parameter is tunable.
CovarianceFunctionBase * getCovarianceFunctionByName(const UserObjectName &name) const
Lookup a CovarianceFunction object by name and return pointer.