gputrace

package module
v0.0.0-...-3d7d32e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 10 Imported by: 0

README

gputrace

gputrace parses and analyzes Apple Metal GPU trace files (.gputrace bundles).

Installation

go install github.com/tmc/gputrace/cmd/gputrace@latest

Verify installation:

gputrace version

Quick Start

# Show trace statistics (dispatch counts, kernel names, timing)
gputrace stats trace.gputrace

# Full profiler breakdown (timing, pipelines, execution cost)
gputrace profiler trace.gputrace

# Export to pprof format for use with go tool pprof
gputrace pprof trace.gputrace -o trace.pb
go tool pprof -http=:8080 trace.pb

# View text timeline or export Chrome/Perfetto timeline
gputrace timeline trace.gputrace --format perfetto -o trace.json

# Compare two traces
gputrace diff A.gputrace B.gputrace --explain

Commands

Group Command Description
Overview stats Comprehensive trace statistics
api-calls API call sequences
dump Raw API call dump
Kernel & Shader shaders Shader performance metrics
kernels Kernel functions and pipeline mappings
shader-source Source-level performance attribution
Timing & Profiling timing Timing metrics export
profiler GPU profiler data extraction
pprof pprof format export
correlate Correlate timing with hardware metrics
Command Buffers command-buffers Command buffer analysis
encoders Compute encoder listing
Buffer Analysis buffers Buffer listing and properties
buffer-access Buffer access patterns
buffer-timeline Buffer allocation timeline
Visualization timeline Text timeline and Chrome/Perfetto export
graph Graph visualization
tree Execution tree view
diff Compare two traces
insights Actionable performance insights
Capture xcode-profile Xcode GPU profiler automation
xcode-bindings Inspect private Xcode GTShaderProfiler bindings
xcode-parity Audit Xcode metric parity for a trace
Utilities mtlb Metal Library Binary inspection
clear-buffers Zero out buffers to reduce trace size
version Print build version

Run gputrace [command] --help for details on any command.

Trace Diff

Compare two profiled traces and explain performance deltas at dispatch, kernel, encoder, and timeline-window levels:

# Human-readable summary
gputrace diff A.gputrace B.gputrace --explain

# Function and encoder views
gputrace diff A.gputrace B.gputrace --by function,encoder --limit 25

# Dispatch outliers (with source indices)
gputrace diff A.gputrace B.gputrace --by dispatch --min-delta-us 30 --limit 50

# JSON or CSV output
gputrace diff A.gputrace B.gputrace --json > diff.json
gputrace diff A.gputrace B.gputrace --csv --by function > function_deltas.csv

# Auto-discover newest trace pair and run quick triage
gputrace diff --bench-dir /path/to/bench-traces --quick

# Write markdown report
gputrace diff A.gputrace B.gputrace --md-out /tmp/report.md

See docs/TRACE_DIFF_WORKFLOW.md for the full workflow and sample output.

Testing

go test ./...

The repository includes small canonical fixtures under testdata/traces:

  • 01-single-encoder for basic parsing and diff smoke tests
  • 02-two-encoders, 03-three-encoders, 04-four-encoders, and 06-six-encoders for multi-encoder parsing
  • known-invocations-*, low-alu-*, high-alu-*, low-occupancy-*, and high-occupancy-* for focused counter and shader-metric scenarios

Some success paths require capabilities that are not shipped in the small in-repo fixtures:

  • profiler requires profiled traces with .gpuprofiler_raw/streamData
  • perf-counter validation and CSV import require local .gpuprofiler_raw counter records or Xcode Counters.csv exports
  • shader-source requires traces with source attribution data

See docs/TESTING.md for opt-in integration test environment variables and fixture handling.

Documentation

Detailed format and workflow documentation lives in docs/:

Reverse-engineering notes and implementation status documents live in docs/research/.

GPU Timing Methodology

.gputrace files do not contain pre-computed timing percentages. Xcode Instruments derives shader cost by replaying captured GPU workloads with performance counters enabled. This library uses .gpuprofiler_raw/streamData for measured timing when profiler data is present: APSTimelineData ReplayerGPUTime, command-buffer timestamps, and encoder/dispatch cumulative offsets. Execution-cost sampling from Profiling_f_*.raw and GPRWCNTR encoder profiles are reported as counter/profile annotations, not as wall-clock timing sources. Non-profiled traces may emit approximate extracted or synthetic timing for visualization and triage; treat those values as estimates.

Developer Convenience

For local macOS reinstall and permission setup:

make reinstall

License

MIT License. See LICENSE for details.

Documentation

Overview

Package gputrace parses Metal .gputrace bundles.

A .gputrace file is a directory bundle containing Metal GPU capture data. Use Open to read a bundle:

trace, err := gputrace.Open("mytrace.gputrace")
if err != nil {
	log.Fatal(err)
}

The returned Trace contains the parsed metadata, capture data, command buffers, timing data, counters, and shaders.

The command-line tool is in cmd/gputrace.

Index

Examples

Constants

View Source
const (
	RecordTypeCommand      = trace.RecordTypeCommand
	RecordTypeString       = trace.RecordTypeString
	RecordTypeFunction     = trace.RecordTypeFunction
	RecordTypeInteger      = trace.RecordTypeInteger
	RecordTypeUnsignedLong = trace.RecordTypeUnsignedLong
)

Re-export constants

View Source
const (
	MagicMTSP   = trace.MagicMTSP
	MagicXDIC   = trace.MagicXDIC
	MagicBPList = trace.MagicBPList
)

Re-export magic constants

View Source
const (
	InsightBottleneck   = analysis.InsightBottleneck
	InsightOptimization = analysis.InsightOptimization
	InsightAntiPattern  = analysis.InsightAntiPattern
	InsightInfo         = analysis.InsightInfo
)

Re-export insight type constants (gputrace-97)

View Source
const (
	SeverityCritical = analysis.SeverityCritical
	SeverityHigh     = analysis.SeverityHigh
	SeverityMedium   = analysis.SeverityMedium
	SeverityLow      = analysis.SeverityLow
	SeverityInfo     = analysis.SeverityInfo
)

Re-export insight severity constants (gputrace-97)

Variables

View Source
var (
	ErrInvalidTrace    = trace.ErrInvalidTrace
	ErrInvalidMagic    = trace.ErrInvalidMagic
	ErrMissingMetadata = trace.ErrMissingMetadata
)

Re-export errors

Functions

func CompareBuffers

func CompareBuffers(info1, info2 *analysis.BufferSizeInfo) *analysis.BufferDiff

CompareBuffers compares two sets of buffer size information.

func CompareTraces

func CompareTraces(baseline, current *TimingMetrics) *timing.TimingComparison

CompareTraces compares baseline and current timing metrics.

func CorrelateShaderMetrics

func CorrelateShaderMetrics(t *Trace) (*shader.ShaderCorrelationReport, error)

CorrelateShaderMetrics correlates shader metrics for t.

func DumpCommandBuffer

func DumpCommandBuffer(t *Trace, w io.Writer, cbIndex int) error

DumpCommandBuffer writes command buffer cbIndex from t to w.

func ExportShaderMetricsCSV

func ExportShaderMetricsCSV(w io.Writer, report *ShaderMetricsReport) error

ExportShaderMetricsCSV writes shader metrics as CSV.

func ExportShaderMetricsJSON

func ExportShaderMetricsJSON(w io.Writer, report *ShaderMetricsReport) error

ExportShaderMetricsJSON writes shader metrics as JSON.

func ExportTimingMetricsCSV

func ExportTimingMetricsCSV(w io.Writer, metrics *TimingMetrics) error

ExportTimingMetricsCSV writes timing metrics as CSV.

func ExportTimingMetricsJSON

func ExportTimingMetricsJSON(w io.Writer, metrics *TimingMetrics) error

ExportTimingMetricsJSON writes timing metrics as JSON.

func ExtractBufferSizes

func ExtractBufferSizes(t *Trace) (*analysis.BufferSizeInfo, error)

ExtractBufferSizes extracts buffer size information from t.

func ExtractShaderSourceAttribution

func ExtractShaderSourceAttribution(t *Trace, shaderName string) (*shader.ShaderSourceAttribution, error)

ExtractShaderSourceAttribution extracts source attribution for shaderName.

func ExtractStore0Timing

func ExtractStore0Timing(t *Trace) (*timing.Store0TimingData, error)

ExtractStore0Timing extracts timing data from the store0 capture stream.

func FormatBufferAccessReport

func FormatBufferAccessReport(a *BufferAccessAnalysis, verbose bool) string

FormatBufferAccessReport formats a buffer access report.

func FormatBufferDiff

func FormatBufferDiff(diff *analysis.BufferDiff, trace1Path, trace2Path string) string

FormatBufferDiff formats a buffer comparison.

func FormatBufferTimelineASCII

func FormatBufferTimelineASCII(a *BufferTimelineAnalysis, width int) string

FormatBufferTimelineASCII formats a buffer timeline with the given width.

func FormatBufferTimelineSummary

func FormatBufferTimelineSummary(a *BufferTimelineAnalysis) string

FormatBufferTimelineSummary formats a buffer timeline summary.

func FormatCorrelationReport

func FormatCorrelationReport(report *shader.ShaderCorrelationReport) string

FormatCorrelationReport formats a shader correlation report.

func FormatCounterSamplingResult

func FormatCounterSamplingResult(result *counter.CounterSamplingResult) string

FormatCounterSamplingResult formats a counter sampling result.

func FormatCounterSamplingSimulation

func FormatCounterSamplingSimulation(sim *replay.CounterSamplingSimulation) string

FormatCounterSamplingSimulation formats a counter sampling simulation.

func FormatInsightsReport

func FormatInsightsReport(report *InsightsReport) string

FormatInsightsReport formats a performance insights report.

func FormatShaderSourceAttribution

func FormatShaderSourceAttribution(attr *shader.ShaderSourceAttribution, showHints bool) string

FormatShaderSourceAttribution formats shader source attribution.

func FormatShaderSourceAttributionHTML

func FormatShaderSourceAttributionHTML(attr *shader.ShaderSourceAttribution) string

FormatShaderSourceAttributionHTML formats shader source attribution as HTML.

func FormatShadersSimple

func FormatShadersSimple(w io.Writer, report *ShaderMetricsReport) error

FormatShadersSimple writes a simple shader report to w.

func FormatShadersXcodeStyle

func FormatShadersXcodeStyle(w io.Writer, report *ShaderMetricsReport, t *Trace, showEstimates bool) error

FormatShadersXcodeStyle writes an Xcode-style shader report to w.

func FormatTimingComparison

func FormatTimingComparison(comp *timing.TimingComparison) string

FormatTimingComparison formats a timing comparison.

func FormatTimingMetrics

func FormatTimingMetrics(metrics *TimingMetrics) string

FormatTimingMetrics formats timing metrics.

func NewCountersCSVExporter

func NewCountersCSVExporter(t *Trace) *counter.CountersCSVExporter

NewCountersCSVExporter returns a counter CSV exporter for t.

func NewReplayEngine

func NewReplayEngine(t *Trace) *replay.ReplayEngine

NewReplayEngine returns a replay engine for t.

func NewTimingExtractorProfilerRaw

func NewTimingExtractorProfilerRaw(t *Trace) *timing.TimingExtractorProfilerRaw

NewTimingExtractorProfilerRaw returns a raw profiler timing extractor for t.

func ParseDetailedCommandBuffer

func ParseDetailedCommandBuffer(t *Trace, cbIndex int) (*command.DetailedCommandBuffer, error)

ParseDetailedCommandBuffer parses command buffer cbIndex from t.

func ToPprof

func ToPprof(t *Trace, timings []*EncoderTiming) (*profile.Profile, error)

ToPprof converts timing data to a pprof profile.

func ToPprofWithMetrics

func ToPprofWithMetrics(t *Trace, mapper *ShaderSourceMapper, stats *PerfCounterStats) (*profile.Profile, error)

ToPprofWithMetrics converts counter metrics to a pprof profile.

func ToPprofWithSource

func ToPprofWithSource(t *Trace, timings []*EncoderTiming, mapper *ShaderSourceMapper) (*profile.Profile, error)

ToPprofWithSource converts timing data and source mappings to a pprof profile.

Types

type APICallList

type APICallList = trace.APICallList

API Call types (for buffer extraction)

type BufferAccessAnalysis

type BufferAccessAnalysis = analysis.BufferAccessAnalysis

Buffer access analysis types (gputrace-93)

func AnalyzeBufferAccess

func AnalyzeBufferAccess(t *Trace) (*BufferAccessAnalysis, error)

AnalyzeBufferAccess analyzes buffer access in t.

type BufferAccessInfo

type BufferAccessInfo = analysis.BufferAccessInfo

Re-export main types from internal packages

type BufferAlias

type BufferAlias = analysis.BufferAlias

Re-export main types from internal packages

type BufferLifecycle

type BufferLifecycle = analysis.BufferLifecycle

Re-export main types from internal packages

type BufferTimelineAnalysis

type BufferTimelineAnalysis = analysis.BufferTimelineAnalysis

Buffer timeline types (gputrace-94)

func ExtractBufferTimeline

func ExtractBufferTimeline(t *Trace) (*BufferTimelineAnalysis, error)

ExtractBufferTimeline extracts the buffer timeline from t.

type CommandBuffer

type CommandBuffer = trace.CommandBuffer

Re-export main types from internal packages

type CommandBufferCalls

type CommandBufferCalls = trace.CommandBufferCalls

Re-export main types from internal packages

type CommandBufferTiming

type CommandBufferTiming = timing.CommandBufferTiming

Re-export main types from internal packages

type ComputeEncoder

type ComputeEncoder = trace.ComputeEncoder

Re-export main types from internal packages

type CounterSamplingConfig

type CounterSamplingConfig = counter.CounterSamplingConfig

Counter sampling types (gputrace-104)

type EncoderAccessInfo

type EncoderAccessInfo = analysis.EncoderAccessInfo

Re-export main types from internal packages

type EncoderTiming

type EncoderTiming = trace.EncoderTiming

Re-export main types from internal packages

func ConvertStore0ToEncoderTimings

func ConvertStore0ToEncoderTimings(t *Trace, store0Data *timing.Store0TimingData) []*EncoderTiming

ConvertStore0ToEncoderTimings converts store0 timing data to encoder timings.

func ExtractTimingData

func ExtractTimingData(t *Trace) ([]*EncoderTiming, error)

ExtractTimingData extracts encoder timing data from t.

func GenerateSyntheticTiming

func GenerateSyntheticTiming(t *Trace) []*EncoderTiming

GenerateSyntheticTiming generates synthetic timing data for t.

type EncoderTimingInfo

type EncoderTimingInfo = counter.EncoderTimingInfo

Encoder timing from profiler data (streamData plist)

func ExtractEncoderTimingsFromProfiler

func ExtractEncoderTimingsFromProfiler(t *Trace) ([]EncoderTimingInfo, int, error)

ExtractEncoderTimingsFromProfiler extracts real timing data from .gpuprofiler_raw streamData. Returns per-encoder timing info, total time in microseconds, and any error.

type FormattedAPICall

type FormattedAPICall = trace.FormattedAPICall

Re-export main types from internal packages

type InitCall

type InitCall = trace.InitCall

Re-export main types from internal packages

type InsightSeverity

type InsightSeverity = analysis.InsightSeverity

Re-export main types from internal packages

type InsightType

type InsightType = analysis.InsightType

Re-export main types from internal packages

type InsightsReport

type InsightsReport = analysis.InsightsReport

Re-export main types from internal packages

func GenerateInsights

func GenerateInsights(t *Trace) (*InsightsReport, error)

GenerateInsights generates performance insights for t.

type KernelStat

type KernelStat = trace.KernelStat

Kernel analysis types

type KernelTiming

type KernelTiming = timing.KernelTiming

Re-export main types from internal packages

type Metadata

type Metadata = trace.Metadata

Re-export main types from internal packages

type PerfCounterStats

type PerfCounterStats = counter.PerfCounterStats

Re-export main types from internal packages

func ParsePerfCounters

func ParsePerfCounters(t *Trace) (*PerfCounterStats, error)

ParsePerfCounters parses performance counters from t.

type PerformanceInsight

type PerformanceInsight = analysis.PerformanceInsight

Insights types (gputrace-97)

type PipelineStats

type PipelineStats = counter.PipelineStats

PipelineStats contains shader compilation statistics from streamData.

type RecordType

type RecordType = trace.RecordType

Re-export main types from internal packages

type ShaderHardwareMetrics

type ShaderHardwareMetrics = counter.ShaderHardwareMetrics

Re-export main types from internal packages

type ShaderMetrics

type ShaderMetrics = shader.ShaderMetrics

Re-export main types from internal packages

type ShaderMetricsReport

type ShaderMetricsReport = shader.ShaderMetricsReport

Re-export main types from internal packages

func ExtractShaderMetrics

func ExtractShaderMetrics(t *Trace) (*ShaderMetricsReport, error)

ExtractShaderMetrics extracts shader metrics from t.

type ShaderSourceMapper

type ShaderSourceMapper = shader.ShaderSourceMapper

Re-export main types from internal packages

func NewShaderSourceMapper

func NewShaderSourceMapper(searchPaths ...string) *ShaderSourceMapper

NewShaderSourceMapper returns a source mapper that searches searchPaths.

type StreamDataStats

type StreamDataStats = counter.StreamDataStats

StreamDataStats contains all parsed statistics from streamData.

func ExtractPipelineStats

func ExtractPipelineStats(t *Trace) (*StreamDataStats, error)

ExtractPipelineStats extracts pipeline compilation stats from .gpuprofiler_raw streamData. This provides instruction counts, register allocation, and other compilation metrics.

type TimingMetrics

type TimingMetrics = timing.TimingMetrics

Timing metrics types (gputrace-106)

type TimingMetricsExtractor

type TimingMetricsExtractor = timing.TimingMetricsExtractor

Re-export main types from internal packages

func NewTimingMetricsExtractor

func NewTimingMetricsExtractor(t *Trace) *TimingMetricsExtractor

NewTimingMetricsExtractor returns a timing metrics extractor for t.

type TimingStat

type TimingStat = trace.TimingStat

Re-export main types from internal packages

type Trace

type Trace = trace.Trace

Re-export main types from internal packages

func Open

func Open(path string) (*Trace, error)

Open opens and parses a .gputrace bundle.

Example
package main

import (
	"fmt"
	"os"
	"path/filepath"
)

func main() {
	dir, err := os.MkdirTemp("", "gputrace-example-*")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer os.RemoveAll(dir)

	tracePath := filepath.Join(dir, "minimal.gputrace")
	if err := writeMinimalTraceBundle(tracePath); err != nil {
		fmt.Println(err)
		return
	}

	trace, err := Open(tracePath)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(trace.Metadata.UUID)
	fmt.Println(len(trace.CaptureData))

}

func writeMinimalTraceBundle(path string) error {
	if err := os.Mkdir(path, 0o777); err != nil {
		return err
	}
	if err := os.WriteFile(filepath.Join(path, "metadata"), []byte(minimalMetadataPlist), 0o666); err != nil {
		return err
	}
	return os.WriteFile(filepath.Join(path, "capture"), []byte(MagicMTSP), 0o666)
}

const minimalMetadataPlist = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>(uuid)</key>
	<string>minimal-test-trace</string>
	<key>DYCaptureSession.capture_version</key>
	<integer>1</integer>
	<key>DYCaptureSession.graphics_api</key>
	<integer>1</integer>
	<key>DYCaptureSession.deviceId</key>
	<integer>0</integer>
	<key>DYCaptureSession.nativePointerSize</key>
	<integer>8</integer>
	<key>DYCaptureEngine.captured_frames_count</key>
	<integer>1</integer>
</dict>
</plist>
`
Output:
minimal-test-trace
4

type TraceStatistics

type TraceStatistics = analysis.TraceStatistics

Re-export main types from internal packages

func ExtractStatistics

func ExtractStatistics(t *Trace) (*TraceStatistics, error)

ExtractStatistics extracts summary statistics from t.

type XcodeCounterData

type XcodeCounterData = counter.XcodeCounterData

Re-export main types from internal packages

func ParseXcodeCountersCSV

func ParseXcodeCountersCSV(t *Trace, csvPath string) (*XcodeCounterData, error)

ParseXcodeCountersCSV parses an Xcode counters CSV file for t.

type XcodeEncoderCounters

type XcodeEncoderCounters = counter.XcodeEncoderCounters

Re-export main types from internal packages

Directories

Path Synopsis
cmd
axperms command
axperms is a utility to check and manage Accessibility permissions on macOS.
axperms is a utility to check and manage Accessibility permissions on macOS.
gputrace command
Command gputrace provides tools for analyzing and converting GPU trace files.
Command gputrace provides tools for analyzing and converting GPU trace files.
gputrace/cmd
Package cmd implements the gputrace CLI commands.
Package cmd implements the gputrace CLI commands.
mlxprof command
examples
source_mapping command
internal
agxps
Package agxps provides a small adapter over github.com/tmc/apple/private/xcode/gtshaderprofiler.
Package agxps provides a small adapter over github.com/tmc/apple/private/xcode/gtshaderprofiler.
buildinfo
Package buildinfo exposes build metadata for release binaries.
Package buildinfo exposes build metadata for release binaries.
fmtutil
Package fmtutil provides small formatting helpers shared by internal packages.
Package fmtutil provides small formatting helpers shared by internal packages.
graph
Package graph provides graph visualization generation for GPU traces.
Package graph provides graph visualization generation for GPU traces.
osa
Package osa provides in-process AppleScript execution via CGO.
Package osa provides in-process AppleScript execution via CGO.
profilerraw
Package profilerraw reads records from Xcode GPU profiler counter files.
Package profilerraw reads records from Xcode GPU profiler counter files.
trace
Package gputrace provides parsing for .gputrace GPU trace files from Metal.
Package gputrace provides parsing for .gputrace GPU trace files from Metal.
xcodebindings
Package xcodebindings probes the private Xcode GTShaderProfiler runtime surface without constructing profiler objects.
Package xcodebindings probes the private Xcode GTShaderProfiler runtime surface without constructing profiler objects.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL