Skip to content

Compile-time GLL quadrature.#1891

Open
int-ptr-ptr wants to merge 10 commits into
PrincetonUniversity:develfrom
int-ptr-ptr:compiletime-gll
Open

Compile-time GLL quadrature.#1891
int-ptr-ptr wants to merge 10 commits into
PrincetonUniversity:develfrom
int-ptr-ptr:compiletime-gll

Conversation

@int-ptr-ptr

Copy link
Copy Markdown
Collaborator

Description

Please describe the changes/features in this pull request.

Issue Number

If there is an issue created for these changes, link it here

Checklist

Please make sure to check developer documentation on specfem docs.

  • I ran the code through pre-commit to check style
  • THE DOCUMENTATION BUILDS WITHOUT WARNINGS/ERRORS
  • I have added labels to the PR (see right hand side of the PR page)
  • My code passes all the integration tests
  • I have added sufficient unittests to test my changes
  • I have added/updated documentation for the changes I am proposing
  • I have updated CMakeLists to ensure my code builds
  • My code builds across all platforms

@lsawade lsawade left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Was working with compiler explorer to analyze what's happening and it found some things that could improve loading.

Compiler Explorer

Comment on lines +78 to +79
* @brief Populates poly.roots using the algo described in
* polynomial_zeros.ipynb

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

???

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Those were my notes for rootfind when I initially wrote the code way back when.


using numerical_type = Nodes::numerical_type;
static constexpr std::size_t N = Nodes::N;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
private:
static constexpr auto coeff_table =
impl::make_lagrange_coeff_table(Nodes::get_nodes());

struct Nodes {
private:
using initializer_node_type = decltype(NodeInitializer::get_nodes());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
private:
static constexpr auto nodes = NodeInitializer::get_nodes();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

constexpr does not guarantee compile-time evaluation. Since NodeInitializer could be anything, I purposefully wrapped NodeInitializer::get_nodes() with a consteval function in case consteval was forgotten.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I had set a private constexpr auto nodes = Nodes::get_nodes();, though, but I ended up removing that (elaborated in the comment about the nvcc issue below).

I re-added it since I found a bypass, so if this suggestion was based on a missing static constexpr variable, consider the suggestion followed. If this was a suggestion to remove the consteval Nodes::get_nodes(), I want to push back, due to the aforementioned behavior of constexpr.

*/
static constexpr KOKKOS_INLINE_FUNCTION numerical_type
node(const int &node_index) {
return get_nodes()[node_index];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return get_nodes()[node_index];
return nodes[node_index];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

nvcc:

error: identifier "specfem::quadrature::compiletime::Lagrange< ::specfem::quadrature::compiletime::gll_initializer<(int)5, float> > ::Nodes::nodes" is undefined in device code

for some reason, declaring the constexpr nodes variable inside the KOKKOS_INLINE_FUNCTION does work, though.

@int-ptr-ptr int-ptr-ptr Jun 5, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This was the fix I ended up with:

    static constexpr KOKKOS_INLINE_FUNCTION numerical_type
    node(const int &node_index) {
      constexpr auto nodes_ = nodes;
      // so for some reason this works, while directly referencing nodes has
      // nvcc crying
      return nodes_[node_index];
    }

It's a little hacky, but my nvcc is okay with it.

Comment on lines +34 to +35
static consteval Kokkos::Array<numerical_type, N> get_nodes() {
return NodeInitializer::get_nodes();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
static consteval Kokkos::Array<numerical_type, N> get_nodes() {
return NodeInitializer::get_nodes();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

see above comment, quote-copied here for reference:

constexpr does not guarantee compile-time evaluation. Since NodeInitializer could be anything, I purposefully wrapped NodeInitializer::get_nodes() with a consteval function in case consteval was forgotten.

I'm taking the care to ensure consteval, since (to my understanding) the C++20 standard requires compile-time evaluation

consteval - specifies that a function is an immediate function, that is, every call to the function must produce a compile-time constant

while (from my conversations with Rohit) constexpr does not have such an explicit requirement.

}
KOKKOS_INLINE_FUNCTION numerical_type
operator()(const int &node_index) const {
return node(node_index);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return node(node_index);
return nodes[node_index];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

See comment on Nodes::node(const int&), quote-copied here for reference:

This was the fix I ended up with:

    static constexpr KOKKOS_INLINE_FUNCTION numerical_type
    node(const int &node_index) {
      constexpr auto nodes_ = nodes;
      // so for some reason this works, while directly referencing nodes has
      // nvcc crying
      return nodes_[node_index];
    }

It's a little hacky, but my nvcc is okay with it.

@Rohit-Kakodkar Rohit-Kakodkar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we just hard code the polynomials for degree 5 and 8? I think it would make this implementation a lot simpler and easier to maintain. Thoughts @lsawade

@lsawade

lsawade commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

While the legendre rootfinding is more elegant in the mathematical sense, I agree with @Rohit-Kakodkar that it would be much simpler to just take NGLL 5-12 and hardcode the GLL points instead for this. This is what I originally had commented as well: #1879

It would drastically reduce code complexity and these roots are not changing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants