Skip to content

Commit

Permalink
ParmParse: queryarrWithParser
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
WeiqunZhang committed Aug 8, 2024
1 parent b6ed523 commit 0027d6f
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 12 deletions.
15 changes: 14 additions & 1 deletion Src/Base/AMReX_ParmParse.H
Original file line number Diff line number Diff line change
Expand Up @@ -1040,14 +1040,27 @@ 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;
int queryWithParser (const char* name, long long& ref) const;
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<int>& ref) const;
int queryarrWithParser (const char* name, int nvals, std::vector<long>& ref) const;
int queryarrWithParser (const char* name, int nvals, std::vector<long long>& ref) const;
int queryarrWithParser (const char* name, int nvals, std::vector<float>& ref) const;
int queryarrWithParser (const char* name, int nvals, std::vector<double>& 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
Expand Down
88 changes: 77 additions & 11 deletions Src/Base/AMReX_ParmParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,8 @@ bldTable (const char*& str, ParmParse::Table& tab)

template <typename T>
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 <class T>
bool
Expand Down Expand Up @@ -673,7 +674,7 @@ squeryval (const ParmParse::Table& table,
std::is_same_v<T,long long> ||
std::is_same_v<T,float> ||
std::is_same_v<T,double>) {
if (pp_parser(table, parser_prefix, name, valname, ref)) {
if (pp_parser(table, parser_prefix, name, valname, ref, false)) {
return true;
}
}
Expand Down Expand Up @@ -786,7 +787,7 @@ squeryarr (const ParmParse::Table& table,
std::is_same_v<T,long long> ||
std::is_same_v<T,float> ||
std::is_same_v<T,double>) {
if (pp_parser(table, parser_prefix, name, valname, ref[n])) {
if (pp_parser(table, parser_prefix, name, valname, ref[n], false)) {
continue;
}
}
Expand Down Expand Up @@ -938,11 +939,18 @@ void pp_print_unused (const std::string& pfx, const ParmParse::Table& table)
}
}

template <class T>
bool squeryWithParser (const ParmParse::Table& table,
const std::string& parser_prefix,
const std::string& name,
T& ref);

template <typename T, typename PARSER_t = std::conditional_t<std::is_integral_v<T>,
IParser, Parser>>
PARSER_t
pp_make_parser (std::string const& func, Vector<std::string> 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<std::is_integral_v<T>, long long, double>;

Expand All @@ -967,8 +975,12 @@ pp_make_parser (std::string const& func, Vector<std::string> 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) {
Expand All @@ -985,7 +997,8 @@ pp_make_parser (std::string const& func, Vector<std::string> const& vars,

template <typename T>
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()) {
Expand All @@ -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<T>(val, {}, table, parser_prefix);
auto parser = pp_make_parser<T>(val, {}, table, parser_prefix, use_querywithparser);
auto exe = parser.template compileHost<0>();
ref = static_cast<T>(exe());

Expand Down Expand Up @@ -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 <class T>
bool squeryarrWithParser (const ParmParse::Table& table,
const std::string& parser_prefix,
const std::string& name,
int nvals,
std::vector<T>& ref)
{
std::vector<std::string> 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);

Check notice

Code scanning / CodeQL

Declaration hides variable Note

Variable exist hides another variable of the same name (on
line 1901
).
if (!exist) { return false; }
}
return true;
}
}

Expand Down Expand Up @@ -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<int>& ref) const
{
return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref);
}

int
ParmParse::queryarrWithParser (const char* name, int nvals, std::vector<long>& ref) const
{
return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref);
}

int
ParmParse::queryarrWithParser (const char* name, int nvals, std::vector<long long>& ref) const
{
return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref);
}

int
ParmParse::queryarrWithParser (const char* name, int nvals, std::vector<float>& ref) const
{
return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref);
}

int
ParmParse::queryarrWithParser (const char* name, int nvals, std::vector<double>& ref) const
{
return squeryarrWithParser(*m_table,m_parser_prefix,prefixedName(name),nvals,ref);
}

Parser
ParmParse::makeParser (std::string const& func,
Vector<std::string> const& vars) const
{
return pp_make_parser<double>(func, vars, *m_table, m_parser_prefix);
return pp_make_parser<double>(func, vars, *m_table, m_parser_prefix, true);
}

IParser
ParmParse::makeIParser (std::string const& func,
Vector<std::string> const& vars) const
{
return pp_make_parser<long long>(func, vars, *m_table, m_parser_prefix);
return pp_make_parser<long long>(func, vars, *m_table, m_parser_prefix, true);
}

}

0 comments on commit 0027d6f

Please sign in to comment.