Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_IParser.H
Go to the documentation of this file.
1#ifndef AMREX_IPARSER_H_
2#define AMREX_IPARSER_H_
3
4#include <AMReX_Arena.H>
5#include <AMReX_Array.H>
6#include <AMReX_GpuDevice.H>
7#include <AMReX_IParser_Exe.H>
8#include <AMReX_Vector.H>
9
10#include <memory>
11#include <string>
12#include <set>
13
14namespace amrex {
15
16template <int N>
18{
19 template <int M=N, std::enable_if_t<M==0,int> = 0>
21 long long operator() () const noexcept
22 {
23 AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, nullptr);))
24 AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, nullptr);))
25 }
26
27 template <typename... Ts>
29 std::enable_if_t<sizeof...(Ts) == N && std::conjunction_v<std::is_integral<Ts>...>,
30 long long>
31 operator() (Ts... var) const noexcept
32 {
33 amrex::GpuArray<long long,N> l_var{var...};
34 AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, l_var.data());))
35 AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, l_var.data());))
36 }
37
39 long long operator() (GpuArray<long long, N> const& var) const noexcept
40 {
41 AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, var.data());))
42 AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, var.data());))
43 }
44
46 explicit operator bool () const {
47 AMREX_IF_ON_DEVICE((return m_device_executor != nullptr;))
48 AMREX_IF_ON_HOST((return m_host_executor != nullptr;))
49 }
50
51 char* m_host_executor = nullptr;
52#ifdef AMREX_USE_GPU
53 char* m_device_executor = nullptr;
54#endif
55};
56
59{
60public:
61 IParser (std::string const& func_body);
62 IParser () = default;
63 void define (std::string const& func_body);
64
65 explicit operator bool () const;
66
67 void setConstant (std::string const& name, long long c);
68
69 void registerVariables (Vector<std::string> const& vars);
70
71 void print () const;
72
73 [[nodiscard]] int depth () const;
74 [[nodiscard]] int maxStackSize () const;
75
76 [[nodiscard]] std::string expr () const;
77
78 [[nodiscard]] std::set<std::string> symbols () const;
79
81 template <int N> [[nodiscard]] IParserExecutor<N> compile () const;
82
84 template <int N> [[nodiscard]] IParserExecutor<N> compileHost () const;
85
86private:
87
89 struct Data {
90 std::string m_expression;
91 struct amrex_iparser* m_iparser = nullptr;
92 int m_nvars = 0;
93 bool m_use_arena = true;
94 char* m_host_executor = nullptr;
95#ifdef AMREX_USE_GPU
96 char* m_device_executor = nullptr;
97#endif
98 int m_max_stack_size = 0;
99 int m_exe_size = 0;
100 Data () = default;
101 ~Data ();
102 Data (Data const&) = delete;
103 Data (Data &&) = delete;
104 Data& operator= (Data const&) = delete;
105 Data& operator= (Data &&) = delete;
106 };
108
109 std::shared_ptr<Data> m_data;
110};
111
112template <int N>
113IParserExecutor<N>
115{
116 if (m_data && m_data->m_iparser) {
117 AMREX_ALWAYS_ASSERT(N == m_data->m_nvars);
118
119 if (!(m_data->m_host_executor)) {
120 int stack_size;
121 m_data->m_exe_size = static_cast<int>
122 (iparser_exe_size(m_data->m_iparser, m_data->m_max_stack_size,
123 stack_size));
124
125 if (m_data->m_max_stack_size > AMREX_IPARSER_STACK_SIZE) {
126 amrex::Abort("amrex::IParser: AMREX_IPARSER_STACK_SIZE, "
127 + std::to_string(AMREX_IPARSER_STACK_SIZE) + ", is too small for "
128 + m_data->m_expression);
129 }
130 if (stack_size != 0) {
131 amrex::Abort("amrex::IParser: something went wrong with iparser stack! "
132 + std::to_string(stack_size));
133 }
134
135 m_data->m_host_executor = (char*)The_Pinned_Arena()->alloc(m_data->m_exe_size);
136 if (m_data->m_host_executor == nullptr) { // Arena is not ready yet
137 m_data->m_host_executor = (char*) std::malloc(m_data->m_exe_size);
138 m_data->m_use_arena = false;
139 }
140
141 try {
142 iparser_compile(m_data->m_iparser, m_data->m_host_executor);
143 } catch (const std::runtime_error& e) {
144 throw std::runtime_error(std::string(e.what()) + " in IParser expression \""
145 + m_data->m_expression + "\"");
146 }
147 }
148
149#ifdef AMREX_USE_GPU
150 return IParserExecutor<N>{m_data->m_host_executor, m_data->m_device_executor};
151#else
152 return IParserExecutor<N>{m_data->m_host_executor};
153#endif
154 } else {
155 return IParserExecutor<N>{};
156 }
157}
158
159template <int N>
162{
163 auto exe = compileHost<N>();
164
165#ifdef AMREX_USE_GPU
166 if (m_data && m_data->m_iparser && !(m_data->m_device_executor)
167 && m_data->m_use_arena)
168 {
169 m_data->m_device_executor = (char*)The_Arena()->alloc(m_data->m_exe_size);
170 Gpu::htod_memcpy_async(m_data->m_device_executor, m_data->m_host_executor,
171 m_data->m_exe_size);
173 exe.m_device_executor = m_data->m_device_executor;
174 }
175#endif
176
177 return exe;
178}
179
180}
181
182#endif
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
virtual void * alloc(std::size_t sz)=0
Definition AMReX_IParser.H:59
void print() const
Definition AMReX_IParser.cpp:86
std::set< std::string > symbols() const
Definition AMReX_IParser.cpp:124
void setConstant(std::string const &name, long long c)
Definition AMReX_IParser.cpp:67
IParserExecutor< N > compileHost() const
This compiles for CPU only.
Definition AMReX_IParser.H:114
std::string expr() const
Definition AMReX_IParser.cpp:114
IParserExecutor< N > compile() const
This compiles for both GPU and CPU.
Definition AMReX_IParser.H:161
void registerVariables(Vector< std::string > const &vars)
Definition AMReX_IParser.cpp:75
int depth() const
Definition AMReX_IParser.cpp:94
void define(std::string const &func_body)
Definition AMReX_IParser.cpp:18
IParser()=default
int maxStackSize() const
Definition AMReX_IParser.cpp:104
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:823
Arena * The_Arena()
Definition AMReX_Arena.cpp:783
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:263
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:301
Definition AMReX_Amr.cpp:49
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:41
Definition AMReX_IParser.H:18
char * m_device_executor
Definition AMReX_IParser.H:53
__host__ __device__ long long operator()() const noexcept
Definition AMReX_IParser.H:21
char * m_host_executor
Definition AMReX_IParser.H:51