mirror of
https://github.com/wolfpld/tracy.git
synced 2026-09-01 07:58:31 +00:00
Also defer GpuContextName for on-demand profiling
Without this, a late-connecting client receives the deferred GpuNewContext but not the GpuContextName, so the GPU context appears unnamed in the profiler. Add check_gpu_ctx_name tool to verify context names in captured traces. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,12 +4,13 @@ CXX := g++
|
||||
ROCM_LIB := /opt/rocm/lib
|
||||
|
||||
TRACY_SRCS := $(TRACY_PUBLIC)/TracyClient.cpp
|
||||
INCLUDES := -I$(TRACY_PUBLIC)
|
||||
ROCM_INC := /opt/rocm/include
|
||||
INCLUDES := -I$(TRACY_PUBLIC) -I$(ROCM_INC)
|
||||
LIBS := -L$(ROCM_LIB) -lrocprofiler-sdk -lpthread -ldl
|
||||
|
||||
# On-demand mode (the default for this repro) — profiling starts when
|
||||
# a client connects, not at program launch.
|
||||
DEFINES := -DTRACY_ENABLE -DTRACY_ON_DEMAND -DTRACY_ROCPROF
|
||||
DEFINES := -DTRACY_ENABLE -DTRACY_ON_DEMAND -DTRACY_ROCPROF -D__HIP_PLATFORM_AMD__
|
||||
CXXFLAGS := -O2 $(DEFINES)
|
||||
HIPCCFLAGS := -O2 $(DEFINES)
|
||||
|
||||
@@ -17,11 +18,14 @@ HIPCCFLAGS := -O2 $(DEFINES)
|
||||
|
||||
all: repro
|
||||
|
||||
repro: repro.cpp tracy_client.o
|
||||
$(HIPCC) $(HIPCCFLAGS) $(INCLUDES) -o $@ $< tracy_client.o $(LIBS)
|
||||
repro: repro.o tracy_client.o
|
||||
$(HIPCC) -o $@ $^ $(LIBS)
|
||||
|
||||
repro.o: repro.cpp
|
||||
$(HIPCC) $(HIPCCFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
tracy_client.o: $(TRACY_SRCS)
|
||||
$(CXX) $(CXXFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f repro tracy_client.o
|
||||
rm -f repro repro.o tracy_client.o
|
||||
|
||||
@@ -5,7 +5,7 @@ HIP application built with `TRACY_ON_DEMAND` and `TRACY_ROCPROF`.
|
||||
|
||||
## Root cause
|
||||
|
||||
Two bugs in `TracyRocprof.cpp` break on-demand profiling:
|
||||
Three bugs in `TracyRocprof.cpp` break on-demand profiling:
|
||||
|
||||
1. **GpuNewContext not deferred.** `gpu_context_allocate()` writes a
|
||||
`GpuNewContext` queue item but does not call `DeferItem()`. When a
|
||||
@@ -15,7 +15,12 @@ Two bugs in `TracyRocprof.cpp` break on-demand profiling:
|
||||
|
||||
Assertion `ctx' failed in ProcessGpuZoneBeginImplCommon
|
||||
|
||||
2. **Kernel symbols dropped before init.** The `data->init` guard at the
|
||||
2. **GpuContextName not deferred.** Same function writes the context
|
||||
name ("rocprofv3") without calling `DeferItem()`. Even after fixing
|
||||
bug 1, a late-connecting client sees the GPU context but it appears
|
||||
unnamed in the profiler. Use `check_gpu_ctx_name` to verify.
|
||||
|
||||
3. **Kernel symbols dropped before init.** The `data->init` guard at the
|
||||
top of `tool_callback_tracing_callback()` blocks all callbacks before
|
||||
the GPU context is allocated. Kernel symbol registrations
|
||||
(`CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER`) happen at HIP init
|
||||
@@ -36,9 +41,24 @@ make
|
||||
tracy-capture -o repro.tracy -s 5
|
||||
```
|
||||
|
||||
## Verifying the context name
|
||||
|
||||
`check_gpu_ctx_name` loads a `.tracy` file and prints the GPU context
|
||||
names. Build it against the Tracy server library (e.g. from a capture
|
||||
build directory) and run:
|
||||
|
||||
```bash
|
||||
./check_gpu_ctx_name repro.tracy
|
||||
# Expected (patched): "GPU context 0: rocprofv3"
|
||||
# Expected (unpatched): "GPU context 0: (unnamed)"
|
||||
```
|
||||
|
||||
Exit codes: 0 = all contexts named, 2 = unnamed context found.
|
||||
|
||||
## What to expect
|
||||
|
||||
| Tracy version | Result |
|
||||
|---|---|
|
||||
| Unpatched | `tracy-capture` crashes: `Assertion 'ctx' failed` |
|
||||
| Patched | Capture succeeds with ~50 GPU zones (`vectorAdd`) with kernel names |
|
||||
| Patched (GpuNewContext only) | Capture succeeds but GPU context is unnamed |
|
||||
| Fully patched | Capture succeeds with ~50 GPU zones and context named "rocprofv3" |
|
||||
|
||||
65
examples/RocprofOnDemandRepro/check_gpu_ctx_name.cpp
Normal file
65
examples/RocprofOnDemandRepro/check_gpu_ctx_name.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// Loads a .tracy file and prints the GPU context names.
|
||||
// Used to verify that on-demand profiling correctly defers the
|
||||
// GpuContextName message so late-connecting clients see the name.
|
||||
//
|
||||
// Usage: ./check_gpu_ctx_name trace.tracy
|
||||
// Expected output: "GPU context 0: rocprofv3"
|
||||
// If name is missing: "GPU context 0: (unnamed)"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "server/TracyFileRead.hpp"
|
||||
#include "server/TracyWorker.hpp"
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if( argc != 2 )
|
||||
{
|
||||
fprintf( stderr, "Usage: %s <trace.tracy>\n", argv[0] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
auto f = std::unique_ptr<tracy::FileRead>( tracy::FileRead::Open( argv[1] ) );
|
||||
if( !f )
|
||||
{
|
||||
fprintf( stderr, "Cannot open %s\n", argv[1] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
tracy::Worker worker( *f, tracy::EventType::None, false );
|
||||
|
||||
const auto& gpuData = worker.GetGpuData();
|
||||
if( gpuData.empty() )
|
||||
{
|
||||
printf( "No GPU contexts found.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool all_named = true;
|
||||
for( size_t i = 0; i < gpuData.size(); i++ )
|
||||
{
|
||||
const auto& ctx = gpuData[i];
|
||||
if( ctx->name.Active() )
|
||||
{
|
||||
const char* name = worker.GetString( ctx->name );
|
||||
bool has_name = name && name[0] != '\0';
|
||||
printf( "GPU context %zu: %s\n", i, has_name ? name : "(unnamed)" );
|
||||
if( !has_name ) all_named = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "GPU context %zu: (unnamed)\n", i );
|
||||
all_named = false;
|
||||
}
|
||||
}
|
||||
|
||||
return all_named ? 0 : 2;
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
fprintf( stderr, "Error: %s\n", e.what() );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -124,6 +124,9 @@ uint8_t gpu_context_allocate( ToolData* data )
|
||||
tracy::MemWrite( &item->gpuContextNameFat.context, context_id );
|
||||
tracy::MemWrite( &item->gpuContextNameFat.ptr, (uint64_t)cloned_name );
|
||||
tracy::MemWrite( &item->gpuContextNameFat.size, name_length );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user