LCOV - code coverage report
Current view: top level - src - Ippl.cpp (source / functions) Coverage Total Hit
Test: final_report.info Lines: 34.8 % 92 32
Test Date: 2025-07-18 17:15:09 Functions: 42.9 % 7 3

            Line data    Source code
       1              : //
       2              : // Class Ippl
       3              : //   Ippl environment.
       4              : //
       5              : #include <Kokkos_Core.hpp>
       6              : #include "Ippl.h"
       7              : 
       8              : #include <cstdlib>
       9              : #include <cstring>
      10              : #include <list>
      11              : 
      12              : #include "Utility/IpplInfo.h"
      13              : 
      14              : namespace ippl {
      15              : 
      16           44 :     void initialize(int& argc, char* argv[], MPI_Comm comm) {
      17           44 :         Env = std::make_unique<mpi::Environment>(argc, argv, comm);
      18              : 
      19           44 :         Comm = std::make_unique<mpi::Communicator>(comm);
      20              : 
      21           44 :         Info  = std::make_unique<Inform>("Ippl");
      22           44 :         Warn  = std::make_unique<Inform>("Warning", std::cerr);
      23           44 :         Error = std::make_unique<Inform>("Error", std::cerr, INFORM_ALL_NODES);
      24              : 
      25              :         try {
      26           44 :             std::list<std::string> notparsed;
      27           44 :             int infoLevel = 0;
      28           44 :             int nargs     = 0;
      29           88 :             while (nargs < argc) {
      30           44 :                 if (detail::checkOption(argv[nargs], "--help", "-h")) {
      31            0 :                     if (Comm->rank() == 0) {
      32            0 :                         IpplInfo::printHelp(argv);
      33              :                     }
      34            0 :                     std::exit(0);
      35           44 :                 } else if (detail::checkOption(argv[nargs], "--info", "-i")) {
      36            0 :                     ++nargs;
      37            0 :                     if (nargs >= argc) {
      38            0 :                         throw std::runtime_error("Missing info level value!");
      39              :                     }
      40            0 :                     infoLevel = detail::getNumericalOption<int>(argv[nargs]);
      41           44 :                 } else if (detail::checkOption(argv[nargs], "--timer-fences", "")) {
      42            0 :                     ++nargs;
      43            0 :                     if (nargs >= argc) {
      44            0 :                         throw std::runtime_error("Missing timer fence enable option!");
      45              :                     }
      46            0 :                     if (std::strcmp(argv[nargs], "on") == 0) {
      47            0 :                         Timer::enableFences = true;
      48            0 :                     } else if (std::strcmp(argv[nargs], "off") == 0) {
      49            0 :                         Timer::enableFences = false;
      50              :                     } else {
      51            0 :                         throw std::runtime_error("Invalid timer fence option");
      52              :                     }
      53           44 :                 } else if (detail::checkOption(argv[nargs], "--version", "-v")) {
      54            0 :                     IpplInfo::printVersion();
      55            0 :                     std::string options = IpplInfo::compileOptions();
      56            0 :                     std::string header("Compile-time options: ");
      57            0 :                     while (options.length() > 58) {
      58            0 :                         std::string line = options.substr(0, 58);
      59            0 :                         size_t n         = line.find_last_of(' ');
      60            0 :                         *Info << header << line.substr(0, n) << "\n";
      61              : 
      62            0 :                         header  = std::string(22, ' ');
      63            0 :                         options = options.substr(n + 1);
      64            0 :                     }
      65            0 :                     *Info << header << options << endl;
      66            0 :                     std::exit(0);
      67           44 :                 } else if (detail::checkOption(argv[nargs], "--overallocate", "-b")) {
      68            0 :                     ++nargs;
      69            0 :                     if (nargs >= argc) {
      70            0 :                         throw std::runtime_error("Missing overallocation factor value!");
      71              :                     }
      72            0 :                     auto factor = detail::getNumericalOption<double>(argv[nargs]);
      73            0 :                     Comm->setDefaultOverallocation(factor);
      74           44 :                 } else if (nargs > 0 && std::strstr(argv[nargs], "--kokkos") == nullptr) {
      75            0 :                     notparsed.push_back(argv[nargs]);
      76              :                 }
      77           44 :                 ++nargs;
      78              :             }
      79              : 
      80           44 :             Info->setOutputLevel(infoLevel);
      81           44 :             Error->setOutputLevel(0);
      82           44 :             Warn->setOutputLevel(0);
      83              : 
      84           44 :             if (infoLevel > 0 && Comm->rank() == 0) {
      85            0 :                 for (auto& l : notparsed) {
      86            0 :                     std::cout << "Warning: Option '" << l << "' is not parsed by Ippl."
      87            0 :                               << std::endl;
      88              :                 }
      89              :             }
      90           44 :         } catch (const std::exception& e) {
      91            0 :             if (Comm->rank() == 0) {
      92            0 :                 std::cerr << e.what() << std::endl;
      93              :             }
      94            0 :             std::exit(0);
      95            0 :         }
      96              : 
      97           44 :         Kokkos::initialize(argc, argv);
      98           44 :     }
      99              : 
     100           44 :     void finalize() {
     101           44 :         Comm->deleteAllBuffers();
     102           44 :         Kokkos::finalize();
     103              :         // we must first delete the communicator and
     104              :         // afterwards the MPI environment
     105           44 :         Comm.reset(nullptr);
     106           44 :         Env.reset(nullptr);
     107           44 :     }
     108              : 
     109            0 :     void fence() {
     110            0 :         Kokkos::fence();
     111            0 :     }
     112              : 
     113            0 :     void abort(const char* msg, int errorcode) {
     114            0 :         if (msg) {
     115            0 :             *Error << msg << endl;
     116              :         }
     117            0 :         Comm->abort(errorcode);
     118            0 :     }
     119              : 
     120              :     namespace detail {
     121          220 :         bool checkOption(const char* arg, const char* lstr, const char* sstr) {
     122          220 :             return (std::strcmp(arg, lstr) == 0) || (std::strcmp(arg, sstr) == 0);
     123              :         }
     124              : 
     125              :         template <typename T, typename>
     126            0 :         T getNumericalOption(const char* arg) {
     127            0 :             constexpr bool isInt = std::is_integral_v<T>;
     128            0 :             std::string sarg     = arg;
     129              :             try {
     130              :                 T ret;
     131              :                 size_t parsed;
     132              :                 if constexpr (isInt) {
     133            0 :                     ret = std::stoll(sarg, &parsed);
     134              :                 } else {
     135            0 :                     ret = std::stold(sarg, &parsed);
     136              :                 }
     137            0 :                 if (parsed != sarg.length())
     138            0 :                     throw std::invalid_argument("Failed to parse");
     139            0 :                 return ret;
     140            0 :             } catch (std::invalid_argument& e) {
     141              :                 if constexpr (isInt) {
     142            0 :                     throw std::runtime_error("Expected integer argument!");
     143              :                 } else {
     144            0 :                     throw std::runtime_error("Expected floating point argument!");
     145              :                 }
     146              :             }
     147              :             // Silence nvcc warning: missing return statement at end of non-void function
     148              :             throw std::runtime_error("Unreachable state");
     149            0 :         }
     150              :     }  // namespace detail
     151              : }  // namespace ippl
        

Generated by: LCOV version 2.0-1