LCOV - code coverage report
Current view: top level - src - Ippl.cpp (source / functions) Coverage Total Hit
Test: final_report.info Lines: 35.2 % 88 31
Test Date: 2025-09-12 21:46:33 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           60 :     void initialize(int& argc, char* argv[], MPI_Comm comm) {
      17           60 :         Env = std::make_unique<mpi::Environment>(argc, argv, comm);
      18              : 
      19           60 :         Comm = std::make_unique<mpi::Communicator>(comm);
      20              : 
      21           60 :         Info  = std::make_unique<Inform>("Ippl");
      22           60 :         Warn  = std::make_unique<Inform>("Warning", std::cerr);
      23           60 :         Error = std::make_unique<Inform>("Error", std::cerr, INFORM_ALL_NODES);
      24              : 
      25              :         try {
      26           60 :             std::list<std::string> notparsed;
      27           60 :             int infoLevel = 0;
      28           60 :             int nargs     = 0;
      29          120 :             while (nargs < argc) {
      30           60 :                 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           60 :                 } 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           60 :                 } 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           60 :                 } 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           60 :                 } 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           60 :                 } else if (nargs > 0 && std::strstr(argv[nargs], "--kokkos") == nullptr) {
      75            0 :                     notparsed.push_back(argv[nargs]);
      76              :                 }
      77           60 :                 ++nargs;
      78              :             }
      79              : 
      80           60 :             Info->setOutputLevel(infoLevel);
      81           60 :             Error->setOutputLevel(infoLevel);
      82           60 :             Warn->setOutputLevel(infoLevel);
      83              :             
      84           60 :         } catch (const std::exception& e) {
      85            0 :             if (Comm->rank() == 0) {
      86            0 :                 std::cerr << e.what() << std::endl;
      87              :             }
      88            0 :             std::exit(0);
      89            0 :         }
      90              : 
      91           60 :         Kokkos::initialize(argc, argv);
      92           60 :     }
      93              : 
      94           60 :     void finalize() {
      95           60 :         Comm->deleteAllBuffers();
      96           60 :         Kokkos::finalize();
      97              :         // we must first delete the communicator and
      98              :         // afterwards the MPI environment
      99           60 :         Comm.reset(nullptr);
     100           60 :         Env.reset(nullptr);
     101           60 :     }
     102              : 
     103            0 :     void fence() {
     104            0 :         Kokkos::fence();
     105            0 :     }
     106              : 
     107            0 :     void abort(const char* msg, int errorcode) {
     108            0 :         if (msg) {
     109            0 :             *Error << msg << endl;
     110              :         }
     111            0 :         Comm->abort(errorcode);
     112            0 :     }
     113              : 
     114              :     namespace detail {
     115          300 :         bool checkOption(const char* arg, const char* lstr, const char* sstr) {
     116          300 :             return (std::strcmp(arg, lstr) == 0) || (std::strcmp(arg, sstr) == 0);
     117              :         }
     118              : 
     119              :         template <typename T, typename>
     120            0 :         T getNumericalOption(const char* arg) {
     121            0 :             constexpr bool isInt = std::is_integral_v<T>;
     122            0 :             std::string sarg     = arg;
     123              :             try {
     124              :                 T ret;
     125              :                 size_t parsed;
     126              :                 if constexpr (isInt) {
     127            0 :                     ret = std::stoll(sarg, &parsed);
     128              :                 } else {
     129            0 :                     ret = std::stold(sarg, &parsed);
     130              :                 }
     131            0 :                 if (parsed != sarg.length())
     132            0 :                     throw std::invalid_argument("Failed to parse");
     133            0 :                 return ret;
     134            0 :             } catch (std::invalid_argument& e) {
     135              :                 if constexpr (isInt) {
     136            0 :                     throw std::runtime_error("Expected integer argument!");
     137              :                 } else {
     138            0 :                     throw std::runtime_error("Expected floating point argument!");
     139              :                 }
     140              :             }
     141              :             // Silence nvcc warning: missing return statement at end of non-void function
     142              :             throw std::runtime_error("Unreachable state");
     143            0 :         }
     144              :     }  // namespace detail
     145              : }  // namespace ippl
        

Generated by: LCOV version 2.0-1