Place a workload graph rather than a peak operation count
Compare heterogeneous placements using dependencies, transfer edges, memory feasibility, and resource contention.
On this page
The question for today
What you’ll understand
- Represent computation and transfers as a placement-dependent DAG.
- Compute a serial offload example with explicit byte units.
- Distinguish dependency lower bounds from a resource-feasible schedule.
An accelerator runs a dense kernel six times faster than a CPU, yet the complete request improves far less after offload. The request also decodes input, transfers tensors, synchronizes, and formats output. Heterogeneous placement is a decision about that whole dependency graph. Begin with a workload definition and candidate mappings, then ask which tensors cross device boundaries and when each resource becomes available. A fast arithmetic unit cannot eliminate a dependency or transfer that the selected mapping creates. Every performance number in the exercises below is fictional and intended only to expose these accounting choices.
Attach costs to vertices and crossing edges
Represent each operation or fused region as a vertex and each produced tensor as a directed edge. A placement assigns vertices to hardware resources; a crossing edge adds data movement, conversion, and synchronization as needed. The same-device case may avoid an interconnect transfer while still paying local memory traffic already included in its execution estimate. Keep units and data representations explicit: an activation in FP32 has different byte volume from its quantized counterpart, and layout conversion can require another kernel.
Estimate operation costs at the actual tensor shape, precision, batch, and compiler configuration. Peak arithmetic throughput is only a ceiling for a compatible operation mix. Small kernels may be dominated by launch costs; irregular kernels may fail to expose enough parallelism. Profile representative regions or use a calibrated model with uncertainty. An operation placement that looks fastest in isolation can also increase its neighbors’ transfer volumes, so optimize graph boundaries rather than selecting the locally fastest device independently for each vertex.
Add capacity and concurrency constraints
A mapping must fit weights, live activations, scratch buffers, and transfers in each memory tier. Tensor lifetimes matter because producer and consumer overlap can keep multiple versions resident at once. A placement that exceeds capacity may require tiling, spilling, or a different batch size, each changing execution and transfer costs. Account for replicated constants and temporary conversion buffers rather than checking only the final model-file size against advertised memory capacity.
Two independent vertices cannot necessarily run simultaneously merely because the DAG permits it. They may share a GPU, a CPU worker, a memory controller, or one link. Model those resources and produce an actual schedule, or label the result as a lower bound. Pipeline overlap can improve throughput while leaving single-request latency larger. State which metric is being optimized and include any admission queue when the target is a loaded service rather than an isolated request.
Search mappings and validate the winning explanation
Search can use measured candidates, dynamic programming for restricted graphs, or broader optimization. Systems such as Alpa demonstrate that inter-operator boundaries and intra-operator partitioning interact; their design is evidence for structured search, not a guarantee that one cost model predicts every heterogeneous machine. Prune infeasible mappings early, and retain the assumed costs with each chosen plan. A winning plan is difficult to debug if the compiler discards the explanation for why its crossing edges were expected to be cheap.
Validate end-to-end latency, sustained throughput, memory high-water marks, and output quality on the final mapping. Compare against an optimized baseline using the same request population and precision. When an estimate misses, identify whether a transfer, launch, conversion, or contention term changed instead of multiplying the whole model by a convenient correction factor. Report sensitivity to batch and working-set size so a plan selected for a large batch is not presented as universally best for interactive requests.
Work it through
An offload wins after paying its edges
A fictional serial request has CPU preprocessing 4 ms, dense compute 12 ms, and postprocessing 3 ms. Offloading only dense compute reduces it to 2 ms. Input transfer is 6 decimal MB and output transfer 1.5 MB over an effective 3 GB/s link; each transfer adds 0.2 ms fixed latency. Assume no overlap or other overhead.
The all-CPU request takes 4+12+3=19 ms. This is the comparison baseline for the same request and output contract.
Input movement takes 6×10⁶/(3×10⁹)=2 ms plus 0.2 ms, or 2.2 ms. Output movement takes 0.5 ms plus 0.2 ms, or 0.7 ms.
The offloaded request takes 4+2.2+2+0.7+3=11.9 ms. End-to-end speedup is 19/11.9≈1.60, substantially smaller than the isolated dense-kernel factor 12/2=6.
The offload helps in this deliberately serial cost model, but the graph edges consume much of the kernel saving. The exercise predicts no real hardware result.
The living notebook
Explore the model
Interactive lab · roofline
A compatible arithmetic ceiling is only one placement term
Reset, set Operational intensity I to 4 and Memory bandwidth B to 100. Predict synthetic ceiling min(1000,4×100)=400 GFLOP/s before Step. Reset, explicitly set I=16 and B=100, then Step: predict the fixed 1000 GFLOP/s compute ceiling. Playback traces the roof without changing these parameters. This hypothetical bound does not schedule a heterogeneous DAG, measure hardware, or account for inter-device transfers.
- Attainable ceiling
- 640 GFLOP/s
- Ridge intensity
- 12.5 FLOP/byte
- Ceiling regime
- Memory-bound ceiling
Synthetic roofline ceiling min(1000, B·I), in GFLOP/s, with B in decimal GB/s and I in FLOP/byte. Playback traces the roof without changing the selected kernel. This upper-bound model is not a measured throughput prediction, hardware comparison or price model. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forA per-kernel ceiling cannot replace complete placement and transfer accounting.
Pause & reason
Check your understanding
Your turn
Try it yourself
Keep the CPU stage times 4,12,3 ms and accelerated dense compute 2 ms, but let each crossing transfer cost 8 ms total. Compute offloaded latency and compare it with the 19 ms all-CPU baseline.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Pay both graph-boundary transfers even though the accelerated compute itself is fast.
Compare with the solution
Offloaded latency is 4+8+2+8+3=25 ms. The speedup ratio is 19/25=0.76, so this mapping is slower than the CPU baseline. Keeping more adjacent work on one device or reducing crossing bytes might change the result, but that requires a new explicit cost calculation.
Keep the idea
Take it with you
- Place operations and their data edges together.
- Distinguish dependency lower bounds from resource-feasible schedules.
- Validate end-to-end effects at the intended shape, precision, and load.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.