mcpbeat Sign in

Perf Workload Profiling Agent Skill

> (1) Training loop — inject manual timing to report per-iteration latency, throughput (samples/sec), and data load time. (2) Standalone kernel/op — write CUDA event timing code with warmup, per-iteration statistics, and anti-pattern avoidance. Also covers NVTX annotation for labeling profiler timelines. Nsight Compute), writing kernels (Triton, CuTe, CUDA), applying optimizations (CUDA Graphs, gradient checkpointing, fusion), or interpreting roofline/SOL% metrics. training loop", "samples per second", "NVTX annotate", "instrument my dataloader", "data load time", "kernel timing", "how do I time".

4k tokens
context cost
the whole folder, loaded on every use
4
files
instructions only
0
copies elsewhere
how many repositories repackaged it
14292
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/NVIDIA/TensorRT-LLM --skill perf-workload-profiling

What comes with it

9 498 bytes besides the instruction
references/benchmarking-patterns.md
references/nvtx-api.md
references/pytorch-profiler-api.md

The instruction itself

13 sections, as written by the author

Workload Profiling

Quick Reference

Pick ONE path based on the workload type:

| Workload | Approach | Section |

|----------|----------|---------|

| Training loop | Manual torch.cuda.synchronize() + time.perf_counter() with warmup | Loop Workloads — Manual Timing |

| Single kernel or op | Write CUDA event benchmark (pre-allocate, warmup, event pairs) | Non-Loop Workloads — CUDA Event Benchmarking |

| Add timeline labels for nsys | Use @nvtx.annotate decorator or context manager | NVTX Reference |

Principles

  • Measure, don't guess. Every performance claim must trace back to profiler output or structured measurement data. Never invent metrics.
  • Isolate steady-state. Warmup costs (CUDA context init, cuDNN autotuning, JIT compilation) distort measurements. Always exclude warmup iterations before collecting data.
  • Use hardware timing. CUDA events measure GPU time precisely. CPU timers (time.perf_counter()) include host overhead and miss asynchronous execution.
  • No sync inside measurement loops. Each torch.cuda.synchronize() adds 10-50us overhead. Record CUDA events asynchronously, sync once at the end.
  • Pre-allocate everything. Tensors, events, compiled kernels — all before the timing loop. For CuTe DSL kernels, pre-compile with cute.compile().
  • Minimize profiler interference. Start with lightweight measurement (manual timing for latency/throughput) and escalate to heavier tools (Kineto, nsys, ncu) only when lighter tools cannot answer the question.

Loop Workloads — Manual Timing

For training loops and iterative workloads, use manual torch.cuda.synchronize() + time.perf_counter() timing with warmup to measure per-iteration latency, throughput, and data load time.

Injection Template

Read the user's training script, understand the dataloader and loop structure, then inject timing code.

import time
import torch

WARMUP = 5
NUM_ITERS = 30
BATCH_SIZE = 128  # global batch size for throughput calculation

iter_times = []
data_times = []

for i, batch in enumerate(dataloader):
    if i >= WARMUP + NUM_ITERS:
        break

    t_data_end = time.perf_counter()

    torch.cuda.synchronize()
    t_start = time.perf_counter()

    # ... existing training loop body ...

    torch.cuda.synchronize()
    t_end = time.perf_counter()

    if i >= WARMUP:
        iter_ms = (t_end - t_start) * 1000
        iter_times.append(iter_ms)
        if i > 0:
            data_times.append((t_data_end - prev_iter_end) * 1000)
        print(f"[{i:04d}]: iter {iter_ms:.2f} ms, fps {BATCH_SIZE / (iter_ms / 1000):.2f}")

    prev_iter_end = t_end

import statistics
print(f"Average: iter {statistics.mean(iter_times):.2f} ms, "
      f"fps {BATCH_SIZE / (statistics.mean(iter_times) / 1000):.2f}")

Interpreting Results

  • iter (ms): Wall-clock time per iteration (compute + communication, excluding data loading)
  • data (ms): Time spent in dataloader between iterations. If data / iter > 0.2, data loading is a bottleneck.
  • fps: Global throughput in samples/second. Use with known FLOPs-per-sample to compute MFU.

Limitations

Manual timing reports aggregate iteration timing — not per-sub-phase breakdown (forward, backward, optimizer). When the user asks where time is spent within compute:

  • Add torch.cuda.synchronize() + time.perf_counter() around each sub-phase for a one-off diagnosis, OR
  • Add NVTX annotations and run with nsys profile for timeline visualization.

Non-Loop Workloads — CUDA Event Benchmarking

For single kernels, one-shot inference, or standalone operations, write CUDA event benchmarking code directly.

PyTorch: Simple (Mean Only)

import torch

def benchmark(fn, warmup=50, iters=100):
    for _ in range(warmup):
        fn()
    torch.cuda.synchronize()

    start = torch.cuda.Event(enable_timing=True)
    end = torch.cuda.Event(enable_timing=True)

    start.record()
    for _ in range(iters):
        fn()
    end.record()
    torch.cuda.synchronize()

    return start.elapsed_time(end) / iters  # ms per iteration

PyTorch: Detailed (Per-Iteration Stats)

import torch
import statistics

def benchmark_detailed(fn, warmup=50, iters=100):
    for _ in range(warmup):
        fn()
    torch.cuda.synchronize()

    starts = [torch.cuda.Event(enable_timing=True) for _ in range(iters)]
    ends = [torch.cuda.Event(enable_timing=True) for _ in range(iters)]

    for i in range(iters):
        starts[i].record()
        fn()
        ends[i].record()

    torch.cuda.synchronize()
    times = [starts[i].elapsed_time(ends[i]) for i in range(iters)]

    return {
        "mean_ms": statistics.mean(times),
        "median_ms": statistics.median(times),
        "std_ms": statistics.stdev(times) if len(times) > 1 else 0,
        "min_ms": min(times),
        "max_ms": max(times),
    }

Anti-Patterns

| Anti-Pattern | Problem |

|--------------|---------|

| torch.cuda.synchronize() before AND after each iteration | Adds ~10-50us overhead per iteration |

| time.perf_counter() for GPU timing | Measures CPU time, misses async GPU execution |

| Missing warmup | First iterations include JIT, clock ramp-up, context init |

| Allocating tensors inside measurement loop | Allocation overhead pollutes timing |

| Reporting only mean | Hides variance, outliers, bimodal distributions |

For additional benchmarking templates (CUDA Graph, CuTe DSL, Triton, Raw CUDA), see references/benchmarking-patterns.md.

NVTX Reference

NVTX (NVIDIA Tools Extension) adds named annotations to profiler timelines. Use NVTX to label phases (forward, backward, optimizer) for readability in nsys — not for measurement.

import nvtx

# Decorator — annotates every call
@nvtx.annotate("training_step", color="blue")
def training_step():
    ...

# Context manager — annotates a code block
with nvtx.annotate("data_loading", color="green"):
    batch = next(dataloader)
  • Do annotate training phases (forward, backward, optimizer, data loading) for nsys timeline clarity.
  • Do not annotate for measurement — use CUDA events or manual timing instead.
  • Do not over-annotate — too many fine-grained ranges add visual clutter and minor overhead.

For NVTX domains, categories, payloads, and legacy API details, see references/nvtx-api.md.

References

  • references/benchmarking-patterns.md — CUDA Graph, CuTe DSL, Triton, Raw CUDA templates; warmup guidance; GPU hardware properties; reporting format
  • references/nvtx-api.md — Domains, categories, payloads, legacy push/pop API
  • references/pytorch-profiler-api.md — PyTorch 2.0+ profiler API changes (device_time vs deprecated cuda_time)

Other skills for the same job

different authors, same section of the catalogue
Datacommons Client
by christophacham
×3

Work with Data Commons, a platform providing programmatic access to public statistical data from global sources. Use this skill when working with demographic data, economic indicators, health statistics, environmental data, or any public datasets available through Data Commons. Applicable for querying population statistics, GDP figures, unemployment rates, disease prevalence, geographic entity resolution, and exploring relationships between statistical entities.

9k tokens
Neuropixels Analysis
by christophacham
×3

Neuropixels neural recording analysis. Load SpikeGLX/OpenEphys data, preprocess, motion correction, Kilosort4 spike sorting, quality metrics, Allen/IBL curation, AI-assisted visual analysis, for Neuropixels 1.0/2.0 extracellular electrophysiology. Use when working with neural recordings, spike sorting, extracellular electrophysiology, or when the user mentions Neuropixels, SpikeGLX, Open Ephys, Kilosort, quality metrics, or unit curation.

36k tokens scripts
Polars
by christophacham
×3

Fast in-memory DataFrame library for datasets that fit in RAM. Use when pandas is too slow but data still fits in memory. Lazy evaluation, parallel execution, Apache Arrow backend. Best for 1-100GB datasets, ETL pipelines, faster pandas replacement. For larger-than-RAM data use dask or vaex.

20k tokens
Senior Data Scientist
by ComeOnOliver
×3

World-class data science skill for statistical modeling, experimentation, causal inference, and advanced analytics. Expertise in Python (NumPy, Pandas, Scikit-learn), R, SQL, statistical methods, A/B testing, time series, and business intelligence. Includes experiment design, feature engineering, model evaluation, and stakeholder communication. Use when designing experiments, building predictive models, performing causal analysis, or driving data-driven decisions.

8k tokens scripts
Pyopenms
by ComeOnOliver
×3

Python interface to OpenMS for mass spectrometry data analysis. Use for LC-MS/MS proteomics and metabolomics workflows including file handling (mzML, mzXML, mzTab, FASTA, pepXML, protXML, mzIdentML), signal processing, feature detection, peptide identification, and quantitative analysis. Apply when working with mass spectrometry data, analyzing proteomics experiments, or processing metabolomics datasets.

28k tokens
Dask
by ComeOnOliver
×2

Parallel/distributed computing. Scale pandas/NumPy beyond memory, parallel DataFrames/Arrays, multi-file processing, task graphs, for larger-than-RAM datasets and parallel workflows.

35k tokens
Tensorboard
by Orchestra-Research
×1

Visualize training metrics, debug models with histograms, compare experiments, visualize model graphs, and profile performance with TensorBoard - Google's ML visualization toolkit

15k tokens
Datacommons Client
by BioTender-max
×1

Work with Data Commons, a platform providing programmatic access to public statistical data from global sources. Use this skill when working with demographic data, economic indicators, health statistics, environmental data, or any public datasets available through Data Commons. Applicable for querying population statistics, GDP figures, unemployment rates, disease prevalence, geographic entity resolution, and exploring relationships between statistical entities.

9k tokens

How to use it

Copy the folder

Take nvidia/perf-workload-profiling from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.