aorta

triton-vecadd — Proton capture of a Triton elementwise kernel

The smallest Proton example: one Triton kernel, launched in a short loop, checked against torch elementwise add. Use it to confirm the proton collector attaches and produces a hatchet tree before pointing it at a real model.

Requirements

   
Runtime Triton + PyTorch built for ROCm, one AMD GPU
Profiler Proton, which ships inside Triton — no separate install
Python deps torch, triton

Not runnable against a bare host interpreter. Proton attaches as python -m triton.profiler.proton using the workload’s own interpreter, so Triton must be importable there. A host that has the proton console script on PATH but no triton in its Python will fail — which is exactly why the collector uses -m rather than the console script.

Run it in a container

Install aorta inside the container and run the sweep there:

docker run --rm -it \
  --device=/dev/kfd --device=/dev/dri \
  --group-add video --ipc=host \
  --security-opt seccomp=unconfined \
  -v "$PWD:/work" -w /work \
  rocm/pytorch:latest \
  bash -lc '
    pip install -e . &&
    aorta sweep run \
      --recipe examples/profiling/proton/triton-vecadd/recipe.yaml \
      --output ./profiling_results \
      -- python examples/profiling/proton/triton-vecadd/vecadd.py \
           --size 1048576 --iters 20
  '

Pin the image by digest for anything you intend to compare over time. A ROCm venv with torch + triton on the host works the same way.

Run standalone

python examples/profiling/proton/triton-vecadd/vecadd.py --size 1048576 --iters 20

Options: --size, --iters, --block-size (must be a power of two, since tl.arange requires one — a non-power-of-two is rejected by argparse rather than failing later inside Triton’s compiler). Output:

vecadd: device=...
vecadd: size=1048576 iters=20 block_size=1024
vecadd: max_abs_err=0.000e+00
vecadd: PASS

The check is exact equality against x + y — elementwise float32 addition has no reassociation freedom, so anything non-zero means a real indexing or masking bug.

Run standalone under Proton

python -m triton.profiler.proton -n vecadd \
  examples/profiling/proton/triton-vecadd/vecadd.py --size 1048576 --iters 20
proton-viewer -m time/s vecadd.hatchet

What you get

A .hatchet JSON tree in the trial’s proton/ directory; the absolute path is reported as proton_artifact_dir. The collector walks the tree and emits proton_kernel_count, proton_gpu_time_ms and proton_top_kernel_ms, which reach perf.md and matrix.json::cells[*].metrics_summary because those reports aggregate numeric scalars only. The non-numeric proton_top_kernels list and proton_artifact_dir ride the same metrics channel but appear only in the per-trial dispatcher JSON (.result.metrics) — look there, not in perf.md, for the kernel names.

Read the raw tree yourself with proton-viewer -m time/s <file>.hatchet (run it in the same environment as the capture).

Notes

Provenance

The kernel is adapted from the Triton tutorial 01-vector-add.py in triton-lang/triton, MIT License.