LCOV - code coverage report
Current view: top level - ext/amrex/2d-coverage-g++-24.08/include - AMReX_Parser_Exe.H (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 81 223 36.3 %
Date: 2024-11-18 05:28:54 Functions: 5 6 83.3 %

          Line data    Source code
       1             : #ifndef AMREX_PARSER_EXE_H_
       2             : #define AMREX_PARSER_EXE_H_
       3             : #include <AMReX_Config.H>
       4             : 
       5             : #include <AMReX_Parser_Y.H>
       6             : #include <AMReX_Vector.H>
       7             : 
       8             : #include <limits>
       9             : 
      10             : #ifndef AMREX_PARSER_STACK_SIZE
      11             : #define AMREX_PARSER_STACK_SIZE 16
      12             : #endif
      13             : 
      14             : #define AMREX_PARSER_LOCAL_IDX0 1000
      15             : #define AMREX_PARSER_GET_DATA(i) ((i)<1000) ? x[i] : pstack[(i)-1000]
      16             : 
      17             : namespace amrex {
      18             : 
      19             : // N: node
      20             : // P: pointer offset
      21             : // V: value (i.e., double literal)
      22             : 
      23             : enum parser_exe_t {
      24             :     PARSER_EXE_NULL = 0,
      25             :     PARSER_EXE_NUMBER,
      26             :     PARSER_EXE_SYMBOL,
      27             :     PARSER_EXE_ADD,
      28             :     PARSER_EXE_SUB_F,
      29             :     PARSER_EXE_SUB_B,
      30             :     PARSER_EXE_MUL,
      31             :     PARSER_EXE_DIV_F,
      32             :     PARSER_EXE_DIV_B,
      33             :     PARSER_EXE_F1,
      34             :     PARSER_EXE_F2_F,
      35             :     PARSER_EXE_F2_B,
      36             :     PARSER_EXE_ADD_VP,
      37             :     PARSER_EXE_SUB_VP,
      38             :     PARSER_EXE_MUL_VP,
      39             :     PARSER_EXE_DIV_VP,
      40             :     PARSER_EXE_ADD_PP,
      41             :     PARSER_EXE_SUB_PP,
      42             :     PARSER_EXE_MUL_PP,
      43             :     PARSER_EXE_DIV_PP,
      44             :     PARSER_EXE_ADD_VN,
      45             :     PARSER_EXE_SUB_VN,
      46             :     PARSER_EXE_MUL_VN,
      47             :     PARSER_EXE_DIV_VN,
      48             :     PARSER_EXE_ADD_PN,
      49             :     PARSER_EXE_SUB_PN,
      50             :     PARSER_EXE_MUL_PN,
      51             :     PARSER_EXE_DIV_PN,
      52             :     PARSER_EXE_SQUARE,
      53             :     PARSER_EXE_POWI,
      54             :     PARSER_EXE_IF,
      55             :     PARSER_EXE_JUMP
      56             : };
      57             : 
      58             : struct alignas(8) ParserExeNull {
      59             :     enum parser_exe_t type = PARSER_EXE_NULL;
      60             : };
      61             : 
      62             : struct alignas(8) ParserExeNumber {
      63             :     enum parser_exe_t type = PARSER_EXE_NUMBER;
      64             :     double v;
      65             : };
      66             : 
      67             : struct alignas(8) ParserExeSymbol {
      68             :     enum parser_exe_t type = PARSER_EXE_SYMBOL;
      69             :     int i;
      70             : };
      71             : 
      72             : struct alignas(8) ParserExeADD {
      73             :     enum parser_exe_t type = PARSER_EXE_ADD;
      74             : };
      75             : 
      76             : struct alignas(8) ParserExeSUB_F {
      77             :     enum parser_exe_t type = PARSER_EXE_SUB_F;
      78             : };
      79             : 
      80             : struct alignas(8) ParserExeSUB_B {
      81             :     enum parser_exe_t type = PARSER_EXE_SUB_B;
      82             : };
      83             : 
      84             : struct alignas(8) ParserExeMUL {
      85             :     enum parser_exe_t type = PARSER_EXE_MUL;
      86             : };
      87             : 
      88             : struct alignas(8) ParserExeDIV_F {
      89             :     enum parser_exe_t type = PARSER_EXE_DIV_F;
      90             : };
      91             : 
      92             : struct alignas(8) ParserExeDIV_B {
      93             :     enum parser_exe_t type = PARSER_EXE_DIV_B;
      94             : };
      95             : 
      96             : struct alignas(8) ParserExeF1 {
      97             :     enum parser_exe_t type = PARSER_EXE_F1;
      98             :     parser_f1_t ftype;
      99             : };
     100             : 
     101             : struct alignas(8) ParserExeF2_F {
     102             :     enum parser_exe_t type = PARSER_EXE_F2_F;
     103             :     parser_f2_t ftype;
     104             : };
     105             : 
     106             : struct alignas(8) ParserExeF2_B {
     107             :     enum parser_exe_t type = PARSER_EXE_F2_B;
     108             :     parser_f2_t ftype;
     109             : };
     110             : 
     111             : struct alignas(8) ParserExeADD_VP {
     112             :     enum parser_exe_t type = PARSER_EXE_ADD_VP;
     113             :     int i;
     114             :     double v;
     115             : };
     116             : 
     117             : struct alignas(8) ParserExeSUB_VP {
     118             :     enum parser_exe_t type = PARSER_EXE_SUB_VP;
     119             :     int i;
     120             :     double v;
     121             : };
     122             : 
     123             : struct alignas(8) ParserExeMUL_VP {
     124             :     enum parser_exe_t type = PARSER_EXE_MUL_VP;
     125             :     int i;
     126             :     double v;
     127             : };
     128             : 
     129             : struct alignas(8) ParserExeDIV_VP {
     130             :     enum parser_exe_t type = PARSER_EXE_DIV_VP;
     131             :     int i;
     132             :     double v;
     133             : };
     134             : 
     135             : struct alignas(8) ParserExeADD_PP {
     136             :     enum parser_exe_t type = PARSER_EXE_ADD_PP;
     137             :     int i1;
     138             :     int i2;
     139             : };
     140             : 
     141             : struct alignas(8) ParserExeSUB_PP {
     142             :     enum parser_exe_t type = PARSER_EXE_SUB_PP;
     143             :     int i1;
     144             :     int i2;
     145             : };
     146             : 
     147             : struct alignas(8) ParserExeMUL_PP {
     148             :     enum parser_exe_t type = PARSER_EXE_MUL_PP;
     149             :     int i1;
     150             :     int i2;
     151             : };
     152             : 
     153             : struct alignas(8) ParserExeDIV_PP {
     154             :     enum parser_exe_t type = PARSER_EXE_DIV_PP;
     155             :     int i1;
     156             :     int i2;
     157             : };
     158             : 
     159             : struct alignas(8) ParserExeADD_VN {
     160             :     enum parser_exe_t type = PARSER_EXE_ADD_VN;
     161             :     double v;
     162             : };
     163             : 
     164             : struct alignas(8) ParserExeSUB_VN {
     165             :     enum parser_exe_t type = PARSER_EXE_SUB_VN;
     166             :     double v;
     167             : };
     168             : 
     169             : struct alignas(8) ParserExeMUL_VN {
     170             :     enum parser_exe_t type = PARSER_EXE_MUL_VN;
     171             :     double v;
     172             : };
     173             : 
     174             : struct alignas(8) ParserExeDIV_VN {
     175             :     enum parser_exe_t type = PARSER_EXE_DIV_VN;
     176             :     double v;
     177             : };
     178             : 
     179             : struct alignas(8) ParserExeADD_PN {
     180             :     enum parser_exe_t type = PARSER_EXE_ADD_PN;
     181             :     int i;
     182             : };
     183             : 
     184             : struct alignas(8) ParserExeSUB_PN {
     185             :     enum parser_exe_t type = PARSER_EXE_SUB_PN;
     186             :     int i;
     187             :     double sign;
     188             : };
     189             : 
     190             : struct alignas(8) ParserExeMUL_PN {
     191             :     enum parser_exe_t type = PARSER_EXE_MUL_PN;
     192             :     int i;
     193             : };
     194             : 
     195             : struct alignas(8) ParserExeDIV_PN {
     196             :     enum parser_exe_t type = PARSER_EXE_DIV_PN;
     197             :     int i;
     198             :     bool reverse;
     199             : };
     200             : 
     201             : struct alignas(8) ParserExeSquare {
     202             :     enum parser_exe_t type = PARSER_EXE_SQUARE;
     203             : };
     204             : 
     205             : struct alignas(8) ParserExePOWI {
     206             :     enum parser_exe_t type = PARSER_EXE_POWI;
     207             :     int i;
     208             : };
     209             : 
     210             : struct alignas(8) ParserExeIF {
     211             :     enum parser_exe_t type = PARSER_EXE_IF;
     212             :     int offset;
     213             : };
     214             : 
     215             : struct alignas(8) ParserExeJUMP {
     216             :     enum parser_exe_t type = PARSER_EXE_JUMP;
     217             :     int offset;
     218             : };
     219             : 
     220             : template <int N>
     221             : struct ParserStack
     222             : {
     223             :     double m_data[N];
     224             :     int m_size = 0;
     225      102654 :     constexpr void push (double v) { m_data[m_size++] = v; }
     226       73278 :     constexpr void pop () { --m_size; }
     227             :     [[nodiscard]] constexpr double const& top () const { return m_data[m_size-1]; }
     228      331818 :     [[nodiscard]] constexpr double      & top ()       { return m_data[m_size-1]; }
     229           0 :     [[nodiscard]] constexpr double operator[] (int i) const { return m_data[i]; }
     230             : };
     231             : 
     232             : AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
     233             : double parser_exe_eval (const char* p, double const* x)
     234             : {
     235       29376 :     if (p == nullptr) { return std::numeric_limits<double>::max(); }
     236             : 
     237       29376 :     ParserStack<AMREX_PARSER_STACK_SIZE> pstack;
     238      332044 :     while (*((parser_exe_t*)p) != PARSER_EXE_NULL) { // NOLINT
     239      302668 :         switch (*((parser_exe_t*)p))
     240             :         {
     241       22290 :         case PARSER_EXE_NUMBER:
     242             :         {
     243       22290 :             pstack.push(((ParserExeNumber*)p)->v);
     244       22290 :             p   += sizeof(ParserExeNumber);
     245       22290 :             break;
     246             :         }
     247       80304 :         case PARSER_EXE_SYMBOL:
     248             :         {
     249       80304 :             int i = ((ParserExeSymbol*)p)->i;
     250       80304 :             double d = AMREX_PARSER_GET_DATA(i);
     251       80304 :             pstack.push(d);
     252       80304 :             p     += sizeof(ParserExeSymbol);
     253       80304 :             break;
     254             :         }
     255       51214 :         case PARSER_EXE_ADD:
     256             :         {
     257       51214 :             double b = pstack.top(); // NOLINT
     258       51214 :             pstack.pop();
     259       51214 :             pstack.top() += b; // NOLINT
     260       51214 :             p += sizeof(ParserExeADD);
     261       51214 :             break;
     262             :         }
     263           0 :         case PARSER_EXE_SUB_F:
     264             :         {
     265           0 :             double b = pstack.top(); // NOLINT
     266           0 :             pstack.pop();
     267           0 :             pstack.top() -= b; // NOLINT
     268           0 :             p += sizeof(ParserExeSUB_F);
     269           0 :             break;
     270             :         }
     271           0 :         case PARSER_EXE_SUB_B:
     272             :         {
     273           0 :             double b = pstack.top(); // NOLINT
     274           0 :             pstack.pop();
     275           0 :             pstack.top() = b - pstack.top(); // NOLINT
     276           0 :             p += sizeof(ParserExeSUB_B);
     277           0 :             break;
     278             :         }
     279           0 :         case PARSER_EXE_MUL:
     280             :         {
     281           0 :             double b = pstack.top(); // NOLINT
     282           0 :             pstack.pop();
     283           0 :             pstack.top() *= b; // NOLINT
     284           0 :             p += sizeof(ParserExeMUL);
     285           0 :             break;
     286             :         }
     287           0 :         case PARSER_EXE_DIV_F:
     288             :         {
     289           0 :             double v = pstack.top(); // NOLINT
     290           0 :             pstack.pop();
     291           0 :             pstack.top() /= v; // NOLINT
     292           0 :             p += sizeof(ParserExeDIV_F);
     293           0 :             break;
     294             :         }
     295           0 :         case PARSER_EXE_DIV_B:
     296             :         {
     297           0 :             double v = pstack.top(); // NOLINT
     298           0 :             pstack.pop();
     299           0 :             pstack.top() = v / pstack.top(); // NOLINT
     300           0 :             p += sizeof(ParserExeDIV_B);
     301           0 :             break;
     302             :         }
     303        7086 :         case PARSER_EXE_F1:
     304             :         {
     305       14172 :             pstack.top() = parser_call_f1(((ParserExeF1*)p)->ftype, pstack.top()); // NOLINT
     306        7086 :             p += sizeof(ParserExeF1);
     307        7086 :             break;
     308             :         }
     309       22064 :         case PARSER_EXE_F2_F:
     310             :         {
     311       22064 :             double v = pstack.top(); // NOLINT
     312       22064 :             pstack.pop();
     313       44128 :             pstack.top() = parser_call_f2(((ParserExeF2_F*)p)->ftype, pstack.top(), v); // NOLINT
     314       22064 :             p += sizeof(ParserExeF2_F);
     315       22064 :             break;
     316             :         }
     317           0 :         case PARSER_EXE_F2_B:
     318             :         {
     319           0 :             double v = pstack.top(); // NOLINT
     320           0 :             pstack.pop();
     321           0 :             pstack.top() = parser_call_f2(((ParserExeF2_B*)p)->ftype, v, pstack.top()); // NOLINT
     322           0 :             p += sizeof(ParserExeF2_B);
     323           0 :             break;
     324             :         }
     325           0 :         case PARSER_EXE_ADD_VP:
     326             :         {
     327           0 :             int i = ((ParserExeADD_VP*)p)->i;
     328           0 :             double d = AMREX_PARSER_GET_DATA(i);
     329           0 :             pstack.push(((ParserExeADD_VP*)p)->v + d);
     330           0 :             p     += sizeof(ParserExeADD_VP);
     331           0 :             break;
     332             :         }
     333           0 :         case PARSER_EXE_SUB_VP:
     334             :         {
     335           0 :             int i = ((ParserExeSUB_VP*)p)->i;
     336           0 :             double d = AMREX_PARSER_GET_DATA(i);
     337           0 :             pstack.push(((ParserExeSUB_VP*)p)->v - d);
     338           0 :             p     += sizeof(ParserExeSUB_VP);
     339           0 :             break;
     340             :         }
     341           0 :         case PARSER_EXE_MUL_VP:
     342             :         {
     343           0 :             int i = ((ParserExeMUL_VP*)p)->i;
     344           0 :             double d = AMREX_PARSER_GET_DATA(i);
     345           0 :             pstack.push(((ParserExeMUL_VP*)p)->v * d);
     346           0 :             p     += sizeof(ParserExeMUL_VP);
     347           0 :             break;
     348             :         }
     349           0 :         case PARSER_EXE_DIV_VP:
     350             :         {
     351           0 :             int i = ((ParserExeDIV_VP*)p)->i;
     352           0 :             double d = AMREX_PARSER_GET_DATA(i);
     353           0 :             pstack.push(((ParserExeDIV_VP*)p)->v / d);
     354           0 :             p     += sizeof(ParserExeDIV_VP);
     355           0 :             break;
     356             :         }
     357           0 :         case PARSER_EXE_ADD_PP:
     358             :         {
     359           0 :             int i = ((ParserExeADD_PP*)p)->i1;
     360           0 :             double d1 = AMREX_PARSER_GET_DATA(i);
     361           0 :             i     = ((ParserExeADD_PP*)p)->i2;
     362           0 :             double d2 = AMREX_PARSER_GET_DATA(i);
     363           0 :             pstack.push(d1+d2);
     364           0 :             p     += sizeof(ParserExeADD_PP);
     365           0 :             break;
     366             :         }
     367          30 :         case PARSER_EXE_SUB_PP:
     368             :         {
     369          30 :             int i = ((ParserExeSUB_PP*)p)->i1;
     370          30 :             double d1 = AMREX_PARSER_GET_DATA(i);
     371          30 :             i     = ((ParserExeSUB_PP*)p)->i2;
     372          30 :             double d2 = AMREX_PARSER_GET_DATA(i);
     373          30 :             pstack.push(d1-d2);
     374          30 :             p     += sizeof(ParserExeSUB_PP);
     375          30 :             break;
     376             :         }
     377          30 :         case PARSER_EXE_MUL_PP:
     378             :         {
     379          30 :             int i = ((ParserExeMUL_PP*)p)->i1;
     380          30 :             double d1 = AMREX_PARSER_GET_DATA(i);
     381          30 :             i     = ((ParserExeMUL_PP*)p)->i2;
     382          30 :             double d2 = AMREX_PARSER_GET_DATA(i);
     383          30 :             pstack.push(d1*d2);
     384          30 :             p     += sizeof(ParserExeMUL_PP);
     385          30 :             break;
     386             :         }
     387           0 :         case PARSER_EXE_DIV_PP:
     388             :         {
     389           0 :             int i = ((ParserExeDIV_PP*)p)->i1;
     390           0 :             double d1 = AMREX_PARSER_GET_DATA(i);
     391           0 :             i     = ((ParserExeDIV_PP*)p)->i2;
     392           0 :             double d2 = AMREX_PARSER_GET_DATA(i);
     393           0 :             pstack.push(d1/d2);
     394           0 :             p      += sizeof(ParserExeDIV_PP);
     395           0 :             break;
     396             :         }
     397       14112 :         case PARSER_EXE_ADD_VN:
     398             :         {
     399       14112 :             pstack.top() += ((ParserExeADD_VN*)p)->v; // NOLINT
     400       14112 :             p       += sizeof(ParserExeADD_VN);
     401       14112 :             break;
     402             :         }
     403           0 :         case PARSER_EXE_SUB_VN:
     404             :         {
     405           0 :             pstack.top() = ((ParserExeSUB_VN*)p)->v - pstack.top(); // NOLINT
     406           0 :             p      += sizeof(ParserExeSUB_VN);
     407           0 :             break;
     408             :         }
     409       25204 :         case PARSER_EXE_MUL_VN:
     410             :         {
     411       25204 :             pstack.top() *= ((ParserExeMUL_VN*)p)->v; // NOLINT
     412       25204 :             p       += sizeof(ParserExeMUL_VN);
     413       25204 :             break;
     414             :         }
     415           0 :         case PARSER_EXE_DIV_VN:
     416             :         {
     417           0 :             pstack.top() = ((ParserExeDIV_VN*)p)->v / pstack.top(); // NOLINT
     418           0 :             p      += sizeof(ParserExeDIV_VN);
     419           0 :             break;
     420             :         }
     421           0 :         case PARSER_EXE_ADD_PN:
     422             :         {
     423           0 :             int i = ((ParserExeADD_PN*)p)->i;
     424           0 :             double d = AMREX_PARSER_GET_DATA(i);
     425           0 :             pstack.top() += d; // NOLINT
     426           0 :             p         += sizeof(ParserExeADD_PN);
     427           0 :             break;
     428             :         }
     429           0 :         case PARSER_EXE_SUB_PN:
     430             :         {
     431           0 :             int i = ((ParserExeSUB_PN*)p)->i;
     432           0 :             double d = AMREX_PARSER_GET_DATA(i);
     433           0 :             pstack.top() = (d - pstack.top()) * (((ParserExeSUB_PN*)p)->sign); // NOLINT
     434           0 :             p         += sizeof(ParserExeSUB_PN);
     435           0 :             break;
     436             :         }
     437           0 :         case PARSER_EXE_MUL_PN:
     438             :         {
     439           0 :             int i = ((ParserExeMUL_PN*)p)->i;
     440           0 :             double d = AMREX_PARSER_GET_DATA(i);
     441           0 :             pstack.top() *= d; // NOLINT
     442           0 :             p         += sizeof(ParserExeMUL_PN);
     443           0 :             break;
     444             :         }
     445           0 :         case PARSER_EXE_DIV_PN:
     446             :         {
     447           0 :             int i = ((ParserExeDIV_PN*)p)->i;
     448           0 :             double d = AMREX_PARSER_GET_DATA(i);
     449           0 :             if (((ParserExeDIV_PN*)p)->reverse) {
     450           0 :                 pstack.top() /= d; // NOLINT
     451             :             } else {
     452           0 :                 pstack.top() = d / pstack.top(); // NOLINT
     453             :             }
     454           0 :             p            += sizeof(ParserExeDIV_PN);
     455           0 :             break;
     456             :         }
     457       80334 :         case PARSER_EXE_SQUARE:
     458             :         {
     459       80334 :             double& d = pstack.top();
     460       80334 :             d *= d;
     461       80334 :             p += sizeof(ParserExeSquare);
     462       80334 :             break;
     463             :         }
     464           0 :         case PARSER_EXE_POWI:
     465             :         {
     466           0 :             double& d = pstack.top();
     467           0 :             int n = ((ParserExePOWI*)p)->i;
     468           0 :             if (n != 0) {
     469           0 :                 if (n < 0) {
     470           0 :                     d = 1.0/d;
     471           0 :                     n = -n;
     472             :                 }
     473           0 :                 double y = 1.0;
     474           0 :                 while (n > 1) {
     475           0 :                     if (n % 2 == 0) {
     476           0 :                         d *= d;
     477           0 :                         n = n/2;
     478             :                     } else {
     479           0 :                         y *= d;
     480           0 :                         d *= d;
     481           0 :                         n = (n-1)/2;
     482             :                     }
     483             :                 }
     484           0 :                 d *= y;
     485             :             } else {
     486           0 :                 d = 1.0;
     487             :             }
     488           0 :             p += sizeof(ParserExePOWI);
     489           0 :             break;
     490             :         }
     491           0 :         case PARSER_EXE_IF:
     492             :         {
     493           0 :             double cond = pstack.top(); // NOLINT
     494           0 :             pstack.pop();
     495           0 :             if (cond == 0.0) { // false branch
     496           0 :                 p += ((ParserExeIF*)p)->offset;
     497             :             }
     498           0 :             p += sizeof(ParserExeIF);
     499           0 :             break;
     500             :         }
     501           0 :         case PARSER_EXE_JUMP:
     502             :         {
     503           0 :             int offset = ((ParserExeJUMP*)p)->offset;
     504           0 :             p += sizeof(ParserExeJUMP) + offset;
     505           0 :             break;
     506             :         }
     507           0 :         default:
     508             :             AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false,"parser_exe_eval: unknown node type");
     509             :         }
     510             :     }
     511       29376 :     return pstack.top(); // NOLINT
     512             : }
     513             : 
     514             : void parser_compile_exe_size (struct parser_node* node, char*& p, std::size_t& exe_size,
     515             :                               int& max_stack_size, int& stack_size, Vector<char const*>& local_variables);
     516             : 
     517             : inline std::size_t
     518          19 : parser_exe_size (struct amrex_parser* parser, int& max_stack_size, int& stack_size)
     519             : {
     520          19 :     parser_ast_sort(parser->ast);
     521          19 :     char* p = nullptr;
     522          19 :     std::size_t exe_size = 0;
     523          19 :     max_stack_size = 0;
     524          19 :     stack_size = 0;
     525          19 :     Vector<char const*> local_variables;
     526          19 :     parser_compile_exe_size(parser->ast, p, exe_size, max_stack_size, stack_size, local_variables);
     527          19 :     stack_size -= static_cast<int>(local_variables.size())+1;
     528          38 :     return exe_size+sizeof(ParserExeNull);
     529             : }
     530             : 
     531             : inline Vector<char const*>
     532          19 : parser_compile (struct amrex_parser* parser, char* p)
     533             : {
     534          19 :     std::size_t exe_size = 0;
     535          19 :     int max_stack_size = 0;
     536          19 :     int stack_size = 0;
     537          19 :     Vector<char const*> local_variables;
     538          19 :     parser_compile_exe_size(parser->ast, p, exe_size, max_stack_size, stack_size, local_variables);
     539          19 :     new(p) ParserExeNull;
     540          38 :     return local_variables;
     541             : }
     542             : 
     543             : void parser_exe_print(char const* parser, Vector<std::string> const& vars,
     544             :                       Vector<char const*> const& locals);
     545             : 
     546             : }
     547             : 
     548             : #endif

Generated by: LCOV version 1.14