profiling-api
Skill34 starsChanged 7 months agoApache-2.0View on GitHub
Add profiling zones, metrics, and annotations to Kit-based C++ and Python code. Covers Carbonite macros (CARB_PROFILE_ZONE, CARB_PROFILE_FUNCTION, GPU zones), Python profiler API (decorators, begin/end), profiler masks, channels, Tracy plot data, event annotations, and automatic Kit Python function capture (CARB_PROFILING_PYTHON). Use when a developer asks how to add profiling spans to Kit/Carbonite code, configure masks/channels, record custom Tracy plots, or annotate traces with event markers. NOT for capturing traces (use profiling), analyzing traces (use nsys-analyze), or non-Kit Python function tracing (use nvtx-python).
In this repository12 other files it gives its agents.
- benchmark-isaaclabSkill
- benchmark-isaacsimSkill
- diagnose-perfSkill
- install-isaaclabSkill
- install-isaacsimSkill
- install-profilersSkill
- kit-app-streaming-debugSkill
- nsys-analyzeSkill
- nvtx-pythonSkill
- perf-tuningSkill
- profilingSkill
- tracy-memorySkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 0 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 28
No variadic args → ProfileZoneStatic (pre-registered, faster)
- Very specific: line 48
Prefer RAII style (CARB_PROFILE_ZONE) over manual begin/end.
- Very specific: line 125
If a zone uses mask 0, Carbonite treats it as kCaptureMaskDefault (1).
- Very specific: line 127
Workflow: Start with --/app/profilerMask=1 (major spans only, minimal overhead).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Profiling API — Instrumenting Kit-Based Code
How to add profiling zones, metrics, and annotations to C++ and Python code in the Carbonite/Kit ecosystem.
For capturing traces, see the profiling skill. For analyzing them, see nsys-analyze.
C++ Profiling Macros
Source: carb/profiler/Profile.h
Scope-Based Zone (most common)
#include <carb/profiler/Profile.h>
constexpr const uint64_t kProfilerMask = 1;
void myFunction() {
CARB_PROFILE_ZONE(kProfilerMask, "My C++ function");
doHeavyWork(); // zone closes automatically at scope exit (RAII)
}Parameters: (maskOrChannel, zoneName, ...variadic_args)
- No variadic args →
ProfileZoneStatic(pre-registered, faster) - With variadic args →
ProfileZoneDynamic(printf formatting)
Auto Function Name
void myFunction() {
CARB_PROFILE_FUNCTION(kProfilerMask);
// zone name = function's pretty-printed name
}Manual Begin/End
auto zoneId = CARB_PROFILE_BEGIN(kProfilerMask, "Manual zone");
// ... work ...
CARB_PROFILE_END(kProfilerMask, zoneId);Prefer RAII style (CARB_PROFILE_ZONE) over manual begin/end.
GPU Zones
Kit's RTX renderer uses query-based GPU zone capture:
auto gpuCtx = CARB_PROFILE_CREATE_GPU_CONTEXT("Vulkan GPU", cpuTs, gpuTs, gpuPeriod, "vulkan");
CARB_PROFILE_GPU_QUERY_BEGIN(kProfilerMask, gpuCtx, queryId, "RTX Render Pass");
// ... submit GPU commands ...
CARB_PROFILE_GPU_QUERY_END(kProfilerMask, gpuCtx, queryId);
CARB_PROFILE_GPU_SET_QUERY_VALUE(kProfilerMask, gpuCtx, queryId, gpuTimestamp);Enable GPU zones in Tracy:
--/profiler/gpu/tracyInject/enabled=true
--/rtx/addTileGpuAnnotations=truePython Profiling API
Decorator (simplest)
import carb.profiler
@carb.profiler.profile
def my_function():
do_something()Manual begin/end
carb.profiler.begin(1, "My Python operation")
# ... work ...
carb.profiler.end(1)Full IProfiler Interface
profiler = carb.profiler.acquire_profiler_interface()
profiler.begin(mask, name) # zone start
profiler.end(mask) # zone end
profiler.set_capture_mask(mask) -> int # returns previous mask
profiler.get_capture_mask() -> int
profiler.value_float(mask, value, name) # Tracy Plot (float)
profiler.value_int(mask, value, name) # Tracy Plot (int)
profiler.value_uint(mask, value, name) # Tracy Plot (uint)
profiler.instant(mask, type, name) # instant event
profiler.flow(mask, type, id, name) # cross-thread flow
profiler.frame(mask, name) # frame marker
profiler.set_python_profiling_enabled(bool) # toggle auto-profiling
profiler.is_python_profiling_enabled() -> boolTypes:
carb.profiler.InstantType.THREAD # thread timeline
carb.profiler.InstantType.PROCESS # process-wide timeline
carb.profiler.FlowType.BEGIN / END # flow start/endProfiler Mask
64-bit bitmask controlling which zones are captured: (zone_mask & capture_mask) != 0
constexpr uint64_t kCaptureMaskNone = 0; // nothing
constexpr uint64_t kCaptureMaskAll = (uint64_t)-1; // everything (default when no mask arg)
constexpr uint64_t kCaptureMaskDefault = uint64_t(1); // bit 0
constexpr uint64_t kCaptureMaskProfiler = uint64_t(1) << 63; // profiler internalsIf a zone uses mask 0, Carbonite treats it as kCaptureMaskDefault (1).
Workflow: Start with --/app/profilerMask=1 (major spans only, minimal overhead). If more detail needed, remove the arg (defaults to ALL). Always start coarse, then zoom in.
Profiler Channels
Higher-level abstraction over masks, toggled at runtime via settings:
Declaring a Channel (C++)
CARB_PROFILE_DECLARE_CHANNEL("myext.rendering", 1, true, g_myRenderingChannel);
CARB_PROFILE_ZONE(g_myRenderingChannel, "My rendering work");Runtime Toggle
--/profiler/channels/<name>/enabled=true|falseCommonly disabled during benchmarks (too noisy):
--/profiler/channels/carb.events/enabled=false
--/profiler/channels/carb.tasking/enabled=falseMemory channels:
--/profiler/channels/cpu.memory/enabled=true
--/profiler/channels/cpu.virtualmemory/enabled=true
--/profiler/channels/graphics.memory/enabled=trueTracy Plot Data (Numeric Metrics)
Record time-series values displayed as graphs in Tracy's Plot view.
C++
float gpuFrameTimeMs = 8.5f;
CARB_PROFILE_VALUE(gpuFrameTimeMs, 1, "GPU Frame Time (ms)");
int32_t triangleCount = 1500000;
CARB_PROFILE_VALUE(triangleCount, 1, "Triangle Count");
uint32_t gpuMemoryMB = 4096;
CARB_PROFILE_VALUE(gpuMemoryMB, 1, "GPU Memory (MB)");
int gpuIndex = 0;
CARB_PROFILE_VALUE(gpuFrameTimeMs, 1, "GPU %d Frame Time", gpuIndex);Python
profiler.value_float(1, 8.5, "GPU Frame Time (ms)")
profiler.value_int(1, 1500000, "Triangle Count")
profiler.value_uint(1, 4096, "GPU Memory (MB)")Event Annotations
Instant Events
// C++
CARB_PROFILE_EVENT(1, carb::profiler::InstantType::Thread, "Scene loading started");
CARB_PROFILE_EVENT(1, carb::profiler::InstantType::Process, "Phase transition: WARM -> BENCHMARK");# Python
profiler.instant(1, carb.profiler.InstantType.THREAD, "Scene loading started")
profiler.instant(1, carb.profiler.InstantType.PROCESS, "Phase transition")Display as Tracy messages (recommended):
--/plugins/carb.profiler-tracy.plugin/instantEventsAsMessages=truecommand_macro.core Annotations
The omni.kit.command_macro.core extension auto-inserts [command_macro][Measurement] Start/End - <tag> events around benchmark measurements.
Automatic Python Function Capture
Capture all Python function calls without per-function instrumentation:
export CARB_PROFILING_PYTHON=1Or programmatically:
profiler.set_python_profiling_enabled(True)Performance warning: Significant overhead. Tracy file size ~4x larger (measured: 275MB → 1.2GB). Never use during benchmark measurement — only in the TRACY analysis phase.
Profiling Backend Summary
| Backend | Plugin | Output | Best For |
| CPU (ChromeTrace) | carb.profiler-cpu.plugin | .json/.gz | Offline analysis, targeted captures |
| Tracy | carb.profiler-tracy.plugin | .tracy (live capture) | Real-time flame graphs, GPU context, stats |
| NVTX | carb.profiler-nvtx.plugin | .nsys-rep (via nsys) | GPU kernels, CUDA/Vulkan analysis |
CPU backend can be toggled on/off at runtime for targeted capture:
profiler.set_capture_mask(1) # start
# ... section to profile ...
profiler.set_capture_mask(0) # stopDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

