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: DETR Encoder
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
Multicore Demo
Chimera LLVM C++ Compiler
Chimera SDK Licensing Policy Documentation
Glossary
Chimera Software User GuideTutorials & Model DemosModel DemosModel Demo: YOLOX End-to-End Detection

Model Demo: YOLOX End-to-End Detection


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/yolo/yolox_e2e/yolox_e2e_chipy.ipynb.


YOLOX End-to-End on Chimera GPNPU

This notebook runs the entire YOLOX detection pipeline on the Chimera GPNPU — backbone inference, box decoding, and NMS — in a single compiled program.

Why end-to-end?

Most detection demos split the pipeline: the backbone runs on the accelerator while postprocessing (decode + NMS) runs on the host CPU. This creates a round-trip penalty and leaves the CPU as a bottleneck.

Here we use Chipy to compose the CGC-compiled backbone with a CCL custom op that handles decode + NMS entirely on-chip. The result is a single GPNPU program with zero host intervention between backbone and output.

Pipeline

YOLOX E2E Pipeline

One switch, two models. Flip a single MODEL line to run either variant — the pipeline and the CCL kernel are identical; only the input resolution, FPN grid sizes, and OCM budget follow along.

ModelInputFPN gridsProposalsTarget
YOLOX-M640×64080/40/208400QC-N, 8 MB OCM
YOLOX-Tiny416×41652/26/133549QC-N, 4 MB OCM

1. Setup

import numpy as np
from tvm.contrib.epu import chipy
from yolox_e2e_helpers import (
    YOLOX_VARIANTS,
    compare_detections,
    cpu_decode_and_nms,
    download_model,
    load_input,
    print_detections,
)

%matplotlib inline

2. Select Model

This is the switch. Choose a variant below. Both are stock models, cut at the 3 FPN heads and quantized to asymmetric int8 with the identical pipeline — they drop straight in. Everything downstream (input size, grids, OCM budget) is read from the variant config.

## ════════════════════════════════════════════════════════════════════════
##  THE SWITCH — pick a model. Everything else follows automatically.
## ════════════════════════════════════════════════════════════════════════
MODEL = "yolox-tiny"  # "yolox-tiny" (416, QC-N 4 MB) | "yolox-m" (640, QC-N 8 MB)
## ════════════════════════════════════════════════════════════════════════

CFG = YOLOX_VARIANTS[MODEL]
IMAGE_SIZE = CFG["image_size"]
print(f"{CFG['display']}  ·  {IMAGE_SIZE}×{IMAGE_SIZE}  ·  {CFG['params']}")
print(f"Target: QC-N  ·  {CFG['ocm_size']} OCM")

model_path, tranges_path = download_model(MODEL)
YOLOX-Tiny  ·  416×416  ·  5.06M params, 6.45 GFLOPs
Target: QC-N  ·  4MB OCM
Downloading yolox-tiny-noconcat_OpSet16_optimized_asym_int8_q_shaped.onnx ...
Model: yolox-tiny-noconcat_OpSet16_optimized_asym_int8_q_shaped.onnx (5.3 MB)
Downloading yolox-tiny-noconcat_OpSet16_optimized_asym_int8_q_shaped.tranges ...
Tranges: yolox-tiny-noconcat_OpSet16_optimized_asym_int8_q_shaped.tranges

3. The CCL Postprocessing Kernel

The decode + NMS pipeline is implemented as a single CCL kernel in yolox_postprocess.hpp.

StageWhat happens
Split DMALoad box+obj [1,5,H,W] and classes [1,80,H,W] separately via channel-offset memCpy
Flow argmaxreduce<Direction::Channel> over 80 class channels → best class index via ReadFlow/WriteFlow
Decode7 RAU loads/proposal: 5 box+obj (batched via rau::load::tiles) + 1 argmax + 1 class value
FastDivfloor(n/d) = (n * ceil(2^22/d)) >> 22 for grid coordinate computation
NMSnn::nms — class-aware, all in OCM

One kernel, any resolution. The per-scale grid sizes and total proposal count are derived at compile time from the FPN head tensor shapes (NUM_ROWS/NUM_COLS) — so the same kernel serves YOLOX-M (80/40/20 → 8400) and YOLOX-Tiny (52/26/13 → 3549) with no edits. Only the FPN strides (8/16/32) are fixed by the architecture. All decoded proposals fit in OCM (~100 KB for boxes + scores + classes in FP16); each FPN head is split-loaded, reduced, decoded, then freed before the next.

## Show key patterns from the CCL kernel
from pathlib import Path

hpp = Path("yolox_postprocess.hpp").read_text()

## Show the ArgmaxLambda functor
print("// === Flow-based argmax over 80 class channels ===")
f_start = hpp.find("template <typename ElemT, std::int32_t numClasses>")
f_end = hpp.find("};", f_start) + 2
print(hpp[f_start:f_end].strip())

print("\n// === Per-scale processing: DMA → argmax → decode ===")
s_start = hpp.find("// Split DMA: channels 0-4")
s_end = hpp.find("ocmMem.free(ocmBoxObj);", s_start)
s_end = hpp.find("\n", s_end) + 1
print(hpp[s_start:s_end].strip())

print("\n// ... [decode reads 7 values/proposal via RAU, then NMS + DMA out]")
// === Flow-based argmax over 80 class channels ===
template <typename ElemT, std::int32_t numClasses>
struct ArgmaxLambda {
    INLINE void operator()(
        container::NDArray<qVar_t<ElemT>, numClasses>& cls,
        qVar_t<std::int16_t>& result)
    {
        qVar_t<ElemT> maxVal = cls[0];
        qVar_t<std::int16_t> maxIdx = 0;
        for (std::int32_t i = 1; i < numClasses; i++) {
            auto better = cls[i] > maxVal;
            maxVal = better ? cls[i] : maxVal;
            maxIdx = better ? static_cast<qVar_t<std::int16_t>>(i) : maxIdx;
        }
        result = maxIdx;
    }
};

// === Per-scale processing: DMA → argmax → decode ===
// Split DMA: channels 0-4 (box+obj) and channels 5-84 (classes)
    memCpy(ddrHead, ocmBoxObj);
    memCpy(ddrHead, ocmCls, 0, 5, 0, 0);

    // Flow-based argmax: 80 class channels → 1 class index per position
    ArgmaxLambda<HeadElemT, YOLOX_NUM_CLASSES> argmaxLambda;
    reduce<Direction::Channel>(ocmCls, ocmArgmax, argmaxLambda);

    yoloxDecodeScale<gridH, gridW, stride, propOffset>(
        ocmBoxObj, ocmCls, ocmArgmax, ocmBoxes, ocmScores, ocmClasses);

    ocmMem.free(ocmArgmax);
    ocmMem.free(ocmCls);
    ocmMem.free(ocmBoxObj);

// ... [decode reads 7 values/proposal via RAU, then NMS + DMA out]

4. Chipy End-to-End Pipeline

Chipy lets us compose the CGC-compiled backbone with our CCL custom op. The @chipy.ccl_custom_op decorator bridges the C++ kernel, and @chipy.func wires the full pipeline in 5 lines.

@chipy.ccl_custom_op(
    ccl_func_name="yoloxPostprocess",
    frac_bits=[4, 15, 0],  # boxes Q11.4 (BoxFP), scores Q0.15 (ScoreFP16), classes int
    reserved_l2m=CFG["reserved_l2m"],  # OCM for heads + decoded buffers + NMS
    reserved_ext=0,
    io_in_ext_mem=True,  # inputs/outputs live in DDR
)
def yolox_postprocess(head0, head1, head2, iou_threshold, score_threshold):
    """CPU reference — Chipy calls this in CPU mode, the HPP on GPNPU."""
    return cpu_decode_and_nms([head0, head1, head2], iou_threshold, score_threshold)


@chipy.func()
def yolox_e2e(model_path, inp, iou_threshold, score_threshold):
    """YOLOX end-to-end: backbone (ONNX) → decode + NMS (CCL)."""
    heads = chipy.infer_onnx(model_path, inp)
    return yolox_postprocess(heads[0], heads[1], heads[2], iou_threshold, score_threshold)


print("Pipeline defined: backbone → decode → NMS")
Pipeline defined: backbone  decode  NMS

5. Compile & Run

We run the pipeline twice:

  1. CPU — ORT backbone + numpy postprocess (float reference)
  2. GPNPU ISS — Fully compiled (CGC backbone + CCL postprocess), with region profiling

We set the TVM logger to INFO to suppress verbose debug output during compilation.

## Load input and run CPU reference
chipy_inp, img, tranges = load_input(
    "../../../common/calibration/coco-like/33887522274_eebd074106_k.jpeg",
    tranges_path,
    image_size=IMAGE_SIZE,
)

## Normalize value_proto_ranges to the nested [[min, max]] shape that
## CompiledChiPyModule.run expects (workaround for tvm#3261).
tranges = {k: ([v] if v and not isinstance(v[0], list) else v) for k, v in tranges.items()}

IOU_THR, SCORE_THR = 0.45, 0.3

out_cpu = yolox_e2e(str(model_path), chipy_inp, IOU_THR, SCORE_THR)
cpu_boxes, cpu_scores, cpu_classes = (
    out_cpu[0].numpy(),
    out_cpu[1].numpy(),
    out_cpu[2].numpy(),
)
n_cpu = int(np.count_nonzero(cpu_scores > 0))
print_detections("CPU", cpu_boxes, cpu_scores, cpu_classes, n_cpu)
CPU: 7 detections
  bus           score=0.896  box=[191, 172, 261, 306]
  car           score=0.852  box=[87, 255, 149, 323]
  person        score=0.831  box=[349, 247, 366, 306]
  person        score=0.784  box=[323, 246, 343, 303]
  person        score=0.451  box=[335, 245, 351, 304]
  truck         score=0.415  box=[90, 252, 148, 321]
  car           score=0.321  box=[143, 265, 153, 276]
import logging
from pathlib import Path

from tvm.contrib.epu.chimera_job.hw_config import HWConfig
from tvm.relay.backend.contrib.epu import util as epu_util
from tvm.relay.backend.contrib.epu.util import logger as tvm_logger

tvm_logger.setLevel(logging.INFO)

module_name = f"yolox_e2e_{MODEL.replace('-', '_')}"
hw_config = HWConfig(product="QC-N", ocm_size=CFG["ocm_size"], macs_per_pe=16)

## Pass-context attrs are inherited from the outer `with` block into
## compile_and_run's internal target + pass_ctx. Alongside profiling
## (output_profile / enable_region_profile) we turn on the compiler's
## optimization passes: enhanced conv fusion, prefetching, QLUT, extra
## aggressive sinking, advanced directives, and LRM-overflow checking.
with epu_util.add_epu_passcontext_attributes(
    output_profile=True,
    enable_region_profile=True,
    enhanced_conv_fusion=True,
    enable_prefetching=True,
    enable_qlut=True,
    enable_extra_aggressive_sinking=True,
    advanced_directives=True,
    check_lrm_overflow=True,
):
    out_gpnpu = yolox_e2e.compile_and_run(
        hw_config=hw_config,
        module_name=module_name,
        custom_op_header=str(Path(".").resolve() / "yolox_postprocess.hpp"),
        value_proto_ranges=tranges,
        model_path=str(model_path),
        inp=chipy_inp,
        iou_threshold=IOU_THR,
        score_threshold=SCORE_THR,
    )
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:197: RuntimeWarning: overflow encountered in multiply
  decoded[:, 0:2] = (decoded[:, 0:2] + grids) * exp_strides
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:198: RuntimeWarning: overflow encountered in exp
  decoded[:, 2:4] = np.exp(decoded[:, 2:4]) * exp_strides
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:206: RuntimeWarning: invalid value encountered in add
  boxes_xyxy[:, 3] = boxes_cxcywh[:, 1] + boxes_cxcywh[:, 3] / 2
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:208: RuntimeWarning: overflow encountered in multiply
  combined = decoded[:, 4, None] * decoded[:, 5:]  # obj * cls
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:208: RuntimeWarning: invalid value encountered in multiply
  combined = decoded[:, 4, None] * decoded[:, 5:]  # obj * cls
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:158: RuntimeWarning: invalid value encountered in subtract
  inter = np.maximum(0, xx2 - xx1) * np.maximum(0, yy2 - yy1)
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:158: RuntimeWarning: invalid value encountered in multiply
  inter = np.maximum(0, xx2 - xx1) * np.maximum(0, yy2 - yy1)
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:159: RuntimeWarning: invalid value encountered in scalar multiply
  a_i = (boxes[idx, 2] - boxes[idx, 0]) * (boxes[idx, 3] - boxes[idx, 1])
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:160: RuntimeWarning: invalid value encountered in subtract
  a_j = (boxes[order[1:], 2] - boxes[order[1:], 0]) * (
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:161: RuntimeWarning: invalid value encountered in subtract
  boxes[order[1:], 3] - boxes[order[1:], 1]
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:160: RuntimeWarning: invalid value encountered in multiply
  a_j = (boxes[order[1:], 2] - boxes[order[1:], 0]) * (
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:163: RuntimeWarning: invalid value encountered in subtract
  iou = inter / (a_i + a_j - inter + 1e-6)
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:158: RuntimeWarning: overflow encountered in subtract
  inter = np.maximum(0, xx2 - xx1) * np.maximum(0, yy2 - yy1)
/quadric/sdk-cli/examples/models/yolo/yolox_e2e/yolox_e2e_helpers.py:159: RuntimeWarning: invalid value encountered in scalar subtract
  a_i = (boxes[idx, 2] - boxes[idx, 0]) * (boxes[idx, 3] - boxes[idx, 1])
2026-07-18 12:09 - INFO - epu - codegen - START==================================build_relay
2026-07-18 12:09 - INFO - epu - codegen - START===============================optimize_relay
2026-07-18 12:09 - INFO - epu - codegen - START====================quantize_to_cpu_runnable_fx
2026-07-18 12:09 - INFO - epu - fx - 

Source name                               Op                             Output 0 Range                              Output 0 Frac Bits  Output 1 Range    Output 1 Frac Bits    Output 2 Range    Output 2 Frac Bits
----------------------------------------  -----------------------------  ----------------------------------------  --------------------  ----------------  --------------------  ----------------  --------------------
450                                       strided_slice                  (0.0, 255.0)                                                23  N/A               N/A                   N/A               N/A
452                                       strided_slice                  (0.0, 255.0)                                                23  N/A               N/A                   N/A               N/A
451                                       strided_slice                  (0.0, 255.0)                                                23  N/A               N/A                   N/A               N/A
453                                       strided_slice                  (0.0, 255.0)                                                23  N/A               N/A                   N/A               N/A
/head/Concat_output_0_DequantizeLinear    contrib.epu.dequantize         (-2.277541358023882, 4.104580029845238)                     28  N/A               N/A                   N/A               N/A
/head/Concat_1_output_0_DequantizeLinear  contrib.epu.dequantize         (-2.5013048574328423, 3.459748774766922)                    28  N/A               N/A                   N/A               N/A
/head/Concat_2_output_0_DequantizeLinear  contrib.epu.dequantize         (-1.8887041509151459, 3.025781139731407)                    28  N/A               N/A                   N/A               N/A
                                          contrib.epu.quadric_custom_op  (-134217728.0, 134217727.9375)                               4  N/A               15                    N/A               0

2026-07-18 12:09 - INFO - epu - codegen - START====================build_cpu_runnable_fx_relay
2026-07-18 12:09 - INFO - epu - codegen - START=======================quantize_to_chimera_fx
2026-07-18 12:09 - INFO - epu - codegen - START=================================relay_to_tir
2026-07-18 12:09 - INFO - epu - codegen - START===========================relay_to_epu_relay
2026-07-18 12:09 - INFO - epu - codegen - START==============================adapt_and_order
2026-07-18 12:09 - INFO - epu - mac_counter - 
2026-07-18 12:09 - INFO - epu - mac_counter - ============================================================
2026-07-18 12:09 - INFO - epu - mac_counter - MAC Operation Count Summary
2026-07-18 12:09 - INFO - epu - mac_counter - ============================================================
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 224,280,576 ops (112,140,288 MACs) - /backbone/backbone/stem/conv/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 224,280,576 ops (112,140,288 MACs) - /backbone/backbone/dark2/dark2.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark2/dark2.1/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark2/dark2.1/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark2/dark2.1/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark2/dark2.1/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/backbone/dark2/dark2.1/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 224,280,576 ops (112,140,288 MACs) - /backbone/backbone/dark3/dark3.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark3/dark3.1/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark3/dark3.1/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark3/dark3.1/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark3/dark3.1/m/m.1/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark3/dark3.1/m/m.1/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark3/dark3.1/m/m.2/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark3/dark3.1/m/m.2/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark3/dark3.1/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/backbone/dark3/dark3.1/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 224,280,576 ops (112,140,288 MACs) - /backbone/backbone/dark4/dark4.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark4/dark4.1/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark4/dark4.1/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark4/dark4.1/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark4/dark4.1/m/m.1/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark4/dark4.1/m/m.1/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark4/dark4.1/m/m.2/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark4/dark4.1/m/m.2/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark4/dark4.1/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/backbone/dark4/dark4.1/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 224,280,576 ops (112,140,288 MACs) - /backbone/backbone/dark5/dark5.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark5/dark5.1/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 99,680,256 ops (49,840,128 MACs) - /backbone/backbone/dark5/dark5.1/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark5/dark5.2/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/backbone/dark5/dark5.2/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/backbone/dark5/dark5.2/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/backbone/dark5/dark5.2/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/backbone/dark5/dark5.2/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/lateral_conv0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_p4/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/C3_p4/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/C3_p4/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_p4/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_p4/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/reduce_conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_p3/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/C3_p3/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/C3_p3/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_p3/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_p3/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /head/stems.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 448,561,152 ops (224,280,576 MACs) - /head/reg_convs.0/reg_convs.0.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 448,561,152 ops (224,280,576 MACs) - /head/reg_convs.0/reg_convs.0.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 2,076,672 ops (1,038,336 MACs) - /head/reg_preds.0/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 519,168 ops (259,584 MACs) - /head/obj_preds.0/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 448,561,152 ops (224,280,576 MACs) - /head/cls_convs.0/cls_convs.0.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 448,561,152 ops (224,280,576 MACs) - /head/cls_convs.0/cls_convs.0.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 41,533,440 ops (20,766,720 MACs) - /head/cls_preds.0/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/bu_conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/C3_n3/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/C3_n3/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/C3_n3/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/C3_n3/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_n3/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /head/stems.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /head/reg_convs.1/reg_convs.1.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /head/reg_convs.1/reg_convs.1.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 519,168 ops (259,584 MACs) - /head/reg_preds.1/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 129,792 ops (64,896 MACs) - /head/obj_preds.1/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /head/cls_convs.1/cls_convs.1.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /head/cls_convs.1/cls_convs.1.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 10,383,360 ops (5,191,680 MACs) - /head/cls_preds.1/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/bu_conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/C3_n4/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /backbone/C3_n4/m/m.0/conv1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 112,140,288 ops (56,070,144 MACs) - /backbone/C3_n4/m/m.0/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 24,920,064 ops (12,460,032 MACs) - /backbone/C3_n4/conv2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 49,840,128 ops (24,920,064 MACs) - /backbone/C3_n4/conv3/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 12,460,032 ops (6,230,016 MACs) - /head/stems.2/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 28,035,072 ops (14,017,536 MACs) - /head/reg_convs.2/reg_convs.2.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 28,035,072 ops (14,017,536 MACs) - /head/reg_convs.2/reg_convs.2.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 129,792 ops (64,896 MACs) - /head/reg_preds.2/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 32,448 ops (16,224 MACs) - /head/obj_preds.2/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 28,035,072 ops (14,017,536 MACs) - /head/cls_convs.2/cls_convs.2.0/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 28,035,072 ops (14,017,536 MACs) - /head/cls_convs.2/cls_convs.2.1/conv/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter -   conv2d: 2,595,840 ops (1,297,920 MACs) - /head/cls_preds.2/Conv_quant
2026-07-18 12:09 - INFO - epu - mac_counter - ------------------------------------------------------------
2026-07-18 12:09 - INFO - epu - mac_counter - Total: 6,412,536,000 ops (3,206,268,000 MACs)
2026-07-18 12:09 - INFO - epu - mac_counter - ============================================================
2026-07-18 12:09 - INFO - epu - mac_counter - 
2026-07-18 12:10 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-07-18 12:10 - INFO - epu - codegen - START=============================plan_lrm_virtual
2026-07-18 12:10 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-07-18 12:10 - INFO - epu - codegen - START===============================lrm_alloc_loop
2026-07-18 12:12 - INFO - epu - codegen - START==============================amend_ctrl_flow
2026-07-18 12:12 - INFO - epu - codegen - START================================lrm_splitting
2026-07-18 12:14 - INFO - epu - codegen - START==============================ext_split_relay
2026-07-18 12:16 - INFO - epu - codegen - START====================================build_tir
2026-07-18 12:17 - INFO - epu - iss_testing - Found tranges for input: <tvm.contrib.epu.interval.Interval object at 0x7933783bd9f0>
2026-07-18 12:17 - INFO - epu - iss_testing - Started Running Graph on Chimera ISS...
FILM 30/30: 100%|███████████████████████████████████████████████████| 30/30 [00:41<00:00,  1.37s/it]
2026-07-18 12:18 - INFO - epu - iss_testing - Done 0:00:42.436318
out_vals = list(out_gpnpu.values())
gpnpu_boxes = out_vals[0].tensor
gpnpu_scores = out_vals[1].tensor
gpnpu_classes = out_vals[2].tensor
n_gpnpu = int(np.count_nonzero(gpnpu_scores > 0))
print_detections("GPNPU", gpnpu_boxes, gpnpu_scores, gpnpu_classes, n_gpnpu)

print(f"\nCPU: {n_cpu} detections | GPNPU: {n_gpnpu} detections")
GPNPU: 7 detections
  car           score=0.896  box=[86, 255, 148, 323]
  bus           score=0.896  box=[188, 170, 262, 302]
  person        score=0.806  box=[349, 246, 366, 306]
  person        score=0.784  box=[324, 246, 342, 302]
  person        score=0.464  box=[336, 244, 350, 302]
  truck         score=0.384  box=[85, 256, 147, 320]
  car           score=0.338  box=[143, 265, 153, 275]

CPU: 7 detections | GPNPU: 7 detections

6. Visualization

compare_detections(
    img,
    (cpu_boxes, cpu_scores, cpu_classes, n_cpu),
    (gpnpu_boxes, gpnpu_scores, gpnpu_classes, n_gpnpu),
    title=f"{CFG['display']} End-to-End: CPU vs Chimera GPNPU",
)
print("Saved: yolox_e2e_detections.png")
Saved: yolox_e2e_detections.png


7. Performance Profile

The ISS emits per-region cycle counts in profile.json. We use the SDK's built-in profiler to summarize execution cycles, stall cycles, and throughput.

import glob

import tvm.relay.backend.contrib.epu.codegen as epu_codegen
from tvm.contrib.epu.chimera_job import core

build_path = epu_codegen.get_module_build_path(module_name)
profile_files = glob.glob(str(build_path / "profile*.json"))
if profile_files:
    profile_files.sort()
    print(f"Profile: {profile_files[0]}")
    core._plot_profile_results(profile_files[0], clock_freq=1.0e9)
else:
    print("No profile.json found — ensure ISS run completed.")
Profile: /quadric/sdk-cli/examples/models/yolo/yolox_e2e/ccl_build/yolox_e2e_yolox_tiny/build/profile.json
[SDK-CLI] : TotalCycles: 11,026,666
[SDK-CLI] : Executions/second: 91

compute      : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 3.533M
data_array   : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1.833M
mac          : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 4.774M
data_ocm     : ▇▇▇▇▇▇▇▇ 795.64K
data_external:  67.964K

Summary

ModelsYOLOX-M (640×640, 8400 props) · YOLOX-Tiny (416×416, 3549 props) — one MODEL switch
PipelineBackbone (CGC) + Decode + NMS (CCL) — fully on Chimera GPNPU
TargetQC-N (8 cores, 16 MACs/PE) — 8 MB OCM for -M, 4 MB for -Tiny
QuantizationAsymmetric int8 activations, int8 weights (COCO calibration)
Custom Opyolox_postprocess.hpp — grid sizes derived from head shapes, class-aware NMS

Postprocess kernel techniques

TechniqueWhat it does
Flow-based argmaxreduce<Direction::Channel> streams 80 class channels through PEs via ReadFlow/WriteFlow
Split DMASeparate memCpy for box+obj (5 ch) and classes (80 ch) with channel offsets
Batched RAU tilesrau::load::tiles / rau::store::tiles for box coordinates
FastDivMultiply-shift reciprocal for grid coordinate division

Key takeaways

  1. Chipy makes it trivial to compose CGC backbones with CCL custom ops — the pipeline is 5 lines of Python
  2. One switch, two models — the CCL kernel derives grid sizes from the head tensor shapes, so YOLOX-M (640) and YOLOX-Tiny (416) share the exact same kernel; only the model, input size, and OCM budget change
  3. CCL custom ops can implement complex postprocessing (decode + NMS) entirely in OCM
  4. YOLOX-Tiny fits QC-N with 4 MB OCM — the smaller backbone leaves room to reserve OCM for on-chip decode + NMS
  5. End-to-end on GPNPU eliminates the host round-trip between backbone and postprocess

Citation

@article{yolox2021,
  title   = {YOLOX: Exceeding YOLO Series in 2021},
  author  = {Ge, Zheng and Liu, Songtao and Wang, Feng and Li, Zeming and Sun, Jian},
  journal = {arXiv preprint arXiv:2107.08430},
  year    = {2021}
}
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: DETR Encoder
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
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.