From 51db5ece14372d6f770531054a52edd4abd07b23 Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Sat, 7 Sep 2024 19:08:34 -0500 Subject: [PATCH] amrex::Stack (#4139) Move the Stack class used in Parser to its own header so that it can be used by others. The Stack class has a fixed maximum size. This is useful for traversing a tree on GPU, because recursive function does not work well in device code. --- Src/Base/AMReX_Stack.H | 24 ++++++++++++++++++++++++ Src/Base/CMakeLists.txt | 1 + Src/Base/Make.package | 2 ++ Src/Base/Parser/AMReX_IParser_Exe.H | 15 ++------------- Src/Base/Parser/AMReX_Parser_Exe.H | 15 ++------------- 5 files changed, 31 insertions(+), 26 deletions(-) create mode 100644 Src/Base/AMReX_Stack.H diff --git a/Src/Base/AMReX_Stack.H b/Src/Base/AMReX_Stack.H new file mode 100644 index 00000000000..8e9e83f8682 --- /dev/null +++ b/Src/Base/AMReX_Stack.H @@ -0,0 +1,24 @@ +#ifndef AMREX_STACK_H_ +#define AMREX_STACK_H_ + +namespace amrex { + +template +struct Stack +{ +public: + constexpr void push (T v) { m_data[m_size++] = v; } + constexpr void pop () { --m_size; } + [[nodiscard]] constexpr bool empty () const { return m_size == 0; } + [[nodiscard]] constexpr int size () const { return m_size; } + [[nodiscard]] constexpr T const& top () const { return m_data[m_size-1]; } + [[nodiscard]] constexpr T & top () { return m_data[m_size-1]; } + [[nodiscard]] constexpr T operator[] (int i) const { return m_data[i]; } +private: + T m_data[N]; + int m_size = 0; +}; + +} + +#endif diff --git a/Src/Base/CMakeLists.txt b/Src/Base/CMakeLists.txt index 0436ad032e4..3a19b917c35 100644 --- a/Src/Base/CMakeLists.txt +++ b/Src/Base/CMakeLists.txt @@ -31,6 +31,7 @@ foreach(D IN LISTS AMReX_SPACEDIM) AMReX_parmparse_fi.cpp AMReX_ParmParse.H AMReX_Functional.H + AMReX_Stack.H AMReX_String.H AMReX_String.cpp AMReX_Utility.H diff --git a/Src/Base/Make.package b/Src/Base/Make.package index b009ebf7d65..361ca079388 100644 --- a/Src/Base/Make.package +++ b/Src/Base/Make.package @@ -23,6 +23,8 @@ C$(AMREX_BASE)_sources += AMReX_PODVector.cpp C$(AMREX_BASE)_headers += AMReX_BlockMutex.H C$(AMREX_BASE)_sources += AMReX_BlockMutex.cpp +C$(AMREX_BASE)_headers += AMReX_Stack.H + C$(AMREX_BASE)_headers += AMReX_String.H C$(AMREX_BASE)_sources += AMReX_String.cpp diff --git a/Src/Base/Parser/AMReX_IParser_Exe.H b/Src/Base/Parser/AMReX_IParser_Exe.H index e7e41c44d48..a68fa32981e 100644 --- a/Src/Base/Parser/AMReX_IParser_Exe.H +++ b/Src/Base/Parser/AMReX_IParser_Exe.H @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -226,24 +227,12 @@ struct alignas(8) IParserExeJUMP { int offset; }; -template -struct IParserStack -{ - long long m_data[N]; - int m_size = 0; - constexpr void push (long long v) { m_data[m_size++] = v; } - constexpr void pop () { --m_size; } - [[nodiscard]] constexpr long long const& top () const { return m_data[m_size-1]; } - [[nodiscard]] constexpr long long & top () { return m_data[m_size-1]; } - [[nodiscard]] constexpr long long operator[] (int i) const { return m_data[i]; } -}; - AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long iparser_exe_eval (const char* p, long long const* x) { if (p == nullptr) { return std::numeric_limits::max(); } - IParserStack pstack; + Stack pstack; while (*((iparser_exe_t*)p) != IPARSER_EXE_NULL) { switch (*((iparser_exe_t*)p)) { diff --git a/Src/Base/Parser/AMReX_Parser_Exe.H b/Src/Base/Parser/AMReX_Parser_Exe.H index 37a0b89da78..a5427e6e65c 100644 --- a/Src/Base/Parser/AMReX_Parser_Exe.H +++ b/Src/Base/Parser/AMReX_Parser_Exe.H @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -217,24 +218,12 @@ struct alignas(8) ParserExeJUMP { int offset; }; -template -struct ParserStack -{ - double m_data[N]; - int m_size = 0; - constexpr void push (double v) { m_data[m_size++] = v; } - constexpr void pop () { --m_size; } - [[nodiscard]] constexpr double const& top () const { return m_data[m_size-1]; } - [[nodiscard]] constexpr double & top () { return m_data[m_size-1]; } - [[nodiscard]] constexpr double operator[] (int i) const { return m_data[i]; } -}; - AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double parser_exe_eval (const char* p, double const* x) { if (p == nullptr) { return std::numeric_limits::max(); } - ParserStack pstack; + Stack pstack; while (*((parser_exe_t*)p) != PARSER_EXE_NULL) { // NOLINT switch (*((parser_exe_t*)p)) {