Skip to content

AMREX_ENUM: Cache String Map#4643

Merged
WeiqunZhang merged 3 commits intoAMReX-Codes:developmentfrom
ax3l:fix-enum-pair-creation
Sep 11, 2025
Merged

AMREX_ENUM: Cache String Map#4643
WeiqunZhang merged 3 commits intoAMReX-Codes:developmentfrom
ax3l:fix-enum-pair-creation

Conversation

@ax3l
Copy link
Copy Markdown
Member

@ax3l ax3l commented Sep 5, 2025

Summary

The getEnumNameValuePairs logic used below a lot of AMREX_ENUM functions is very slow for long-enough (e.g., N>70) enums.

In WarpX 1D simulations, it took up close to 50% of the runtime, as Dave Grote found.

This caches the key-value string list on first creation, because the type is known at compile-time.

A better implementation might skip the dictionary altogether for functions that just need one string, like getEnumNameString.

Additional background

BLAST-WarpX/warpx#6139

Checklist

The proposed changes:

  • fix a bug or incorrect behavior in AMReX
  • add new capabilities to AMReX
  • changes answers in the test suite to more than roundoff level
  • are likely to significantly affect the results of downstream AMReX users
  • include documentation in the code and/or rst files, if appropriate

The `getEnumNameValuePairs` logic used below a lot of
`AMREX_ENUM` functions is very slow for long-enough (e.g.,
N>70) enums.

In WarpX 1D simulations, it took up close to 50% of the runtime,
as Dave Grote found.

This caches the key-value string list on first creation, because
the type is known at compile-time.

A better implementation might skip the dictionary altogether for
functions that just need one string, like `getEnumNameString`.
Seems... off.
@WeiqunZhang
Copy link
Copy Markdown
Member

I think we should create a helper function to avoid multiple statics. Something like

    template <typename T, typename ET = amrex_enum_traits<T>,
              std::enable_if_t<ET::value,int> = 0>
    std::vector<std::pair<std::string,T>> getEnumNameValuePairs_helper ()
    {
            // the function body of current getEnumNameValuePairs
    }

    template <typename T, typename ET = amrex_enum_traits<T>,
              std::enable_if_t<ET::value,int> = 0>
    std::vector<std::pair<std::string,T>> const& getEnumNameValuePairs ()
    {
        static auto r = getNumNameValuePairs_helper<T>();
        return r;
    }

@ax3l
Copy link
Copy Markdown
Member Author

ax3l commented Sep 8, 2025

Can we even create an optimized version of getEnumNameString that avoids creating a list of all (unused) names altogether? @WeiqunZhang

@WeiqunZhang
Copy link
Copy Markdown
Member

Depending the size, maybe using std::map or std::unordered_map is better than std::vector. But it's hard to avoid building the whole list.

@ax3l
Copy link
Copy Markdown
Member Author

ax3l commented Sep 10, 2025

@WeiqunZhang ready from my end

@dpgrote can you please test if this solves your performance issue on WarpX 1D runs? :)

@WeiqunZhang
Copy link
Copy Markdown
Member

We could also test alternative versions using std::map or std::unordered_map.

@dpgrote
Copy link
Copy Markdown
Contributor

dpgrote commented Sep 10, 2025

This seems to work, thanks! I did a test comparing the time spent in the getExtractedName in WarpX. The original version was taking 0.8 seconds. With this PR, it is 0.1 seconds. With the PR in WarpX, it is 0.07 seconds. Not sure why that would be slightly faster.

@WeiqunZhang
Copy link
Copy Markdown
Member

Probably because the WarpX PR uses std::map.


template <typename T, typename ET = amrex_enum_traits<T>,
std::enable_if_t<ET::value,int> = 0>
std::vector<std::pair<std::string,T>> getEnumNameValuePairs ()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should return by const&.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we never resolved this comment. I believe we should return by const& for performance.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do in #4655

@WeiqunZhang WeiqunZhang merged commit 55ce8b3 into AMReX-Codes:development Sep 11, 2025
76 of 80 checks passed
@ax3l ax3l deleted the fix-enum-pair-creation branch September 11, 2025 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants