LCOV - code coverage report
Current view: top level - ext/amrex/2d-coverage-g++-24.08/include - AMReX_Parser_Y.H (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 10 83 12.0 %
Date: 2024-11-18 05:28:54 Functions: 2 21 9.5 %

          Line data    Source code
       1             : #ifndef AMREX_PARSER_Y_H_
       2             : #define AMREX_PARSER_Y_H_
       3             : #include <AMReX_Config.H>
       4             : 
       5             : #include <AMReX_GpuQualifiers.H>
       6             : #include <AMReX_GpuPrint.H>
       7             : #include <AMReX_Math.H>
       8             : #include <AMReX_Print.H>
       9             : #include <AMReX_REAL.H>
      10             : 
      11             : #include <cstddef>
      12             : #include <cstdio>
      13             : #include <cstdlib>
      14             : #include <cstring>
      15             : #include <set>
      16             : #include <string>
      17             : #include <string_view>
      18             : #include <type_traits>
      19             : 
      20             : void amrex_parsererror (char const *s, ...);
      21             : 
      22             : namespace amrex {
      23             : 
      24             : enum parser_f1_t {  // Built-in functions with one argument
      25             :     PARSER_SQRT,
      26             :     PARSER_EXP,
      27             :     PARSER_LOG,
      28             :     PARSER_LOG10,
      29             :     PARSER_SIN,
      30             :     PARSER_COS,
      31             :     PARSER_TAN,
      32             :     PARSER_ASIN,
      33             :     PARSER_ACOS,
      34             :     PARSER_ATAN,
      35             :     PARSER_SINH,
      36             :     PARSER_COSH,
      37             :     PARSER_TANH,
      38             :     PARSER_ASINH,
      39             :     PARSER_ACOSH,
      40             :     PARSER_ATANH,
      41             :     PARSER_ABS,
      42             :     PARSER_FLOOR,
      43             :     PARSER_CEIL,
      44             :     PARSER_COMP_ELLINT_1,
      45             :     PARSER_COMP_ELLINT_2,
      46             :     PARSER_ERF
      47             : };
      48             : 
      49             : static
      50             : #if defined(__INTEL_COMPILER) && defined(__EDG__)
      51             :     const
      52             : #else
      53             :     constexpr
      54             : #endif
      55             : std::string_view parser_f1_s[] =
      56             : {
      57             :     "sqrt",
      58             :     "exp",
      59             :     "log",
      60             :     "log10",
      61             :     "sin",
      62             :     "cos",
      63             :     "tan",
      64             :     "asin",
      65             :     "acos",
      66             :     "atan",
      67             :     "sinh",
      68             :     "cosh",
      69             :     "tanh",
      70             :     "asinh",
      71             :     "acosh",
      72             :     "atanh",
      73             :     "abs",
      74             :     "floor",
      75             :     "ceil",
      76             :     "comp_ellint_1",
      77             :     "comp_ellint_2",
      78             :     "erf"
      79             : };
      80             : 
      81             : enum parser_f2_t {  // Built-in functions with two arguments
      82             :     PARSER_POW,
      83             :     PARSER_ATAN2,
      84             :     PARSER_GT,
      85             :     PARSER_LT,
      86             :     PARSER_GEQ,
      87             :     PARSER_LEQ,
      88             :     PARSER_EQ,
      89             :     PARSER_NEQ,
      90             :     PARSER_AND,
      91             :     PARSER_OR,
      92             :     PARSER_HEAVISIDE,
      93             :     PARSER_JN,
      94             :     PARSER_MIN,
      95             :     PARSER_MAX,
      96             :     PARSER_FMOD
      97             : };
      98             : 
      99             : static
     100             : #if defined(__INTEL_COMPILER) && defined(__EDG__)
     101             :     const
     102             : #else
     103             :     constexpr
     104             : #endif
     105             : std::string_view parser_f2_s[] =
     106             : {
     107             :     "pow",
     108             :     "atan2",
     109             :     "gt",
     110             :     "lt",
     111             :     "geq",
     112             :     "leq",
     113             :     "eq",
     114             :     "neq",
     115             :     "and",
     116             :     "or",
     117             :     "heaviside",
     118             :     "jn",
     119             :     "min",
     120             :     "max",
     121             :     "fmod"
     122             : };
     123             : 
     124             : enum parser_f3_t { // functions with three arguments
     125             :     PARSER_IF
     126             : };
     127             : 
     128             : static
     129             : #if defined(__INTEL_COMPILER) && defined(__EDG__)
     130             :     const
     131             : #else
     132             :     constexpr
     133             : #endif
     134             : std::string_view parser_f3_s[] =
     135             : {
     136             :     "if"
     137             : };
     138             : 
     139             : enum parser_node_t {
     140             :     PARSER_NUMBER,
     141             :     PARSER_SYMBOL,
     142             :     PARSER_ADD,
     143             :     PARSER_SUB,
     144             :     PARSER_MUL,
     145             :     PARSER_DIV,
     146             :     PARSER_F1,
     147             :     PARSER_F2,
     148             :     PARSER_F3,
     149             :     PARSER_ASSIGN,
     150             :     PARSER_LIST
     151             : };
     152             : 
     153             : static
     154             : #if defined(__INTEL_COMPILER) && defined(__EDG__)
     155             :     const
     156             : #else
     157             :     constexpr
     158             : #endif
     159             : std::string_view parser_node_s[] =
     160             : {
     161             :     "number",
     162             :     "symbol",
     163             :     "add",
     164             :     "sub",
     165             :     "mul",
     166             :     "div",
     167             :     "f1",
     168             :     "f2",
     169             :     "f3",
     170             :     "assign",
     171             :     "list"
     172             : };
     173             : 
     174             : /* In C, the address of the first member of a struct is the same as
     175             :  * the address of the struct itself.  Because of this, all struct parser_*
     176             :  * pointers can be passed around as struct parser_node pointer and enum
     177             :  * parser_node_t type can be safely checked to determine their real type.
     178             :  */
     179             : 
     180             : struct parser_node {
     181             :     enum parser_node_t type;
     182             :     enum parser_node_t padding;
     183             :     struct parser_node* l; // NOLINT(misc-confusable-identifiers)
     184             :     struct parser_node* r;
     185             :     struct parser_node* padding2;
     186             : };
     187             : 
     188             : struct alignas(parser_node) parser_number {
     189             :     enum parser_node_t type;
     190             :     double value;
     191             : };
     192             : 
     193             : struct alignas(parser_node) parser_symbol {
     194             :     enum parser_node_t type;
     195             :     char* name;
     196             :     int ip;
     197             : };
     198             : 
     199             : struct alignas(parser_node) parser_f1 {  /* Builtin functions with one argument */
     200             :     enum parser_node_t type;
     201             :     enum parser_f1_t ftype;
     202             :     struct parser_node* l; // NOLINT(misc-confusable-identifiers)
     203             :     struct parser_node* padding1;
     204             :     struct parser_node* padding2;
     205             : };
     206             : 
     207             : struct alignas(parser_node) parser_f2 {  /* Builtin functions with two arguments */
     208             :     enum parser_node_t type;
     209             :     enum parser_f2_t ftype;
     210             :     struct parser_node* l; // NOLINT(misc-confusable-identifiers)
     211             :     struct parser_node* r;
     212             :     struct parser_node* padding;
     213             : };
     214             : 
     215             : struct alignas(parser_node) parser_f3 { /* Builtin functions with three arguments */
     216             :     enum parser_node_t type;
     217             :     enum parser_f3_t ftype;
     218             :     struct parser_node* n1;
     219             :     struct parser_node* n2;
     220             :     struct parser_node* n3;
     221             : };
     222             : 
     223             : struct alignas(parser_node) parser_assign {
     224             :     enum parser_node_t type;
     225             :     struct parser_symbol* s;
     226             :     struct parser_node* v;
     227             : };
     228             : 
     229             : static_assert(sizeof(parser_f3) <= sizeof(parser_node), "amrex parser: sizeof parser_node too small");
     230             : 
     231             : /*******************************************************************/
     232             : 
     233             : /* These functions are used in bison rules to generate the original AST. */
     234             : void parser_defexpr (struct parser_node* body);
     235             : struct parser_symbol* parser_makesymbol (char* name);
     236             : struct parser_node* parser_newnode (enum parser_node_t type, struct parser_node* l,
     237             :                                     struct parser_node* r);
     238             : struct parser_node* parser_newneg (struct parser_node* n);
     239             : struct parser_node* parser_newnumber (double d);
     240             : struct parser_node* parser_newsymbol (struct parser_symbol* sym);
     241             : struct parser_node* parser_newf1 (enum parser_f1_t ftype, struct parser_node* l);
     242             : struct parser_node* parser_newf2 (enum parser_f2_t ftype, struct parser_node* l,
     243             :                                   struct parser_node* r);
     244             : struct parser_node* parser_newf3 (enum parser_f3_t ftype, struct parser_node* n1,
     245             :                                   struct parser_node* n2, struct parser_node* n3);
     246             : struct parser_node* parser_newassign (struct parser_symbol* s, struct parser_node* v);
     247             : struct parser_node* parser_newlist (struct parser_node* nl, struct parser_node* nr);
     248             : 
     249             : /*******************************************************************/
     250             : 
     251             : /* This is our struct for storing AST in a more packed way.  The whole
     252             :  * tree is stored in a contiguous chunk of memory starting from void*
     253             :  * p_root with a size of sz_mempool.
     254             :  */
     255             : struct amrex_parser {
     256             :     void* p_root;
     257             :     void* p_free;
     258             :     struct parser_node* ast;
     259             :     std::size_t sz_mempool;
     260             : };
     261             : 
     262             : struct amrex_parser* amrex_parser_new ();
     263             : void amrex_parser_delete (struct amrex_parser* parser);
     264             : 
     265             : struct amrex_parser* parser_dup (struct amrex_parser* source);
     266             : struct parser_node* parser_ast_dup (struct amrex_parser* parser, struct parser_node* node, int move);
     267             : 
     268             : void parser_regvar (struct amrex_parser* parser, char const* name, int i);
     269             : void parser_setconst (struct amrex_parser* parser, char const* name, double c);
     270             : void parser_print (struct amrex_parser* parser);
     271             : std::set<std::string> parser_get_symbols (struct amrex_parser* parser);
     272             : int parser_depth (struct amrex_parser* parser);
     273             : 
     274             : /* We need to walk the tree in these functions */
     275             : void parser_ast_optimize (struct parser_node* node);
     276             : std::size_t parser_ast_size (struct parser_node* node);
     277             : void parser_ast_print (struct parser_node* node, std::string const& space, std::ostream& printer);
     278             : void parser_ast_regvar (struct parser_node* node, char const* name, int i);
     279             : void parser_ast_setconst (struct parser_node* node, char const* name, double c);
     280             : void parser_ast_get_symbols (struct parser_node* node, std::set<std::string>& symbols,
     281             :                              std::set<std::string>& local_symbols);
     282             : int parser_ast_depth (struct parser_node* node);
     283             : void parser_ast_sort (struct parser_node* node);
     284             : 
     285             : /*******************************************************************/
     286             : double parser_get_number (struct parser_node* node);
     287             : void parser_set_number (struct parser_node* node, double v);
     288             : bool parser_node_equal (struct parser_node* a, struct parser_node* b);
     289             : /*******************************************************************/
     290             : 
     291             : template <typename T>
     292             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     293          30 : T parser_math_exp (T a) { return std::exp(a); }
     294             : 
     295             : template <typename T>
     296             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     297           0 : T parser_math_log (T a) { return std::log(a); }
     298             : 
     299             : template <typename T>
     300             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     301           0 : T parser_math_log10 (T a) { return std::log10(a); }
     302             : 
     303             : template <typename T>
     304             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     305           0 : T parser_math_sin (T a) { return std::sin(a); }
     306             : 
     307             : template <typename T>
     308             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     309           0 : T parser_math_cos (T a) { return std::cos(a); }
     310             : 
     311             : template <typename T>
     312             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     313           0 : T parser_math_tan (T a) { return std::tan(a); }
     314             : 
     315             : template <typename T>
     316             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     317           0 : T parser_math_asin (T a) { return std::asin(a); }
     318             : 
     319             : template <typename T>
     320             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     321           0 : T parser_math_acos (T a) { return std::acos(a); }
     322             : 
     323             : template <typename T>
     324             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     325           0 : T parser_math_atan (T a) { return std::atan(a); }
     326             : 
     327             : template <typename T>
     328             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     329           0 : T parser_math_sinh (T a) { return std::sinh(a); }
     330             : 
     331             : template <typename T>
     332             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     333           0 : T parser_math_cosh (T a) { return std::cosh(a); }
     334             : 
     335             : template <typename T>
     336             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     337        7056 : T parser_math_tanh (T a) { return std::tanh(a); }
     338             : 
     339             : template <typename T>
     340             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     341           0 : T parser_math_asinh (T a) { return std::asinh(a); }
     342             : 
     343             : template <typename T>
     344             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     345           0 : T parser_math_acosh (T a) { return std::acosh(a); }
     346             : 
     347             : template <typename T>
     348             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     349           0 : T parser_math_atanh (T a) { return std::atanh(a); }
     350             : 
     351             : template <typename T>
     352             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     353           0 : T parser_math_comp_ellint_1 (T a)
     354             : {
     355             : #if defined(__GNUC__) && !defined(__clang__) && !defined(__CUDA_ARCH__) && !defined(__NVCOMPILER)
     356           0 :     return std::comp_ellint_1(a);
     357             : #else
     358             :     amrex::ignore_unused(a);
     359             :     AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false, "parser: comp_ellint_1 only supported with gcc and cpu");
     360             :     return 0.0;
     361             : #endif
     362             : }
     363             : 
     364             : template <typename T>
     365             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     366           0 : T parser_math_comp_ellint_2 (T a)
     367             : {
     368             : #if defined(__GNUC__) && !defined(__clang__) && !defined(__CUDA_ARCH__) && !defined(__NVCOMPILER)
     369           0 :     return std::comp_ellint_2(a);
     370             : #else
     371             :     amrex::ignore_unused(a);
     372             :     AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false, "parser: comp_ellint_2 only supported with gcc and cpu");
     373             :     return 0.0;
     374             : #endif
     375             : }
     376             : 
     377             : template <typename T>
     378             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     379           0 : T parser_math_erf(T a)
     380             : {
     381           0 :     return std::erf(a);
     382             : }
     383             : 
     384             : template <typename T>
     385             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     386           0 : T parser_math_pow (T a, T b) { return std::pow(a,b); }
     387             : 
     388             : template <typename T>
     389             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     390           0 : T parser_math_atan2 (T a, T b) { return std::atan2(a,b); }
     391             : 
     392             : template <typename T>
     393             : AMREX_GPU_HOST_DEVICE AMREX_NO_INLINE
     394           0 : T parser_math_jn (int a, T b)
     395             : {
     396             : #if defined AMREX_USE_SYCL || defined __MINGW32__
     397             :     amrex::ignore_unused(a,b);
     398             :     // neither jn(f) nor std::cyl_bessel_j work yet
     399             :     // https://github.com/oneapi-src/oneAPI-spec/issues/308
     400             :     AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false, "parser: jn in SYCL not supported yet");
     401             :     return 0.0;
     402             : #else
     403           0 :     return jn(a, b);
     404             : #endif
     405             : }
     406             : 
     407             : AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double
     408             : parser_call_f1 (enum parser_f1_t type, double a)
     409             : {
     410        7086 :     switch (type) {
     411           0 :     case PARSER_SQRT:        return std::sqrt(a);
     412          30 :     case PARSER_EXP:         return parser_math_exp<double>(a);
     413           0 :     case PARSER_LOG:         return parser_math_log<double>(a);
     414           0 :     case PARSER_LOG10:       return parser_math_log10<double>(a);
     415           0 :     case PARSER_SIN:         return parser_math_sin<double>(a);
     416           0 :     case PARSER_COS:         return parser_math_cos<double>(a);
     417           0 :     case PARSER_TAN:         return parser_math_tan<double>(a);
     418           0 :     case PARSER_ASIN:        return parser_math_asin<double>(a);
     419           0 :     case PARSER_ACOS:        return parser_math_acos<double>(a);
     420           0 :     case PARSER_ATAN:        return parser_math_atan<double>(a);
     421           0 :     case PARSER_SINH:        return parser_math_sinh<double>(a);
     422           0 :     case PARSER_COSH:        return parser_math_cosh<double>(a);
     423        7056 :     case PARSER_TANH:        return parser_math_tanh<double>(a);
     424           0 :     case PARSER_ASINH:       return parser_math_asinh<double>(a);
     425           0 :     case PARSER_ACOSH:       return parser_math_acosh<double>(a);
     426           0 :     case PARSER_ATANH:       return parser_math_atanh<double>(a);
     427           0 :     case PARSER_ABS:         return std::abs(a);
     428           0 :     case PARSER_FLOOR:       return std::floor(a);
     429           0 :     case PARSER_CEIL:        return std::ceil(a);
     430           0 :     case PARSER_COMP_ELLINT_1: return parser_math_comp_ellint_1<double>(a);
     431           0 :     case PARSER_COMP_ELLINT_2: return parser_math_comp_ellint_2<double>(a);
     432           0 :     case PARSER_ERF:         return parser_math_erf<double>(a);
     433           0 :     default:
     434             :         amrex::Abort("parser_call_f1: Unknown function ");
     435           0 :         return 0.0;
     436             :     }
     437             : }
     438             : 
     439             : AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double
     440             : parser_call_f2 (enum parser_f2_t type, double a, double b)
     441             : {
     442       22064 :     switch (type) {
     443           0 :     case PARSER_POW:
     444           0 :         return parser_math_pow<double>(a,b);
     445           0 :     case PARSER_ATAN2:
     446           0 :         return parser_math_atan2<double>(a,b);
     447       11032 :     case PARSER_GT:
     448       11032 :         return (a > b) ? 1.0 : 0.0;
     449       11032 :     case PARSER_LT:
     450       11032 :         return (a < b) ? 1.0 : 0.0;
     451           0 :     case PARSER_GEQ:
     452           0 :         return (a >= b) ? 1.0 : 0.0;
     453           0 :     case PARSER_LEQ:
     454           0 :         return (a <= b) ? 1.0 : 0.0;
     455           0 :     case PARSER_EQ:
     456           0 :         return (a == b) ? 1.0 : 0.0;
     457           0 :     case PARSER_NEQ:
     458           0 :         return (a != b) ? 1.0 : 0.0;
     459           0 :     case PARSER_AND:
     460           0 :         return ((a != 0.0) && (b != 0.0)) ? 1.0 : 0.0;
     461           0 :     case PARSER_OR:
     462           0 :         return ((a != 0.0) || (b != 0.0)) ? 1.0 : 0.0;
     463           0 :     case PARSER_HEAVISIDE:
     464           0 :         return (a < 0.0) ? 0.0 : ((a > 0.0) ? 1.0 : b);
     465           0 :     case PARSER_JN:
     466           0 :         return parser_math_jn<double>(int(a),b);
     467           0 :     case PARSER_MIN:
     468           0 :         return (a < b) ? a : b;
     469           0 :     case PARSER_MAX:
     470           0 :         return (a > b) ? a : b;
     471           0 :     case PARSER_FMOD:
     472           0 :         return std::fmod(a,b);
     473           0 :     default:
     474             :         amrex::Abort("parser_call_f2: Unknown function");
     475           0 :         return 0.0;
     476             :     }
     477             : }
     478             : 
     479             : AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double
     480             : parser_call_f3 (enum parser_f3_t /*type*/, double a, double b, double c)
     481             : {
     482             :     // There is only one type currently
     483             :     return (a != 0.0) ? b : c;
     484             : }
     485             : 
     486             : }
     487             : 
     488             : #endif

Generated by: LCOV version 1.14