Skip to content

Add range-based for and ND to BoxIterator#4668

Merged
WeiqunZhang merged 3 commits intoAMReX-Codes:developmentfrom
AlexanderSinn:Add_range_based_for_and_ND_to_BoxIterator
Sep 22, 2025
Merged

Add range-based for and ND to BoxIterator#4668
WeiqunZhang merged 3 commits intoAMReX-Codes:developmentfrom
AlexanderSinn:Add_range_based_for_and_ND_to_BoxIterator

Conversation

@AlexanderSinn
Copy link
Copy Markdown
Member

@AlexanderSinn AlexanderSinn commented Sep 19, 2025

Summary

This PR extends BoxIterator to be n-dimensional. Additionally, it now supports a range-based for loops. The hope is that this can be useful to reduce the reliance on ifdefs/macros to write loops over boxes that run on CPUs, though so far I haven't found that many places where this can be used.

Box b;
...
for (IntVect iv : b.iterator()) {
    // do operations involving iv
}

Note that while regular iteration of the range-based version is reasonably performant,
it is not compatible with omp parallel for or simd autovectorization.

Additional background

The range-based version produces good assembly when compiling with -O3, having minimal instructions in the innermost loop.
https://godbolt.org/z/MTcM8Ysaq

void g (const IntVect&);

void test (Box bx) {
    for (auto iv : bx.iterator()) {
        g(iv);
    }
}
        ...
.L3:
        mov     ebx, DWORD PTR [rsp+8]
.L4:
        mov     r15d, r13d
.L6:
        mov     DWORD PTR [rsp+16], r15d
        lea     rdi, [rsp+16]
        add     r15d, 1
        mov     DWORD PTR [rsp+20], ebx
        mov     DWORD PTR [rsp+24], ebp
        call    "g(IntVectND<3> const&)"
        cmp     r15d, r12d
        jle     .L6
        add     ebx, 1
        cmp     r14d, ebx
        jge     .L4
        cmp     ebp, DWORD PTR [rsp+12]
        je      .L13
        add     ebp, 1
        jmp     .L3
        ...

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

* a_bx (not modified) the Box to iterate over.
*/
void define (const BoxND<dim>& a_bx) noexcept {
if (a_bx.ok() && a_bx.smallEnd().allLE(a_bx.bigEnd())) {
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.

The second part of the test seems redundant.

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.

It is. It was a leftover from the previous version. I removed it now.

@WeiqunZhang WeiqunZhang merged commit d62e94b into AMReX-Codes:development Sep 22, 2025
90 of 93 checks passed
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.

2 participants