Branch data 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 : 657 : void initialize(int& argc, char* argv[], MPI_Comm comm) {
17 [ + - ]: 657 : Env = std::make_unique<mpi::Environment>(argc, argv, comm);
18 : :
19 [ + - ]: 657 : Comm = std::make_unique<mpi::Communicator>(comm);
20 : :
21 [ + - ]: 657 : Info = std::make_unique<Inform>("Ippl");
22 [ + - ]: 657 : Warn = std::make_unique<Inform>("Warning", std::cerr);
23 [ + - ]: 657 : Error = std::make_unique<Inform>("Error", std::cerr, INFORM_ALL_NODES);
24 : :
25 : : try {
26 : 657 : std::list<std::string> notparsed;
27 : 657 : int infoLevel = 0;
28 : 657 : int nargs = 0;
29 [ + + ]: 2613 : while (nargs < argc) {
30 [ - + ]: 1956 : 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 [ - + ]: 1956 : } 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 [ - + ]: 1956 : } 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 [ - + ]: 1956 : } 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 [ - + ]: 1956 : } 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 [ + + + - ]: 1956 : } else if (nargs > 0 && std::strstr(argv[nargs], "--kokkos") == nullptr) {
75 [ + - + - ]: 2598 : notparsed.push_back(argv[nargs]);
76 : : }
77 : 1956 : ++nargs;
78 : : }
79 : :
80 [ + - ]: 657 : Info->setOutputLevel(infoLevel);
81 [ + - ]: 657 : Error->setOutputLevel(0);
82 [ + - ]: 657 : Warn->setOutputLevel(0);
83 : :
84 [ - + - - : 657 : 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 [ - - ]: 657 : } 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 : 657 : Kokkos::initialize(argc, argv);
98 : 657 : }
99 : :
100 : 657 : void finalize() {
101 : 657 : Comm->deleteAllBuffers();
102 : 657 : Kokkos::finalize();
103 : : // we must first delete the communicator and
104 : : // afterwards the MPI environment
105 : 657 : Comm.reset(nullptr);
106 : 657 : Env.reset(nullptr);
107 : 657 : }
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 : 9780 : bool checkOption(const char* arg, const char* lstr, const char* sstr) {
122 [ + - - + ]: 9780 : 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
|