Example: jetson.pyΒΆ

# Copyright (c) 2026 Justin Davis (davisjustin302@gmail.com)
#
# MIT License
"""
File showcasing Jetson-specific benchmarking and profiling.

Demonstrates :func:`trtutils.jetson.benchmark_engine` (latency + power + energy)
and :func:`trtutils.jetson.profile_engine` (per-layer energy contributions).
These mirror the standard :mod:`trtutils` benchmark / profile functions but
also sample VDD_TOTAL via tegrastats.

Exits cleanly when not running on a Jetson device. ``cuda_graph=False`` is
required for engines with DLA layers because DLA does not support CUDA graphs.
"""

from __future__ import annotations

import tempfile
from pathlib import Path

import tensorrt as trt

from trtutils import FLAGS, build_engine, set_log_level
from trtutils.download import download

# trtutils.jetson is only importable on Jetson; do the import lazily.
if FLAGS.IS_JETSON:
    from trtutils import jetson


def main() -> None:
    if not FLAGS.IS_JETSON:
        print("Skipping: not running on a Jetson device.")
        return

    tmp_dir = Path(tempfile.gettempdir())
    onnx_path = tmp_dir / "yolov8n.onnx"
    engine_path = tmp_dir / "yolov8n_detailed.engine"

    if not onnx_path.exists():
        print("Downloading yolov8n ONNX model...")
        download("yolov8n", onnx_path, imgsz=640, simplify=True)
    if not engine_path.exists():
        print("Building yolov8n engine with DETAILED profiling verbosity...")
        build_engine(
            onnx_path,
            engine_path,
            fp16=True,
            shapes=[("images", (1, 3, 640, 640))],
            profiling_verbosity=trt.ProfilingVerbosity.DETAILED,
        )

    print("Benchmarking on Jetson (measures latency + power + energy)...")
    result = jetson.benchmark_engine(
        engine_path,
        iterations=500,
        warmup_iterations=20,
        cuda_graph=False,
    )
    # latency Metric is in seconds; power is mW and energy mJ already
    print(f"  latency:   mean={result.latency.mean * 1000:.3f} ms")
    print(f"  power:     mean={result.power_draw.mean:.1f} mW")
    print(f"  energy:    mean={result.energy.mean:.3f} mJ/iter")

    print("\nProfiling per-layer energy (this takes a while)...")
    prof = jetson.profile_engine(
        engine_path,
        iterations=2000,
        warmup_iterations=20,
        cuda_graph=False,
    )
    print(f"  layers profiled: {len(prof.layers)}")
    print(f"  total power:     {prof.power_draw.mean:.1f} mW")
    print(f"  total energy:    {prof.energy.mean:.3f} mJ/iter")

    hottest = sorted(prof.layers, key=lambda layer: layer.energy, reverse=True)[:5]
    print("\nTop 5 layers by energy:")
    for layer in hottest:
        print(
            f"  {layer.energy:7.3f} mJ  ({layer.power:6.1f} mW for {layer.mean:5.3f} ms)  "
            f"{layer.name}"
        )


if __name__ == "__main__":
    set_log_level("ERROR")
    main()