Fitting a timing model
The loop timing model predicts cycles = latency + ii·(m − 1) from two
parameters. This page recovers those parameters from measurement — the direct method: run the
kernel at a range of sizes, record the cycles, and fit. (Reusable infra components use the
residual fit instead; this simple case comes first.)
The sweep
The datapoints are a sweep: the kernel run at several input sizes n, each yielding one measured
(n, cycles) row. Those rows are the corpus — a CalibDataFrame, one row per
measurement:
from waveflow.calib.calib import CalibDataFrame
corpus = CalibDataFrame()
for n in (64, 128, 256, 512):
cycles = measure(n) # one cosim/RTL run at size n (see below)
corpus.add_datapoint({"n": n, "cycles": cycles})
The fit
The loop model is linear in latency and ii — with the basis map [1, m − 1] (m = ceil(n / U)),
the two coefficients are the parameters (see Timing models for loops).
Fitting is one call:
import math
from waveflow.calib.calib import LinCalibModel
tm = LinCalibModel(
basis=["const", "trip"], target="cycles",
coeff_names=["latency", "ii"], fit_intercept=False,
transform=lambda r: [1.0, math.ceil(r["n"] / U) - 1],
)
tm.fit(corpus)
print(tm.coeffs) # {"latency": …, "ii": …} — recovered from the sweep
Two points suffice in principle (two unknowns); use more and a least-squares fit averages out measurement noise. Then check the model generalizes rather than merely interpolates — hold a size out and measure the error on it:
report = tm.holdout_report(train=corpus_wo_512, test=corpus_512) # R² + held-out rel error
Recovering unroll_factor
unroll_factor (U) is not a fitted coefficient — it reshapes the basis through m = ceil(n / U).
Two ways to pin it down:
- Known from synthesis — you set the unroll pragma, so plug
Uin and fit onlylatency,ii. - Swept — fit for each candidate
U, pick the best R². The throughput asymptote also reveals it: at largen,cycles / n → ii / U.
Where the data comes from
The (n, cycles) points are ground truth, and the faithful source is a Vitis HLS cosim sweep:
synthesize the kernel, run cosim at each size, and read the cycle count. That is a cycle-timed
measurement (LT vs CT) used to calibrate the loosely-timed model so the
fast LT sim predicts the slow RTL. See cosim timing for extracting the
counts.
The line-fit here uses a LinCalibModel; for a smooth, saturating curve that no line
captures, an InterpCalibModel is a calibrated lookup instead (see
the worked example).
See also
- Timing models for loops — the
latency + ii·(m − 1)model this fits. - Models / The corpus —
CalibDataFrame— theLinCalibModeland corpus this uses. - A worked example — the primitive fit mechanics (score, holdout,
InterpCalibModel). - Component residuals — the residual fitting method, for reusable infra.
- Timing Analysis Tools — cosim timing — the measurement side of the fit.