rework documentation
Validate Operations / validate-operations (push) Failing after 3h10m55s

add plot generation scripts
adjust validation tools
add up-to-date results
This commit is contained in:
NiccoloN
2026-10-19 16:34:01 +02:00
parent 9053cc5e8b
commit 034c197260
33 changed files with 3077 additions and 1798 deletions
@@ -0,0 +1,98 @@
# Scheduling implementation notes
The [scheduling overview](scheduling.md) maps ownership and summarizes costs/complexity.
Normative graph, pipeline, synchronization, and target contracts are linked
there; the details below describe current implementation choices.
## Publication, order, and local materialization
[`materializeScheduledCompute`](../../src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/ScheduledComputeMaterialization.cpp) records
graph IDs for publication identity, not execution order. Class lanes retain
graph encounter order independently of physical core IDs, preserving regular
source-lane mappings. Within each core, instances sort by verified scheduler
slots. Only consecutive compatible instances form homogeneous runs; class-lane
ordering must not reorder a core's work.
`insertLocalFragment` replaces a complete singleton insertion with a leading
unit-dimension reshape view only when:
- source and destination have static shapes;
- destination rank is source rank + 1, with leading dimension 1 and remaining
dimensions exactly equal to the source shape;
- element type and encoding match;
- offset/size/stride lists all match destination rank; and
- every offset is statically zero, every size is the full corresponding
destination dimension, and every stride is statically one.
This includes scalar sources. Other insertions retain `tensor.insert_slice`
semantics rather than being converted into views.
Receive forwarding belongs to
[`PimBufferizationPass.cpp`](../../src/PIM/Dialect/Pim/Passes/Transforms/Bufferization/PimBufferizationPass.cpp),
after copy lowering and contiguity normalization. It requires a private
allocation and single-use receive/copy chain in the same block, zero source and
receive offsets, and equal sizes. The receive can sink to the copy target past
memory-effect-free operations and `memref.load` (including lane lookup loads).
Writes, synchronization, and other effectful operations are barriers. Forwarding
does not establish synchronization policy.
## Transfer accounting and transpose costs
[`ComputeGraph.cpp`](../../src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/ComputeGraph.cpp) uses the same cached publication map for
dependency extraction and projected transfer volume. Physical slots map back
to graph lanes; graph-range overlap is not a byte estimate. Blueprint edges
belong to this shared graph for both scheduling strategies.
Exact projections charge selected physical fragments individually, including
each fragment's byte, endpoint-memory, and packet rounding. Conservative batch
dependencies charge a producer chunk as one aggregate: scale element count by
chunk lanes, multiply by effective bitwidth, then round to bytes once before
memory-access/flit rounding. Dividing an already rounded whole-result byte
count would lose sub-byte payloads. These two granularities are deliberate.
Spatial can analyze sub-byte storage; PIM communication lowering requires
byte-sized elements. Blueprint assembly charges per fragment. A full fragment
receive directly into assembly storage omits duplicate endpoint-memory edge
cost; later copy elimination can leave this estimate conservative.
Execution transpose costs share `getTransposeRun` with lowering: round memory
reads/writes per run and add vector execution when source stride is not one.
The [Pimsim vector unit](../../backend-simulators/pim/pimsim-nn/src/core/component/VectorUnit.cpp)
charges vector payload bytes, not the full strided address footprint. The
compiler model follows that accounting; instruction setup/issue and contention
remain approximations, not extra inferred memory traffic.
## Priorities, placement, and recovery limits
[`PipelineScheduling.cpp`](../../src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PipelineScheduling.cpp) caches a per-template
adjustment between physical execution cost and nominal volume priority, scaling
it by chunk lanes. Partitioning and packing use the nominal priorities;
transposes count as bulk moves there. PEFT, final schedule evaluation, and
reported per-core demand use physical estimates. These quantities must not be
substituted for one another when interpreting results.
Placement compares maximum per-core serial compute plus incident same-stage
transfer demand, then completion/span and compute load. Each participating core
is charged incident transfer demand as a placement proxy; those charges are not
summed twice into elapsed time. Within 1% demand difference, span breaks the tie.
Ordered packing plus dependency-tail priority biases cuts away from long
dependent groups; it is not a throughput prediction. Measured simulator periods
remain authoritative, including when a proxy improves.
Core budgets come from stage allocation and bounded capacity recovery. Failed
packing budgets are not lower bounds. [PEFT reservations](../../src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/PeftScheduler.cpp)
prefer weight reuse when distinct weights exceed half the fleet's one-copy
resident capacity; otherwise they favor communication/load. The reuse-first
constructor supplies feasibility recovery without replacing a successful
reservation, and can concentrate work. No exact combinatorial solver proves
infeasibility after heuristic failure.
[`ResidentWeightPacking.hpp`](../../src/PIM/Dialect/Spatial/Passes/Transforms/MergeComputeNodes/Scheduling/ResidentWeightPacking.hpp) adds at most 17
constructions after initial failure: one reverse traversal, then up to 16
single-choice replays sharing 65,536 candidate checks. Scratch buffers are reused;
an extra `O(T)` failed-assignment snapshot is created only after both initial
orders fail. Weight indexing still has `O(R W)` worst-case equality work; partition
DP and latency insertion-gap searches remain superlinear as listed in the
scheduling overview. Cached PEFT center distances avoid a topology scan per task/candidate;
projection and priority analyses share/cache work rather than revisiting every
template body per chunk. Ready-transfer signature searches remain another
potential compile-time hotspot.