← back

api_specialize

One module with an interface, n conforming impl structs, and a generic computeMain<T : IOp>. The driver's specialize mode compiles one variant per impl through IEntryPoint::specialize — the application pattern where one kernel is stamped out per material/config type, stressing specialization + link cost per variant.

bucket: api_overhead  ·  compile mode: api  ·  flags: (none)  ·  default N: 60

Phase composition across releases

Full sub-counter decomposition of compileInner — named leaf timers plus (self) residuals (a parent's time not covered by a named child, e.g. the autodiff transform in linkAndOptimizeIR (self)). Topmost band traces compileInner; hover a band for its phase.

Across releases

api_specialize — Across releases (median ms) api_specialize 0.63× 0.0 673 1347 25.12 25.13 25.14 25.15 25.16 25.17 25.18 25.19 25.20 25.21 25.22 25.23 25.24 26.1 26.2 26.3 26.4 26.5 26.7 26.8 26.9 26.10 26.11 26.12 26.13 26.13.1 26.14 26.14.1 26.16 26.16.1 api_specialize — apiCreateGlobalSession api_specialize — apiCreateSession api_specialize — apiLoadModule api_specialize — apiComposite api_specialize — apiSpecialize api_specialize — apiLink api_specialize — apiGetCode api_specialize — apiTotal (self) phase buckets apiCreateGlobalSession apiCreateSession apiLoadModule apiFindEntryPoint apiComposite apiSpecialize apiLink apiGetCode apiReflection apiTotal (self)

Daily tip-of-tree (last 30 days)

api_specialize — Daily tip-of-tree (last 30 days) (median ms) api_specialize 0.95× 0.0 135 270 07-30 07-31 08-01 08-02 08-03 08-04 08-05 08-06 08-07 08-08 08-09 08-10 08-11 08-12 08-13 08-14 08-15 08-15 08-18 08-19 08-20 08-21 08-22 08-23 08-24 08-25 08-26 08-27 08-28 08-29 api_specialize — apiCreateGlobalSession api_specialize — apiCreateSession api_specialize — apiLoadModule api_specialize — apiComposite api_specialize — apiSpecialize api_specialize — apiLink api_specialize — apiGetCode api_specialize — apiTotal (self) phase buckets apiCreateGlobalSession apiCreateSession apiLoadModule apiFindEntryPoint apiComposite apiSpecialize apiLink apiGetCode apiReflection apiTotal (self)

Daily window progress

Overall apiTotal: 248.8 → 237.2 ms  -4.6%  (2026-07-30 7c58a326b → 2026-08-29 28c755b09)

Contributors — the mutually-exclusive phase buckets (named leaves + (self) residuals) that tile apiTotal; the pp column sums to the overall %. Buckets moving the total by ≥0.2% are listed, the rest fold into the remainder row. Below them, every other reported counter (nested/overlapping, e.g. serialized-module reads — own change only):

counterΔown %of total
apiGetCode-8.4 ms-6.7%-3.4pp
apiTotal (self)-2.3 ms-55.5%-0.9pp
apiLoadModule-0.7 ms-4.9%-0.3pp
(remaining 5 buckets)-0.1 ms-0.1pp

Largest day steps (≥5% of the previous day, both directions; bisect with git log <c0>..<c1> -- source/):

boundary% vs prev daycommitstop buckets (own %)
none

Reproduce

Run from the slang repo root. This regenerates the sources below and re-runs this workload's measurement; --gen-dir keeps the generated files (they go to a tempdir and are deleted otherwise).

python3 tools/compile-perf/bench.py --slangc /path/to/slangc --only api_specialize --label repro --gen-dir repro-api_specialize

Compiled Slang source

the complete compiled source (N = 60), shown in full

spec_root.slang (316 lines)

// AUTO-GENERATED by perf-suite/workloads.py - do not edit by hand.
module spec_root;

public interface IOp
{
    static float eval(float x);
}

public struct Impl_0 : IOp
{
    public static float eval(float x) { return sin(x * 1.0) + x * 0.0; }
}

public struct Impl_1 : IOp
{
    public static float eval(float x) { return sin(x * 1.01) + x * 0.1; }
}

public struct Impl_2 : IOp
{
    public static float eval(float x) { return sin(x * 1.02) + x * 0.2; }
}

public struct Impl_3 : IOp
{
    public static float eval(float x) { return sin(x * 1.03) + x * 0.3; }
}

public struct Impl_4 : IOp
{
    public static float eval(float x) { return sin(x * 1.04) + x * 0.4; }
}

public struct Impl_5 : IOp
{
    public static float eval(float x) { return sin(x * 1.05) + x * 0.5; }
}

public struct Impl_6 : IOp
{
    public static float eval(float x) { return sin(x * 1.06) + x * 0.6; }
}

public struct Impl_7 : IOp
{
    public static float eval(float x) { return sin(x * 1.07) + x * 0.7; }
}

public struct Impl_8 : IOp
{
    public static float eval(float x) { return sin(x * 1.08) + x * 0.8; }
}

public struct Impl_9 : IOp
{
    public static float eval(float x) { return sin(x * 1.09) + x * 0.9; }
}

public struct Impl_10 : IOp
{
    public static float eval(float x) { return sin(x * 1.1) + x * 1.0; }
}

public struct Impl_11 : IOp
{
    public static float eval(float x) { return sin(x * 1.11) + x * 1.1; }
}

public struct Impl_12 : IOp
{
    public static float eval(float x) { return sin(x * 1.12) + x * 1.2; }
}

public struct Impl_13 : IOp
{
    public static float eval(float x) { return sin(x * 1.13) + x * 1.3; }
}

public struct Impl_14 : IOp
{
    public static float eval(float x) { return sin(x * 1.1400000000000001) + x * 1.4; }
}

public struct Impl_15 : IOp
{
    public static float eval(float x) { return sin(x * 1.15) + x * 1.5; }
}

public struct Impl_16 : IOp
{
    public static float eval(float x) { return sin(x * 1.16) + x * 1.6; }
}

public struct Impl_17 : IOp
{
    public static float eval(float x) { return sin(x * 1.17) + x * 1.7; }
}

public struct Impl_18 : IOp
{
    public static float eval(float x) { return sin(x * 1.18) + x * 1.8; }
}

public struct Impl_19 : IOp
{
    public static float eval(float x) { return sin(x * 1.19) + x * 1.9; }
}

public struct Impl_20 : IOp
{
    public static float eval(float x) { return sin(x * 1.2) + x * 2.0; }
}

public struct Impl_21 : IOp
{
    public static float eval(float x) { return sin(x * 1.21) + x * 2.1; }
}

public struct Impl_22 : IOp
{
    public static float eval(float x) { return sin(x * 1.22) + x * 2.2; }
}

public struct Impl_23 : IOp
{
    public static float eval(float x) { return sin(x * 1.23) + x * 2.3; }
}

public struct Impl_24 : IOp
{
    public static float eval(float x) { return sin(x * 1.24) + x * 2.4; }
}

public struct Impl_25 : IOp
{
    public static float eval(float x) { return sin(x * 1.25) + x * 2.5; }
}

public struct Impl_26 : IOp
{
    public static float eval(float x) { return sin(x * 1.26) + x * 2.6; }
}

public struct Impl_27 : IOp
{
    public static float eval(float x) { return sin(x * 1.27) + x * 2.7; }
}

public struct Impl_28 : IOp
{
    public static float eval(float x) { return sin(x * 1.28) + x * 2.8; }
}

public struct Impl_29 : IOp
{
    public static float eval(float x) { return sin(x * 1.29) + x * 2.9; }
}

public struct Impl_30 : IOp
{
    public static float eval(float x) { return sin(x * 1.3) + x * 3.0; }
}

public struct Impl_31 : IOp
{
    public static float eval(float x) { return sin(x * 1.31) + x * 0.0; }
}

public struct Impl_32 : IOp
{
    public static float eval(float x) { return sin(x * 1.32) + x * 0.1; }
}

public struct Impl_33 : IOp
{
    public static float eval(float x) { return sin(x * 1.33) + x * 0.2; }
}

public struct Impl_34 : IOp
{
    public static float eval(float x) { return sin(x * 1.34) + x * 0.3; }
}

public struct Impl_35 : IOp
{
    public static float eval(float x) { return sin(x * 1.35) + x * 0.4; }
}

public struct Impl_36 : IOp
{
    public static float eval(float x) { return sin(x * 1.3599999999999999) + x * 0.5; }
}

public struct Impl_37 : IOp
{
    public static float eval(float x) { return sin(x * 1.37) + x * 0.6; }
}

public struct Impl_38 : IOp
{
    public static float eval(float x) { return sin(x * 1.38) + x * 0.7; }
}

public struct Impl_39 : IOp
{
    public static float eval(float x) { return sin(x * 1.3900000000000001) + x * 0.8; }
}

public struct Impl_40 : IOp
{
    public static float eval(float x) { return sin(x * 1.4) + x * 0.9; }
}

public struct Impl_41 : IOp
{
    public static float eval(float x) { return sin(x * 1.41) + x * 1.0; }
}

public struct Impl_42 : IOp
{
    public static float eval(float x) { return sin(x * 1.42) + x * 1.1; }
}

public struct Impl_43 : IOp
{
    public static float eval(float x) { return sin(x * 1.43) + x * 1.2; }
}

public struct Impl_44 : IOp
{
    public static float eval(float x) { return sin(x * 1.44) + x * 1.3; }
}

public struct Impl_45 : IOp
{
    public static float eval(float x) { return sin(x * 1.45) + x * 1.4; }
}

public struct Impl_46 : IOp
{
    public static float eval(float x) { return sin(x * 1.46) + x * 1.5; }
}

public struct Impl_47 : IOp
{
    public static float eval(float x) { return sin(x * 1.47) + x * 1.6; }
}

public struct Impl_48 : IOp
{
    public static float eval(float x) { return sin(x * 1.48) + x * 1.7; }
}

public struct Impl_49 : IOp
{
    public static float eval(float x) { return sin(x * 1.49) + x * 1.8; }
}

public struct Impl_50 : IOp
{
    public static float eval(float x) { return sin(x * 1.5) + x * 1.9; }
}

public struct Impl_51 : IOp
{
    public static float eval(float x) { return sin(x * 1.51) + x * 2.0; }
}

public struct Impl_52 : IOp
{
    public static float eval(float x) { return sin(x * 1.52) + x * 2.1; }
}

public struct Impl_53 : IOp
{
    public static float eval(float x) { return sin(x * 1.53) + x * 2.2; }
}

public struct Impl_54 : IOp
{
    public static float eval(float x) { return sin(x * 1.54) + x * 2.3; }
}

public struct Impl_55 : IOp
{
    public static float eval(float x) { return sin(x * 1.55) + x * 2.4; }
}

public struct Impl_56 : IOp
{
    public static float eval(float x) { return sin(x * 1.56) + x * 2.5; }
}

public struct Impl_57 : IOp
{
    public static float eval(float x) { return sin(x * 1.5699999999999998) + x * 2.6; }
}

public struct Impl_58 : IOp
{
    public static float eval(float x) { return sin(x * 1.58) + x * 2.7; }
}

public struct Impl_59 : IOp
{
    public static float eval(float x) { return sin(x * 1.5899999999999999) + x * 2.8; }
}

RWStructuredBuffer<float> outBuf;

[shader("compute")]
[numthreads(1,1,1)]
void computeMain<T : IOp>()
{
    outBuf[0] = T.eval(outBuf[0]);
}