Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 79 additions & 4 deletions Src/Base/Parser/AMReX_IParser.H
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#ifndef AMREX_IPARSER_H_
#define AMREX_IPARSER_H_

/**
* \file AMReX_IParser.H
* \brief Integer-only runtime expression parser and executor helpers.
*/

#include <AMReX_Arena.H>
#include <AMReX_Array.H>
#include <AMReX_GpuDevice.H>
Expand All @@ -13,9 +18,19 @@

namespace amrex {

/**
* \struct amrex::IParserExecutor
* \brief Callable wrapper around an integer parser expression with \p N variables.
*
* Instances are returned by IParser::compile() / IParser::compileHost() and expose
* host/device operator() overloads that evaluate to 64-bit integers.
*/
template <int N>
struct IParserExecutor
{
/**
* \brief Evaluate constant expressions (\p N == 0) and return the integer result.
*/
template <int M=N, std::enable_if_t<M==0,int> = 0>
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
long long operator() () const noexcept
Expand All @@ -24,6 +39,11 @@ struct IParserExecutor
AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, nullptr);))
}

/**
* \brief Evaluate the expression with \p N integral arguments.
* \param var Scalar arguments supplied in registration order.
* \return Result promoted to \c long long.
*/
template <typename... Ts>
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
std::enable_if_t<sizeof...(Ts) == N && std::conjunction_v<std::is_integral<Ts>...>,
Expand All @@ -35,52 +55,107 @@ struct IParserExecutor
AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, l_var.data());))
}

/**
* \brief Evaluate using an explicit array of integer arguments.
* \param var Argument array in registration order.
*/
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
long long operator() (GpuArray<long long, N> const& var) const noexcept
{
AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, var.data());))
AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, var.data());))
}

//! True when this is a valid executor.
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
explicit operator bool () const {
AMREX_IF_ON_DEVICE((return m_device_executor != nullptr;))
AMREX_IF_ON_HOST((return m_host_executor != nullptr;))
}

char* m_host_executor = nullptr;
char* m_host_executor = nullptr; ///< Pointer to host bytecode.
#ifdef AMREX_USE_GPU
char* m_device_executor = nullptr;
char* m_device_executor = nullptr; ///< Pointer to device bytecode (if copied).
#endif
};

/// \ingroup amrex_utilities
/**
* \brief Integer-only variant of amrex::Parser.
*
* IParser parses expressions composed of integer literals, integer variables,
* and integer-returning functions. It emits executors that evaluate to long long
* on host or GPU.
*/
class IParser
{
public:
/**
* \brief Construct a parser by immediately parsing \p func_body.
* \param func_body Expression to parse (empty to defer define()).
*/
IParser (std::string const& func_body);
//! Default-construct; call define() before compile().
IParser () = default;
/**
* \brief Parse and own a new integer expression, replacing any previous state.
* \param func_body Expression text.
*/
void define (std::string const& func_body);

//! True when an expression has been parsed successfully.
explicit operator bool () const;

/**
* \brief Bind a named integer constant.
* \param name Identifier referenced inside the expression.
* \param c Constant value substituted during compilation.
*/
void setConstant (std::string const& name, long long c);

/**
* \brief Register the ordered list of integer variables referenced by the expression.
*
* \param vars Variable names supplied in parser argument order.
*/
void registerVariables (Vector<std::string> const& vars);

//! Print the parse tree to stdout for debugging.
void print () const;

/**
* \brief Return the maximum parse-tree depth.
* \return Depth measured in tree levels (0 if undefined).
*/
[[nodiscard]] int depth () const;
/**
* \brief Return the maximum parser stack usage.
* \return Stack size required during execution (0 if undefined).
*/
[[nodiscard]] int maxStackSize () const;

/**
* \brief Return the sanitized expression string.
* \return Copy of the parsed expression or an empty string if undefined.
*/
[[nodiscard]] std::string expr () const;

/**
* \brief Return the set of symbols referenced by the expression.
* \return Sorted symbol names.
*/
[[nodiscard]] std::set<std::string> symbols () const;

//! This compiles for both GPU and CPU
/**
* \brief Compile the expression into a host/device IParserExecutor.
* \tparam N Number of registered variables.
*/
template <int N> [[nodiscard]] IParserExecutor<N> compile () const;

//! This compiles for CPU only
/**
* \brief Compile the expression into a host-only executor.
* \tparam N Number of registered variables.
*/
template <int N> [[nodiscard]] IParserExecutor<N> compileHost () const;

private:
Expand Down
5 changes: 5 additions & 0 deletions Src/Base/Parser/AMReX_IParser_Exe.H
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
#define AMREX_IPARSER_EXE_H_
#include <AMReX_Config.H>

/**
* \file AMReX_IParser_Exe.H
* \brief Bytecode instruction formats for the integer parser backend.
*/

#include <AMReX_IParser_Y.H>
#include <AMReX_Stack.H>
#include <AMReX_Vector.H>
Expand Down
5 changes: 5 additions & 0 deletions Src/Base/Parser/AMReX_IParser_Y.H
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
#define AMREX_IPARSER_Y_H_
#include <AMReX_Config.H>

/**
* \file AMReX_IParser_Y.H
* \brief Symbol-table definitions shared by the integer parser lexer/parser.
*/

#include <AMReX_GpuQualifiers.H>
#include <AMReX_GpuPrint.H>
#include <AMReX_Math.H>
Expand Down
Loading
Loading