WarpX
wp_parser_c.h
Go to the documentation of this file.
1 #ifndef WP_PARSER_C_H_
2 #define WP_PARSER_C_H_
3 
4 #include "wp_parser_y.h"
5 
6 #include <AMReX_GpuQualifiers.H>
7 #include <AMReX_GpuPrint.H>
8 #include <AMReX_Extension.H>
9 #include <AMReX_REAL.H>
10 #include <AMReX_Print.H>
11 #include <AMReX.H>
12 
13 #include <cassert>
14 #include <set>
15 #include <string>
16 #include <type_traits>
17 
18 struct wp_parser* wp_c_parser_new (char const* function_body);
19 
20 #ifdef AMREX_USE_GPU
21 
22 template <int Depth, std::enable_if_t<(Depth<WARPX_PARSER_DEPTH), int> = 0>
23 AMREX_GPU_DEVICE AMREX_NO_INLINE
24 void wp_ast_update_device_ptr (struct wp_node* node, char* droot, char* hroot)
25 {
26  switch (node->type)
27  {
28  case WP_NUMBER:
29  break;
30  case WP_SYMBOL:
31  {
32  auto p = (struct wp_symbol*)node;
33  p->name = droot + (p->name - hroot);
34  break;
35  }
36  case WP_ADD:
37  case WP_SUB:
38  case WP_MUL:
39  case WP_DIV:
40  {
41  node->l = (wp_node*)(droot + ((char*)node->l - hroot));
42  node->r = (wp_node*)(droot + ((char*)node->r - hroot));
43  wp_ast_update_device_ptr<Depth+1>(node->l, droot, hroot);
44  wp_ast_update_device_ptr<Depth+1>(node->r, droot, hroot);
45  break;
46  }
47  case WP_NEG:
48  {
49  node->l = (wp_node*)(droot + ((char*)node->l - hroot));
50  wp_ast_update_device_ptr<Depth+1>(node->l, droot, hroot);
51  break;
52  }
53  case WP_F1:
54  {
55  auto p = (struct wp_f1*)node;
56  p->l = (wp_node*)(droot + ((char*)p->l - hroot));
57  wp_ast_update_device_ptr<Depth+1>(p->l, droot, hroot);
58  break;
59  }
60  case WP_F2:
61  {
62  auto p = (struct wp_f2*)node;
63  p->l = (wp_node*)(droot + ((char*)p->l - hroot));
64  p->r = (wp_node*)(droot + ((char*)p->r - hroot));
65  wp_ast_update_device_ptr<Depth+1>(p->l, droot, hroot);
66  wp_ast_update_device_ptr<Depth+1>(p->r, droot, hroot);
67  break;
68  }
69  case WP_ADD_VP:
70  case WP_ADD_PP:
71  case WP_SUB_VP:
72  case WP_SUB_PP:
73  case WP_MUL_VP:
74  case WP_MUL_PP:
75  case WP_DIV_VP:
76  case WP_DIV_PP:
77  case WP_NEG_P:
78  {
79  // No need to update node->l and node->r that contain a string for
80  // variable name because we don't need them for device code.
81  break;
82  }
83  default:
84  {
85 #if AMREX_DEVICE_COMPILE
86  AMREX_DEVICE_PRINTF("wp_ast_update_device_ptr: unknown node type %d\n",
87  static_cast<int>(node->type));
88  amrex::Abort();
89 #endif
90  }
91  }
92 }
93 
94 template <int Depth, std::enable_if_t<Depth == WARPX_PARSER_DEPTH,int> = 0>
95 AMREX_GPU_DEVICE AMREX_NO_INLINE
96 void wp_ast_update_device_ptr (struct wp_node*, char*, char*)
97 {
98 #if AMREX_DEVICE_COMPILE
99  AMREX_DEVICE_PRINTF("wp_ast_update_device_ptr: WARPX_PARSER_DEPTH %d not big enough\n",
100  WARPX_PARSER_DEPTH);
101  amrex::Abort();
102 #endif
103 }
104 
105 #endif
106 
107 template <int Depth, std::enable_if_t<(Depth<WARPX_PARSER_DEPTH), int> = 0>
108 AMREX_GPU_HOST_DEVICE
109 #ifdef AMREX_USE_GPU
110 AMREX_NO_INLINE
111 #endif
112 amrex::Real
113 wp_ast_eval (struct wp_node* node, amrex::Real const* x)
114 {
115  amrex::Real result = 0.0;
116 
117  switch (node->type)
118  {
119  case WP_NUMBER:
120  {
121  result = ((struct wp_number*)node)->value;
122  break;
123  }
124  case WP_SYMBOL:
125  {
126 #if AMREX_DEVICE_COMPILE
127  int i =((struct wp_symbol*)node)->ip.i;
128  result = x[i];
129 #else
130  result = *(((struct wp_symbol*)node)->ip.p);
131 #endif
132  break;
133  }
134  case WP_ADD:
135  {
136  result = wp_ast_eval<Depth+1>(node->l,x) + wp_ast_eval<Depth+1>(node->r,x);
137  break;
138  }
139  case WP_SUB:
140  {
141  result = wp_ast_eval<Depth+1>(node->l,x) - wp_ast_eval<Depth+1>(node->r,x);
142  break;
143  }
144  case WP_MUL:
145  {
146  result = wp_ast_eval<Depth+1>(node->l,x) * wp_ast_eval<Depth+1>(node->r,x);
147  break;
148  }
149  case WP_DIV:
150  {
151  result = wp_ast_eval<Depth+1>(node->l,x) / wp_ast_eval<Depth+1>(node->r,x);
152  break;
153  }
154  case WP_NEG:
155  {
156  result = -wp_ast_eval<Depth+1>(node->l,x);
157  break;
158  }
159  case WP_F1:
160  {
161  result = wp_call_f1(((struct wp_f1*)node)->ftype,
162  wp_ast_eval<Depth+1>(((struct wp_f1*)node)->l,x));
163  break;
164  }
165  case WP_F2:
166  {
167  result = wp_call_f2(((struct wp_f2*)node)->ftype,
168  wp_ast_eval<Depth+1>(((struct wp_f2*)node)->l,x),
169  wp_ast_eval<Depth+1>(((struct wp_f2*)node)->r,x));
170  break;
171  }
172  case WP_ADD_VP:
173  {
174 #if AMREX_DEVICE_COMPILE
175  int i = node->rip.i;
176  result = node->lvp.v + x[i];
177 #else
178  result = node->lvp.v + *(node->rip.p);
179 #endif
180  break;
181  }
182  case WP_ADD_PP:
183  {
184 #if AMREX_DEVICE_COMPILE
185  int i = node->lvp.ip.i;
186  int j = node->rip.i;
187  result = x[i] + x[j];
188 #else
189  result = *(node->lvp.ip.p) + *(node->rip.p);
190 #endif
191  break;
192  }
193  case WP_SUB_VP:
194  {
195 #if AMREX_DEVICE_COMPILE
196  int i = node->rip.i;
197  result = node->lvp.v - x[i];
198 #else
199  result = node->lvp.v - *(node->rip.p);
200 #endif
201  break;
202  }
203  case WP_SUB_PP:
204  {
205 #if AMREX_DEVICE_COMPILE
206  int i = node->lvp.ip.i;
207  int j = node->rip.i;
208  result = x[i] - x[j];
209 #else
210  result = *(node->lvp.ip.p) - *(node->rip.p);
211 #endif
212  break;
213  }
214  case WP_MUL_VP:
215  {
216 #if AMREX_DEVICE_COMPILE
217  int i = node->rip.i;
218  result = node->lvp.v * x[i];
219 #else
220  result = node->lvp.v * *(node->rip.p);
221 #endif
222  break;
223  }
224  case WP_MUL_PP:
225  {
226 #if AMREX_DEVICE_COMPILE
227  int i = node->lvp.ip.i;
228  int j = node->rip.i;
229  result = x[i] * x[j];
230 #else
231  result = *(node->lvp.ip.p) * *(node->rip.p);
232 #endif
233  break;
234  }
235  case WP_DIV_VP:
236  {
237 #if AMREX_DEVICE_COMPILE
238  int i = node->rip.i;
239  result = node->lvp.v / x[i];
240 #else
241  result = node->lvp.v / *(node->rip.p);
242 #endif
243  break;
244  }
245  case WP_DIV_PP:
246  {
247 #if AMREX_DEVICE_COMPILE
248  int i = node->lvp.ip.i;
249  int j = node->rip.i;
250  result = x[i] / x[j];
251 #else
252  result = *(node->lvp.ip.p) / *(node->rip.p);
253 #endif
254  break;
255  }
256  case WP_NEG_P:
257  {
258 #if AMREX_DEVICE_COMPILE
259  int i = node->rip.i;
260  result = -x[i];
261 #else
262  result = -*(node->lvp.ip.p);
263 #endif
264  break;
265  }
266  default:
267  {
268 #if AMREX_DEVICE_COMPILE
269  AMREX_DEVICE_PRINTF("wp_ast_eval: unknown node type %d\n", node->type);
270 #else
271  amrex::AllPrint() << "wp_ast_eval: unknown node type " << node->type << "\n";
272 #endif
273  }
274  }
275 
276  return result;
277 }
278 
279 template <int Depth, std::enable_if_t<Depth == WARPX_PARSER_DEPTH,int> = 0>
280 AMREX_GPU_HOST_DEVICE
281 #ifdef AMREX_USE_GPU
282 AMREX_NO_INLINE
283 #endif
284 amrex::Real
285 wp_ast_eval (struct wp_node* node, amrex::Real const* x)
286 {
287 #if AMREX_DEVICE_COMPILE
288  AMREX_DEVICE_PRINTF("wp_ast_eval: WARPX_PARSER_DEPTH %d not big enough\n",
289  WARPX_PARSER_DEPTH);
290 #else
291  amrex::AllPrint() << "wp_ast_eval: WARPX_PARSER_DEPTH" << WARPX_PARSER_DEPTH
292  << "not big enough\n";
293 #endif
294  amrex::ignore_unused(node, x);
295  return 0.;
296 }
297 
298 inline
299 void
300 wp_ast_get_symbols (struct wp_node* node, std::set<std::string>& symbols)
301 {
302  switch (node->type)
303  {
304  case WP_NUMBER:
305  break;
306  case WP_SYMBOL:
307  symbols.emplace(((struct wp_symbol*)node)->name);
308  break;
309  case WP_ADD:
310  case WP_SUB:
311  case WP_MUL:
312  case WP_DIV:
313  case WP_ADD_PP:
314  case WP_SUB_PP:
315  case WP_MUL_PP:
316  case WP_DIV_PP:
317  wp_ast_get_symbols(node->l, symbols);
318  wp_ast_get_symbols(node->r, symbols);
319  break;
320  case WP_NEG:
321  case WP_NEG_P:
322  wp_ast_get_symbols(node->l, symbols);
323  break;
324  case WP_F1:
325  wp_ast_get_symbols(((struct wp_f1*)node)->l, symbols);
326  break;
327  case WP_F2:
328  wp_ast_get_symbols(((struct wp_f2*)node)->l, symbols);
329  wp_ast_get_symbols(((struct wp_f2*)node)->r, symbols);
330  break;
331  case WP_ADD_VP:
332  case WP_SUB_VP:
333  case WP_MUL_VP:
334  case WP_DIV_VP:
335  wp_ast_get_symbols(node->r, symbols);
336  break;
337  default:
338  amrex::AllPrint() << "wp_ast_get_symbols: unknown node type " << node->type << "\n";
339  }
340 }
341 
342 #endif
Definition: wp_parser_y.h:69
Definition: wp_parser_y.h:71
Definition: wp_parser_y.h:72
Definition: wp_parser_y.h:58
struct wp_parser * wp_c_parser_new(char const *function_body)
Definition: wp_parser_c.cpp:6
Definition: wp_parser_y.h:60
Definition: wp_parser_y.h:65
void wp_ast_get_symbols(struct wp_node *node, std::set< std::string > &symbols)
Definition: wp_parser_c.h:300
def x
Definition: read_lab_particles.py:25
Definition: wp_parser_y.h:67
Definition: wp_parser_y.h:68
Definition: wp_parser_y.h:55
Definition: wp_parser_y.h:70
Definition: wp_parser_y.h:145
Definition: wp_parser_y.h:104
Definition: wp_parser_y.h:56
AMREX_GPU_HOST_DEVICE T wp_call_f2(enum wp_f2_t type, T a, T b)
Definition: wp_parser_y.h:217
AMREX_GPU_HOST_DEVICE amrex::Real wp_ast_eval(struct wp_node *node, amrex::Real const *x)
Definition: wp_parser_c.h:113
enum wp_node_t type
Definition: wp_parser_y.h:117
i
Definition: check_interp_points_and_weights.py:171
Definition: wp_parser_y.h:61
Definition: wp_parser_y.h:66
Definition: wp_parser_y.h:91
Definition: wp_parser_y.h:59
type
Definition: run_alltests_1node.py:67
Definition: wp_parser_y.h:62
struct wp_node * r
Definition: wp_parser_y.h:119
name
Definition: run_automated.py:204
AMREX_GPU_HOST_DEVICE T wp_call_f1(enum wp_f1_t type, T a)
Definition: wp_parser_y.h:177
Definition: wp_parser_y.h:64
enum wp_node_t type
Definition: wp_parser_y.h:92
Definition: wp_parser_y.h:116
Definition: wp_parser_y.h:57
Definition: wp_parser_y.h:63
Definition: wp_parser_y.h:99
Definition: wp_parser_y.h:110