Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_Parser.H
Go to the documentation of this file.
1#ifndef AMREX_PARSER_H_
2#define AMREX_PARSER_H_
3
4#include <AMReX_Arena.H>
5#include <AMReX_Array.H>
6#include <AMReX_GpuDevice.H>
7#include <AMReX_Parser_Exe.H>
8#include <AMReX_REAL.H>
9#include <AMReX_Vector.H>
10
11#include <memory>
12#include <string>
13#include <set>
14
15namespace amrex {
16
17template <int N>
19{
20 template <int M=N, std::enable_if_t<M==0,int> = 0>
22 double operator() () const noexcept
23 {
26 }
27
28 template <typename... Ts>
30 std::enable_if_t<sizeof...(Ts) == N && !amrex::Same<float,Ts...>::value, double>
31 operator() (Ts... var) const noexcept
32 {
33 amrex::GpuArray<double,N> l_var{var...};
35 AMREX_IF_ON_HOST((return parser_exe_eval(m_host_executor, l_var.data());))
36 }
37
38 template <typename... Ts>
40 std::enable_if_t<sizeof...(Ts) == N && amrex::Same<float,Ts...>::value, float>
41 operator() (Ts... var) const noexcept
42 {
43 amrex::GpuArray<double,N> l_var{var...};
44 AMREX_IF_ON_DEVICE((return static_cast<float>(parser_exe_eval(m_device_executor, l_var.data()));))
45 AMREX_IF_ON_HOST((return static_cast<float>(parser_exe_eval(m_host_executor, l_var.data()));))
46 }
47
49 double operator() (GpuArray<double,N> const& var) const noexcept
50 {
53 }
54
56 explicit operator bool () const {
57 AMREX_IF_ON_DEVICE((return m_device_executor != nullptr;))
58 AMREX_IF_ON_HOST((return m_host_executor != nullptr;))
59 }
60
61 char* m_host_executor = nullptr;
62#ifdef AMREX_USE_GPU
63 char* m_device_executor = nullptr;
64#endif
65};
66
67class Parser
68{
69public:
70 Parser (std::string const& func_body);
71 Parser () = default;
72 void define (std::string const& func_body);
73
74 explicit operator bool () const;
75
76 void setConstant (std::string const& name, double c);
77
78 void registerVariables (Vector<std::string> const& vars);
79
80 void print () const;
81 void printExe () const;
82
83 [[nodiscard]] int depth () const;
84 [[nodiscard]] int maxStackSize () const;
85
86 [[nodiscard]] std::string expr () const;
87
88 [[nodiscard]] std::set<std::string> symbols () const;
89
91 template <int N> [[nodiscard]] ParserExecutor<N> compile () const;
92
94 template <int N> [[nodiscard]] ParserExecutor<N> compileHost () const;
95
96private:
97
98 struct Data {
99 std::string m_expression;
100 struct amrex_parser* m_parser = nullptr;
101 int m_nvars = 0;
102 bool m_use_arena = true;
103 char* m_host_executor = nullptr;
104#ifdef AMREX_USE_GPU
105 char* m_device_executor = nullptr;
106#endif
108 int m_exe_size = 0;
110 Data () = default;
111 ~Data ();
112 Data (Data const&) = delete;
113 Data (Data &&) = delete;
114 Data& operator= (Data const&) = delete;
115 Data& operator= (Data &&) = delete;
116 };
117
118 std::shared_ptr<Data> m_data;
120};
121
122template <int N>
125{
126 if (m_data && m_data->m_parser) {
127 AMREX_ASSERT(N == m_data->m_nvars);
128
129 if (!(m_data->m_host_executor)) {
130 int stack_size;
131 m_data->m_exe_size = static_cast<int>
132 (parser_exe_size(m_data->m_parser, m_data->m_max_stack_size,
133 stack_size));
134
135 if (m_data->m_max_stack_size > AMREX_PARSER_STACK_SIZE) {
136 amrex::Abort("amrex::Parser: AMREX_PARSER_STACK_SIZE, "
137 + std::to_string(AMREX_PARSER_STACK_SIZE) + ", is too small for "
138 + m_data->m_expression);
139 }
140 if (stack_size != 0) {
141 amrex::Abort("amrex::Parser: something went wrong with parser stack! "
142 + std::to_string(stack_size));
143 }
144
145 m_data->m_host_executor = (char*)The_Pinned_Arena()->alloc(m_data->m_exe_size);
146 if (m_data->m_host_executor == nullptr) { // Arena is not ready yet
147 m_data->m_host_executor = (char*) std::malloc(m_data->m_exe_size);
148 m_data->m_use_arena = false;
149 }
150
151 try {
152 m_data->m_locals = parser_compile(m_data->m_parser,
153 m_data->m_host_executor);
154 } catch (const std::runtime_error& e) {
155 throw std::runtime_error(std::string(e.what()) + " in Parser expression \""
156 + m_data->m_expression + "\"");
157 }
158 }
159
160#ifdef AMREX_USE_GPU
161 return ParserExecutor<N>{m_data->m_host_executor, m_data->m_device_executor};
162#else
164#endif
165 } else {
166 return ParserExecutor<N>{};
167 }
168}
169
170template <int N>
173{
174 auto exe = compileHost<N>();
175
176#ifdef AMREX_USE_GPU
177 if (m_data && m_data->m_parser && !(m_data->m_device_executor)
178 && m_data->m_use_arena)
179 {
180 m_data->m_device_executor = (char*)The_Arena()->alloc(m_data->m_exe_size);
181 Gpu::htod_memcpy_async(m_data->m_device_executor, m_data->m_host_executor,
182 m_data->m_exe_size);
184 exe.m_device_executor = m_data->m_device_executor;
185 }
186#endif
187
188 return exe;
189}
190
191}
192
193#endif
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#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
#define AMREX_PARSER_STACK_SIZE
Definition AMReX_Parser_Exe.H:12
virtual void * alloc(std::size_t sz)=0
Definition AMReX_Parser.H:68
std::set< std::string > symbols() const
Definition AMReX_Parser.cpp:121
void print() const
Definition AMReX_Parser.cpp:83
std::shared_ptr< Data > m_data
Definition AMReX_Parser.H:118
int maxStackSize() const
Definition AMReX_Parser.cpp:101
ParserExecutor< N > compileHost() const
This compiles for CPU only.
Definition AMReX_Parser.H:124
Vector< std::string > m_vars
Definition AMReX_Parser.H:119
std::string expr() const
Definition AMReX_Parser.cpp:111
void define(std::string const &func_body)
Definition AMReX_Parser.cpp:18
ParserExecutor< N > compile() const
This compiles for both GPU and CPU.
Definition AMReX_Parser.H:172
Parser()=default
void printExe() const
Definition AMReX_Parser.cpp:131
void setConstant(std::string const &name, double c)
Definition AMReX_Parser.cpp:63
void registerVariables(Vector< std::string > const &vars)
Definition AMReX_Parser.cpp:71
int depth() const
Definition AMReX_Parser.cpp:91
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:27
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:237
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:251
Definition AMReX_Amr.cpp:49
Vector< char const * > parser_compile(struct amrex_parser *parser, char *p)
Definition AMReX_Parser_Exe.H:521
Arena * The_Pinned_Arena()
Definition AMReX_Arena.cpp:656
std::size_t parser_exe_size(struct amrex_parser *parser, int &max_stack_size, int &stack_size)
Definition AMReX_Parser_Exe.H:507
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double parser_exe_eval(const char *p, double const *x)
Definition AMReX_Parser_Exe.H:222
Arena * The_Arena()
Definition AMReX_Arena.cpp:616
Definition AMReX_Array.H:34
Definition AMReX_Parser.H:19
char * m_host_executor
Definition AMReX_Parser.H:61
char * m_device_executor
Definition AMReX_Parser.H:63
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double operator()() const noexcept
Definition AMReX_Parser.H:22
Definition AMReX_Parser.H:98
~Data()
Definition AMReX_Parser.cpp:41
int m_max_stack_size
Definition AMReX_Parser.H:107
bool m_use_arena
Definition AMReX_Parser.H:102
Data(Data &&)=delete
int m_exe_size
Definition AMReX_Parser.H:108
Data & operator=(Data const &)=delete
int m_nvars
Definition AMReX_Parser.H:101
struct amrex_parser * m_parser
Definition AMReX_Parser.H:100
std::string m_expression
Definition AMReX_Parser.H:99
Data(Data const &)=delete
Vector< char const * > m_locals
Definition AMReX_Parser.H:109
char * m_host_executor
Definition AMReX_Parser.H:103
char * m_device_executor
Definition AMReX_Parser.H:105
Definition AMReX_TypeTraits.H:130
Definition AMReX_Parser_Y.H:257