From 0027d6fe4b817c1dc1afbf9b0d4d33e65c45763d Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Thu, 8 Aug 2024 16:24:46 -0700 Subject: [PATCH] ParmParse: queryarrWithParser Add a new function queryarrWithParser that will query an array of values using Parser. The function takes the number of elements as an argument too. If the size of the input found with ParmParse does not match the size argument, it's a runtime error. For each individual array element, queryWithParser is used for the query. The behavior of queryWithParser has changed. Previously, the query function is used for unresolved symbols. Now the queryWithParser function is used instead. The difference is that the latter will ignore the spaces in the input and combine the entire input into a single string. --- Src/Base/AMReX_ParmParse.H | 15 +++++- Src/Base/AMReX_ParmParse.cpp | 88 +++++++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/Src/Base/AMReX_ParmParse.H b/Src/Base/AMReX_ParmParse.H index c9e273643e..04c3c8c9a8 100644 --- a/Src/Base/AMReX_ParmParse.H +++ b/Src/Base/AMReX_ParmParse.H @@ -1040,7 +1040,8 @@ public: /** * \brief Query with Parser. If `name` is found, this uses amrex::Parser * to parse the entire list of empty space separated values as a single - * scalar. The return value indicates whether it's found. + * scalar. The return value indicates whether it's found. Note that + * queryWithParser will be used recursively for unresolved symbols. */ int queryWithParser (const char* name, int& ref) const; int queryWithParser (const char* name, long& ref) const; @@ -1048,6 +1049,18 @@ public: int queryWithParser (const char* name, float& ref) const; int queryWithParser (const char* name, double& ref) const; + /** + * \brief Query with Parser. The return value indicates whether it's + * found. Note that queryWithParser will be used for unresolved + * symbols. If the number of elements in the input does not equal to + * `nvals`, it's a runtime error. + */ + int queryarrWithParser (const char* name, int nvals, std::vector& ref) const; + int queryarrWithParser (const char* name, int nvals, std::vector& ref) const; + int queryarrWithParser (const char* name, int nvals, std::vector& ref) const; + int queryarrWithParser (const char* name, int nvals, std::vector& ref) const; + int queryarrWithParser (const char* name, int nvals, std::vector& ref) const; + /** * \brief Query with Parser. If `name` is found, this uses amrex::Parser * to parse the entire list of empty space separated values as a single diff --git a/Src/Base/AMReX_ParmParse.cpp b/Src/Base/AMReX_ParmParse.cpp index 523e944cda..e998130374 100644 --- a/Src/Base/AMReX_ParmParse.cpp +++ b/Src/Base/AMReX_ParmParse.cpp @@ -625,7 +625,8 @@ bldTable (const char*& str, ParmParse::Table& tab) template bool pp_parser (const ParmParse::Table& table, const std::string& parser_prefix, - const std::string& name, const std::string& val, T& ref); + const std::string& name, const std::string& val, T& ref, + bool use_querywithparser); template bool @@ -673,7 +674,7 @@ squeryval (const ParmParse::Table& table, std::is_same_v || std::is_same_v || std::is_same_v) { - if (pp_parser(table, parser_prefix, name, valname, ref)) { + if (pp_parser(table, parser_prefix, name, valname, ref, false)) { return true; } } @@ -786,7 +787,7 @@ squeryarr (const ParmParse::Table& table, std::is_same_v || std::is_same_v || std::is_same_v) { - if (pp_parser(table, parser_prefix, name, valname, ref[n])) { + if (pp_parser(table, parser_prefix, name, valname, ref[n], false)) { continue; } } @@ -938,11 +939,18 @@ void pp_print_unused (const std::string& pfx, const ParmParse::Table& table) } } +template +bool squeryWithParser (const ParmParse::Table& table, + const std::string& parser_prefix, + const std::string& name, + T& ref); + template , IParser, Parser>> PARSER_t pp_make_parser (std::string const& func, Vector const& vars, - ParmParse::Table const& table, std::string const& parser_prefix) + ParmParse::Table const& table, std::string const& parser_prefix, + bool use_querywithparser) { using value_t = std::conditional_t, long long, double>; @@ -967,8 +975,12 @@ pp_make_parser (std::string const& func, Vector const& vars, value_t v = 0; bool r = false; for (auto const& pf : prefixes) { - r = squeryval(table, parser_prefix, pf+s, v, - ParmParse::FIRST, ParmParse::LAST); + if (use_querywithparser) { + r = squeryWithParser(table, parser_prefix, pf+s, v); + } else { + r = squeryval(table, parser_prefix, pf+s, v, + ParmParse::FIRST, ParmParse::LAST); + } if (r) { break; } } if (r == false) { @@ -985,7 +997,8 @@ pp_make_parser (std::string const& func, Vector const& vars, template bool pp_parser (const ParmParse::Table& table, const std::string& parser_prefix, - const std::string& name, const std::string& val, T& ref) + const std::string& name, const std::string& val, T& ref, + bool use_querywithparser) { auto& recursive_symbols = g_parser_recursive_symbols[OpenMP::get_thread_num()]; if (auto found = recursive_symbols.find(name); found != recursive_symbols.end()) { @@ -995,7 +1008,7 @@ bool pp_parser (const ParmParse::Table& table, const std::string& parser_prefix, recursive_symbols.insert(name); } - auto parser = pp_make_parser(val, {}, table, parser_prefix); + auto parser = pp_make_parser(val, {}, table, parser_prefix, use_querywithparser); auto exe = parser.template compileHost<0>(); ref = static_cast(exe()); @@ -1874,7 +1887,30 @@ bool squeryWithParser (const ParmParse::Table& table, for (auto const& v : vals) { combined_string.append(v); } - return pp_parser(table, parser_prefix, name, combined_string, ref); + return pp_parser(table, parser_prefix, name, combined_string, ref, true); +} + +template +bool squeryarrWithParser (const ParmParse::Table& table, + const std::string& parser_prefix, + const std::string& name, + int nvals, + std::vector& ref) +{ + std::vector vals; + bool exist = squeryarr(table, parser_prefix, name, vals, + ParmParse::FIRST, ParmParse::ALL, ParmParse::LAST); + if (!exist) { return false; } + + AMREX_ALWAYS_ASSERT(int(vals.size()) == nvals); + if (ref.size() < vals.size()) { + ref.resize(nvals); + } + for (int ival = 0; ival < nvals; ++ival) { + bool exist = pp_parser(table, parser_prefix, name, vals[ival], ref[ival], true); + if (!exist) { return false; } + } + return true; } } @@ -1908,18 +1944,48 @@ ParmParse::queryWithParser (const char* name, double& ref) const return squeryWithParser(*m_table,m_parser_prefix,prefixedName(name),ref); } +int +ParmParse::queryarrWithParser (const char* name, int nvals, std::vector& ref) const +{ + return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref); +} + +int +ParmParse::queryarrWithParser (const char* name, int nvals, std::vector& ref) const +{ + return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref); +} + +int +ParmParse::queryarrWithParser (const char* name, int nvals, std::vector& ref) const +{ + return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref); +} + +int +ParmParse::queryarrWithParser (const char* name, int nvals, std::vector& ref) const +{ + return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref); +} + +int +ParmParse::queryarrWithParser (const char* name, int nvals, std::vector& ref) const +{ + return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref); +} + Parser ParmParse::makeParser (std::string const& func, Vector const& vars) const { - return pp_make_parser(func, vars, *m_table, m_parser_prefix); + return pp_make_parser(func, vars, *m_table, m_parser_prefix, true); } IParser ParmParse::makeIParser (std::string const& func, Vector const& vars) const { - return pp_make_parser(func, vars, *m_table, m_parser_prefix); + return pp_make_parser(func, vars, *m_table, m_parser_prefix, true); } }