Skip to content

VTK algorithms of the temporal filters, in situ and driving - #342

Merged
berkgeveci merged 3 commits into
Kitware:mainfrom
berkgeveci:vis/vtk-algorithms-temporal
Nov 5, 2026
Merged

berkgeveci merged 3 commits into
Kitware:mainfrom
berkgeveci:vis/vtk-algorithms-temporal

Conversation

@berkgeveci

Copy link
Copy Markdown
Collaborator

Stacked on #341 (and #340, #301; their commits show here until they merge; this merges after them). The seventh step of the VTK algorithms plan (#303), to berk's design.

RunningStatistics, TimeDerivative, Advection, Pathlines, Streaklines as VTK algorithms, each in two modes, the Tack filter (tack.dataset.temporal) the same in both; only who advances time differs (_Temporal).

  • In situ (the filter cannot drive the pipeline): each execution takes the step its input holds and gives the output at that step, stamped with its time: the statistics or paths up to it, the particles at it, the streaklines or the derivative at it. An execution at the time of the step taken last gives the kept output, without taking the step twice. A step back in time, a parameter changed, or VTK's NO_PRIOR_TEMPORAL_ACCESS set to reset starts over.
  • Driving: the filter asks its input for the steps it needs, one per pass (CONTINUE_EXECUTING), never one it has taken since it last started over.
    • RunningStatistics, Advection, Pathlines take every step (or those in time_range) and give one output after the last, with no time, reporting no time steps downstream; time is in the data (time on the paths' points; for Advection the particles at every step in one cloud, with step and time).
    • Streaklines and TimeDerivative give their answer at the time requested, stamped with it, going on from the steps taken (a derivative takes only the requested step where it holds the one before); a request before them starts over, the only case that asks for a step again.
  • The mode: in situ where the input carries NO_PRIOR_TEMPORAL_ACCESS (as an in situ adaptor sets it), else driving where the input has time steps; mode= chooses.
  • Seeds are seeds= or the points of the data on port 1; a partitioned dataset's pieces each keep their state; trees and AMR hierarchies are refused.

Fixed in tack.dataset.temporal: Advection (and so Pathlines, Streaklines) over pieces on MPI ranks waited forever where a rank had no particles, released particles at other steps, or saw its particles stop at another substep: the probes over pieces are collective, and such a rank skipped them. Every rank now takes part in each (_velocities, _release, the substep loop).

Tested:

  • A source that records each time it is asked for: every step once when driving, the steps after when a later time is requested, none for the same time, a restart for an earlier one or a changed parameter.
  • Driving to step N against N steps in situ, bit for bit: statistics, pathlines, advection's every-step cloud, streaklines and derivatives; the statistics against NumPy, the derivative against the backward difference.
  • In situ: the same step not taken twice, going back and a changed parameter starting over, NO_PRIOR_TEMPORAL_ACCESS (continue and reset), mode=.
  • 3 MPI ranks: pathlines in situ over slabs with the seeds on rank 0, particles crossing ranks, against the whole (world given, and from VTK's controller on a local master build). Tack's own MPI advection case now also has every seed on rank 0, a particle leaving the mesh and a release on the last rank alone (2 and 3 ranks).

VTK, AMR and temporal tests: 367 passed on the 9.7.1 wheel, 383 on a local VTK master; MPI tests passed; quick tier 3055 passed; lint and the guide's example (driving vtkTimeSourceExample, and in situ) clean.

🤖 Generated with Claude Code

…per, no observer

The cache of Tack datasets per VTK dataset kept entries by address and dropped
them from a DeleteEvent observer, which needed a registry to keep the observers
reachable (VTK bugs 19: the collector cleared one as garbage, then the deletion
called it) and deferred drops. The entry is now an attribute of the dataset's
Python wrapper: VTK keeps a wrapper's attributes while its C++ object lives, on
every later wrapper of it (GetInputData's in the next filter), and frees them with
the object, so an entry lives exactly as long as its dataset with no observer.

Measured (yavin, the wheel and a VTK master build): on master a wrapper costs
0.6 us however many objects keep attributes (10,000), and Contour over 1,000 and
5,000 boxes runs as fast with the attribute as with the observer (951 against 943
ms, 4,803 against 4,817); VTK 9.7.1 sweeps kept attributes at every wrapper (50 us
with 10,000), which it does for the attributes the pythonic API gives every wrapper
anyway, and the two caches cost the same there too.

An entry is stale when the dataset's modification time or time step differs from
when it was cached, as before. The comment says what that sees: Modified() (an
array's, the points'), arrays added or removed; not values written in place without
it, nor InsertNextCell, which VTK's own pipeline would not run again for either.
Tests: the entry outlives the wrapper and goes with the dataset, goes in the
collector's cycle (the crash's case), and is stale after Modified() or a new time
step but not after a write without it.
…by box

A vtkOverlappingAMR is one Tack AMRDataSet. Probe (as its source), Statistics,
Entropy, Integrate, Voxelize, GhostCells and the new AverageDown take it whole,
declaring vtkOverlappingAMR as an input type; every other wrapper runs box by
box, each level's boxes as pieces with the covered cells left out, a field
filter giving the hierarchy back and one that makes a dataset a partitioned
collection per level. GenerateGlobalIds, Streamlines and Advect refuse one.
Before, a hierarchy (a vtkPartitionedDataSetCollection subclass) went down the
tree path into an empty output with no error.

A hierarchy's conversion is kept on its metadata, which shallow copies share,
keyed by its blocks' arrays, so GhostCells' grown hierarchy reaches the next
filter. vtk_to_dataset takes world= for a hierarchy spread over MPI ranks.
RunningStatistics, TimeDerivative, Advection, Pathlines and Streaklines as VTK
algorithms, in two modes. In situ, each execution takes the step the input
holds and gives the output at it; the same step is not taken twice, and a step
back, a parameter changed or NO_PRIOR_TEMPORAL_ACCESS's reset starts over.
Driving, the filter asks for the steps it needs, one per pass and none it has
taken: statistics, particles and paths over every step in one output with no
time (time in the data), streaklines and derivatives at the time requested,
going on from the steps taken. A filter drives where its input has time steps
and the pipeline can go back in time; mode= chooses.

Advection over pieces on MPI ranks waited forever where a rank had no
particles, released at other steps or stopped at another substep: its probes
are collective, and every rank now takes part in each.
@berkgeveci
berkgeveci merged commit 7d29f9b into Kitware:main Nov 5, 2026
31 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.

1 participant