AMReX-Astro / AMReX-Astro/Castro

`plotFileOutput` uses inconsistent derive filtering and can overrun `plotMF` components

Open Beginner friendly
#3,241 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ai-code-audit bug :bug: particles
Dominant language
C++
Stars
340
Forks
105
Avg merge
3d 8h
Merged PRs (30d)
8

Description

Summary

Castro::plotFileOutput excludes particle-derived fields (particle_count, total_particle_count) from num_derive when TracerPC is null, but later copies derived data using a different filter that does not apply that exclusion. This can copy extra components beyond the allocated plotMF size.

Location

  • Source/driver/Castro_io.cpp:972
  • Source/driver/Castro_io.cpp:995
  • Source/driver/Castro_io.cpp:1182
  • Source/driver/Castro_io.cpp:1186

Problem Details

First pass (num_derive) applies a particles-specific guard:

if (dd.name() == "particle_count" || dd.name() == "total_particle_count") {
    if (Castro::theTracerPC()) {
        num_derive += dd.numDerive();
    }
}

But second pass (copy into plotMF) does not:

if (isDerivePlotVar...) {
    auto derive_dat = derive(...);
    MultiFab::Copy(plotMF, *derive_dat, 0, cnt, dd.numDerive(), nGrow);
    cnt += dd.numDerive();
}

So cnt can exceed n_data_items and write past the intended component range.

Impact

  • Potential out-of-bounds component copy into plotMF.
  • Plotfile corruption or runtime failure when particle derived fields are requested without an active tracer container.

Suggested Patch

Apply the same particle guard in the copy loop:

diff --git a/Source/driver/Castro_io.cpp b/Source/driver/Castro_io.cpp
--- a/Source/driver/Castro_io.cpp
+++ b/Source/driver/Castro_io.cpp
@@
         for (const auto & dd : dlist) {

             if ((parent->isDerivePlotVar(dd.name()) && is_small == 0) ||
                 (parent->isDeriveSmallPlotVar(dd.name()) && is_small == 1)) {
+#ifdef AMREX_PARTICLES
+                if ((dd.name() == "particle_count" || dd.name() == "total_particle_count") &&
+                    !Castro::theTracerPC()) {
+                    continue;
+                }
+#endif

                 auto derive_dat = derive(dd.variableName(0), cur_time, nGrow);
                 MultiFab::Copy(plotMF, *derive_dat, 0, cnt, dd.numDerive(), nGrow);
                 cnt = cnt + dd.numDerive();
             }
         }

Prepared by Codex

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in Source/driver/Castro_io.cpp at lines 972, 995, 1182, and 1186. Compare the particle-derived-field filtering used for num_derive with the later copy loop into plotMF, including the AMREX_PARTICLES guard. Done means both passes apply the same filtering so cnt cannot exceed the allocated component range.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
hpc
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.