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 :
10 : // Needs to be included before Capabilities.h, which
11 : // includes nlohmann/json_fwd.h
12 : #include "nlohmann/json.h"
13 :
14 : #include "Capabilities.h"
15 : #include "CapabilityException.h"
16 : #include "MooseUtils.h"
17 : #include "Conversion.h"
18 :
19 : #include <vector>
20 :
21 : #include "libmesh/libmesh_config.h"
22 : #include "petscconf.h"
23 : #include "petscpkg_version.h"
24 :
25 : #ifdef MOOSE_LIBTORCH_ENABLED
26 : #include <torch/version.h>
27 : #endif
28 :
29 : #if __has_include(<torch/xpu.h>)
30 : #include <torch/xpu.h>
31 : #define MOOSE_HAVE_XPU 1
32 : #endif
33 :
34 : #ifdef MOOSE_MFEM_ENABLED
35 : #include "mfem/config/config.hpp"
36 : #endif
37 :
38 : #ifdef LIBMESH_HAVE_NETGEN
39 : #include "netgen/netgen_version.hpp"
40 : #endif
41 :
42 : namespace Moose::internal
43 : {
44 :
45 55395 : Capabilities::Capabilities() : CapabilityRegistry()
46 : {
47 : // Register the moose capabilities, just once
48 55395 : registerMooseCapabilities();
49 55395 : }
50 :
51 : Capabilities &
52 647820 : Capabilities::getCapabilities(const Capabilities::GetCapabilitiesPassKey)
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 647820 : if (!capability_registry)
58 55395 : capability_registry = new Capabilities();
59 647820 : return *capability_registry;
60 : }
61 :
62 : std::string
63 21 : Capabilities::dump() const
64 : {
65 21 : nlohmann::json root;
66 1151 : for (const auto & [name, capability] : _registry)
67 : {
68 1130 : auto & entry = root[name];
69 2260 : std::visit([&entry](const auto & v) { entry["value"] = v; }, capability.getValue());
70 1130 : entry["doc"] = capability.getDoc();
71 1130 : if (const auto enumeration_ptr = capability.queryEnumeration())
72 1130 : entry["enumeration"] = *enumeration_ptr;
73 1130 : if (!capability.hasBoolValue())
74 560 : entry["explicit"] = capability.getExplicit();
75 : }
76 42 : return root.dump(2);
77 21 : }
78 :
79 : void
80 389 : Capabilities::augment(const nlohmann::json & input, const Capabilities::AugmentPassKey)
81 : {
82 828 : for (const auto & [name_json, entry] : input.items())
83 : {
84 445 : const std::string name = name_json;
85 :
86 6 : const auto error = [&name](const std::string & message)
87 6 : { throw CapabilityException("Capabilities::augment: Capability '" + name + "' " + message); };
88 :
89 445 : std::string doc;
90 445 : if (const auto it = entry.find("doc"); it != entry.end())
91 441 : doc = *it;
92 : else
93 8 : error("missing 'doc' entry");
94 :
95 441 : Moose::Capability::Value value;
96 441 : if (const auto it = entry.find("value"); it != entry.end())
97 : {
98 439 : if (it->is_boolean())
99 124 : value = it->get<bool>();
100 315 : else if (it->is_number_integer())
101 16 : value = it->get<int>();
102 : else
103 299 : value = it->get<std::string>();
104 : }
105 : else
106 4 : error("missing 'value' entry");
107 :
108 439 : auto & capability = add(name, value, doc);
109 :
110 439 : if (const auto it = entry.find("explicit"); it != entry.end() && it->get<bool>())
111 291 : capability.setExplicit();
112 :
113 439 : if (const auto it = entry.find("enumeration"); it != entry.end())
114 283 : capability.setEnumeration(it->get<std::set<std::string>>());
115 848 : }
116 383 : }
117 :
118 : bool
119 24 : Capabilities::isInstallationType(const std::string & installation_type) const
120 : {
121 48 : const auto & capability = get("installation_type");
122 : mooseAssert(capability.getEnumeration().count(installation_type), "Not a valid enumeration");
123 24 : return capability.getStringValue() == installation_type;
124 : }
125 :
126 : void
127 55401 : Capabilities::registerMooseCapabilities()
128 : {
129 : // helper lambdas for explicitly adding typed capabilities
130 1465351 : const auto add_bool = [&](const std::string_view capability,
131 : const bool value,
132 : const std::string_view doc) -> Capability &
133 1465351 : { return add(capability, value, doc); };
134 110802 : const auto add_int = [&](const std::string_view capability,
135 : const int value,
136 : const std::string_view doc) -> Capability &
137 110802 : { return add(capability, value, doc); };
138 1138496 : const auto add_string = [&](const std::string_view capability,
139 : const std::string_view value,
140 : const std::string_view doc) -> Capability &
141 3415488 : { return add(capability, std::string(value), doc); };
142 :
143 : // helper lambdas for adding capabilities
144 448457 : const auto have = [&](const std::string & capability, const std::string & doc) -> Capability &
145 448457 : { return add_bool(capability, true, doc + " is available."); };
146 410959 : const auto missing = [&](const std::string & capability,
147 : const std::string & doc,
148 : const std::string & help = "") -> Capability &
149 410959 : { return add_bool(capability, false, doc + " is not available. " + help); };
150 :
151 166203 : const auto have_version = [&](const std::string & capability,
152 : const std::string & doc,
153 : const std::string & version) -> Capability &
154 166203 : { return add_string(capability, version, doc + " version " + version + " is available."); };
155 110802 : const auto petsc_missing = [&](const std::string & capability,
156 : const std::string & doc) -> Capability &
157 : {
158 110802 : return add_bool(
159 221604 : capability, false, doc + " is not available. Check your PETSc configure options.");
160 55401 : };
161 384331 : const auto libmesh_missing = [&](const std::string & capability,
162 : const std::string & doc,
163 : const std::string & config_option) -> Capability &
164 : {
165 384331 : return add_bool(capability,
166 : false,
167 768662 : doc + " is not available. It is controlled by the `" + config_option +
168 768662 : "` libMesh configure option.");
169 55401 : };
170 :
171 : {
172 55401 : const auto doc = "LibTorch machine learning and parallel tensor algebra library";
173 : #ifdef MOOSE_LIBTORCH_ENABLED
174 1773 : add_string("libtorch", TORCH_VERSION, doc);
175 : #else
176 268140 : 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 55401 : const auto doc = "MFEM finite element library";
187 : #ifdef MOOSE_MFEM_ENABLED
188 41183 : add_string("mfem", MFEM_VERSION_STRING, doc);
189 : #else
190 71090 : 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 55401 : const auto doc = "New Engineering Material model Library, version 2";
200 : #ifdef NEML2_ENABLED
201 5319 : have("neml2", doc);
202 : #else
203 268140 : 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 55401 : const auto doc = "gperftools code performance analysis and profiling library";
212 : #ifdef HAVE_GPERFTOOLS
213 : have("gperftools", doc);
214 : #else
215 277005 : 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 55401 : const auto doc = "libPNG portable network graphics format library";
224 : #ifdef MOOSE_HAVE_LIBPNG
225 166203 : 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 55401 : 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 1738 : PETSC_PKG_CUDA_VERSION_MINOR) "." QUOTE(PETSC_PKG_CUDA_VERSION_SUBMINOR);
239 1738 : add_string("cuda", version, doc);
240 : #else
241 268315 : missing("cuda", doc, "Add the CUDA bin directory to your path and rebuild PETSc.");
242 : #endif
243 1738 : }
244 :
245 : {
246 55401 : const auto doc = "AMD GPU parallel computing platform";
247 : #ifdef PETSC_HAVE_HIPROCM
248 : const std::string version = QUOTE(PETSC_PKG_HIP_VERSION_MAJOR) "." QUOTE(
249 : PETSC_PKG_HIP_VERSION_MINOR) "." QUOTE(PETSC_PKG_HIP_VERSION_SUBMINOR);
250 : add_string("hip", version, doc);
251 : #else
252 277005 : missing("hip", doc, "Add the HIP bin directory to your path and rebuild PETSc.");
253 : #endif
254 : }
255 :
256 : {
257 55401 : const auto doc = "Intel GPU parallel computing platform";
258 : #ifdef PETSC_HAVE_SYCL
259 : const std::string version = QUOTE(PETSC_PKG_SYCL_VERSION_MAJOR) "." QUOTE(
260 : PETSC_PKG_SYCL_VERSION_MINOR) "." QUOTE(PETSC_PKG_SYCL_VERSION_SUBMINOR);
261 : add_string("sycl", version, doc);
262 : #else
263 277005 : missing("sycl", doc, "Add the SYCL bin directory to your path and rebuild PETSc.");
264 : #endif
265 : }
266 :
267 : {
268 55401 : const auto doc = "Kokkos performance portability programming ecosystem";
269 : #ifdef MOOSE_KOKKOS_ENABLED
270 : const std::string version = QUOTE(PETSC_PKG_KOKKOS_VERSION_MAJOR) "." QUOTE(
271 41183 : PETSC_PKG_KOKKOS_VERSION_MINOR) "." QUOTE(PETSC_PKG_KOKKOS_VERSION_SUBMINOR);
272 41183 : add_string("kokkos", version, doc);
273 : #else
274 71090 : missing("kokkos",
275 : doc,
276 : "Rebuild PETSc with Kokkos support and libMesh. Then, reconfigure MOOSE with "
277 : "--with-kokkos.");
278 : #endif
279 41183 : }
280 :
281 : {
282 55401 : const auto doc = "Kokkos support for PETSc";
283 : #ifdef PETSC_HAVE_KOKKOS
284 : const std::string version = QUOTE(PETSC_PKG_KOKKOS_VERSION_MAJOR) "." QUOTE(
285 55401 : PETSC_PKG_KOKKOS_VERSION_MINOR) "." QUOTE(PETSC_PKG_KOKKOS_VERSION_SUBMINOR);
286 55401 : add_string("petsc_kokkos", version, doc);
287 : #else
288 : missing(
289 : "petsc_kokkos", doc, "Rebuild PETSc with Kokkos support, then rebuild libMesh and MOOSE.");
290 : #endif
291 55401 : }
292 :
293 : {
294 55401 : const auto doc = "Intel OneAPI XPU accelerator support";
295 : #ifdef MOOSE_HAVE_XPU
296 1773 : if (torch::xpu::is_available())
297 0 : have("xpu", doc);
298 : else
299 10638 : missing("xpu", doc, "No usable XPU devices have been found.");
300 : #else
301 268140 : missing("xpu", doc, "The torch version used to build this app has no XPU support.");
302 : #endif
303 : }
304 :
305 55401 : add_int(
306 : "ad_size",
307 : MOOSE_AD_MAX_DOFS_PER_ELEM,
308 110802 : "MOOSE was configured and built with a dual number backing store size of " +
309 221604 : Moose::stringify(MOOSE_AD_MAX_DOFS_PER_ELEM) +
310 : ". Complex simulations with many variables or contact problems may require larger "
311 : "values. Reconfigure MOOSE with the --with-derivative-size=<n> option in the root of the "
312 : "repository.")
313 55401 : .setExplicit();
314 :
315 : {
316 55401 : const std::string method = QUOTE(METHOD);
317 110802 : add_string("method", method, "The executable was built with METHOD=\"" + method + "\"")
318 55401 : .setExplicit()
319 55401 : .setEnumeration({"dbg", "devel", "oprof", "opt"});
320 55401 : }
321 :
322 : {
323 : const std::string version = QUOTE(LIBMESH_DETECTED_PETSC_VERSION_MAJOR) "." QUOTE(
324 55401 : LIBMESH_DETECTED_PETSC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR);
325 55401 : add_string("petsc", version, "Using PETSc version " + version + ".");
326 55401 : }
327 :
328 : #ifdef LIBMESH_PETSC_USE_DEBUG
329 55401 : add_bool("petsc_debug", true, "PETSc was built with debugging options.");
330 : #else
331 : add_bool("petsc_debug", false, "PETSc was built without debugging options.");
332 : #endif
333 :
334 : {
335 55401 : const auto doc = "SuperLU direct solver";
336 : #ifdef LIBMESH_PETSC_HAVE_SUPERLU_DIST
337 : const std::string version = QUOTE(PETSC_PKG_SUPERLU_DIST_VERSION_MAJOR) "." QUOTE(
338 55401 : PETSC_PKG_SUPERLU_DIST_VERSION_MINOR) "." QUOTE(PETSC_PKG_SUPERLU_DIST_VERSION_SUBMINOR);
339 55401 : add_string("superlu", version, doc);
340 : #else
341 : petsc_missing("superlu", doc);
342 : #endif
343 55401 : }
344 :
345 : {
346 55401 : const auto doc = "MUltifrontal Massively Parallel sparse direct Solver (MUMPS)";
347 : #ifdef LIBMESH_PETSC_HAVE_MUMPS
348 : const std::string version = QUOTE(PETSC_PKG_MUMPS_VERSION_MAJOR) "." QUOTE(
349 55401 : PETSC_PKG_MUMPS_VERSION_MINOR) "." QUOTE(PETSC_PKG_MUMPS_VERSION_SUBMINOR);
350 55401 : add_string("mumps", version, doc);
351 : #else
352 : petsc_missing("mumps", doc);
353 : #endif
354 55401 : }
355 :
356 : {
357 55401 : const auto doc = "STRUMPACK - STRUctured Matrix PACKage solver library";
358 : #ifdef LIBMESH_PETSC_HAVE_STRUMPACK
359 : const std::string version = QUOTE(PETSC_PKG_STRUMPACK_VERSION_MAJOR) "." QUOTE(
360 55401 : PETSC_PKG_STRUMPACK_VERSION_MINOR) "." QUOTE(PETSC_PKG_STRUMPACK_VERSION_SUBMINOR);
361 55401 : add_string("strumpack", version, doc);
362 : #else
363 : petsc_missing("strumpack", doc);
364 : #endif
365 55401 : }
366 :
367 : {
368 55401 : const auto doc = "Parmetis partitioning library";
369 : #if defined(LIBMESH_PETSC_HAVE_PARMETIS)
370 : const std::string version = QUOTE(PETSC_PKG_PARMETIS_VERSION_MAJOR) "." QUOTE(
371 55401 : PETSC_PKG_PARMETIS_VERSION_MINOR) "." QUOTE(PETSC_PKG_PARMETIS_VERSION_SUBMINOR);
372 55401 : add_string("parmetis", version, doc);
373 : #elif defined(LIBMESH_HAVE_PARMETIS)
374 : have("parmetis", doc);
375 : #else
376 : petsc_missing("parmetis", doc);
377 : #endif
378 55401 : }
379 :
380 : {
381 55401 : const auto doc = "Chaco graph partitioning library";
382 : #ifdef LIBMESH_PETSC_HAVE_CHACO
383 : have("chaco", doc);
384 : #else
385 166203 : petsc_missing("chaco", doc);
386 : #endif
387 : }
388 :
389 : {
390 55401 : const auto doc = "Party matrix or graph partitioning library";
391 : #ifdef LIBMESH_PETSC_HAVE_PARTY
392 : have("party", doc);
393 : #else
394 166203 : petsc_missing("party", doc);
395 : #endif
396 : }
397 :
398 : {
399 55401 : const auto doc = "PT-Scotch graph partitioning library";
400 : #ifdef LIBMESH_PETSC_HAVE_PTSCOTCH
401 : const std::string version = QUOTE(PETSC_PKG_PTSCOTCH_VERSION_MAJOR) "." QUOTE(
402 55401 : PETSC_PKG_PTSCOTCH_VERSION_MINOR) "." QUOTE(PETSC_PKG_PTSCOTCH_VERSION_SUBMINOR);
403 55401 : add_string("ptscotch", version, doc);
404 : #else
405 : petsc_missing("ptscotch", doc);
406 : #endif
407 55401 : }
408 :
409 : {
410 55401 : const auto doc = "Optimized BLAS library";
411 : #ifdef PETSC_HAVE_OPENBLAS
412 : const std::string version = QUOTE(PETSC_PKG_OPENBLAS_VERSION_MAJOR) "." QUOTE(
413 55401 : PETSC_PKG_OPENBLAS_VERSION_MINOR) "." QUOTE(PETSC_PKG_OPENBLAS_VERSION_SUBMINOR);
414 55401 : add_string("openblas", version, doc);
415 : #else
416 : petsc_missing("openblas", doc);
417 : #endif
418 55401 : }
419 :
420 : {
421 55401 : const auto doc = "Umpire resource management library";
422 : #ifdef PETSC_HAVE_UMPIRE
423 166203 : have("umpire", doc);
424 : #else
425 : petsc_missing("umpire", doc);
426 : #endif
427 : }
428 :
429 : {
430 55401 : const auto doc = "Scalable Library for Eigenvalue Problem Computations (SLEPc)";
431 : #ifdef LIBMESH_HAVE_SLEPC
432 55401 : const auto version = QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_MAJOR) "." QUOTE(
433 : LIBMESH_DETECTED_SLEPC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_SUBMINOR);
434 277005 : have_version("slepc", doc, version);
435 : #else
436 : petsc_missing("slepc", doc);
437 : #endif
438 : }
439 :
440 : {
441 55401 : const auto doc = "Exodus mesh file format library";
442 : #ifdef LIBMESH_HAVE_EXODUS_API
443 110802 : const std::string version = QUOTE(LIBMESH_DETECTED_EXODUS_VERSION_MAJOR) "." QUOTE(
444 : LIBMESH_DETECTED_EXODUS_VERSION_MINOR);
445 166203 : have_version("exodus", doc, version);
446 : #else
447 : libmesh_missing("exodus", doc, "--enable-exodus");
448 : #endif
449 55401 : }
450 :
451 : {
452 55401 : const auto doc = "Netgen meshing library";
453 : #ifdef LIBMESH_HAVE_NETGEN
454 : const std::string version =
455 55401 : QUOTE(NETGEN_VERSION_MAJOR) "." QUOTE(NETGEN_VERSION_MINOR) "." QUOTE(NETGEN_VERSION_PATCH);
456 55401 : add_string("netgen", version, doc);
457 : #else
458 : libmesh_missing("netgen", doc, "--enable-netgen");
459 : #endif
460 55401 : }
461 :
462 : {
463 55401 : const auto doc = "Visualization Toolkit (VTK)";
464 : #ifdef LIBMESH_HAVE_VTK
465 : const std::string version = QUOTE(LIBMESH_DETECTED_VTK_VERSION_MAJOR) "." QUOTE(
466 110802 : LIBMESH_DETECTED_VTK_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_VTK_VERSION_SUBMINOR);
467 166203 : have_version("vtk", doc, version);
468 : #else
469 : libmesh_missing("vtk", doc, "--disable-vtk and --enable-vtk-required");
470 : #endif
471 55401 : }
472 :
473 : {
474 55401 : const auto doc = "libcurl - the multiprotocol file transfer library";
475 : #ifdef LIBMESH_HAVE_CURL
476 : have("curl", doc);
477 : #else
478 277005 : libmesh_missing("curl", doc, "--enable-curl");
479 : #endif
480 : }
481 :
482 : {
483 55401 : const auto doc = "Tecplot post-processing tools API";
484 : #ifdef LIBMESH_HAVE_TECPLOT_API
485 : have("tecplot", doc);
486 : #else
487 277005 : libmesh_missing("tecplot", doc, "--enable-tecplot");
488 : #endif
489 : }
490 :
491 : {
492 55401 : const auto doc = "NVIDIA Tools Extension Library API";
493 : #ifdef LIBMESH_HAVE_NVTX_API
494 5214 : have("nvtx_api", doc);
495 : #else
496 268315 : libmesh_missing("nvtx_api", doc, "--with-nvtx");
497 : #endif
498 : }
499 :
500 : {
501 55401 : const auto doc = "libMesh performance logging";
502 : #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
503 5214 : have("libmesh_perflog", doc);
504 : #else
505 268315 : libmesh_missing("libmesh_perflog", doc, "--enable-perflog");
506 : #endif
507 : }
508 :
509 : {
510 55401 : const auto doc = "Boost C++ library";
511 : #ifdef LIBMESH_HAVE_EXTERNAL_BOOST
512 : have("boost", doc);
513 : #else
514 277005 : libmesh_missing("boost", doc, "--with-boost");
515 : #endif
516 : }
517 :
518 : // libmesh stuff
519 : {
520 55401 : const auto doc = "Adaptive mesh refinement";
521 : #ifdef LIBMESH_ENABLE_AMR
522 166203 : have("amr", doc);
523 : #else
524 : libmesh_missing("amr", doc, "--disable-amr");
525 : #endif
526 : }
527 :
528 : {
529 55401 : const auto doc = "nanoflann library for Nearest Neighbor (NN) search with KD-trees";
530 : #ifdef LIBMESH_HAVE_NANOFLANN
531 166203 : have("nanoflann", doc);
532 : #else
533 : libmesh_missing("nanoflann", doc, "--disable-nanoflann");
534 : #endif
535 : }
536 :
537 : {
538 55401 : const auto doc = "sfcurves library for space filling curves (required by geometric "
539 : "partitioners such as SFCurves, Hilbert and Morton - not LGPL compatible)";
540 : #ifdef LIBMESH_HAVE_SFCURVES
541 : have("sfcurves", doc);
542 : #else
543 277005 : libmesh_missing("sfcurves", doc, "--disable-sfc");
544 : #endif
545 : }
546 :
547 : {
548 : #ifdef LIBMESH_HAVE_FPARSER
549 : #ifdef LIBMESH_HAVE_FPARSER_JIT
550 55401 : const auto value = "jit";
551 55401 : const auto doc = "FParser enabled with just in time compilation support.";
552 : #else
553 : const auto value = "byte_code";
554 : const auto doc = "FParser enabled.";
555 : #endif
556 55401 : add_string("fparser", value, doc);
557 : #else
558 : add_bool("fparser",
559 : false,
560 : "FParser is disabled, libMesh was likely configured with --disable-fparser.");
561 : #endif
562 : }
563 :
564 : #ifdef LIBMESH_HAVE_DLOPEN
565 55401 : add_bool("dlopen", true, "The dlopen() system call is available to dynamically load libraries.");
566 : #else
567 : add_bool("dlopen",
568 : false,
569 : "The dlopen() system call is not available. Dynamic library loading is "
570 : "not supported on this system.");
571 : #endif
572 :
573 : {
574 55401 : const auto doc = "LibMesh support for threaded execution";
575 : #ifdef LIBMESH_USING_THREADS
576 166203 : have("threads", doc);
577 : #else
578 : libmesh_missing("threads", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
579 : #endif
580 : }
581 :
582 : {
583 55401 : const auto doc = "OpenMP multi-platform shared-memory parallel programming API";
584 : #ifdef LIBMESH_HAVE_OPENMP
585 166203 : have("openmp", doc);
586 : #else
587 : libmesh_missing("openmp", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
588 : #endif
589 : }
590 : {
591 55401 : const auto doc = "POSIX Threads API";
592 : #ifdef LIBMESH_HAVE_PTHREAD
593 166203 : have("pthread", doc);
594 : #else
595 : libmesh_missing("pthread", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
596 : #endif
597 : }
598 : {
599 55401 : const auto doc = "oneAPI Threading Building Blocks (TBB) API";
600 : #ifdef LIBMESH_HAVE_TBB_API
601 : have("tbb", doc);
602 : #else
603 277005 : libmesh_missing("tbb", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
604 : #endif
605 : }
606 :
607 : {
608 55401 : const auto doc = "libMesh unique ID support";
609 : #ifdef LIBMESH_ENABLE_UNIQUE_ID
610 166203 : have("unique_id", doc);
611 : #else
612 : libmesh_missing("unique_id", doc, "--enable-unique-id");
613 : #endif
614 : }
615 :
616 : {
617 : #ifdef LIBMESH_ENABLE_PARMESH
618 : const auto value = "distributed";
619 : #else
620 55401 : const auto value = "replicated";
621 : #endif
622 55401 : add_string("mesh_mode", value, "libMesh default mesh mode")
623 55401 : .setExplicit()
624 55401 : .setEnumeration({"distributed", "replicated"});
625 : }
626 :
627 55401 : add_int("dof_id_bytes",
628 : static_cast<int>(sizeof(dof_id_type)),
629 110802 : "Degree of freedom (DOF) identifiers use " + Moose::stringify(sizeof(dof_id_type)) +
630 : " bytes for storage. This is controlled by the "
631 : "--with-dof-id-bytes=<1|2|4|8> libMesh configure option.")
632 55401 : .setExplicit();
633 :
634 : {
635 : #ifdef LIBMESH_HAVE_STATIC_LIBS
636 : const auto value = "static";
637 : #else
638 55401 : const auto value = "dynamic";
639 : #endif
640 55401 : add_string("library_mode",
641 : value,
642 : "The libMesh library mode. This is controlled by the --enable-static libMesh "
643 : "configure option.")
644 55401 : .setExplicit()
645 55401 : .setEnumeration({"dynamic", "static"});
646 : }
647 :
648 : // compiler
649 : {
650 55401 : const auto doc = "Compiler used to build the MOOSE framework.";
651 : #if defined(__INTEL_LLVM_COMPILER)
652 : const auto value = "intel";
653 : #elif defined(__clang__)
654 : const auto value = "clang";
655 : #elif defined(__GNUC__) || defined(__GNUG__)
656 55401 : const auto value = "gcc";
657 : #elif defined(_MSC_VER)
658 : const auto value = "msvc";
659 : #else
660 : mooseDoOnce(mooseWarning("Failed to determine compiler; setting capability compiler=unknown"));
661 : const auto value = "unknown";
662 : #endif
663 55401 : add_string("compiler", value, doc)
664 55401 : .setExplicit()
665 55401 : .setEnumeration({"clang", "gcc", "intel", "msvc", "unknown"});
666 : }
667 :
668 : // OS related
669 : {
670 : #ifdef __APPLE__
671 : const auto value = "darwin";
672 : #elif __WIN32__
673 : const auto value = "win32";
674 : #elif __linux__
675 55401 : const auto value = "linux";
676 : #elif __unix__
677 : const auto value = "unix";
678 : #else
679 : mooseDoOnce(mooseWarning("Failed to determine platform; setting capability platform=unknown"));
680 : const auto value = "unknown";
681 : #endif
682 55401 : add_string("platform", value, "Operating system this executable is running on.")
683 55401 : .setExplicit()
684 55401 : .setEnumeration({"darwin", "linux", "unix", "unknown", "win32"});
685 : }
686 :
687 : // Installation type (in tree or installed)
688 : {
689 : // Try to find the path to the running executable
690 55401 : std::optional<std::string> executable_path;
691 : {
692 55401 : Moose::ScopedThrowOnError scoped_throw_on_error;
693 : try
694 : {
695 55401 : executable_path = Moose::getExec();
696 : }
697 0 : catch (const MooseException &)
698 : {
699 0 : }
700 55401 : }
701 :
702 55401 : std::string value = "unknown";
703 :
704 55401 : if (executable_path)
705 : {
706 : // Try to follow all symlinks to get the real path
707 55401 : std::error_code ec;
708 : const auto resolved_path =
709 55401 : std::filesystem::weakly_canonical(std::filesystem::path(*executable_path), ec);
710 55401 : if (ec)
711 0 : mooseDoOnce(mooseWarning("Failed to resolve executable path '",
712 : *executable_path,
713 : "':\n",
714 : ec.message(),
715 : "\n\nSetting capability installation_type=unknown"));
716 : else
717 : {
718 : // If the binary is in a folder "bin", we'll consider it installed.
719 : // This isn't the best check, but it works with how we currently
720 : // install applications in app.mk
721 55401 : value = resolved_path.parent_path().filename() == "bin" ? "relocated" : "in_tree";
722 : }
723 55401 : }
724 : else
725 0 : mooseDoOnce(mooseWarning(
726 : "Failed to determine executable path; setting capability installation_type=unknown"));
727 :
728 55401 : add_string("installation_type", value, "The installation type of the application.")
729 55401 : .setExplicit()
730 55401 : .setEnumeration({"in_tree", "relocated", "unknown"});
731 :
732 : mooseAssert(isInstallationType(value), "Value mismatch");
733 55401 : }
734 55401 : }
735 :
736 : } // namespace Moose
|