# SPDX-License-Identifier: Apache-2.0 """Build-time knobs of the sceneseg-p150 graph (``ttaw.knobs``): each is read once when the graph is built and has a ``SCENESEG_`` environment switch for A/B runs; the defaults are the published configuration and are pinned in ``tt-model.yaml serve.env``.""" from __future__ import annotations from ..ttaw.knobs import Knob, Knobs __all__ = ["KNOBS"] KNOBS = Knobs("SCENESEG", [ Knob("WEIGHT_TERMS", 2, "every conv, transposed conv and linear runs its weights as two bf16 terms (hi + lo, ~16 significant bits), " "one bias-free conv per product, summed in fp32; the bias is added afterwards as an fp32 row, never fused " "(C17 weight_terms; PLAN.md 9.3 precision policy: plain bf16 weights failed the CenterPoint / BEVDet / YOLOX " "gates; fix round 1: a fused bias truncates toward zero). 1 = plain bf16 weights (biases still fp32): " "21.6 ms less per replay, A/B only (OPT_BASELINE.md)", choices=(1, 2)), Knob("ACT_TERMS", 2, "the backbone (stem, 16 MBConv blocks incl. SE) keeps its activations in float32 and feeds each conv / linear " "two bf16 terms of them (hi + lo, ~16 significant bits; fix round 1: bf16 activation rounding in the backbone " "decided the held-out frames that missed argmax agreement 0.995); the decoder and SceneContext stay bf16. " "1 = bf16 backbone activations (as the first port), A/B only", choices=(1, 2)), Knob("EPI", True, "conv / linear epilogue (OPT_PLAN EPI): the fp32 term sum, the fp32 bias row, the fp32 activation and the " "cast of every layer as ONE generic_op (tt/epi.py, the stock LLKs in the stock order: bit-identical) instead " "of up to four stock programs (OPT_REPORT R1.3: b2b 60.93 -> 49.55 ms); 0 = the stock ttnn.add / activation / " "typecast sequence"), Knob("TERM_STACK", "exact", "ST2 (needs EPI): a two-term conv / transposed conv (groups 1, Cout % 32 == 0) runs as ONE conv over " "[W_hi ; W_lo] stacked on the output channels, its fp32 halves read by the EPI kernel as the two products " "(one input read / halo / slice sequence instead of two). exact = every such layer except the 7 whose " "stacked form is not bit-identical (tt/model.py ST2_INEXACT, st2_probe.py); all = every such layer (not " "bit-identical; OPT_REPORT R1.4: exact 44.82 ms, all 46.66, off 49.55 b2b); off = one conv per weight term", choices=("off", "exact", "all")), Knob("DW_KERNEL", True, "K11 (OPT_PLAN K11): the 16 backbone depthwise convs (groups=C) + bias + SiLU as ONE generic_op each " "(tt/dw.py: float32 input and weights, one SFPMAD per tap, the stock fp32 bias add and silu_tile) on the " "float32 backbone map, instead of the dense groups=C conv per term product after the hi / lo activation split " "plus EPI. More precise than the stock form (probe dw_probe.py: max rel. error 1e-7 vs 1e-3), not " "bit-identical: gated (OPT_REPORT round 2). Needs ACT_TERMS=2 (a float32 backbone); 0 = the stock path"), Knob("DW_STAGE", True, "K11 stride-2 band load (OPT_REPORT R2.2): each input row is read as whole 16-pixel face runs into a staging " "row and scattered to the column-parity planes by local copies; 0 = one 64 B DRAM read per pixel and channel " "half (R2.1 form: latency-bound, 1.06 ms for the 160x320x96 layer). Bit-identical"), Knob("DW_WPACK", True, "R7.1 K11 packed weights: each depthwise weight tile carries 8 taps (rows 4l..4l+3 = tap l, all 32 channels) " "instead of one tap broadcast to 32 rows, so a channel tile's weights are ceil(k*k/8) tiles (2 / 4 instead " "of 9 / 25: 4.5-6x less DRAM weight traffic per core and channel tile) and they are unpacked to DEST once " "per output tile (twice for 5x5) instead of once per tap; the SFPU reads each tap's weight vector at its " "DEST row group. Same SFPMAD operands and order: bit-identical; 0 = one weight tile per tap"), Knob("EPI_SPLIT", True, "EPI-split (OPT_REPORT R2.3, needs EPI and ACT_TERMS=2): the MBConv project conv's epilogue also adds the " "residual and writes the next conv's bf16 (hi, lo) activation terms, and the SE gate multiply is fused with " "the split of the project conv's input (one generic_op instead of multiply + typecast / typecast / subtract " "/ typecast); the stage outputs' hi term is the decoder's bf16 cast. Bit-identical; 0 = the stock ops"), Knob("CLASS_KERNEL", True, "K8 (OPT_REPORT R2.4, needs EPI): the served class map decided in the class-margin conv's epilogue (the EPI " "writer runs ttnn.argmax's SFPU compare semantics on the three margins) and written as uint8 [1, 320, 640] " "(200 KB) instead of fp32 margins + transpose + reshape + argmax + untilize (uint32, 800 KB). Bit-identical " "class map; the debug variant (margins / logits) keeps the stock path; 0 = the stock path"), Knob("CONV_L1", 3200, "L1P (OPT_REPORT R2.5): decoder / SceneContext kxk convs whose input map has at most this many pixels " "(3200 = the 10x20, 20x40 and 40x80 maps) run ttnn's L1 path (Conv2dL1FullSliceConfig: the whole input moved " "to L1) instead of the automatic DRAM slicing (its PaddedSlice / SliceWrite / ReshapeView programs); 12800 " "(80x160) overflows L1 (2.6 MB of CBs per core); 0 = never"), Knob("SUBPIXEL", "01234", "S1 (OPT_PLAN rank 1): the decoder up-blocks listed (digits 0-4: neck 0-2, head 3-4; 'all' / 'off') run " "the sub-pixel form (tt/subpixel.py): ConvT k2 s2 + 1x1 skip + the first 3x3 + GELU as a 2x2 phase conv on " "the low-res map, the composed skip 3x3 and ONE generic_op epilogue (depth-to-space gather, skip terms, " "border-aware bias, GELU). Exact in real arithmetic, rounds differently (no bf16 rounding of the up-block " "sum): gated. Needs EPI and WEIGHT_TERMS=2"), Knob("SUBPIXEL_Z", "ssspr", "S1 Z-conv form per decoder block (5 letters): s = one 2x2 conv over all 8 Cout stacked phase outputs, " "e = one 2x2 conv per weight term (4 Cout each), p = one 2x2 conv per phase (2 Cout each); t / r / q = the " "same as 3x3 convs on the H x W grid (each phase's taps placed in a 3x3 kernel: 2.25x MACs, but ttnn's " "3x3 path is faster on the 160x320 map); the fastest per block in s1_zsweep*.log"), Knob("DEC_W1", "1,3,5,7,9,10", "P2 decoder precision map (OPT_REPORT round 4, gated): the decoder 3x3 convs decode_layer_ listed (comma " "separated n; the second 3x3 of each block is 1, 3, 5, 7, 9; 10 = the class-margin conv and the debug logit " "conv) run ONE bf16 weight " "term instead of two (hi + lo): half the conv MACs and half the fp32 conv output the epilogue reads. The " "decoder activations are bf16 already; the products still accumulate in fp32 and the bias stays an unfused " "fp32 row. Chosen on a tuning set disjoint from the gated frames (OPT_REPORT R4.1); '' = every layer two " "terms"), Knob("S1_W1", "bbbbb", "P2 for the S1 blocks (round 4, gated): one letter per decoder block 0-4, '-' = two weight terms, 'z' = the " "Z conv with ONE bf16 weight term (the composed G rounded once; the S1 epilogue adds no lo product), 's' = " "the composed skip conv with one term, 'b' = both (OPT_REPORT R4.2). Needs SUBPIXEL for that block"), Knob("W1_EXTRA", "ctx", "P2 beyond the decoder (OPT_REPORT R4.3 / R4.5, gated): comma separated groups that run ONE bf16 weight " "term: expand (the MBConv expand 1x1 convs), project (the MBConv project 1x1 convs), head (features.8 1x1), " "ctx (SceneContext linears and convs); the backbone keeps its two activation terms. Tuning set (tune2): ctx " "neutral, head no gain, project -4e-3 on the worst frame; expand -2e-4 there but -2.5e-3 on the held-out " "gate (0.998574 -> 0.996045 bgr, job3_w1x): rejected. off = none"), Knob("S1_SHARDED", "all", "R5.1 (OPT_PLAN round-4 item 2): S1 convs whose output the S1 epilogue reads straight from the conv's L1 " "shards (the reader's TensorAccessor resolves sharded pages; no ShardedToInterleaved DRAM round trip): " "skip = the composed skip convs (forced onto ttnn's L1 path), all = the skip and the L1-path Z convs; " "off = every S1 conv output moved to DRAM interleaved. Bit-identical (same values, other memory)", choices=("off", "skip", "all")), Knob("DEC_FID", "HiFi3", "R5.3 (gated): math fidelity of the decoder / SceneContext convs: '[:]', fidelity one of " "HiFi4 / HiFi3 / HiFi2 / LoFi, groups a comma list of s1 (the S1 Z / skip convs), dec (the decoder 3x3 " "convs decode_layer_*), ctx (SceneContext convs), margin (class-margin + debug logit conv); default all " "four. The decoder runs bf16 activations and (P2) one bf16 weight term; fp32 accumulation unchanged. '' = " "the model precision (HiFi4) everywhere"), Knob("EPI_BIAS_LOCAL", True, "EPI-B (OPT_REPORT R4.4): the EPI and S1 epilogue readers load only the resident bias / gate-row tiles of the " "output columns each core writes, instead of every column tile on every core (CT x 4 KB per core: up to " "17.7 MB of reads per program on the 1152-channel maps). Bit-identical; 0 = every tile on every core"), Knob("STEM_KERNEL", True, "K-IN kernel form (OPT_PLAN rank 5 / MK0, needs INPUT_LAYOUT=rows, EPI, two weight and activation terms): the " "stem conv + bias map + SiLU as ONE generic_op on the uploaded uint8 rows (tt/stem.py: bf16 im2col tiles " "built by the reader, the two weight-term products on the FPU, the EPI epilogue LLKs) instead of the bf16 " "cast, the 6-byte-stick reshape and one re-sharded conv per weight term + EPI; 0 = the stock stem"), Knob("SE_KERNEL", True, "SE-K (OPT_PLAN rank 10, needs EPI_SPLIT): each MBConv squeeze-excitation MLP (fc1 + SiLU + fc2 + sigmoid on " "the fp32 row sum) as ONE generic_op (tt/sek.py: every core computes fc1, its share of fc2; the stock " "products and epilogue LLKs, all products of a layer accumulated in one fp32 DEST tile) instead of two " "Linear layers (activation split, three GEMVs and an epilogue each); 0 = the stock path"), Knob("CONV_CFG", "dl1=db,dl3=db,dl5=h3db,z0=db,z1=db,z2=db,s0=db,s1=db,s2=db,s3=db,ctx=db", "R6: per-layer ttnn conv configuration, comma list tag=preset (tags dl = decode_layer_, z / s = " "S1 block b's Z / skip convs, mrg = class-margin conv, ctx = SceneContext convs; presets db / adb / wdb = activation and weight double " "buffers, h / w [db] = explicit DRAM slices; tt/model.py conv_presets). Default: double buffers on the L1-path decoder / SceneContext convs and decode_layer_5 as 3 " "height slices with double buffers (bit-identical, OPT_REPORT R6.2; slice_probe.py); off = ttnn's defaults"), Knob("TAIL_MK", False, "MK-T (OPT_PLAN 3.4, the D19 module megakernel; needs CLASS_KERNEL and DEC_W1 9 and 10): decode_layer_9 (3x3 " "128 -> 64 + bias + GELU) + the class-margin conv + the class decision as ONE generic_op (tt/mkt.py: per " "core 2-3 image rows, implicit-GEMM 3x3 convs from L1 column bands, the 64-channel map kept in an L1 store " "with its halo rows exchanged between neighbour cores by unicast semaphores); uint8 class map. Not " "bit-identical (in-DEST accumulation order, the bias as hi + lo bf16 terms): gated; 0 = the stock convs " "+ EPI + K8"), Knob("INPUT_LAYOUT", "rows", "uploaded squash layout (OPT_PLAN K-IN, stock form): rows = [1, 1, 320, 1920] uint8 (320 pages of 1,920 B), " "cast to bf16 then reshaped to pixel rows on the device; pixels = [1, 1, 204800, 3] (204,800 pages of 3 B: " "5.3 ms of H2D). Bit-identical", choices=("rows", "pixels")), Knob("HOST_SQUASH", "numba", "host squash (OPT_PLAN H1): numba = the compiled twin of host/fast.py (RGB in, the BGR swap folded into its " "reads, one thread), bit-identical to numpy = the vendored ttaw.image_linear oracle on a BGR copy", choices=("numba", "numpy")), Knob("HOST_SQUASH_THREADS", 4, "R6 (HOST_SQUASH=numba): the squash twin as one fused pass per output row (the two horizontal source rows " "in registers, no int32 scratch map) on this many numba threads (<= 4 of the 8 shared vCPUs); 0 = the " "round-1 two-pass kernel on one thread. Bit-identical (integer arithmetic)", choices=(0, 1, 2, 4)), Knob("LOAD_BIAS_HASH", 1, "R8 (load time only): S1 bias_patterns finds the interior bias row with a 64-bit row hash + exact check " "instead of np.unique(axis=0) (about 20 s of the graph build); a hash collision or a count tie falls back " "to np.unique, so the result is bit-identical. 0 = np.unique always", choices=(0, 1)), Knob("HOST_POST", "numba", "host post-processing (OPT_PLAN H2): numba = the compiled twin of host/fast.py (mask + class map gathered to " "the source size in one pass, 4 threads), bit-identical to numpy = host/postprocess.py's where + " "INTER_NEAREST oracle", choices=("numba", "numpy")), ])