11#include "Teuchos_EnvVariables.hpp" 
   15#if !defined(__GNUC__) || (__GNUC__ >= 10) 
   23#if not(defined(WIN) && (_MSC_VER >= 1900)) 
   28namespace Teuchos::SystemInformation {
 
   32std::map<std::string, std::pair<std::string, std::string>>& getCommandsMap() {
 
   33  static std::map<std::string, std::pair<std::string, std::string>> commands;
 
   37std::set<std::string>& getEnvironmentVariablesSet() {
 
   38  static std::set<std::string> environmentVariables;
 
   39  return environmentVariables;
 
   44bool commandIsAvailable(
const std::string &command) {
 
   46      std::string(
"command -v " + command + 
" > /dev/null 2>&1").c_str());
 
   49std::string runCommandAndCaptureOutput(
const std::string &command) {
 
   51  std::string result = 
"";
 
   52  FILE *pipe = popen(command.c_str(), 
"r");
 
   54    return "command \"" + command + 
"\"failed";
 
   56    while (fgets(buffer, 
sizeof buffer, pipe) != NULL) {
 
   61    return "command \"" + command + 
"\"failed";
 
   68registerEnvironmentVariable(
const std::string &variableName) {
 
   69  auto &environmentVariables = getEnvironmentVariablesSet();
 
   71  if (
auto search = environmentVariables.find(variableName);
 
   72      search != environmentVariables.end()) {
 
   74    return ALREADY_PRESENT;
 
   77    environmentVariables.insert(variableName);
 
   82void registerAllPrefixedVariables(
const std::string &prefix) {
 
   84#if defined(WIN) && (_MSC_VER >= 1900) 
   85  env = *__p__environ();
 
   94    std::string name = substrings[0];
 
   96    if (name.size() >= prefix.size() &&
 
   97        name.substr(0, prefix.size()) == prefix) {
 
   98      Teuchos::SystemInformation::registerEnvironmentVariable(name);
 
  104registerCommand(
const std::string &commandLabel,
 
  105                const std::string &commandToRunAndCapture,
 
  106                const std::string &commandToCheckForExistence) {
 
  107  auto &commands = getCommandsMap();
 
  109  std::string myCommandToRunAndCapture = commandToRunAndCapture;
 
  110  if (myCommandToRunAndCapture.empty())
 
  111    myCommandToRunAndCapture = commandLabel;
 
  113  std::string myCommandToCheckForExistence = commandToCheckForExistence;
 
  114  if (myCommandToCheckForExistence.empty())
 
  115    myCommandToCheckForExistence = myCommandToRunAndCapture;
 
  117  if (
auto search = commands.find(commandLabel); search != commands.end()) {
 
  118    if ((commands[commandLabel].first == myCommandToCheckForExistence) &&
 
  119        (commands[commandLabel].second == myCommandToRunAndCapture))
 
  120      return ALREADY_PRESENT;
 
  123          << 
"Teuchos::SystemInformation: Attempted to register a command (\"" 
  124          << commandLabel << 
"\", \"" << myCommandToRunAndCapture << 
"\", \"" 
  125          << myCommandToCheckForExistence << 
"\") " 
  126          << 
"that clashes with already registered command: (" << commandLabel
 
  127          << 
"\", \"" << commands[commandLabel].first << 
"\", \"" 
  128          << commands[commandLabel].second << 
"\")." << std::endl;
 
  133    commands[commandLabel] = {myCommandToCheckForExistence, myCommandToRunAndCapture};
 
  138void initializeCollection() {
 
  140  std::string userProvidedEnvVariables =
 
  142          "TEUCHOS_USER_ENVIRONMENT_VARIABLES", 
"");
 
  143  if (!userProvidedEnvVariables.empty()) {
 
  145    bool isValid = (strings.size() >= 1);
 
  148          << 
"Teuchos::SystemInformation: The value of the environment " 
  150             "TEUCHOS_USER_ENVIRONMENT_VARIABLES needs to be a semi-colon " 
  151             "seperated string. Value: " 
  152          << userProvidedEnvVariables << std::endl;
 
  153    for (
int itemNo = 0; itemNo < strings.size(); ++itemNo) {
 
  154      std::string &variableName = strings[itemNo];
 
  155      if (registerEnvironmentVariable(variableName) == FAILURE)
 
  159        !isValid, std::runtime_error,
 
  160        "Teuchos::SystemInformation: Invalid environment variable " 
  161        "TEUCHOS_USER_ENVIRONMENT_VARIABLES");
 
  164  std::string userProvidedCommands =
 
  166  if (!userProvidedCommands.empty()) {
 
  168    bool isValid = (strings.size() % 3 == 0) && (strings.size() >= 3);
 
  170      std::cerr << 
"Teuchos::SystemInformation: The value of the environment " 
  171                   "variable TEUCHOS_USER_COMMANDS " 
  172                   "needs to be a semi-colon seperated string with a number of " 
  173                   "elements that is a multiple of 3. Value: " 
  174                << userProvidedCommands << std::endl;
 
  176    while (isValid && (3 * tupleNo + 2 < strings.size())) {
 
  177      std::string &commandLabel = strings[3 * tupleNo];
 
  178      std::string &commandToRunAndCapture = strings[3 * tupleNo + 1];
 
  179      std::string &commandToCheckForExistence = strings[3 * tupleNo + 2];
 
  180      if (registerCommand(commandLabel, commandToRunAndCapture,
 
  181                          commandToCheckForExistence) == FAILURE) {
 
  187                               "Teuchos::SystemInformation: Invalid " 
  188                               "environment variable TEUCHOS_USER_COMMANDS");
 
  191#if !defined(__GNUC__) || (__GNUC__ >= 10) 
  193    const std::string executable = std::filesystem::canonical(
"/proc/self/exe");
 
  194    if (!executable.empty()) {
 
  195      registerCommand(
"ldd", 
"ldd " + executable, 
"ldd");
 
  197  } 
catch (std::filesystem::filesystem_error &) {
 
  203  registerCommand(
"lscpu");
 
  206  registerCommand(
"sensors");
 
  209  registerAllPrefixedVariables(
"OMP");
 
  212  registerCommand(
"ompi_info");
 
  213  registerAllPrefixedVariables(
"OMPI");
 
  216  registerCommand(
"mpichinfo");
 
  217  registerAllPrefixedVariables(
"MPICH");
 
  220  registerAllPrefixedVariables(
"CRAY");
 
  223  registerCommand(
"module", 
"module list", 
"module");
 
  226  registerCommand(
"nvidia-smi", 
"nvidia-smi --query", 
"nvidia-smi");
 
  227  registerAllPrefixedVariables(
"CUDA");
 
  230  registerCommand(
"rocm-smi", 
"rocm-smi --showallinfo", 
"rocm-smi");
 
  233  registerCommand(
"sycl-ls", 
"sycl-ls --verbose", 
"sycl-ls");
 
  236  for (
auto &prefix : {
"TEUCHOS", 
"KOKKOS", 
"TPETRA", 
"STK"})
 
  237    registerAllPrefixedVariables(prefix);
 
  240std::map<std::string, std::string> collectSystemInformation() {
 
  242  std::map<std::string, std::string> data;
 
  244  const std::string DATA_NOT_AVAILABLE = 
"NOT AVAILABLE";
 
  246  auto &commands = getCommandsMap();
 
  247  for (
auto &command : commands) {
 
  248    const bool isAvailable = commandIsAvailable(command.second.first);
 
  250      data[command.first] = runCommandAndCaptureOutput(command.second.second);
 
  252      data[command.first] = DATA_NOT_AVAILABLE;
 
  256  auto &environmentVariables = getEnvironmentVariablesSet();
 
  257  for (
auto &envVariable : environmentVariables) {
 
  258    const char *varVal = std::getenv(envVariable.c_str());
 
  259    if (varVal == 
nullptr)
 
  260      data[envVariable] = 
"NOT SET";
 
A std::string utilities class for Teuchos.
 
Standard test and throw macros.
 
Smart reference counting pointer class for automatic garbage collection.
 
static Array< std::string > splitString(const std::string_view s, const char sep=',')
Split an input std::string using a seperator char sep.
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.