UH-OH

It looks like you don’t have access to that feature yet

Contact sales to get upgraded to the full DevStudio experience.

UH-OH

It looks like you don't have access to that feature yet.

Introduction to the Chimera SDK
Chimera SDK Quick Start Guide
Chimera SDK Command Line Interface (CLI)
Tutorial: Using SDK as a Library
Tutorials & Model Demos
Model Demos
Model Demo: Llama-2 15M (Baby Llama-2)
Model Demo: QWEN3 8B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Prefill All Decoders
Model Demo: DeepSeek-R1-Distill-Qwen-1.5B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Single Decoder
Model Demo: Qwen2.5-0.5B INT8 Quantization Pipeline
Model Demo: ConvNeXt Detection
Model Demo: QWEN3 Prefill Decoder Validation
Model Demo: ConvNeXt Segmentation
Model Demo: Classifiers Zoo
Model Demo: Detectors Zoo - MMDetection
Model Demo: Segmentors Zoo - MMSegmentation
Model Demo: Pose Estimators Zoo - MMPose
Model Demo: Detectors3D Zoo - MMDetection3D
MODEL Demo: Optical Character Recognition (OCR) Zoo - MMOCR
Model Demo: YOLOv3 Object Detection
Model Demo: YOLOv4 Object Detection
Model Demo: YOLOv5 Detection
Model Demo: YOLOv5 Detection and Segmentation
Model Demo: YOLOR Detection
Model Demo: YOLOX End-to-End Detection
Model Demo: YOLOv7 Detection
Model Demo: YOLOv8 Detection
Model Demo: YOLOv8 Pose Estimation
Model Demo: YOLOP Detection and Segmentation
Model Demo: QAT Vision Transformer (ViT)
Model Demo: QAT Swin Transformer
Model Demo: Mediapipe Face Pipeline
Demo: DOOM Renderer on Chimera GPNPU
Model Demo: Mediapipe Hand Pipeline
Model Demo: Whisper Tiny (Encoder + Decoder)
Model Demo: L2CS Fine-Grained Gaze Estimation
Model Demo: ASVspoof2021 LA Anti-Spoofing (LFCC-LCNN-BiLSTM)
Model Demo: UNET Tumor Segmentation
Model Demo: FFNet Segmentation
Model Demo: Centernet Detection
Model Demo: RetinaNet End-to-End Detection
Model Demo: Blazepose Pose Estimation
Model Demo: Pose Resnet Human Pose Estimation
Model Demo: MaskRCNN Detection and Segmentation
Model Demo: Keypoint R-CNN
Model Demo: Faster R-CNN Detection
Model Demo: FCOS Detection
Model Demo: DDRNet Classificationls
Model Demo: PI0.5 End-to-End VLA Inference
Model Demo: BEVFormer End-to-End 3D Detection
Model Demo: SegFormer Semantic Segmentation
Model Demo: DETR Object Detection
Model Demo: VGG-16 A8W4 Quantization
Model Demo: WaveFormer sEMG Gesture Classification
Multicore Demo
Chimera LLVM C++ Compiler
Chimera SDK Licensing Policy Documentation
Glossary
Chimera Software User GuideTutorials & Model DemosModel DemosModel Demo: WaveFormer sEMG Gesture Classification

Model Demo: WaveFormer sEMG Gesture Classification


NOTE: The Jupyter Notebook below is included in the Chimera SDK and can be run interactively by running the following CLI command:

$ quadric sdk notebook

From the Jupyter Notebook window in your browser, select the notebook named /quadric/sdk-cli/examples/models/waveformer/waveformer.ipynb.


WaveFormer sEMG Gesture Classification on Chimera GPNPU

WaveFormer pipeline

End-to-end walkthrough of taking the INT8 WaveFormer encoder onto the Chimera GPNPU with the Chimera Graph Compiler (CGC), following the same shape as the other sdk-cli model notebooks:

  1. Model Setup - export + INT8-quantize (export_quant.py) / inspect the ONNX, and set up the SDK env + QC-Nano HWConfig.
  2. Prepare inputs & calibration - a real sEMG window + ORT reference, and the .tranges (compute_tensor_ranges).
  3. Compile through CGC - compile the graph (only waveAttention x6 stays a custom op; everything else - patch conv, LayerNorms, residual adds, the FFN/projection QGemms, the CLS head - compiles natively).
  4. Build the EPU binary (sdk source) - compile the CGC-generated CCL C++ + the waveAttention kernel into the EPU binary / host executable via Quadric LLVM: (4a) prepare the input, then (4b) compile + run on the ISS.
  5. Validate against ORT - decode the EPU logits and check argmax + logit closeness vs ONNX Runtime.

What WaveFormer is. An sEMG gesture classifier (EPN612: 8 channels, 6 classes, ~3.1M params) - a ViT-style encoder (6 blocks, 8 heads, head_dim 32, embed_dim 256, seq 161 = 160 patch tokens + 1 CLS, mlp_ratio=1). Input [1,1,8,1000] fp32 (8-channel x 1000-sample signal) -> output [1,6] class logits.

Target HW. QC-Nano: 8x8 PE array, 4 MB L2/OCM, 4 kB LRM, 8 MACs/PE, single core.


1. Model Setup

export_quant.py is the checkpoint -> INT8-ONNX conversion (no external download; built from the local waveformer_epn612.pth). As a process it is a 4-stage pipeline:

Stage 1 - Rebuild the trained model in PyTorch. Loads waveformer_epn612.pth into a Waveformer_base (EPN612 config), then applies two structural patches so it exports cleanly: RoPE attention is rewritten to run qkv/proj on 2D tensors (and drop a zero-width slice that breaks ORT's calibrator), and each block's MLP is wrapped so fc1/fc2 collapse into a single Gemm. Both exist so the linears export as Gemm -> QGemm.

Stage 2 - Export to fp32 ONNX. torch.onnx.export(..., opset_version=17) traces the model on a dummy [1,1,8,1000] input -> waveformer_fp32.onnx (output [1,6]); quant_pre_process then runs shape-inference / cleanup into a temporary _prep.onnx. Nothing is quantized yet.

Stage 3 - Calibrate + decide the fp32/int8 split. Feeds data/calib.npy (representative sEMG windows) through the graph via a CalibrationDataReader, collecting per-tensor min/max ranges (MinMax) that set each int8 scale. Builds a nodes_to_exclude list that keeps every /attn/ node fp32 except qkv, proj, and /attn/MatMul_1 - i.e. quantize the projections + the A.V matmul, keep Q.K + softmax + RoPE in fp32 (softmax probs in [0,1] map poorly onto symmetric int8).

Stage 4 - Quantize to INT8 ONNX. quantize_static(...) inserts the int8 kernels using the calibrated scales. Key settings: QuantFormat.QOperator (fused int8 ops - QGemm, QLinearAdd, QLinearConv - not QDQ pairs), QInt8 activations + weights, per_channel=False (per-tensor scale), ActivationSymmetric=True + WeightSymmetric=True (zero-point 0, which the Quadric matmul path requires). Writes waveformer_int8.onnx and removes the temp _prep.onnx.

Result: waveformer_epn612.pth -> waveformer_fp32.onnx (float) -> waveformer_int8.onnx (symmetric per-tensor int8, QOperator; projections + A.V quantized, Q.K / softmax / RoPE fp32) - the graph the later steps calibrate (.tranges) and compile through CGC. This step does not produce the .tranges (that is step 2); the ranges computed here are baked into the ONNX quant scales.

The cell below sets up the SDK env (imports + the QC-Nano HWConfig), then loads and inspects waveformer_int8.onnx - regenerating it via export_quant.py only if missing (needs torch/timm + the checkpoint). Run inside the Quadric SDK env (tvm.contrib.epu must be importable).

from collections import Counter
from pathlib import Path

import numpy as np
import onnx
import onnxruntime as ort

from tvm.contrib.epu.chimera_job.chimera_job import ChimeraJob
from tvm.contrib.epu.chimera_job.hw_config import HWConfig

## --- paths ---
INT8_ONNX = "waveformer_int8.onnx"
TRANGES = "waveformer_int8.tranges"
CUSTOM_OP_ONNX = "waveformer_int8_custom_op.onnx"
TEST_X = "data/test_x.npy"  # real sEMG windows [N,1,8,1000]
TEST_Y = "data/test_y.npy"  # labels

## --- WaveFormer config (fixed by the EPN612 / Waveformer_base checkpoint) ---
N_BLOCKS, NUM_HEADS, HEAD_DIM, EMBED_DIM, SEQ_LEN = 6, 8, 32, 256, 161
CLASSES = [
    "hand relax",
    "hand close",
    "wrist flexion",
    "wrist extension",
    "ulnar dev.",
    "radial dev.",
]

## --- QC-Nano hardware target---
HW = HWConfig(
    product="QC-N",
    ocm_size="4MB",
    macs_per_pe=8,
    num_cores=1,
    lrm_size="4kB",
    ext_rd_bw="8GBps",
    ext_wr_bw="8GBps",
    clock_freq_ghz=0.5,
)  # QC-Nano: 8 GB/s DDR, 500 MHz
print("HW target:", HW, "| onnxruntime", ort.__version__, "| onnx", onnx.__version__)

## --- load + inspect the committed INT8 model ---
model = onnx.load(INT8_ONNX)
g = model.graph
in_name = g.input[0].name
out_name = g.output[0].name


def _shape(v):
    return [d.dim_value for d in v.type.tensor_type.shape.dim]


ops = Counter(n.op_type for n in g.node)
print(f"model      : {INT8_ONNX}  ({len(g.node)} nodes)")
print(f"input      : {in_name}  {_shape(g.input[0])}")
print(f"output     : {out_name}  {_shape(g.output[0])}")
print(
    f"encoder    : {N_BLOCKS} blocks x (LayerNorm -> attention -> residual -> LayerNorm -> MLP -> residual)"
)
print(f"op types   : {dict(sorted(ops.items()))}")
HW target: QC-N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1 | onnxruntime 1.20.0 | onnx 1.16.2
model      : waveformer_int8.onnx  (449 nodes)
input      : input  [1, 1, 8, 1000]
output     : logits  [1, 6]
encoder    : 6 blocks x (LayerNorm -> attention -> residual -> LayerNorm -> MLP -> residual)
op types   : {'Add': 12, 'Concat': 12, 'DequantizeLinear': 39, 'Div': 7, 'Erf': 7, 'Gather': 43, 'LayerNormalization': 15, 'MatMul': 6, 'Mul': 54, 'QGemm': 25, 'QLinearAdd': 19, 'QLinearConcat': 1, 'QLinearConv': 1, 'QLinearMatMul': 6, 'QLinearMul': 14, 'QuantizeLinear': 46, 'Reshape': 61, 'Softmax': 6, 'Sub': 12, 'Transpose': 39, 'Unsqueeze': 24}

2. Prepare inputs & calibration

Two things: (a) a real sEMG window to run plus its ORT golden; (b) the per-tensor ranges (.tranges) CGC needs to assign fixed-point fractional bits.

The tranges come from 3_make_tranges.py via sdk_cli.lib.quantize.compute_tensor_ranges (the ORT MinMax calibrator over data/calib.npy) - not sdk graph quantize, whose opset down-convert dies on the opset-17 LayerNormalization. The cell regenerates them only if missing.

## --- (a) a real sEMG input window + ORT golden ---
X = np.load(TEST_X).astype(np.float32)
Y = np.load(TEST_Y) if Path(TEST_Y).exists() else None
SAMPLE = 0
x = X[SAMPLE : SAMPLE + 1]  # [1,1,8,1000]
print(f"input window : {x.shape}  dtype={x.dtype}")
if Y is not None:
    print(f"true label   : {int(Y[SAMPLE])}  ({CLASSES[int(Y[SAMPLE])]})")

sess = ort.InferenceSession(INT8_ONNX, providers=["CPUExecutionProvider"])
ort_logits = sess.run(None, {in_name: x})[0]  # [1,6]
pred = int(np.argmax(ort_logits))
print(f"ORT logits   : {np.round(ort_logits, 3).tolist()}")
print(f"ORT pred     : {pred}  ({CLASSES[pred]})")

## --- (b) tensor-range calibration (.tranges) ---
import json

print(f"[tranges] {TRANGES}: {len(json.load(open(TRANGES)))} entries")
input window : (1, 1, 8, 1000)  dtype=float32
true label   : 5  (radial dev.)
ORT logits   : [[-2.7939999103546143, -0.847000002861023, -4.317999839782715, 5.926000118255615, -4.656000137329102, 4.572000026702881]]
ORT pred     : 3  (wrist extension)
[tranges] waveformer_int8.tranges: 328 entries

3. Compile through CGC

custom_op_match.py replaces each block's head-split + RoPE + flash-attention core with a waveAttention custom op (its [1,161,3,8,32] tensors are 5-D, so the attention core stays a custom CCL kernel). Everything else compiles natively - the patch conv, all LayerNorms, both residual QLinearAdds per block, the qkv/proj/fc1/fc2 QGemms, the erf-GELU (as a qlut), and the CLS head.

The cell calls ChimeraJob(...).compile() - the same single call the other model notebooks use - which runs the CGC front/middle end + back end + Quadric LLVM build in one shot and emits the generated CCL C++ for the whole graph.

import custom_op_match

## waveAttention x6; everything else native
custom_op_match.prepare_custom_ops_graph(INT8_ONNX, CUSTOM_OP_ONNX, to_print=True)

co = Counter(n.op_type for n in onnx.load(CUSTOM_OP_ONNX).graph.node)
n_custom = sum(v for k, v in co.items() if k.startswith("QuadricCustomOp"))
native = {k: v for k, v in sorted(co.items()) if not k.startswith("QuadricCustomOp")}
print(f"custom ops      : {n_custom}  (waveAttention x{N_BLOCKS})")
print(f"native (CGC)    : {native}\n")

## compile through CGC; custom_ops = local waveformer_ops.hpp providing nn::waveAttentionOp
cgc_job = ChimeraJob(
    CUSTOM_OP_ONNX,
    hw_config=HW,
    trange_file=TRANGES,
    target_lang="ASM",
    custom_ops=custom_op_match.WAVE_ATTENTION_HEADER,
    validate_iss=False,
)
cgc_job.compile()
print(cgc_job)
[match] loading waveformer_int8.onnx
[match] 11 custom ops; CGC lowers natively: {'DequantizeLinear': 28, 'Div': 2, 'Erf': 2, 'Gather': 1, 'LayerNormalization': 15, 'QGemm': 15, 'QLinearAdd': 14, 'QLinearConcat': 1, 'QLinearConv': 1, 'QLinearMul': 4, 'QuantizeLinear': 24, 'Reshape': 15, 'Transpose': 3}
[match] wrote waveformer_int8_custom_op.onnx
custom ops      : 11  (waveAttention x6)
native (CGC)    : {'DequantizeLinear': 28, 'Div': 2, 'Erf': 2, 'Gather': 1, 'LayerNormalization': 15, 'QGemm': 15, 'QLinearAdd': 14, 'QLinearConcat': 1, 'QLinearConv': 1, 'QLinearMul': 4, 'QuantizeLinear': 24, 'Reshape': 15, 'Transpose': 3}



2026-08-20 14:34 - INFO - epu - chimera_job - START==================================onnx_ingest
2026-08-20 14:34 - INFO - epu - chimera_job - Numerical ranges provided
2026-08-20 14:34 - INFO - epu - codegen - START===============================optimize_relay
2026-08-20 14:34 - INFO - epu - codegen - START====================quantize_to_cpu_runnable_fx
2026-08-20 14:34 - INFO - epu - fx - Clamped annotated range on /blocks.1/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-14.693208694458008, 15.295390129089355) -> (-14.693208694458008, 15.295389704406261) (within tol 0.120436)
2026-08-20 14:34 - INFO - epu - fx - Clamped annotated range on /blocks.2/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-17.228588104248047, 18.862335205078125) -> (-17.228588104248047, 18.862334311008453) (within tol 0.148522)
2026-08-20 14:34 - INFO - epu - fx - Clamped annotated range on /blocks.3/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-15.205657958984375, 16.93963623046875) -> (-15.205657958984375, 16.939636066555977) (within tol 0.133383)
2026-08-20 14:34 - INFO - epu - fx - Clamped annotated range on /blocks.5/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-13.569168090820312, 14.360703468322754) -> (-13.569168090820312, 14.360703274607658) (within tol 0.113076)
2026-08-20 14:34 - INFO - epu - fx - 

Source name                                        Op                             Output 0 Range            Output 0 Frac Bits
-------------------------------------------------  -----------------------------  ----------------------  --------------------
/patch_embed/Transpose_output_0_DequantizeLinear   contrib.epu.dequantize         [-1.54369f, 1.38568f]                     30
/patch_embed/norm/LayerNormalization               nn.layer_norm                  [-4.8421f, 4.83072f]                      28
/Concat_output_0_DequantizeLinear                  contrib.epu.dequantize         [-0.189842f, 4.82199f]                    28
/blocks.0/norm1/LayerNormalization                 nn.layer_norm                  [-3.98641f, 7.42318f]                     27
/blocks.0/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-9.86747f, 10.191f]                      27
CustomOp/waveAttention0                            contrib.epu.quadric_custom_op  [-5.80482f, 7.42834f]                     16
/blocks.0/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-16.4873f, 16.6182f]                     26
/blocks.0/norm2/LayerNormalization                 nn.layer_norm                  [-4.29883f, 4.49691f]                     28
/blocks.0/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-25.4366f, 28.588f]                      26
/blocks.1/norm1/LayerNormalization                 nn.layer_norm                  [-4.55638f, 4.75343f]                     28
/blocks.1/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-14.6932f, 15.2954f]                     27
CustomOp/waveAttention1                            contrib.epu.quadric_custom_op  [-6.26072f, 5.9012f]                      16
/blocks.1/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-35.7952f, 31.2498f]                     25
/blocks.1/norm2/LayerNormalization                 nn.layer_norm                  [-5.17243f, 4.5562f]                      28
/blocks.1/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-43.3882f, 40.2891f]                     25
/blocks.2/norm1/LayerNormalization                 nn.layer_norm                  [-5.59709f, 4.7339f]                      28
/blocks.2/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-17.2286f, 18.8623f]                     26
CustomOp/waveAttention2                            contrib.epu.quadric_custom_op  [-7.09626f, 6.56859f]                     16
/blocks.2/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-49.343f, 44.2922f]                      25
/blocks.2/norm2/LayerNormalization                 nn.layer_norm                  [-5.38715f, 4.78134f]                     28
/blocks.2/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-50.7397f, 47.1155f]                     25
/blocks.3/norm1/LayerNormalization                 nn.layer_norm                  [-5.57496f, 5.23384f]                     28
/blocks.3/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-15.2057f, 16.9396f]                     26
CustomOp/waveAttention3                            contrib.epu.quadric_custom_op  [-6.79083f, 6.45284f]                     16
/blocks.3/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-51.7598f, 49.6894f]                     25
/blocks.3/norm2/LayerNormalization                 nn.layer_norm                  [-5.60962f, 5.0564f]                      28
/blocks.3/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-51.7394f, 49.6698f]                     25
/blocks.4/norm1/LayerNormalization                 nn.layer_norm                  [-5.45329f, 4.92244f]                     28
/blocks.4/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-14.9916f, 14.5194f]                     27
CustomOp/waveAttention4                            contrib.epu.quadric_custom_op  [-10.1218f, 10.8138f]                     16
/blocks.4/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-55.8718f, 54.9849f]                     25
/blocks.4/norm2/LayerNormalization                 nn.layer_norm                  [-5.38267f, 5.16993f]                     28
/blocks.4/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-54.7764f, 54.3417f]                     25
/blocks.5/norm1/LayerNormalization                 nn.layer_norm                  [-5.79005f, 5.02069f]                     28
/blocks.5/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-13.5692f, 14.3607f]                     27
CustomOp/waveAttention5                            contrib.epu.quadric_custom_op  [-9.16577f, 8.51346f]                     16
/blocks.5/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-52.2163f, 51.8083f]                     25
/blocks.5/norm2/LayerNormalization                 nn.layer_norm                  [-5.40404f, 4.50069f]                     28
/blocks.5/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-66.6578f, 65.0955f]                     24
/norm/LayerNormalization                           nn.layer_norm                  [-5.00211f, 4.32799f]                     28
/Gather                                            take                           [-3.8103f, 3.45511f]                      28
/fc_norm/LayerNormalization                        nn.layer_norm                  [-3.87842f, 3.78483f]                     29
logits_DequantizeLinear                            contrib.epu.dequantize         [-8.80456f, 10.7517f]                     27

2026-08-20 14:34 - INFO - epu - codegen - START====================build_cpu_runnable_fx_relay
2026-08-20 14:34 - INFO - epu - codegen - START=======================quantize_to_chimera_fx
2026-08-20 14:34 - INFO - epu - codegen - START=================================relay_to_tir
2026-08-20 14:34 - INFO - epu - codegen - START===========================relay_to_epu_relay
2026-08-20 14:34 - INFO - epu - codegen - START==============================adapt_and_order
2026-08-20 14:34 - INFO - epu - mac_counter - 
2026-08-20 14:34 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:34 - INFO - epu - mac_counter - MAC Operation Count Summary
2026-08-20 14:34 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:34 - INFO - epu - mac_counter -   conv2d: 4,096,000 ops (2,048,000 MACs) - /patch_embed/proj/Conv_quant
2026-08-20 14:34 - INFO - epu - mac_counter - ------------------------------------------------------------
2026-08-20 14:34 - INFO - epu - mac_counter - Total: 4,096,000 ops (2,048,000 MACs)
2026-08-20 14:34 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:34 - INFO - epu - mac_counter - 
2026-08-20 14:34 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:35 - INFO - epu - codegen - START=============================plan_lrm_virtual
2026-08-20 14:36 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:36 - INFO - epu - codegen - START===============================lrm_alloc_loop
2026-08-20 14:37 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:37 - INFO - epu - codegen - START================================lrm_splitting
2026-08-20 14:39 - INFO - epu - fuse_weights - No optimization for node /patch_embed/proj/Conv_quant with properties { kernel_size: [1, 50], channels: 256, strides:[1, 50], padding:[0, 0, 0, 0], data_layout:NCHW, dilation:[1, 1], groups:1, kernel_layout:OIHW, out_dtype:int8, out_layout: }.Applying General Convolution algorithm. Performance for this node can be improved significantly. Please refer to the documentation or contact Quadric Support.
2026-08-20 14:39 - INFO - epu - codegen - START==============================ext_split_relay
2026-08-20 14:40 - INFO - epu - codegen - START====================================build_tir
2026-08-20 14:40 - INFO - epu - chimera_job - StackOverflow detected. Disabling LUT-init hoisting and retrying compilation.
2026-08-20 14:40 - INFO - epu - chimera_job - START==================================onnx_ingest
2026-08-20 14:40 - INFO - epu - chimera_job - Numerical ranges provided
2026-08-20 14:41 - INFO - epu - codegen - START===============================optimize_relay
2026-08-20 14:41 - INFO - epu - codegen - START====================quantize_to_cpu_runnable_fx
2026-08-20 14:41 - INFO - epu - fx - Clamped annotated range on /blocks.1/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-14.693208694458008, 15.295390129089355) -> (-14.693208694458008, 15.295389704406261) (within tol 0.120436)
2026-08-20 14:41 - INFO - epu - fx - Clamped annotated range on /blocks.2/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-17.228588104248047, 18.862335205078125) -> (-17.228588104248047, 18.862334311008453) (within tol 0.148522)
2026-08-20 14:41 - INFO - epu - fx - Clamped annotated range on /blocks.3/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-15.205657958984375, 16.93963623046875) -> (-15.205657958984375, 16.939636066555977) (within tol 0.133383)
2026-08-20 14:41 - INFO - epu - fx - Clamped annotated range on /blocks.5/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-13.569168090820312, 14.360703468322754) -> (-13.569168090820312, 14.360703274607658) (within tol 0.113076)
2026-08-20 14:41 - INFO - epu - fx - 

Source name                                        Op                             Output 0 Range            Output 0 Frac Bits
-------------------------------------------------  -----------------------------  ----------------------  --------------------
/patch_embed/Transpose_output_0_DequantizeLinear   contrib.epu.dequantize         [-1.54369f, 1.38568f]                     30
/patch_embed/norm/LayerNormalization               nn.layer_norm                  [-4.8421f, 4.83072f]                      28
/Concat_output_0_DequantizeLinear                  contrib.epu.dequantize         [-0.189842f, 4.82199f]                    28
/blocks.0/norm1/LayerNormalization                 nn.layer_norm                  [-3.98641f, 7.42318f]                     27
/blocks.0/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-9.86747f, 10.191f]                      27
CustomOp/waveAttention0                            contrib.epu.quadric_custom_op  [-5.80482f, 7.42834f]                     16
/blocks.0/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-16.4873f, 16.6182f]                     26
/blocks.0/norm2/LayerNormalization                 nn.layer_norm                  [-4.29883f, 4.49691f]                     28
/blocks.0/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-25.4366f, 28.588f]                      26
/blocks.1/norm1/LayerNormalization                 nn.layer_norm                  [-4.55638f, 4.75343f]                     28
/blocks.1/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-14.6932f, 15.2954f]                     27
CustomOp/waveAttention1                            contrib.epu.quadric_custom_op  [-6.26072f, 5.9012f]                      16
/blocks.1/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-35.7952f, 31.2498f]                     25
/blocks.1/norm2/LayerNormalization                 nn.layer_norm                  [-5.17243f, 4.5562f]                      28
/blocks.1/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-43.3882f, 40.2891f]                     25
/blocks.2/norm1/LayerNormalization                 nn.layer_norm                  [-5.59709f, 4.7339f]                      28
/blocks.2/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-17.2286f, 18.8623f]                     26
CustomOp/waveAttention2                            contrib.epu.quadric_custom_op  [-7.09626f, 6.56859f]                     16
/blocks.2/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-49.343f, 44.2922f]                      25
/blocks.2/norm2/LayerNormalization                 nn.layer_norm                  [-5.38715f, 4.78134f]                     28
/blocks.2/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-50.7397f, 47.1155f]                     25
/blocks.3/norm1/LayerNormalization                 nn.layer_norm                  [-5.57496f, 5.23384f]                     28
/blocks.3/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-15.2057f, 16.9396f]                     26
CustomOp/waveAttention3                            contrib.epu.quadric_custom_op  [-6.79083f, 6.45284f]                     16
/blocks.3/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-51.7598f, 49.6894f]                     25
/blocks.3/norm2/LayerNormalization                 nn.layer_norm                  [-5.60962f, 5.0564f]                      28
/blocks.3/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-51.7394f, 49.6698f]                     25
/blocks.4/norm1/LayerNormalization                 nn.layer_norm                  [-5.45329f, 4.92244f]                     28
/blocks.4/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-14.9916f, 14.5194f]                     27
CustomOp/waveAttention4                            contrib.epu.quadric_custom_op  [-10.1218f, 10.8138f]                     16
/blocks.4/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-55.8718f, 54.9849f]                     25
/blocks.4/norm2/LayerNormalization                 nn.layer_norm                  [-5.38267f, 5.16993f]                     28
/blocks.4/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-54.7764f, 54.3417f]                     25
/blocks.5/norm1/LayerNormalization                 nn.layer_norm                  [-5.79005f, 5.02069f]                     28
/blocks.5/attn/qkv/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-13.5692f, 14.3607f]                     27
CustomOp/waveAttention5                            contrib.epu.quadric_custom_op  [-9.16577f, 8.51346f]                     16
/blocks.5/Add_output_0_DequantizeLinear            contrib.epu.dequantize         [-52.2163f, 51.8083f]                     25
/blocks.5/norm2/LayerNormalization                 nn.layer_norm                  [-5.40404f, 4.50069f]                     28
/blocks.5/Add_1_output_0_DequantizeLinear          contrib.epu.dequantize         [-66.6578f, 65.0955f]                     24
/norm/LayerNormalization                           nn.layer_norm                  [-5.00211f, 4.32799f]                     28
/Gather                                            take                           [-3.8103f, 3.45511f]                      28
/fc_norm/LayerNormalization                        nn.layer_norm                  [-3.87842f, 3.78483f]                     29
logits_DequantizeLinear                            contrib.epu.dequantize         [-8.80456f, 10.7517f]                     27

2026-08-20 14:41 - INFO - epu - codegen - START====================build_cpu_runnable_fx_relay
2026-08-20 14:41 - INFO - epu - codegen - START=======================quantize_to_chimera_fx
2026-08-20 14:41 - INFO - epu - codegen - START=================================relay_to_tir
2026-08-20 14:41 - INFO - epu - codegen - START===========================relay_to_epu_relay
2026-08-20 14:41 - INFO - epu - codegen - START==============================adapt_and_order
2026-08-20 14:41 - INFO - epu - mac_counter - 
2026-08-20 14:41 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:41 - INFO - epu - mac_counter - MAC Operation Count Summary
2026-08-20 14:41 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:41 - INFO - epu - mac_counter -   conv2d: 4,096,000 ops (2,048,000 MACs) - /patch_embed/proj/Conv_quant
2026-08-20 14:41 - INFO - epu - mac_counter - ------------------------------------------------------------
2026-08-20 14:41 - INFO - epu - mac_counter - Total: 4,096,000 ops (2,048,000 MACs)
2026-08-20 14:41 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:41 - INFO - epu - mac_counter - 
2026-08-20 14:41 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:41 - INFO - epu - codegen - START=============================plan_lrm_virtual
2026-08-20 14:41 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:41 - INFO - epu - codegen - START===============================lrm_alloc_loop
2026-08-20 14:42 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:42 - INFO - epu - codegen - START================================lrm_splitting
2026-08-20 14:44 - INFO - epu - fuse_weights - No optimization for node /patch_embed/proj/Conv_quant with properties { kernel_size: [1, 50], channels: 256, strides:[1, 50], padding:[0, 0, 0, 0], data_layout:NCHW, dilation:[1, 1], groups:1, kernel_layout:OIHW, out_dtype:int8, out_layout: }.Applying General Convolution algorithm. Performance for this node can be improved significantly. Please refer to the documentation or contact Quadric Support.
2026-08-20 14:44 - INFO - epu - codegen - START==============================ext_split_relay
2026-08-20 14:45 - INFO - epu - codegen - START====================================build_tir
2026-08-20 14:45 - INFO - epu - chimera_job - StackOverflow detected. Disabling qlut optimizations and retrying compilation.
2026-08-20 14:45 - INFO - epu - chimera_job - START==================================onnx_ingest
2026-08-20 14:45 - INFO - epu - chimera_job - Numerical ranges provided
2026-08-20 14:45 - INFO - epu - codegen - START===============================optimize_relay
2026-08-20 14:46 - INFO - epu - codegen - START====================quantize_to_cpu_runnable_fx
2026-08-20 14:46 - INFO - epu - fx - Clamped annotated range on /patch_embed/act_ft/Div to static range: (-3.423882007598877, 3.415832281112671) -> (-3.423882007598877, 3.4096643847449313) (within tol 0.0268478)
2026-08-20 14:46 - INFO - epu - fx - Clamped annotated range on /blocks.1/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-14.693208694458008, 15.295390129089355) -> (-14.693208694458008, 15.295389704406261) (within tol 0.120436)
2026-08-20 14:46 - INFO - epu - fx - Clamped annotated range on /blocks.2/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-17.228588104248047, 18.862335205078125) -> (-17.228588104248047, 18.862334311008453) (within tol 0.148522)
2026-08-20 14:46 - INFO - epu - fx - Clamped annotated range on /blocks.3/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-15.205657958984375, 16.93963623046875) -> (-15.205657958984375, 16.939636066555977) (within tol 0.133383)
2026-08-20 14:46 - INFO - epu - fx - Clamped annotated range on /blocks.5/attn/qkv/Gemm_output_0_DequantizeLinear to static range: (-13.569168090820312, 14.360703468322754) -> (-13.569168090820312, 14.360703274607658) (within tol 0.113076)
2026-08-20 14:46 - INFO - epu - fx - 

Source name                                           Op                             Output 0 Range                             Output 0 Frac Bits
----------------------------------------------------  -----------------------------  ---------------------------------------  --------------------
/patch_embed/Transpose_output_0_DequantizeLinear      contrib.epu.dequantize         [-1.54369f, 1.38568f]                                      30
/patch_embed/norm/LayerNormalization                  nn.layer_norm                  [-4.8421f, 4.83072f]                                       28
                                                      contrib.epu.dequantize         (-4.859961986541748, 4.821993533521891)                    28
/patch_embed/act_ft/Div                               divide                         [-3.42388f, 3.41583f]                                      29
/patch_embed/act_ft/Erf                               erf                            [-0.999999f, 0.999999f]                                    30
/Concat_output_0_DequantizeLinear                     contrib.epu.dequantize         [-0.189842f, 4.82199f]                                     28
/blocks.0/norm1/LayerNormalization                    nn.layer_norm                  [-3.98641f, 7.42318f]                                      27
/blocks.0/attn/qkv/Gemm_output_0_DequantizeLinear     contrib.epu.dequantize         [-9.86747f, 10.191f]                                       27
CustomOp/waveAttention0                               contrib.epu.quadric_custom_op  [-5.80482f, 7.42834f]                                      16
/blocks.0/Add_output_0_DequantizeLinear               contrib.epu.dequantize         [-16.4873f, 16.6182f]                                      26
/blocks.0/norm2/LayerNormalization                    nn.layer_norm                  [-4.29883f, 4.49691f]                                      28
/blocks.0/Add_1_output_0_DequantizeLinear             contrib.epu.dequantize         [-25.4366f, 28.588f]                                       26
/blocks.1/norm1/LayerNormalization                    nn.layer_norm                  [-4.55638f, 4.75343f]                                      28
/blocks.1/attn/qkv/Gemm_output_0_DequantizeLinear     contrib.epu.dequantize         [-14.6932f, 15.2954f]                                      27
CustomOp/waveAttention1                               contrib.epu.quadric_custom_op  [-6.26072f, 5.9012f]                                       16
/blocks.1/Add_output_0_DequantizeLinear               contrib.epu.dequantize         [-35.7952f, 31.2498f]                                      25
/blocks.1/norm2/LayerNormalization                    nn.layer_norm                  [-5.17243f, 4.5562f]                                       28
/blocks.1/Add_1_output_0_DequantizeLinear             contrib.epu.dequantize         [-43.3882f, 40.2891f]                                      25
/blocks.2/norm1/LayerNormalization                    nn.layer_norm                  [-5.59709f, 4.7339f]                                       28
/blocks.2/attn/qkv/Gemm_output_0_DequantizeLinear     contrib.epu.dequantize         [-17.2286f, 18.8623f]                                      26
CustomOp/waveAttention2                               contrib.epu.quadric_custom_op  [-7.09626f, 6.56859f]                                      16
/blocks.2/Add_output_0_DequantizeLinear               contrib.epu.dequantize         [-49.343f, 44.2922f]                                       25
/blocks.2/norm2/LayerNormalization                    nn.layer_norm                  [-5.38715f, 4.78134f]                                      28
/blocks.2/Add_1_output_0_DequantizeLinear             contrib.epu.dequantize         [-50.7397f, 47.1155f]                                      25
/blocks.3/norm1/LayerNormalization                    nn.layer_norm                  [-5.57496f, 5.23384f]                                      28
/blocks.3/attn/qkv/Gemm_output_0_DequantizeLinear     contrib.epu.dequantize         [-15.2057f, 16.9396f]                                      26
CustomOp/waveAttention3                               contrib.epu.quadric_custom_op  [-6.79083f, 6.45284f]                                      16
/blocks.3/Add_output_0_DequantizeLinear               contrib.epu.dequantize         [-51.7598f, 49.6894f]                                      25
/blocks.3/norm2/LayerNormalization                    nn.layer_norm                  [-5.60962f, 5.0564f]                                       28
/blocks.3/Add_1_output_0_DequantizeLinear             contrib.epu.dequantize         [-51.7394f, 49.6698f]                                      25
/blocks.4/norm1/LayerNormalization                    nn.layer_norm                  [-5.45329f, 4.92244f]                                      28
/blocks.4/attn/qkv/Gemm_output_0_DequantizeLinear     contrib.epu.dequantize         [-14.9916f, 14.5194f]                                      27
CustomOp/waveAttention4                               contrib.epu.quadric_custom_op  [-10.1218f, 10.8138f]                                      16
/blocks.4/Add_output_0_DequantizeLinear               contrib.epu.dequantize         [-55.8718f, 54.9849f]                                      25
/blocks.4/norm2/LayerNormalization                    nn.layer_norm                  [-5.38267f, 5.16993f]                                      28
/blocks.4/Add_1_output_0_DequantizeLinear             contrib.epu.dequantize         [-54.7764f, 54.3417f]                                      25
/blocks.5/norm1/LayerNormalization                    nn.layer_norm                  [-5.79005f, 5.02069f]                                      28
/blocks.5/attn/qkv/Gemm_output_0_DequantizeLinear     contrib.epu.dequantize         [-13.5692f, 14.3607f]                                      27
CustomOp/waveAttention5                               contrib.epu.quadric_custom_op  [-9.16577f, 8.51346f]                                      16
/blocks.5/Add_output_0_DequantizeLinear               contrib.epu.dequantize         [-52.2163f, 51.8083f]                                      25
/blocks.5/norm2/LayerNormalization                    nn.layer_norm                  [-5.40404f, 4.50069f]                                      28
/blocks.5/mlp/mod/fc1/Gemm_output_0_DequantizeLinear  contrib.epu.dequantize         [-13.0614f, 13.1659f]                                      27
/blocks.5/mlp/mod/act/Div                             divide                         [-9.23584f, 9.30973f]                                      27
/blocks.5/mlp/mod/act/Erf                             erf                            [-1f, 1f]                                                  30
/blocks.5/Add_1_output_0_DequantizeLinear             contrib.epu.dequantize         [-66.6578f, 65.0955f]                                      24
/norm/LayerNormalization                              nn.layer_norm                  [-5.00211f, 4.32799f]                                      28
/Gather                                               take                           [-3.8103f, 3.45511f]                                       28
/fc_norm/LayerNormalization                           nn.layer_norm                  [-3.87842f, 3.78483f]                                      29
logits_DequantizeLinear                               contrib.epu.dequantize         [-8.80456f, 10.7517f]                                      27

2026-08-20 14:46 - INFO - epu - codegen - START====================build_cpu_runnable_fx_relay
2026-08-20 14:46 - INFO - epu - codegen - START=======================quantize_to_chimera_fx
2026-08-20 14:46 - INFO - epu - codegen - START=================================relay_to_tir
2026-08-20 14:46 - INFO - epu - codegen - START===========================relay_to_epu_relay
2026-08-20 14:46 - INFO - epu - codegen - START==============================adapt_and_order
2026-08-20 14:46 - INFO - epu - mac_counter - 
2026-08-20 14:46 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:46 - INFO - epu - mac_counter - MAC Operation Count Summary
2026-08-20 14:46 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:46 - INFO - epu - mac_counter -   conv2d: 4,096,000 ops (2,048,000 MACs) - /patch_embed/proj/Conv_quant
2026-08-20 14:46 - INFO - epu - mac_counter - ------------------------------------------------------------
2026-08-20 14:46 - INFO - epu - mac_counter - Total: 4,096,000 ops (2,048,000 MACs)
2026-08-20 14:46 - INFO - epu - mac_counter - ============================================================
2026-08-20 14:46 - INFO - epu - mac_counter - 
2026-08-20 14:46 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:46 - INFO - epu - codegen - START=============================plan_lrm_virtual
2026-08-20 14:46 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:46 - INFO - epu - codegen - START===============================lrm_alloc_loop
2026-08-20 14:47 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-08-20 14:47 - INFO - epu - codegen - START================================lrm_splitting
2026-08-20 14:48 - INFO - epu - fuse_weights - No optimization for node /patch_embed/proj/Conv_quant with properties { kernel_size: [1, 50], channels: 256, strides:[1, 50], padding:[0, 0, 0, 0], data_layout:NCHW, dilation:[1, 1], groups:1, kernel_layout:OIHW, out_dtype:int8, out_layout: }.Applying General Convolution algorithm. Performance for this node can be improved significantly. Please refer to the documentation or contact Quadric Support.
2026-08-20 14:48 - INFO - epu - codegen - START==============================ext_split_relay
2026-08-20 14:49 - INFO - epu - codegen - START====================================build_tir
2026-08-20 14:50 - INFO - epu - chimera_job - Compilation of waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1 successful



╒═════════════════════╤════════════════════════════════════════════════════════════════════╕
│ Module Name         │ waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1 │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ ONNX File           │ waveformer_int8_custom_op.onnx                                     │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Custom Ops          │ /quadric/sdk-cli/examples/models/waveformer/waveformer_ops.hpp     │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Product Target      │ QC-N                                                               │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Number of Cores     │ 1                                                                  │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ ISS Clock Frequency │ 0.500                                                              │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ L2M Size            │ 4MB                                                                │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ LRM Size            │ 4kB                                                                │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ External Read BW    │ 8GBps                                                              │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ External Write BW   │ 8GBps                                                              │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ MACS per PE         │ 8                                                                  │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Max L2M             │ 0.903MB                                                            │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Max LRM             │ 0.299kB                                                            │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Max Temp Ext Bytes  │ 0.629MB                                                            │
├─────────────────────┼────────────────────────────────────────────────────────────────────┤
│ Network GMACs       │ 0.356                                                              │
╘═════════════════════╧════════════════════════════════════════════════════════════════════╛
NOTE: CGC has used general convolution for some nodes, which may result in suboptimal performance. For performance-critical applications, please contact Quadric support to explore optimization strategies.
General convolution nodes: /patch_embed/proj/Conv_quant, /patch_embed/proj/Conv_quant, /patch_embed/proj/Conv_quant
For more details, see: https://app.quadric.ai/docs/latest/chimera-software-user-guide/chimera-graph-compiler-cgc/graph-optimizations-performed-by-cgc#general-convolution


╒════╤════════╤════════╤═════════════════╤══════════════════════════╤═══════╕
│    │ Type   │ Name   │ shape           │ type                     │ mse   │
╞════╪════════╪════════╪═════════════════╪══════════════════════════╪═══════╡
│  0 │ Input  │ input  │ [1, 1, 8, 1000] │ tensor[FixedPoint32<30>] │ n/a   │
├────┼────────┼────────┼─────────────────┼──────────────────────────┼───────┤
│  1 │ Output │ logits │ [1, 6]          │ tensor[FixedPoint32<27>] │ n/a   │
╘════╧════════╧════════╧═════════════════╧══════════════════════════╧═══════╛

4. Build the EPU binary (sdk source)

Section 3 runs CGC and emits the generated CCL C++ for the whole graph under ccl_build/waveformer_int8_custom_op_QC_N_.../ - the nn::waveAttentionOp calls (one per block) plus every natively-compiled op. This step compiles that generated .cpp into the EPU binary + host executable with the SDK's sdk source tool (Quadric LLVM + the Chimera runtime + the waveAttention kernel), the same explicit build step the qwen / whisper notebooks use.

  • --include-cgc-headers pulls in CGC's generated headers (the custom-op prototypes / const buffers).
  • The --target QC-N / cores / OCM / MAC / bandwidth flags mirror the HWConfig used to compile.

Steps 4a-4b stage the input and run that build; section 5 validates the result against the ORT golden.

4a. Prepare input

The generated host reads its input as a raw input.bin from the build dir. This cell converts the sEMG window x from fp32 to fixed-point.

## Stage input.bin (sEMG window as FixedPoint32<30>) next to const_tensor_data.bin, where the host reads it.
INPUT_FRAC_BITS = 30
_BASE = "waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1"
input_fx = np.round(x.astype(np.float64) * (1 << INPUT_FRAC_BITS)).astype(np.int32)
input_fx.tofile(f"ccl_build/{_BASE}/build/input.bin")
print(
    f"[input.bin] FixedPoint32<{INPUT_FRAC_BITS}>  {tuple(input_fx.shape)}  -> ccl_build/{_BASE}/build/"
)
[input.bin] FixedPoint32<30>  (1, 1, 8, 1000)  -> ccl_build/waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1/build/

4b. Compile and run on the ISS

sdk source compiles the CGC-generated .cpp with the Quadric LLVM toolchain and runs it on the ISS.

%%bash
set -euo pipefail
BASE=waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1
BD=${BASE}_QC-N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1
## wipe the build dir so find_package reconfigures against the current SDK_INSTALL_PATH (a stale
## CMakeCache would otherwise pin QuadricSdk_DIR to the previous SDK).
rm -rf "$BD"
## generated host reads input.bin + const_tensor_data.bin from its run dir (BD/output); stage them there.
mkdir -p "$BD/output"
cp "ccl_build/$BASE/build/input.bin" "ccl_build/$BASE/build/const_tensor_data.bin" "$BD/output/"
## --clock-freq-ghz 0.5 = 500 MHz (needs ALLOWED_CLK floor <= 0.5 in tvm hw_config.py -> dir 0d5).
sdk source ccl_build/$BASE/$BASE.cpp \
    --include-cgc-headers \
    --target QC-N \
    --num-cores 1 \
    --ocm-size 4MB \
    --macs-per-pe 8 \
    --clock-freq-ghz 0.5 \
    --ext-read-bw 8GBps \
    --ext-write-bw 8GBps \
    --ddr-axi-width 256 \
    --quiet
2026-08-20 14:50 - DEBUG - sdk - cli - Executing command: cmake CMakeLists.txt -B /quadric/sdk-cli/examples/models/waveformer/waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1_QC-N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1/build -DNUM_GPNPUS=1 -DNUM_CORES=8 -DNUM_BORDERS=2 -DEPU_VERSION=2.0.0 -DQLLVM_ROOT_PATH=/quadric/llvm -DOCM_SIZE_KIBIBYTES=4096 -DNUM_PE_MACS=8 -DASSERT_MLS_WIDTH_LINE_ALIGN=ON -DSTACKOVERFLOW_ERROR=OFF -DHARDWARE_TARGET=OFF 
2026-08-20 14:50 - DEBUG - sdk - cli - Executing command: make -j8


[SDK-CLI] : Executing on QC-N simulator


2026-08-20 14:50 - DEBUG - sdk - cli - Executing command: ./waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1_host -c --ddrRdBwTotal 65536.0 --ddrWrBwTotal 65536.0 --ddrAxiWidth 256 --instMemDepth 1310720 --ocmSize 4194304 --cycleTimeNS 2.0 --no-check --ddrRdAvgPct 100 --ddrRdMaxPct 100 --ddrWrAvgPct 100 --ddrWrMaxPct 100 --postKernelFlowTimeoutCycles 4000000 --clusterSize 1 --numClusters 1 


[SDK-CLI] : TotalCycles: 8,681,144
[SDK-CLI] : Executions/second: 58

compute      : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇���▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 4.07M
data_array   : ▇▇▇▇���▇▇▇▇ 795.54K
mac          : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1.186M
data_ocm     : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 2.068M
data_external: ▇▇▇▇▇▇ 523.706K

[SDK-CLI] : Execution completed.

5. Validate against ORT

Model output. The model produces [1,6] class logits - one score per gesture class - and its prediction is the argmax over them.

EPU vs ORT. This cell decodes the EPU logits from logits.bin and runs the same INT8 ONNX through ORT on the identical window, then compares the two.

Threshold. Both paths dequantize the same int8 output tensor, so their differences are whole multiples of the model's logits_scale (~0.0847) - on this window the per-class errors are exactly 1, 2, 2, 3, 4 and 5 of those steps. The threshold is therefore expressed in output steps rather than as an absolute constant: the cell asserts the argmax classes match and that max|EPU-ORT| stays within TOL_LSB = 6 steps (0.508), against a measured max of 5 steps (0.423). A clean run prints VALIDATED.

For scale: the logit span is ~10.8 (128 steps) and the argmax margin is ~1.6 (19 steps), so a 5-step error is ~3.9% of full scale and would have to grow ~2x to flip the prediction. Most of the residual is int8 quantization of the attention P.V product, which is design-inherent rather than a defect.

## Decode the EPU logits (FixedPoint32<27>) and validate vs ORT: argmax AND logit closeness.
import numpy as np
import onnx
import onnxruntime as ort
from onnx import numpy_helper

CLASSES = [
    "hand relax",
    "hand close",
    "wrist flexion",
    "wrist extension",
    "ulnar dev.",
    "radial dev.",
]

## EPU and ORT land on the same int8 output grid: every observed difference is a whole
## multiple of the model's own logits_scale (1-5 steps on this window). Bounding in grid
## units ties the threshold to the model's quantization instead of an arbitrary constant.
## An absolute 0.2 would be ~2.4 steps -- below the noise floor of a 6-block int8
## requantization chain; a broken RoPE/layout is >50 steps.
_g = onnx.load("waveformer_int8.onnx").graph
_init = {i.name: numpy_helper.to_array(i) for i in _g.initializer}
_deq = next(n for n in _g.node if _g.output[0].name in n.output)  # logits DequantizeLinear
LOGIT_LSB = float(_init[_deq.input[1]])  # int8 output step (logits_scale), ~0.0847
TOL_LSB = 6  # 6 output steps = 0.508; measured max is 5 steps (0.423)
TOL = TOL_LSB * LOGIT_LSB

_BD = "waveformer_int8_custom_op_QC_N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1_QC-N_0d5_4MB_4kB_8GBps_8GBps_8_OFF_x1_x1"
epu = np.fromfile(f"{_BD}/output/logits.bin", dtype=np.int32).astype(np.float64) / (1 << 27)
_x = np.load("data/test_x.npy").astype(np.float32)[0:1]
_ort = (
    ort.InferenceSession("waveformer_int8.onnx", providers=["CPUExecutionProvider"])
    .run(None, {"input": _x})[0]
    .flatten()
)
ep, op = int(np.argmax(epu)), int(np.argmax(_ort))
max_diff = float(np.abs(epu - _ort).max())
_top2 = np.sort(_ort)[::-1]
margin = float(_top2[0] - _top2[1])
print(f"EPU logits : {np.round(epu, 3).tolist()}  -> {ep} ({CLASSES[ep]})")
print(f"ORT logits : {np.round(_ort, 3).tolist()}  -> {op} ({CLASSES[op]})")
print(
    f"argmax {'match' if ep == op else 'MISMATCH'}   "
    f"max|EPU-ORT| = {max_diff:.3f} = {max_diff / LOGIT_LSB:.1f} LSB  "
    f"(tol {TOL:.3f} = {TOL_LSB} LSB)"
)
print(
    f"argmax margin : {margin:.3f} ({margin / LOGIT_LSB:.1f} LSB) -- a flip needs {margin / 2:.3f}"
)
assert ep == op, f"argmax mismatch: EPU {ep} vs ORT {op}"
assert max_diff <= TOL, (
    f"logits diverge: max|EPU-ORT|={max_diff:.3f} ({max_diff / LOGIT_LSB:.1f} LSB) "
    f"> {TOL:.3f} ({TOL_LSB} LSB) (argmax-correct-by-luck?)"
)
print("VALIDATED")
EPU logits : [-2.878, -0.762, -4.487, 6.095, -4.656, 4.318]  -> 3 (wrist extension)
ORT logits : [-2.7939999103546143, -0.847000002861023, -4.317999839782715, 5.926000118255615, -4.656000137329102, 4.572000026702881]  -> 3 (wrist extension)
argmax match   max|EPU-ORT| = 0.254 = 3.0 LSB  (tol 0.508 = 6 LSB)
argmax margin : 1.355 (16.0 LSB) -- a flip needs 0.677
VALIDATED
Table of Contents
Introduction to the Chimera SDK
Chimera SDK Quick Start Guide
Chimera SDK Command Line Interface (CLI)
Tutorial: Using SDK as a Library
Tutorials & Model Demos
Model Demos
Model Demo: Llama-2 15M (Baby Llama-2)
Model Demo: QWEN3 8B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Prefill All Decoders
Model Demo: DeepSeek-R1-Distill-Qwen-1.5B End-to-End CGC and ISS Execution
Model Demo: QWEN3 Single Decoder
Model Demo: Qwen2.5-0.5B INT8 Quantization Pipeline
Model Demo: ConvNeXt Detection
Model Demo: QWEN3 Prefill Decoder Validation
Model Demo: ConvNeXt Segmentation
Model Demo: Classifiers Zoo
Model Demo: Detectors Zoo - MMDetection
Model Demo: Segmentors Zoo - MMSegmentation
Model Demo: Pose Estimators Zoo - MMPose
Model Demo: Detectors3D Zoo - MMDetection3D
MODEL Demo: Optical Character Recognition (OCR) Zoo - MMOCR
Model Demo: YOLOv3 Object Detection
Model Demo: YOLOv4 Object Detection
Model Demo: YOLOv5 Detection
Model Demo: YOLOv5 Detection and Segmentation
Model Demo: YOLOR Detection
Model Demo: YOLOX End-to-End Detection
Model Demo: YOLOv7 Detection
Model Demo: YOLOv8 Detection
Model Demo: YOLOv8 Pose Estimation
Model Demo: YOLOP Detection and Segmentation
Model Demo: QAT Vision Transformer (ViT)
Model Demo: QAT Swin Transformer
Model Demo: Mediapipe Face Pipeline
Demo: DOOM Renderer on Chimera GPNPU
Model Demo: Mediapipe Hand Pipeline
Model Demo: Whisper Tiny (Encoder + Decoder)
Model Demo: L2CS Fine-Grained Gaze Estimation
Model Demo: ASVspoof2021 LA Anti-Spoofing (LFCC-LCNN-BiLSTM)
Model Demo: UNET Tumor Segmentation
Model Demo: FFNet Segmentation
Model Demo: Centernet Detection
Model Demo: RetinaNet End-to-End Detection
Model Demo: Blazepose Pose Estimation
Model Demo: Pose Resnet Human Pose Estimation
Model Demo: MaskRCNN Detection and Segmentation
Model Demo: Keypoint R-CNN
Model Demo: Faster R-CNN Detection
Model Demo: FCOS Detection
Model Demo: DDRNet Classificationls
Model Demo: PI0.5 End-to-End VLA Inference
Model Demo: BEVFormer End-to-End 3D Detection
Model Demo: SegFormer Semantic Segmentation
Model Demo: DETR Object Detection
Model Demo: VGG-16 A8W4 Quantization
Model Demo: WaveFormer sEMG Gesture Classification
Multicore Demo
Chimera LLVM C++ Compiler
Chimera SDK Licensing Policy Documentation
Glossary

Sign in to your account

Don't have an account? Create an Account
By signing in, you are agreeing to our Terms of Use and Privacy Policy.

Develop.

Simulate.

Profile.

Collaborate.