aboutsummaryrefslogtreecommitdiff
path: root/Source/Parser/wp_parser_c.h
blob: 182df712102896e49eefcc466528e058d34be865 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#ifndef WP_PARSER_C_H_
#define WP_PARSER_C_H_

#include "wp_parser_y.h"
#include <AMReX_GpuQualifiers.H>
#include <AMReX_Extension.H>
#include <AMReX_REAL.H>
#include <cassert>

#ifdef __cplusplus
extern "C" {
#endif

    struct wp_parser* wp_c_parser_new (char const* function_body);

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

#include <set>
#include <string>

AMREX_GPU_HOST_DEVICE
inline amrex_real
wp_ast_eval (struct wp_node* node, amrex_real const* x)
{
#if defined(__SYCL_DEVICE_ONLY__)
    assert(0); // Recursive funciton is not support in DPC++
    return 0.;
#else
    amrex_real result;

    switch (node->type)
    {
    case WP_NUMBER:
    {
        result = ((struct wp_number*)node)->value;
        break;
    }
    case WP_SYMBOL:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i =((struct wp_symbol*)node)->ip.i;
        result = x[i];
#else
        result = *(((struct wp_symbol*)node)->ip.p);
#endif
        break;
    }
    case WP_ADD:
    {
        result = wp_ast_eval(node->l,x) + wp_ast_eval(node->r,x);
        break;
    }
    case WP_SUB:
    {
        result = wp_ast_eval(node->l,x) - wp_ast_eval(node->r,x);
        break;
    }
    case WP_MUL:
    {
        result = wp_ast_eval(node->l,x) * wp_ast_eval(node->r,x);
        break;
    }
    case WP_DIV:
    {
        result = wp_ast_eval(node->l,x) / wp_ast_eval(node->r,x);
        break;
    }
    case WP_NEG:
    {
        result = -wp_ast_eval(node->l,x);
        break;
    }
    case WP_F1:
    {
        result = wp_call_f1(((struct wp_f1*)node)->ftype,
                wp_ast_eval(((struct wp_f1*)node)->l,x));
        break;
    }
    case WP_F2:
    {
        result = wp_call_f2(((struct wp_f2*)node)->ftype,
                wp_ast_eval(((struct wp_f2*)node)->l,x),
                wp_ast_eval(((struct wp_f2*)node)->r,x));
        break;
    }
    case WP_ADD_VP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->rip.i;
        result = node->lvp.v + x[i];
#else
        result = node->lvp.v + *(node->rip.p);
#endif
        break;
    }
    case WP_ADD_PP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->lvp.ip.i;
        int j = node->rip.i;
        result = x[i] + x[j];
#else
        result = *(node->lvp.ip.p) + *(node->rip.p);
#endif
        break;
    }
    case WP_SUB_VP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->rip.i;
        result = node->lvp.v - x[i];
#else
        result = node->lvp.v - *(node->rip.p);
#endif
        break;
    }
    case WP_SUB_PP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->lvp.ip.i;
        int j = node->rip.i;
        result = x[i] - x[j];
#else
        result = *(node->lvp.ip.p) - *(node->rip.p);
#endif
        break;
    }
    case WP_MUL_VP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->rip.i;
        result = node->lvp.v * x[i];
#else
        result = node->lvp.v * *(node->rip.p);
#endif
        break;
    }
    case WP_MUL_PP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->lvp.ip.i;
        int j = node->rip.i;
        result = x[i] * x[j];
#else
        result = *(node->lvp.ip.p) * *(node->rip.p);
#endif
        break;
    }
    case WP_DIV_VP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->rip.i;
        result = node->lvp.v / x[i];
#else
        result = node->lvp.v / *(node->rip.p);
#endif
        break;
    }
    case WP_DIV_PP:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->lvp.ip.i;
        int j = node->rip.i;
        result = x[i] / x[j];
#else
        result = *(node->lvp.ip.p) / *(node->rip.p);
#endif
        break;
    }
    case WP_NEG_P:
    {
#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
        int i = node->rip.i;
        result = -x[i];
#else
        result = -*(node->lvp.ip.p);
#endif
        break;
    }
    default:
        yyerror("wp_ast_eval: unknown node type %d\n", node->type);
    }

    return result;
#endif
}

inline
void
wp_ast_get_symbols (struct wp_node* node, std::set<std::string>& symbols)
{
    switch (node->type)
    {
    case WP_NUMBER:
        break;
    case WP_SYMBOL:
        symbols.emplace(((struct wp_symbol*)node)->name);
        break;
    case WP_ADD:
    case WP_SUB:
    case WP_MUL:
    case WP_DIV:
    case WP_ADD_PP:
    case WP_SUB_PP:
    case WP_MUL_PP:
    case WP_DIV_PP:
        wp_ast_get_symbols(node->l, symbols);
        wp_ast_get_symbols(node->r, symbols);
        break;
    case WP_NEG:
    case WP_NEG_P:
        wp_ast_get_symbols(node->l, symbols);
        break;
    case WP_F1:
        wp_ast_get_symbols(((struct wp_f1*)node)->l, symbols);
        break;
    case WP_F2:
        wp_ast_get_symbols(((struct wp_f2*)node)->l, symbols);
        wp_ast_get_symbols(((struct wp_f2*)node)->r, symbols);
        break;
    case WP_ADD_VP:
    case WP_SUB_VP:
    case WP_MUL_VP:
    case WP_DIV_VP:
        wp_ast_get_symbols(node->r, symbols);
        break;
    default:
        yyerror("wp_ast_get_symbols: unknown node type %d\n", node->type);
    }
}

#endif

#endif