IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
Ippl.cpp
Go to the documentation of this file.
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
14namespace ippl {
15
16 void initialize(int& argc, char* argv[], MPI_Comm comm) {
17 Env = std::make_unique<mpi::Environment>(argc, argv, comm);
18
19 Comm = std::make_unique<mpi::Communicator>(comm);
20
21 Info = std::make_unique<Inform>("Ippl");
22 Warn = std::make_unique<Inform>("Warning", std::cerr);
23 Error = std::make_unique<Inform>("Error", std::cerr, INFORM_ALL_NODES);
24
25 try {
26 std::list<std::string> notparsed;
27 int infoLevel = 0;
28 int nargs = 0;
29 while (nargs < argc) {
30 if (detail::checkOption(argv[nargs], "--help", "-h")) {
31 if (Comm->rank() == 0) {
33 }
34 std::exit(0);
35 } else if (detail::checkOption(argv[nargs], "--info", "-i")) {
36 ++nargs;
37 if (nargs >= argc) {
38 throw std::runtime_error("Missing info level value!");
39 }
40 infoLevel = detail::getNumericalOption<int>(argv[nargs]);
41 } else if (detail::checkOption(argv[nargs], "--timer-fences", "")) {
42 ++nargs;
43 if (nargs >= argc) {
44 throw std::runtime_error("Missing timer fence enable option!");
45 }
46 if (std::strcmp(argv[nargs], "on") == 0) {
48 } else if (std::strcmp(argv[nargs], "off") == 0) {
49 Timer::enableFences = false;
50 } else {
51 throw std::runtime_error("Invalid timer fence option");
52 }
53 } else if (detail::checkOption(argv[nargs], "--version", "-v")) {
55 std::string options = IpplInfo::compileOptions();
56 std::string header("Compile-time options: ");
57 while (options.length() > 58) {
58 std::string line = options.substr(0, 58);
59 size_t n = line.find_last_of(' ');
60 *Info << header << line.substr(0, n) << "\n";
61
62 header = std::string(22, ' ');
63 options = options.substr(n + 1);
64 }
65 *Info << header << options << endl;
66 std::exit(0);
67 } else if (detail::checkOption(argv[nargs], "--overallocate", "-b")) {
68 ++nargs;
69 if (nargs >= argc) {
70 throw std::runtime_error("Missing overallocation factor value!");
71 }
72 auto factor = detail::getNumericalOption<double>(argv[nargs]);
73 Comm->setDefaultOverallocation(factor);
74 } else if (nargs > 0 && std::strstr(argv[nargs], "--kokkos") == nullptr) {
75 notparsed.push_back(argv[nargs]);
76 }
77 ++nargs;
78 }
79
80 Info->setOutputLevel(infoLevel);
81 Error->setOutputLevel(infoLevel);
82 Warn->setOutputLevel(infoLevel);
83
84 } catch (const std::exception& e) {
85 if (Comm->rank() == 0) {
86 std::cerr << e.what() << std::endl;
87 }
88 std::exit(0);
89 }
90
91 Kokkos::initialize(argc, argv);
92 }
93
94 void finalize() {
95 Comm->deleteAllBuffers();
96 Kokkos::finalize();
97 // we must first delete the communicator and
98 // afterwards the MPI environment
99 Comm.reset(nullptr);
100 Env.reset(nullptr);
101 }
102
103 void fence() {
104 Kokkos::fence();
105 }
106
107 void abort(const char* msg, int errorcode) {
108 if (msg) {
109 *Error << msg << endl;
110 }
111 Comm->abort(errorcode);
112 }
113
114 namespace detail {
115 bool checkOption(const char* arg, const char* lstr, const char* sstr) {
116 return (std::strcmp(arg, lstr) == 0) || (std::strcmp(arg, sstr) == 0);
117 }
118
119 template <typename T, typename>
120 T getNumericalOption(const char* arg) {
121 constexpr bool isInt = std::is_integral_v<T>;
122 std::string sarg = arg;
123 try {
124 T ret;
125 size_t parsed;
126 if constexpr (isInt) {
127 ret = std::stoll(sarg, &parsed);
128 } else {
129 ret = std::stold(sarg, &parsed);
130 }
131 if (parsed != sarg.length())
132 throw std::invalid_argument("Failed to parse");
133 return ret;
134 } catch (std::invalid_argument& e) {
135 if constexpr (isInt) {
136 throw std::runtime_error("Expected integer argument!");
137 } else {
138 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 }
144 } // namespace detail
145} // namespace ippl
Inform & endl(Inform &inf)
Definition Inform.cpp:42
#define INFORM_ALL_NODES
Definition Inform.h:38
Definition Archive.h:20
void initialize(int &argc, char *argv[], MPI_Comm comm)
Definition Ippl.cpp:16
std::unique_ptr< Inform > Info
Definition Ippl.h:29
std::unique_ptr< Inform > Error
Definition Ippl.h:31
void finalize()
Definition Ippl.cpp:94
void fence()
Definition Ippl.cpp:103
std::unique_ptr< Inform > Warn
Definition Ippl.h:30
std::unique_ptr< mpi::Communicator > Comm
Definition Ippl.h:22
std::unique_ptr< mpi::Environment > Env
Definition Ippl.h:24
void abort(const char *msg, int errorcode)
Definition Ippl.cpp:107
T getNumericalOption(const char *arg)
Definition Ippl.cpp:120
bool checkOption(const char *arg, const char *lstr, const char *sstr)
Definition Ippl.cpp:115
static void printVersion(void)
Definition IpplInfo.cpp:17
static void printHelp(char **argv)
Definition IpplInfo.cpp:24
static const char * compileOptions()
Definition IpplInfo.cpp:74
static bool enableFences
Definition Timer.h:22