https://mooseframework.inl.gov
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Attributes | Private Member Functions | Friends | List of all members
Moose::internal::Capabilities Class Reference

Holds the public (to MooseApp) facing CapabilityRegistry for storing and checking capabilities. More...

#include <Capabilities.h>

Inheritance diagram for Moose::internal::Capabilities:
[legend]

Classes

class  AugmentPassKey
 Passkey for augment() More...
 
class  GetCapabilitiesPassKey
 Passkey for get() More...
 

Public Types

enum  CheckState {
  CERTAIN_FAIL = 0, POSSIBLE_FAIL = 1, UNKNOWN = 2, POSSIBLE_PASS = 3,
  CERTAIN_PASS = 4, IGNORE = 5
}
 Return state for check. More...
 
using RegistryType = std::map< std::string, Capability, std::less<> >
 Type for the registry. More...
 

Public Member Functions

std::string dump () const
 create a JSON dump of the capabilities registry More...
 
void augment (const nlohmann::json &input, const AugmentPassKey)
 Augment the capabilities with the given input capabilities. More...
 
bool isRelocated () const
 
bool isInTree () const
 
Capabilityadd (const std::string_view name, const Moose::Capability::Value &value, const std::string_view doc)
 Add a capability. More...
 
std::size_t size () const
 
CheckResult check (std::string requirements, const CapabilityRegistry::CheckOptions &options=CapabilityRegistry::CheckOptions()) const
 Checks if a set of requirements is satisified by the capabilities. More...
 
 Capabilities (Capabilities const &)=delete
 Don't allow creation through copy/move construction or assignment. More...
 
Capabilitiesoperator= (Capabilities const &)=delete
 
 Capabilities (Capabilities &&)=delete
 
Capabilitiesoperator= (Capabilities &&)=delete
 
const Capabilityquery (std::string capability) const
 Query a capability, if it exists, otherwise nullptr. More...
 
Capabilityquery (std::string capability)
 
const Capabilityget (const std::string &capability) const
 Get a capability. More...
 
Capabilityget (const std::string &capability)
 

Static Public Member Functions

static CapabilitiesgetCapabilities (const GetCapabilitiesPassKey)
 Get the singleton Capabilities. More...
 

Static Public Attributes

static const std::set< std::string, std::less<> > augmented_capability_names
 Capabilities that are reserved and can only be augmented. More...
 

Protected Attributes

RegistryType _registry
 Registry storage. More...
 

Private Member Functions

 FRIEND_TEST (::CapabilitiesTest, isInstallationType)
 
 FRIEND_TEST (::CapabilitiesTest, mooseAppIsRelocated)
 
 FRIEND_TEST (::CapabilitiesTest, mooseAppisInTree)
 
bool isInstallationType (const std::string &installation_type) const
 Helper for isRelocated() and isInTree() More...
 
void registerMooseCapabilities ()
 Register the MOOSE capabilities. More...
 
 Capabilities ()
 

Friends

class ::CapabilitiesTest
 
class ::DataFileUtilsTest
 
class ::RegistryTest
 

Detailed Description

Holds the public (to MooseApp) facing CapabilityRegistry for storing and checking capabilities.

A capability can refer to an optional library or optional functionality. Capabilities can either be registered as boolean values (present or not), an integer quantity (like the AD backing store size), a string (like the compiler used to build the executable), or a version number (numbers separated by dots, e.g. the petsc version).

Definition at line 50 of file Capabilities.h.

Member Typedef Documentation

◆ RegistryType

using Moose::internal::CapabilityRegistry::RegistryType = std::map<std::string, Capability, std::less<> >
inherited

Type for the registry.

Definition at line 43 of file CapabilityRegistry.h.

Member Enumeration Documentation

◆ CheckState

Return state for check.

We use a plain enum because we rely on implicit conversion to int. Capability checks are run in the test harness using the JSON dump exported from the executable using --show-capabilities. This static check does not take dynamic loading into account, as capabilities that would be registered after initializing the dynamically loaded application will not exist with --show-capabilities.

A requested capability that is not registered at all is considered in a "possible" state, as we cannot guarantee that it does or not exist with a dynamic application. If no dynamic application loading is used, the possible states can be considered certain states.

When the test harness Tester specification "dynamic_capabilities" is set to True, it will run the test unless the result of the check is CERTAIN_FAIL. In this case, the runtime check in the executable will terminate if the result is either CERTAIN_FAIL or POSSIBLE_FAIL.

Enumerator
CERTAIN_FAIL 
POSSIBLE_FAIL 
UNKNOWN 
POSSIBLE_PASS 
CERTAIN_PASS 
IGNORE 

Definition at line 61 of file CapabilityRegistry.h.

Constructor & Destructor Documentation

◆ Capabilities() [1/3]

Moose::internal::Capabilities::Capabilities ( Capabilities const &  )
delete

Don't allow creation through copy/move construction or assignment.

◆ Capabilities() [2/3]

Moose::internal::Capabilities::Capabilities ( Capabilities &&  )
delete

◆ Capabilities() [3/3]

Moose::internal::Capabilities::Capabilities ( )
private

Definition at line 45 of file Capabilities.C.

Referenced by getCapabilities().

45  : CapabilityRegistry()
46 {
47  // Register the moose capabilities, just once
49 }
void registerMooseCapabilities()
Register the MOOSE capabilities.
Definition: Capabilities.C:127

Member Function Documentation

◆ add()

Capability & Moose::internal::CapabilityRegistry::add ( const std::string_view  name,
const Moose::Capability::Value value,
const std::string_view  doc 
)
inherited

Add a capability.

Parameters
registryThe registry
capabilityThe name of the capability
valueThe value of the capability
docThe documentation string
Returns
The capability

Definition at line 34 of file CapabilityRegistry.C.

Referenced by Registry::addDataFilePathCapability(), augment(), AppFactory::registerAppCapability(), and registerMooseCapabilities().

37 {
38  auto it_pair = _registry.lower_bound(name);
39  if (it_pair != _registry.end() && it_pair->first == name)
40  {
41  auto & capability = it_pair->second;
42  if (capability.getValue() != value || capability.getDoc() != doc)
43  throw CapabilityException("Capability '" + std::string(name) +
44  "' already exists and is not equal");
45  return capability;
46  }
47 
48  return _registry
49  .emplace_hint(it_pair,
50  std::piecewise_construct,
51  std::forward_as_tuple(name),
52  std::forward_as_tuple(name, value, doc))
53  ->second;
54 }
std::string name(const ElemQuality q)
RegistryType _registry
Registry storage.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)

◆ augment()

void Moose::internal::Capabilities::augment ( const nlohmann::json &  input,
const AugmentPassKey   
)

Augment the capabilities with the given input capabilities.

This is used when loading additional capabilities at run time from the TestHarness and thus is only allowed to be used by the MooseApp.

Definition at line 80 of file Capabilities.C.

81 {
82  for (const auto & [name_json, entry] : input.items())
83  {
84  const std::string name = name_json;
85 
86  const auto error = [&name](const std::string & message)
87  { throw CapabilityException("Capabilities::augment: Capability '" + name + "' " + message); };
88 
89  std::string doc;
90  if (const auto it = entry.find("doc"); it != entry.end())
91  doc = *it;
92  else
93  error("missing 'doc' entry");
94 
96  if (const auto it = entry.find("value"); it != entry.end())
97  {
98  if (it->is_boolean())
99  value = it->get<bool>();
100  else if (it->is_number_integer())
101  value = it->get<int>();
102  else
103  value = it->get<std::string>();
104  }
105  else
106  error("missing 'value' entry");
107 
108  auto & capability = add(name, value, doc);
109 
110  if (const auto it = entry.find("explicit"); it != entry.end() && it->get<bool>())
111  capability.setExplicit();
112 
113  if (const auto it = entry.find("enumeration"); it != entry.end())
114  capability.setEnumeration(it->get<std::set<std::string>>());
115  }
116 }
std::string name(const ElemQuality q)
std::variant< bool, int, std::string > Value
A capability can have a bool, int, or string value.
Definition: Capability.h:33
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
Capability & add(const std::string_view name, const Moose::Capability::Value &value, const std::string_view doc)
Add a capability.

◆ check()

CapabilityRegistry::CheckResult Moose::internal::CapabilityRegistry::check ( std::string  requirements,
const CapabilityRegistry::CheckOptions options = CapabilityRegistry::CheckOptions() 
) const
inherited

Checks if a set of requirements is satisified by the capabilities.

Parameters
requirementsThe requirement string
optionsOptions to apply to the check

This method is exposed to Python within pycapabilities.Capabilities.check in python/pycapabilities/_pycapabilities.C. This external method is used significantly by the TestHarness to check capabilities for individual test specs.

Additionally, this method is used by the MooseApp command line option "--required-capabilities ...".

Requirements can use comparison operators (>,<,>=,<=,=!,=), where the name of the capability must always be on the left hand side. Comparisons can be performed on strings "compiler!=GCC" (which are case insensitive), integer numbers "ad_size>=50", and version numbers "petsc>3.8.0". The state of a boolean valued capability can be tested by just specifying the capability name "chaco". This check can be inverted using the ! operator as "!chaco".

The logic operators & and | can be used to chain multiple checks as "thermochimica & thermochimica>1.0". Parenthesis can be used to build complex logic expressions.

Definition at line 86 of file CapabilityRegistry.C.

89 {
90  using namespace peg;
91 
92  // unquote
93  while (true)
94  {
95  const auto len = requirements.length();
96  if (len >= 2 && ((requirements[0] == '\'' && requirements[len - 1] == '\'') ||
97  (requirements[0] == '"' && requirements[len - 1] == '"')))
98  requirements = requirements.substr(1, len - 2);
99  else
100  break;
101  }
102 
103  CheckResult result;
104  result.state = CheckState::CERTAIN_FAIL;
105 
106  if (requirements.length() == 0)
107  {
108  result.state = CheckState::CERTAIN_PASS;
109  return result;
110  }
111 
112  static parser parser(R"(
113  Expression <- _ Bool _ LogicOperator _ Expression / Bool _
114  Bool <- Comparison / '!' Bool / '!' Identifier / Identifier / '(' _ Expression _ ')'
115  Comparison <- Identifier _ Operator _ Version / Identifier _ Operator _ String
116  String <- [a-zA-Z0-9_-]+
117  Identifier <- [a-zA-Z][a-zA-Z0-9_]*
118  Operator <- [<>=!]+
119  LogicOperator <- [&|]
120  Version <- Number '.' Version / Number
121  Number <- [0-9]+
122  ~_ <- [ \t]*
123  )");
124 
125  if (!static_cast<bool>(parser))
126  throw CapabilityException("Capabilities parser build failure.");
127 
128  // Keep track of unknown capabilities in the event that
129  // the check must be certain
130  std::set<std::string> unknown_capabilities;
131  const auto add_unknown_capability = [&unknown_capabilities](const auto & name)
132  { unknown_capabilities.insert(MooseUtils::toLower(name)); };
133 
134  // Make sure that the capabilities to ignore are valid capabilities
135  for (const auto & name : options.ignore_capabilities)
136  if (!_registry.count(name))
137  throw CapabilityException("Capability to ignore '" + name + "' is not known");
138 
139  parser["Number"] = [](const SemanticValues & vs) { return vs.token_to_number<int>(); };
140 
141  parser["Version"] = [](const SemanticValues & vs)
142  {
143  switch (vs.choice())
144  {
145  case 0: // Number '.' Version
146  {
147  std::vector<int> ret{std::any_cast<int>(vs[0])};
148  const auto & vs1 = std::any_cast<std::vector<int>>(vs[1]);
149  ret.insert(ret.end(), vs1.begin(), vs1.end());
150  return ret;
151  }
152 
153  case 1: // Number
154  return std::vector<int>{std::any_cast<int>(vs[0])};
155  }
156 
157  checkException(vs, "unknown number match.");
158  };
159 
160  enum LogicOperator
161  {
162  OP_AND,
163  OP_OR
164  };
165 
166  parser["LogicOperator"] = [](const SemanticValues & vs)
167  {
168  const auto op = vs.token();
169  if (op == "&")
170  return OP_AND;
171  if (op == "|")
172  return OP_OR;
173  checkException(vs, "unknown logic operator.");
174  };
175 
176  enum Operator
177  {
178  OP_LESS_EQ,
179  OP_GREATER_EQ,
180  OP_LESS,
181  OP_GREATER,
182  OP_NOT_EQ,
183  OP_EQ
184  };
185 
186  parser["Operator"] = [](const SemanticValues & vs)
187  {
188  const auto op = vs.token();
189  if (op == "<=")
190  return OP_LESS_EQ;
191  if (op == ">=")
192  return OP_GREATER_EQ;
193  if (op == "<")
194  return OP_LESS;
195  if (op == ">")
196  return OP_GREATER;
197  if (op == "!=")
198  return OP_NOT_EQ;
199  if (op == "=" || op == "==")
200  return OP_EQ;
201  checkException(vs, "unknown operator.");
202  };
203 
204  parser["String"] = [](const SemanticValues & vs) { return vs.token_to_string(); };
205  parser["Identifier"] = [](const SemanticValues & vs) { return vs.token_to_string(); };
206 
207  parser["Comparison"] =
208  [this, &add_unknown_capability, &options, &result](const SemanticValues & vs)
209  {
210  const auto left = std::any_cast<std::string>(vs[0]);
211  const auto op = std::any_cast<Operator>(vs[1]);
212 
213  // check existence
214  const auto capability_ptr = query(left);
215  if (!capability_ptr)
216  {
217  // return an unknown if the capability does not exist, this is important as it
218  // stays unknown upon negation
219  add_unknown_capability(left);
220  return CheckState::UNKNOWN;
221  }
222 
223  // capability is registered by the app
224  const auto & capability = *capability_ptr;
225  const auto & name = capability.getName();
226 
227  // register capability as seen
228  result.capability_names.insert(name);
229 
230  // whether or not the capability is ignored
231  const auto is_ignored = [&name, &options]() { return options.ignore_capabilities.count(name); };
232 
233  // explicitly false causes any comparison to fail unless ignored
234  if (const auto bool_ptr = capability.queryBoolValue(); (bool_ptr && !(*bool_ptr)))
235  return is_ignored() ? CheckState::IGNORE : CheckState::CERTAIN_FAIL;
236 
237  // comparator
238  auto comp = [&is_ignored](const int i, const auto & a, const auto & b)
239  {
240  // early exit for ignored capabilities
241  if (is_ignored())
242  return CheckState::IGNORE;
243 
244  // do the comparison
245  const auto do_comp = [&i, &a, &b]()
246  {
247  switch (i)
248  {
249  case OP_LESS_EQ:
250  return a <= b;
251  case OP_GREATER_EQ:
252  return a >= b;
253  case OP_LESS:
254  return a < b;
255  case OP_GREATER:
256  return a > b;
257  case OP_NOT_EQ:
258  return a != b;
259  case OP_EQ:
260  return a == b;
261  }
262  return false;
263  };
264  return do_comp() ? CheckState::CERTAIN_PASS : CheckState::CERTAIN_FAIL;
265  };
266 
267  // version comparison
268  std::vector<int> app_value_version;
269 
270  switch (vs.choice())
271  {
272  case 0: // Identifier _ Operator _ Version
273  {
274  // int comparison
275  const auto right = std::any_cast<std::vector<int>>(vs[2]);
276  if (const auto int_ptr = capability.queryIntValue())
277  {
278  if (right.size() != 1)
279  checkException(vs, "cannot be compared to a version.", capability);
280 
281  return comp(op, *int_ptr, right[0]);
282  }
283 
284  const auto string_ptr = capability.queryStringValue();
285  if (!string_ptr)
286  checkException(vs,
287  "cannot be compared to a " +
288  std::string(right.size() == 1 ? "number" : "version number") + ".",
289  capability);
290 
291  if (!MooseUtils::tokenizeAndConvert(*string_ptr, app_value_version, "."))
292  checkException(vs, "cannot be compared to a version.", capability);
293 
294  // compare versions
295  return comp(op, app_value_version, right);
296  }
297 
298  case 1: // Identifier _ Operator _ String
299  {
300  // here we would check for valid options and throw if not valid
301  const auto right = MooseUtils::toLower(std::any_cast<std::string>(vs[2]));
302  // the capability value has to be a string
303  const auto string_ptr = capability.queryStringValue();
304  if (!string_ptr)
305  checkException(vs, "cannot be compared to a string.", capability);
306 
307  // If this capability has an enumeration, make sure a valid
308  // choice is used
309  if (!capability.hasEnumeration(right))
310  checkException(vs,
311  "'" + right + "' invalid for capability '" + left +
312  "'; valid values: " + capability.enumerationToString());
313 
314  // Capability is a version
315  if (MooseUtils::tokenizeAndConvert(*string_ptr, app_value_version, "."))
316  checkException(vs, "cannot be compared to a string.", capability);
317 
318  return comp(op, *string_ptr, right);
319  }
320  }
321 
322  checkException(vs, "failed comparison.", capability);
323  };
324 
325  parser["Bool"] = [this, &add_unknown_capability, &options, &result](const SemanticValues & vs)
326  {
327  switch (vs.choice())
328  {
329  case 0: // Comparison
330  case 4: // '(' _ Expression _ ')'
331  return std::any_cast<CheckState>(vs[0]);
332 
333  case 1: // '!' Bool
334  switch (std::any_cast<CheckState>(vs[0]))
335  {
336  case CheckState::CERTAIN_FAIL:
337  return CheckState::CERTAIN_PASS;
338  case CheckState::CERTAIN_PASS:
339  return CheckState::CERTAIN_FAIL;
340  case CheckState::POSSIBLE_FAIL:
341  return CheckState::POSSIBLE_PASS;
342  case CheckState::POSSIBLE_PASS:
343  return CheckState::POSSIBLE_FAIL;
344  case CheckState::IGNORE:
345  return CheckState::IGNORE;
346  default:
347  return CheckState::UNKNOWN;
348  }
349 
350  case 2: // '!' Identifier
351  case 3: // Identifier
352  {
353  const bool negated = vs.choice() == 2;
354  const auto identifier = std::any_cast<std::string>(vs[0]);
355  if (const auto capability_ptr = query(identifier))
356  {
357  const auto & capability = *capability_ptr;
358  const auto & name = capability.getName();
359 
360  // explicit; cannot be a bool expression
361  if (capability.getExplicit())
362  {
363  std::string message = "capability '" + name +
364  "' requires a value and cannot be used in a boolean expression";
365  if (capability.queryEnumeration())
366  message += "; valid values: " + capability.enumerationToString();
367  checkException(vs, message);
368  }
369 
370  // mark as used
371  result.capability_names.insert(name);
372  // is ignored
373  if (options.ignore_capabilities.count(name))
374  return CheckState::IGNORE;
375 
376  // helper for negating a passing value if needed
377  const auto bool_to_pass = [&negated](const bool val)
378  { return (val ^ negated) ? CheckState::CERTAIN_FAIL : CheckState::CERTAIN_PASS; };
379  // has a boolean value, so use it
380  if (const auto bool_ptr = capability.queryBoolValue())
381  return bool_to_pass(!*bool_ptr);
382  // not ignored and doesn't have a boolean value
383  return bool_to_pass(false);
384  }
385 
386  add_unknown_capability(identifier);
387  return negated ? CheckState::POSSIBLE_PASS : CheckState::POSSIBLE_FAIL;
388  }
389 
390  default:
391  throw CapabilityException("Unknown choice in Bool non-terminal");
392  }
393  };
394 
395  parser["Expression"] = [](const SemanticValues & vs)
396  {
397  switch (vs.choice())
398  {
399  case 0: // Bool _ LogicOperator _ Expression
400  {
401  const auto left = std::any_cast<CheckState>(vs[0]);
402  const auto right = std::any_cast<CheckState>(vs[2]);
403  const auto op = std::any_cast<LogicOperator>(vs[1]);
404 
405  switch (op)
406  {
407  case OP_AND:
408  if (left == CheckState::IGNORE)
409  return right;
410  if (right == CheckState::IGNORE)
411  return left;
412  for (const auto state : {CheckState::CERTAIN_FAIL,
413  CheckState::POSSIBLE_FAIL,
414  CheckState::UNKNOWN,
415  CheckState::POSSIBLE_PASS,
416  CheckState::CERTAIN_PASS})
417  if (left == state || right == state)
418  return state;
419  throw CapabilityException("Conjunction failure");
420 
421  case OP_OR:
422  if (left == CheckState::IGNORE || right == CheckState::IGNORE)
423  return CheckState::IGNORE;
424  for (const auto state : {CheckState::CERTAIN_PASS,
425  CheckState::POSSIBLE_PASS,
426  CheckState::UNKNOWN,
427  CheckState::POSSIBLE_FAIL,
428  CheckState::CERTAIN_FAIL})
429  if (left == state || right == state)
430  return state;
431  throw CapabilityException("Conjunction failure");
432 
433  default:
434  throw CapabilityException("Unknown logic operator");
435  }
436  }
437 
438  case 1: // Bool
439  return std::any_cast<CheckState>(vs[0]);
440 
441  default:
442  throw CapabilityException("Unknown choice in Expression non-terminal");
443  }
444  };
445 
446  // (4) Parse
447  parser.enable_packrat_parsing(); // Enable packrat parsing.
448 
449  if (!parser.parse(requirements, result.state))
450  throw CapabilityException("Unable to parse requested capabilities '", requirements, "'.");
451 
452  // If certain and unknown capabilities were found, throw accordingly
453  if (options.certain && unknown_capabilities.size())
454  throw UnknownCapabilitiesException({unknown_capabilities.begin(), unknown_capabilities.end()});
455 
456  // Consider an ignored state to be a pass
457  if (result.state == CheckState::IGNORE)
458  result.state = CheckState::CERTAIN_PASS;
459 
460  return result;
461 }
std::string name(const ElemQuality q)
bool tokenizeAndConvert(const std::string &str, std::vector< T > &tokenized_vector, const std::string &delimiter=" \\\)
tokenizeAndConvert splits a string using delimiter and then converts to type T.
RegistryType _registry
Registry storage.
void checkException(const peg::SemanticValues &vs, const std::string &message, const std::optional< Capability > capability={})
std::string toLower(std::string name)
Convert supplied string to lower case.
const Capability * query(std::string capability) const
Query a capability, if it exists, otherwise nullptr.

◆ dump()

std::string Moose::internal::Capabilities::dump ( ) const

create a JSON dump of the capabilities registry

Definition at line 63 of file Capabilities.C.

64 {
65  nlohmann::json root;
66  for (const auto & [name, capability] : _registry)
67  {
68  auto & entry = root[name];
69  std::visit([&entry](const auto & v) { entry["value"] = v; }, capability.getValue());
70  entry["doc"] = capability.getDoc();
71  if (const auto enumeration_ptr = capability.queryEnumeration())
72  entry["enumeration"] = *enumeration_ptr;
73  if (!capability.hasBoolValue())
74  entry["explicit"] = capability.getExplicit();
75  }
76  return root.dump(2);
77 }
std::string name(const ElemQuality q)
RegistryType _registry
Registry storage.

◆ FRIEND_TEST() [1/3]

Moose::internal::Capabilities::FRIEND_TEST ( ::CapabilitiesTest  ,
isInstallationType   
)
private

◆ FRIEND_TEST() [2/3]

Moose::internal::Capabilities::FRIEND_TEST ( ::CapabilitiesTest  ,
mooseAppIsRelocated   
)
private

◆ FRIEND_TEST() [3/3]

Moose::internal::Capabilities::FRIEND_TEST ( ::CapabilitiesTest  ,
mooseAppisInTree   
)
private

◆ get() [1/2]

const Capability & Moose::internal::CapabilityRegistry::get ( const std::string &  capability) const
inherited

Get a capability.

Will convert the capability name to lowercase.

Definition at line 66 of file CapabilityRegistry.C.

Referenced by MooseApp::setupOptions().

67 {
68  if (const auto capability_ptr = query(capability))
69  return *capability_ptr;
70  throw CapabilityException("Capability '" + capability + "' not registered");
71 }
const Capability * query(std::string capability) const
Query a capability, if it exists, otherwise nullptr.

◆ get() [2/2]

Capability & Moose::internal::CapabilityRegistry::get ( const std::string &  capability)
inlineinherited

Definition at line 184 of file CapabilityRegistry.h.

185 {
186  return const_cast<Capability &>(std::as_const(*this).get(capability));
187 }

◆ getCapabilities()

Capabilities & Moose::internal::Capabilities::getCapabilities ( const GetCapabilitiesPassKey  )
static

Get the singleton Capabilities.

Only accessible through MooseApp and AppFactory. Addition of capabilities should be done through the MooseApp::add[Bool,Int,String]capability() method.

Definition at line 52 of file Capabilities.C.

Referenced by MooseApp::addCapability(), MooseApp::addCapabilityInternal(), Registry::addDataFilePathCapability(), MooseApp::isInTree(), MooseApp::isRelocated(), AppFactory::registerAppCapability(), and MooseApp::setupOptions().

53 {
54  // We need a naked new here (_not_ a smart pointer or object instance) due to what seems like a
55  // bug in clang's static object destruction when using dynamic library loading.
56  static Capabilities * capability_registry = nullptr;
57  if (!capability_registry)
58  capability_registry = new Capabilities();
59  return *capability_registry;
60 }

◆ isInstallationType()

bool Moose::internal::Capabilities::isInstallationType ( const std::string &  installation_type) const
private

Helper for isRelocated() and isInTree()

Definition at line 119 of file Capabilities.C.

Referenced by isInTree(), isRelocated(), and registerMooseCapabilities().

120 {
121  const auto & capability = get("installation_type");
122  mooseAssert(capability.getEnumeration().count(installation_type), "Not a valid enumeration");
123  return capability.getStringValue() == installation_type;
124 }

◆ isInTree()

bool Moose::internal::Capabilities::isInTree ( ) const
inline
Returns
Whether or not the application is in-tree

Definition at line 126 of file Capabilities.h.

126 { return isInstallationType("in_tree"); }
bool isInstallationType(const std::string &installation_type) const
Helper for isRelocated() and isInTree()
Definition: Capabilities.C:119

◆ isRelocated()

bool Moose::internal::Capabilities::isRelocated ( ) const
inline
Returns
Whether or not the application is relocated

Definition at line 121 of file Capabilities.h.

121 { return isInstallationType("relocated"); }
bool isInstallationType(const std::string &installation_type) const
Helper for isRelocated() and isInTree()
Definition: Capabilities.C:119

◆ operator=() [1/2]

Capabilities& Moose::internal::Capabilities::operator= ( Capabilities const &  )
delete

◆ operator=() [2/2]

Capabilities& Moose::internal::Capabilities::operator= ( Capabilities &&  )
delete

◆ query() [1/2]

const Capability * Moose::internal::CapabilityRegistry::query ( std::string  capability) const
inherited

Query a capability, if it exists, otherwise nullptr.

Will convert the capability name to lowercase.

Definition at line 57 of file CapabilityRegistry.C.

Referenced by Moose::internal::CapabilityRegistry::check(), and Moose::internal::CapabilityRegistry::get().

58 {
59  capability = MooseUtils::toLower(capability);
60  if (const auto it = _registry.find(capability); it != _registry.end())
61  return &it->second;
62  return nullptr;
63 }
RegistryType _registry
Registry storage.
std::string toLower(std::string name)
Convert supplied string to lower case.

◆ query() [2/2]

Capability * Moose::internal::CapabilityRegistry::query ( std::string  capability)
inlineinherited

Definition at line 176 of file CapabilityRegistry.h.

177 {
178  return const_cast<Capability *>(std::as_const(*this).query(capability));
179 }

◆ registerMooseCapabilities()

void Moose::internal::Capabilities::registerMooseCapabilities ( )
private

Register the MOOSE capabilities.

Called during the construction of the registry.

Putting this here enforces that only capabilities that represent context before the app is constructed can be added.

Definition at line 127 of file Capabilities.C.

Referenced by Capabilities().

128 {
129  // helper lambdas for explicitly adding typed capabilities
130  const auto add_bool = [&](const std::string_view capability,
131  const bool value,
132  const std::string_view doc) -> Capability &
133  { return add(capability, value, doc); };
134  const auto add_int = [&](const std::string_view capability,
135  const int value,
136  const std::string_view doc) -> Capability &
137  { return add(capability, value, doc); };
138  const auto add_string = [&](const std::string_view capability,
139  const std::string_view value,
140  const std::string_view doc) -> Capability &
141  { return add(capability, std::string(value), doc); };
142 
143  // helper lambdas for adding capabilities
144  const auto have = [&](const std::string & capability, const std::string & doc) -> Capability &
145  { return add_bool(capability, true, doc + " is available."); };
146  const auto missing = [&](const std::string & capability,
147  const std::string & doc,
148  const std::string & help = "") -> Capability &
149  { return add_bool(capability, false, doc + " is not available. " + help); };
150 
151  const auto have_version = [&](const std::string & capability,
152  const std::string & doc,
153  const std::string & version) -> Capability &
154  { return add_string(capability, version, doc + " version " + version + " is available."); };
155  const auto petsc_missing = [&](const std::string & capability,
156  const std::string & doc) -> Capability &
157  {
158  return add_bool(
159  capability, false, doc + " is not available. Check your PETSc configure options.");
160  };
161  const auto libmesh_missing = [&](const std::string & capability,
162  const std::string & doc,
163  const std::string & config_option) -> Capability &
164  {
165  return add_bool(capability,
166  false,
167  doc + " is not available. It is controlled by the `" + config_option +
168  "` libMesh configure option.");
169  };
170 
171  {
172  const auto doc = "LibTorch machine learning and parallel tensor algebra library";
173 #ifdef MOOSE_LIBTORCH_ENABLED
174  add_string("libtorch", TORCH_VERSION, doc);
175 #else
176  missing("libtorch",
177  doc,
178  "Check "
179  "https://mooseframework.inl.gov/moose/getting_started/installation/"
180  "install_libtorch.html for "
181  "instructions on how to configure and build moose with libTorch.");
182 #endif
183  }
184 
185  {
186  const auto doc = "MFEM finite element library";
187 #ifdef MOOSE_MFEM_ENABLED
188  add_string("mfem", MFEM_VERSION_STRING, doc);
189 #else
190  missing("mfem",
191  doc,
192  "Install mfem using the scripts/update_and_rebuild_mfem.sh script after "
193  "first running scripts/update_and_rebuild_conduit.sh. Finally, configure "
194  "moose with ./configure --with-mfem");
195 #endif
196  }
197 
198  {
199  const auto doc = "New Engineering Material model Library, version 2";
200 #ifdef NEML2_ENABLED
201  have("neml2", doc);
202 #else
203  missing("neml2",
204  doc,
205  "Install neml2 using the scripts/update_and_rebuild_neml2.sh script, then "
206  "configure moose with ./configure --with-neml2 --with-libtorch");
207 #endif
208  }
209 
210  {
211  const auto doc = "gperftools code performance analysis and profiling library";
212 #ifdef HAVE_GPERFTOOLS
213  have("gperftools", doc);
214 #else
215  missing("gperftools",
216  doc,
217  "Check https://mooseframework.inl.gov/application_development/profiling.html "
218  "for instructions on profiling MOOSE based applications.");
219 #endif
220  }
221 
222  {
223  const auto doc = "libPNG portable network graphics format library";
224 #ifdef MOOSE_HAVE_LIBPNG
225  have("libpng", doc);
226 #else
227  missing("libpng",
228  doc,
229  "Install libpng through conda or your distribution and check that it gets "
230  "detected through pkg-config, then reconfigure and rebuild MOOSE.");
231 #endif
232  }
233 
234  {
235  const auto doc = "NVIDIA GPU parallel computing platform";
236 #ifdef PETSC_HAVE_CUDA
237  const std::string version = QUOTE(PETSC_PKG_CUDA_VERSION_MAJOR) "." QUOTE(
238  PETSC_PKG_CUDA_VERSION_MINOR) "." QUOTE(PETSC_PKG_CUDA_VERSION_SUBMINOR);
239  add_string("cuda", version, doc);
240 #else
241  missing("cuda", doc, "Add the CUDA bin directory to your path and rebuild PETSc.");
242 #endif
243  }
244 
245  {
246  const auto doc = "Kokkos performance portability programming ecosystem";
247 #ifdef MOOSE_KOKKOS_ENABLED
248  const std::string version = QUOTE(PETSC_PKG_KOKKOS_VERSION_MAJOR) "." QUOTE(
249  PETSC_PKG_KOKKOS_VERSION_MINOR) "." QUOTE(PETSC_PKG_KOKKOS_VERSION_SUBMINOR);
250  add_string("kokkos", version, doc);
251 #else
252  missing("kokkos",
253  doc,
254  "Rebuild PETSc with Kokkos support and libMesh. Then, reconfigure MOOSE with "
255  "--with-kokkos.");
256 #endif
257  }
258 
259  {
260  const auto doc = "Kokkos support for PETSc";
261 #ifdef PETSC_HAVE_KOKKOS
262  const std::string version = QUOTE(PETSC_PKG_KOKKOS_VERSION_MAJOR) "." QUOTE(
263  PETSC_PKG_KOKKOS_VERSION_MINOR) "." QUOTE(PETSC_PKG_KOKKOS_VERSION_SUBMINOR);
264  add_string("petsc_kokkos", version, doc);
265 #else
266  missing(
267  "petsc_kokkos", doc, "Rebuild PETSc with Kokkos support, then rebuild libMesh and MOOSE.");
268 #endif
269  }
270 
271  {
272  const auto doc = "Intel OneAPI XPU accelerator support";
273 #ifdef MOOSE_HAVE_XPU
274  if (torch::xpu::is_available())
275  have("xpu", doc);
276  else
277  missing("xpu", doc, "No usable XPU devices have been found.");
278 #else
279  missing("xpu", doc, "The torch version used to build this app has no XPU support.");
280 #endif
281  }
282 
283  add_int(
284  "ad_size",
285  MOOSE_AD_MAX_DOFS_PER_ELEM,
286  "MOOSE was configured and built with a dual number backing store size of " +
287  Moose::stringify(MOOSE_AD_MAX_DOFS_PER_ELEM) +
288  ". Complex simulations with many variables or contact problems may require larger "
289  "values. Reconfigure MOOSE with the --with-derivative-size=<n> option in the root of the "
290  "repository.")
291  .setExplicit();
292 
293  {
294  const std::string method = QUOTE(METHOD);
295  add_string("method", method, "The executable was built with METHOD=\"" + method + "\"")
296  .setExplicit()
297  .setEnumeration({"dbg", "devel", "oprof", "opt"});
298  }
299 
300  {
301  const std::string version = QUOTE(LIBMESH_DETECTED_PETSC_VERSION_MAJOR) "." QUOTE(
302  LIBMESH_DETECTED_PETSC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR);
303  add_string("petsc", version, "Using PETSc version " + version + ".");
304  }
305 
306 #ifdef LIBMESH_PETSC_USE_DEBUG
307  add_bool("petsc_debug", true, "PETSc was built with debugging options.");
308 #else
309  add_bool("petsc_debug", false, "PETSc was built without debugging options.");
310 #endif
311 
312  {
313  const auto doc = "SuperLU direct solver";
314 #ifdef LIBMESH_PETSC_HAVE_SUPERLU_DIST
315  const std::string version = QUOTE(PETSC_PKG_SUPERLU_DIST_VERSION_MAJOR) "." QUOTE(
316  PETSC_PKG_SUPERLU_DIST_VERSION_MINOR) "." QUOTE(PETSC_PKG_SUPERLU_DIST_VERSION_SUBMINOR);
317  add_string("superlu", version, doc);
318 #else
319  petsc_missing("superlu", doc);
320 #endif
321  }
322 
323  {
324  const auto doc = "MUltifrontal Massively Parallel sparse direct Solver (MUMPS)";
325 #ifdef LIBMESH_PETSC_HAVE_MUMPS
326  const std::string version = QUOTE(PETSC_PKG_MUMPS_VERSION_MAJOR) "." QUOTE(
327  PETSC_PKG_MUMPS_VERSION_MINOR) "." QUOTE(PETSC_PKG_MUMPS_VERSION_SUBMINOR);
328  add_string("mumps", version, doc);
329 #else
330  petsc_missing("mumps", doc);
331 #endif
332  }
333 
334  {
335  const auto doc = "STRUMPACK - STRUctured Matrix PACKage solver library";
336 #ifdef LIBMESH_PETSC_HAVE_STRUMPACK
337  const std::string version = QUOTE(PETSC_PKG_STRUMPACK_VERSION_MAJOR) "." QUOTE(
338  PETSC_PKG_STRUMPACK_VERSION_MINOR) "." QUOTE(PETSC_PKG_STRUMPACK_VERSION_SUBMINOR);
339  add_string("strumpack", version, doc);
340 #else
341  petsc_missing("strumpack", doc);
342 #endif
343  }
344 
345  {
346  const auto doc = "Parmetis partitioning library";
347 #if defined(LIBMESH_PETSC_HAVE_PARMETIS)
348  const std::string version = QUOTE(PETSC_PKG_PARMETIS_VERSION_MAJOR) "." QUOTE(
349  PETSC_PKG_PARMETIS_VERSION_MINOR) "." QUOTE(PETSC_PKG_PARMETIS_VERSION_SUBMINOR);
350  add_string("parmetis", version, doc);
351 #elif defined(LIBMESH_HAVE_PARMETIS)
352  have("parmetis", doc);
353 #else
354  petsc_missing("parmetis", doc);
355 #endif
356  }
357 
358  {
359  const auto doc = "Chaco graph partitioning library";
360 #ifdef LIBMESH_PETSC_HAVE_CHACO
361  have("chaco", doc);
362 #else
363  petsc_missing("chaco", doc);
364 #endif
365  }
366 
367  {
368  const auto doc = "Party matrix or graph partitioning library";
369 #ifdef LIBMESH_PETSC_HAVE_PARTY
370  have("party", doc);
371 #else
372  petsc_missing("party", doc);
373 #endif
374  }
375 
376  {
377  const auto doc = "PT-Scotch graph partitioning library";
378 #ifdef LIBMESH_PETSC_HAVE_PTSCOTCH
379  const std::string version = QUOTE(PETSC_PKG_PTSCOTCH_VERSION_MAJOR) "." QUOTE(
380  PETSC_PKG_PTSCOTCH_VERSION_MINOR) "." QUOTE(PETSC_PKG_PTSCOTCH_VERSION_SUBMINOR);
381  add_string("ptscotch", version, doc);
382 #else
383  petsc_missing("ptscotch", doc);
384 #endif
385  }
386 
387  {
388  const auto doc = "Optimized BLAS library";
389 #ifdef PETSC_HAVE_OPENBLAS
390  const std::string version = QUOTE(PETSC_PKG_OPENBLAS_VERSION_MAJOR) "." QUOTE(
391  PETSC_PKG_OPENBLAS_VERSION_MINOR) "." QUOTE(PETSC_PKG_OPENBLAS_VERSION_SUBMINOR);
392  add_string("openblas", version, doc);
393 #else
394  petsc_missing("openblas", doc);
395 #endif
396  }
397 
398  {
399  const auto doc = "Umpire resource management library";
400 #ifdef PETSC_HAVE_UMPIRE
401  have("umpire", doc);
402 #else
403  petsc_missing("umpire", doc);
404 #endif
405  }
406 
407  {
408  const auto doc = "Scalable Library for Eigenvalue Problem Computations (SLEPc)";
409 #ifdef LIBMESH_HAVE_SLEPC
410  const auto version = QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_MAJOR) "." QUOTE(
411  LIBMESH_DETECTED_SLEPC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_SUBMINOR);
412  have_version("slepc", doc, version);
413 #else
414  petsc_missing("slepc", doc);
415 #endif
416  }
417 
418  {
419  const auto doc = "Exodus mesh file format library";
420 #ifdef LIBMESH_HAVE_EXODUS_API
421  const std::string version = QUOTE(LIBMESH_DETECTED_EXODUS_VERSION_MAJOR) "." QUOTE(
422  LIBMESH_DETECTED_EXODUS_VERSION_MINOR);
423  have_version("exodus", doc, version);
424 #else
425  libmesh_missing("exodus", doc, "--enable-exodus");
426 #endif
427  }
428 
429  {
430  const auto doc = "Netgen meshing library";
431 #ifdef LIBMESH_HAVE_NETGEN
432  const std::string version =
433  QUOTE(NETGEN_VERSION_MAJOR) "." QUOTE(NETGEN_VERSION_MINOR) "." QUOTE(NETGEN_VERSION_PATCH);
434  add_string("netgen", version, doc);
435 #else
436  libmesh_missing("netgen", doc, "--enable-netgen");
437 #endif
438  }
439 
440  {
441  const auto doc = "Visualization Toolkit (VTK)";
442 #ifdef LIBMESH_HAVE_VTK
443  const std::string version = QUOTE(LIBMESH_DETECTED_VTK_VERSION_MAJOR) "." QUOTE(
444  LIBMESH_DETECTED_VTK_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_VTK_VERSION_SUBMINOR);
445  have_version("vtk", doc, version);
446 #else
447  libmesh_missing("vtk", doc, "--disable-vtk and --enable-vtk-required");
448 #endif
449  }
450 
451  {
452  const auto doc = "libcurl - the multiprotocol file transfer library";
453 #ifdef LIBMESH_HAVE_CURL
454  have("curl", doc);
455 #else
456  libmesh_missing("curl", doc, "--enable-curl");
457 #endif
458  }
459 
460  {
461  const auto doc = "Tecplot post-processing tools API";
462 #ifdef LIBMESH_HAVE_TECPLOT_API
463  have("tecplot", doc);
464 #else
465  libmesh_missing("tecplot", doc, "--enable-tecplot");
466 #endif
467  }
468 
469  {
470  const auto doc = "NVIDIA Tools Extension Library API";
471 #ifdef LIBMESH_HAVE_NVTX_API
472  have("nvtx_api", doc);
473 #else
474  libmesh_missing("nvtx_api", doc, "--with-nvtx");
475 #endif
476  }
477 
478  {
479  const auto doc = "libMesh performance logging";
480 #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
481  have("libmesh_perflog", doc);
482 #else
483  libmesh_missing("libmesh_perflog", doc, "--enable-perflog");
484 #endif
485  }
486 
487  {
488  const auto doc = "Boost C++ library";
489 #ifdef LIBMESH_HAVE_EXTERNAL_BOOST
490  have("boost", doc);
491 #else
492  libmesh_missing("boost", doc, "--with-boost");
493 #endif
494  }
495 
496  // libmesh stuff
497  {
498  const auto doc = "Adaptive mesh refinement";
499 #ifdef LIBMESH_ENABLE_AMR
500  have("amr", doc);
501 #else
502  libmesh_missing("amr", doc, "--disable-amr");
503 #endif
504  }
505 
506  {
507  const auto doc = "nanoflann library for Nearest Neighbor (NN) search with KD-trees";
508 #ifdef LIBMESH_HAVE_NANOFLANN
509  have("nanoflann", doc);
510 #else
511  libmesh_missing("nanoflann", doc, "--disable-nanoflann");
512 #endif
513  }
514 
515  {
516  const auto doc = "sfcurves library for space filling curves (required by geometric "
517  "partitioners such as SFCurves, Hilbert and Morton - not LGPL compatible)";
518 #ifdef LIBMESH_HAVE_SFCURVES
519  have("sfcurves", doc);
520 #else
521  libmesh_missing("sfcurves", doc, "--disable-sfc");
522 #endif
523  }
524 
525  {
526 #ifdef LIBMESH_HAVE_FPARSER
527 #ifdef LIBMESH_HAVE_FPARSER_JIT
528  const auto value = "jit";
529  const auto doc = "FParser enabled with just in time compilation support.";
530 #else
531  const auto value = "byte_code";
532  const auto doc = "FParser enabled.";
533 #endif
534  add_string("fparser", value, doc);
535 #else
536  add_bool("fparser",
537  false,
538  "FParser is disabled, libMesh was likely configured with --disable-fparser.");
539 #endif
540  }
541 
542 #ifdef LIBMESH_HAVE_DLOPEN
543  add_bool("dlopen", true, "The dlopen() system call is available to dynamically load libraries.");
544 #else
545  add_bool("dlopen",
546  false,
547  "The dlopen() system call is not available. Dynamic library loading is "
548  "not supported on this system.");
549 #endif
550 
551  {
552  const auto doc = "LibMesh support for threaded execution";
553 #ifdef LIBMESH_USING_THREADS
554  have("threads", doc);
555 #else
556  libmesh_missing("threads", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
557 #endif
558  }
559 
560  {
561  const auto doc = "OpenMP multi-platform shared-memory parallel programming API";
562 #ifdef LIBMESH_HAVE_OPENMP
563  have("openmp", doc);
564 #else
565  libmesh_missing("openmp", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
566 #endif
567  }
568  {
569  const auto doc = "POSIX Threads API";
570 #ifdef LIBMESH_HAVE_PTHREAD
571  have("pthread", doc);
572 #else
573  libmesh_missing("pthread", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
574 #endif
575  }
576  {
577  const auto doc = "oneAPI Threading Building Blocks (TBB) API";
578 #ifdef LIBMESH_HAVE_TBB_API
579  have("tbb", doc);
580 #else
581  libmesh_missing("tbb", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
582 #endif
583  }
584 
585  {
586  const auto doc = "libMesh unique ID support";
587 #ifdef LIBMESH_ENABLE_UNIQUE_ID
588  have("unique_id", doc);
589 #else
590  libmesh_missing("unique_id", doc, "--enable-unique-id");
591 #endif
592  }
593 
594  {
595 #ifdef LIBMESH_ENABLE_PARMESH
596  const auto value = "distributed";
597 #else
598  const auto value = "replicated";
599 #endif
600  add_string("mesh_mode", value, "libMesh default mesh mode")
601  .setExplicit()
602  .setEnumeration({"distributed", "replicated"});
603  }
604 
605  add_int("dof_id_bytes",
606  static_cast<int>(sizeof(dof_id_type)),
607  "Degree of freedom (DOF) identifiers use " + Moose::stringify(sizeof(dof_id_type)) +
608  " bytes for storage. This is controlled by the "
609  "--with-dof-id-bytes=<1|2|4|8> libMesh configure option.")
610  .setExplicit();
611 
612  {
613 #ifdef LIBMESH_HAVE_STATIC_LIBS
614  const auto value = "static";
615 #else
616  const auto value = "dynamic";
617 #endif
618  add_string("library_mode",
619  value,
620  "The libMesh library mode. This is controlled by the --enable-static libMesh "
621  "configure option.")
622  .setExplicit()
623  .setEnumeration({"dynamic", "static"});
624  }
625 
626  // compiler
627  {
628  const auto doc = "Compiler used to build the MOOSE framework.";
629 #if defined(__INTEL_LLVM_COMPILER)
630  const auto value = "intel";
631 #elif defined(__clang__)
632  const auto value = "clang";
633 #elif defined(__GNUC__) || defined(__GNUG__)
634  const auto value = "gcc";
635 #elif defined(_MSC_VER)
636  const auto value = "msvc";
637 #else
638  mooseDoOnce(mooseWarning("Failed to determine compiler; setting capability compiler=unknown"));
639  const auto value = "unknown";
640 #endif
641  add_string("compiler", value, doc)
642  .setExplicit()
643  .setEnumeration({"clang", "gcc", "intel", "msvc", "unknown"});
644  }
645 
646  // OS related
647  {
648 #ifdef __APPLE__
649  const auto value = "darwin";
650 #elif __WIN32__
651  const auto value = "win32";
652 #elif __linux__
653  const auto value = "linux";
654 #elif __unix__
655  const auto value = "unix";
656 #else
657  mooseDoOnce(mooseWarning("Failed to determine platform; setting capability platform=unknown"));
658  const auto value = "unknown";
659 #endif
660  add_string("platform", value, "Operating system this executable is running on.")
661  .setExplicit()
662  .setEnumeration({"darwin", "linux", "unix", "unknown", "win32"});
663  }
664 
665  // Installation type (in tree or installed)
666  {
667  // Try to find the path to the running executable
668  std::optional<std::string> executable_path;
669  {
670  Moose::ScopedThrowOnError scoped_throw_on_error;
671  try
672  {
673  executable_path = Moose::getExec();
674  }
675  catch (const MooseException &)
676  {
677  }
678  }
679 
680  std::string value = "unknown";
681 
682  if (executable_path)
683  {
684  // Try to follow all symlinks to get the real path
685  std::error_code ec;
686  const auto resolved_path =
687  std::filesystem::weakly_canonical(std::filesystem::path(*executable_path), ec);
688  if (ec)
689  mooseDoOnce(mooseWarning("Failed to resolve executable path '",
690  *executable_path,
691  "':\n",
692  ec.message(),
693  "\n\nSetting capability installation_type=unknown"));
694  else
695  {
696  // If the binary is in a folder "bin", we'll consider it installed.
697  // This isn't the best check, but it works with how we currently
698  // install applications in app.mk
699  value = resolved_path.parent_path().filename() == "bin" ? "relocated" : "in_tree";
700  }
701  }
702  else
703  mooseDoOnce(mooseWarning(
704  "Failed to determine executable path; setting capability installation_type=unknown"));
705 
706  add_string("installation_type", value, "The installation type of the application.")
707  .setExplicit()
708  .setEnumeration({"in_tree", "relocated", "unknown"});
709 
710  mooseAssert(isInstallationType(value), "Value mismatch");
711  }
712 }
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:345
std::string getExec()
Gets the full path to the running executable on Mac OS X and linux.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
Capability & add(const std::string_view name, const Moose::Capability::Value &value, const std::string_view doc)
Add a capability.
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
std::string help
Provides a way for users to bail out of the current solve.
Scoped helper for setting Moose::_throw_on_error during this scope.
Definition: Moose.h:295
bool isInstallationType(const std::string &installation_type) const
Helper for isRelocated() and isInTree()
Definition: Capabilities.C:119
uint8_t dof_id_type

◆ size()

std::size_t Moose::internal::CapabilityRegistry::size ( ) const
inlineinherited
Returns
The size of the registry (number of capabilities registered).

Definition at line 135 of file CapabilityRegistry.h.

135 { return _registry.size(); }
RegistryType _registry
Registry storage.

Friends And Related Function Documentation

◆ ::CapabilitiesTest

friend class ::CapabilitiesTest
friend

Definition at line 130 of file Capabilities.h.

◆ ::DataFileUtilsTest

friend class ::DataFileUtilsTest
friend

Definition at line 131 of file Capabilities.h.

◆ ::RegistryTest

friend class ::RegistryTest
friend

Definition at line 132 of file Capabilities.h.

Member Data Documentation

◆ _registry

RegistryType Moose::internal::CapabilityRegistry::_registry
protectedinherited

◆ augmented_capability_names

const std::set< std::string, std::less<> > Moose::internal::CapabilityRegistry::augmented_capability_names
staticinherited
Initial value:
{
"hpc",
"machine",
"library_mode",
"mpi_procs",
"num_threads"}

Capabilities that are reserved and can only be augmented.

Definition at line 38 of file CapabilityRegistry.h.


The documentation for this class was generated from the following files: