Skip to content

A lockstep batch observes every member's field at every plane, even when the scan keeps none #299

Open

Description

@jtravs

What happens

At each saved plane _save calls runner.observe_members(), which drains each member's full observation. The lone-run protocol can do better: observe(field=False) is in the backend protocol, and a batch has no such route. So Batch with fields="none" still moves every member's field, which by reading means a copy to the host on a GPU build. SEP 22 left this out when it gave single runs the field retention.

Batch runs modal propagation only, so the fields are small next to a spatial run's, and the gain has not been measured. Read, not run.

To do

  • Time observe_members() against the step on a native GPU Batch(8), to see whether there is anything to gain, and stop here if it is under 5 % of a plane interval.
  • If there is: add a field-free member observation to the batch protocol, on numpy_ref and native, and use it where the retention keeps no field of that plane. The statistics that need a field still get one.

Must not change: a member's stored output against the same point run alone, to rounding.

Done when

The measurement is recorded here with machine and shape, and either the change lands with a test that a fields="none" batch takes no field copy, or this issue closes on the number.


Checked against commit 8a9f764. Takes over the second half of the roadmap's entry "Runner reuse and field-free members in scans."

Activity

  1. added
    performanceSlower or larger than it should be, with no wrong result
    area: scansScans, batches and their queues
    on Nov 1, 2026
  2. jtravs commented on Nov 5, 2026

    @jtravs
    ContributorAuthor

    Measured and fixed in #520. On an NVIDIA H200 (CUDA 13.1), Batch(8) of a fibre on native, 8 steps a plane, one process, at 8cd170e2:

    n_omega Plane interval, field Observation, field Plane interval, no field Observation, no field
    768 23.0 ms 5.2 ms, 23 % 17.8 ms 0.24 ms, 1.3 %
    8,192 28.5 ms 6.6 ms, 23 % 19.3 ms 0.23 ms, 1.2 %
    32,768 27.1 ms 6.1 ms, 22 % 21.3 ms 0.23 ms, 1.1 %

    The share was also 13 to 16 % on an AMD Instinct MI325X, and 1 to 4 % on CPU, which is why the gain is a device's. The saving falls as planes get further apart, and the statistics at each plane, 0.8 to 2.1 ms, are unchanged.

    BatchBackend.observe_members now takes field=, as observe does, and a Batch scan asks for a field only at a plane the scan reads, by the rule a lone point of that scan keeps. Native's own byte count says no member's field crossed, and a scan's stored points match the same points run alone, in tests/driver/test_scan_batch.py and tests/backends/test_batch_lockstep.py. #520 will close this.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: scansScans, batches and their queuesperformanceSlower or larger than it should be, with no wrong resultpriority: lowWorth doing, no hurry

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions