LCOV - code coverage report
Current view: top level - src/covariances - CovarianceFunctionBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: #33416 (b10b36) with base 9fbd27 Lines: 75 83 90.4 %
Date: 2026-07-23 16:21:17 Functions: 14 15 93.3 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.14