Adding Make for bulding code samples
Change-Id: I7b62a4c65c5560239e69ea121c6fdaef188f709d
Bu işleme şunda yer alıyor:
işlemeyi yapan:
Ammar ELWazir
ebeveyn
03c305dbd4
işleme
763799349b
@@ -0,0 +1,68 @@
|
||||
# -*- makefile-gmake -*-
|
||||
|
||||
ROCM_PATH ?= /opt/rocm
|
||||
HIP_PATH ?= $(ROCM_PATH)/hip
|
||||
HIPCC := $(HIP_PATH)/bin/hipcc
|
||||
|
||||
ifndef ROCPROFILER_PATH
|
||||
$(warning You may need to set ROCPROFILER_PATH to the path of the rocprofiler source)
|
||||
endif
|
||||
|
||||
ROCPROFILER_PATH ?= $(ROCM_PATH)/include/rocprofiler
|
||||
|
||||
CXXFLAGS += -std=c++17 -Wall
|
||||
|
||||
ifdef DEBUG
|
||||
CXXFLAGS += -gdwarf-4 -O0
|
||||
else
|
||||
ifdef DEBUGOPT
|
||||
CXXFLAGS += -gdwarf-4 -Og
|
||||
else
|
||||
CXXFLAGS += -gdwarf-4 -O2
|
||||
endif
|
||||
endif
|
||||
|
||||
###
|
||||
|
||||
srcs := $(wildcard *.cpp)
|
||||
prog := main
|
||||
|
||||
objs := $(srcs:%.cpp=%.o)
|
||||
deps := $(srcs:%.cpp=%.d)
|
||||
|
||||
# Kernel program
|
||||
|
||||
CPPFLAGS += -DHAVE_MEMFD_CREATE
|
||||
|
||||
$(prog): CC = $(HIPCC)
|
||||
$(prog): CPPFLAGS += -I$(ROCM_PATH)/include -I$(ROCPROFILER_PATH)
|
||||
$(prog): LDFLAGS := -L$(ROCM_PATH)/lib -L$(ROCPROFILER_PATH)/build
|
||||
$(prog): LDLIBS += -ldl -lpthread -lhsa-runtime64 -lrocprofiler64 -lrocm-dbgapi -ldw -lelf
|
||||
$(objs): CXX = $(HIPCC)
|
||||
|
||||
# Targets
|
||||
|
||||
all: $(prog)
|
||||
|
||||
$(prog): $(objs)
|
||||
|
||||
-include $(deps)
|
||||
|
||||
OUTPUT_OPTION = -MMD -MP -o $@
|
||||
|
||||
%.so: %.o
|
||||
$(LINK.o) $(OUTPUT_OPTION) $^ $(LDLIBS)
|
||||
|
||||
#COMPILE.hip = $(COMPILE.cpp)
|
||||
#LINK.hip = $(LINK.cpp)
|
||||
|
||||
#%.o: %.hip
|
||||
# $(COMPILE.hip) $(OUTPUT_OPTION) $<
|
||||
|
||||
clean:
|
||||
$(RM) $(prog) $(objs) $(deps)
|
||||
|
||||
distclean: | clean
|
||||
$(RM) compile_commands.json
|
||||
|
||||
.PHONY: all clean distclean
|
||||
@@ -0,0 +1,149 @@
|
||||
# ROCProfiler PC sampling example code
|
||||
|
||||
The ROCProfiler library includes an API to enable periodic sampling of the GPU
|
||||
program counter during kernel execution. This program demonstrates the PC
|
||||
sampling API, with additional code to illustrate a typical non-trivial use case:
|
||||
correlation of sampled PC addresses with their disassembled machine code, as
|
||||
well as source code and symbolic debugging information if available.
|
||||
|
||||
## Building the demo program
|
||||
|
||||
If your ROCm installation already includes ROCProfiler, the only requirements to
|
||||
build the demo program are:
|
||||
|
||||
* GNU `make`
|
||||
* libdw (**not** libdwarf)
|
||||
* libelf
|
||||
|
||||
If ROCm is installed in the standard location (`/opt/rocm`), running `make` in
|
||||
the same directory as this README should work; otherwise, set `ROCM_PATH` to the
|
||||
location of the ROCm installation in your environment and `ROCPROFILER_PATH` to
|
||||
the location of the ROCProfiler source repo before running `make`.
|
||||
|
||||
If your ROCm installation does **not** include ROCProfiler, you will need to build
|
||||
it yourself. This demo program will be built as part of that process. See the
|
||||
main ROCProfiler README for additional requirements and directions.
|
||||
|
||||
## Running the demo program
|
||||
|
||||
The demo program simply fills a vector with random 64-bit unsigned integers and
|
||||
tallies the count of those greater than the mandatory `MIN` argument:
|
||||
|
||||
```
|
||||
usage: code_printing_sample [OPTION]... MIN [SEED]
|
||||
-d DEV HIP device number
|
||||
-n LEN Length of random integer array
|
||||
-D Print kernel disassembly
|
||||
-P Print source and disassembly of sampled PC locations
|
||||
where
|
||||
DEV : i32
|
||||
MIN : u64
|
||||
LEN : u64
|
||||
SEED : u64
|
||||
```
|
||||
|
||||
### Defaults and troubleshooting
|
||||
|
||||
* `-d`: use HIP device 0
|
||||
* `-n`: 4194304 (1024 * 1024 * 4)
|
||||
* `-D`: false
|
||||
* `-P`: false
|
||||
* `SEED`: random seed; taken from the system's monotonic clock
|
||||
|
||||
The program contains two trivial GPU kernels: an implementation of `memset`, and
|
||||
the parallel counting procedure. Because the actual point is to demonstrate the
|
||||
PC sampling functionality, it is recommended to use the `-n` option with an
|
||||
argument such that the allocated vector fits in the smaller of available host as
|
||||
well as device memory, but sufficiently large argument such that the kernels run
|
||||
long enough for ROCProfiler to actually collect some samples.
|
||||
|
||||
In order for the `-P` option to display source, the demo program must have been
|
||||
built with debug symbols (at least `-gdwarf-4`). Any optimization level is
|
||||
fine, but if the kernels run too quickly for ROCProfiler to collect any samples
|
||||
even when a very large vector is given with the `-n` option, try rebuilding the
|
||||
demo program without optimizations by adding `-O0` to the `hipcc` compilation
|
||||
flags.
|
||||
|
||||
## Files
|
||||
|
||||
* `main.cpp`: initializes ROCProfiler and PC sampling and runs the GPU kernels
|
||||
* `code_printing.cpp`: inspects the ELF and DWARF info for the GPU programs
|
||||
embedded in the host binary and uses amd-dbgapi to print disassembly and
|
||||
source
|
||||
* `disassembly.cpp`: wrapper for `code_printing.cpp`
|
||||
|
||||
## PC sampling API
|
||||
|
||||
Adding PC sampling to a program already using the ROCProfiler API requires only
|
||||
two changes:
|
||||
|
||||
1. Call `rocprofiler_create_filter` to create a `ROCPROFILER_PC_SAMPLING_COLLECTION`
|
||||
filter, then `rocprofiler_set_filter_buffer` to add the filter to the desired
|
||||
buffer (see functions `main` and `run_kernel` in `main.cpp`)
|
||||
|
||||
2. Handle records of kind `ROCPROFILER_PC_SAMPLING_RECORD` in the buffer callback
|
||||
function. These should be cast to `rocprofiler_record_pc_sample_t *` (see
|
||||
function `callback_flush_fn` in `main.cpp`)
|
||||
|
||||
Like all ROCProfiler records, PC sample records contain a standard header followed
|
||||
by one or more payloads:
|
||||
|
||||
```c
|
||||
/**
|
||||
* PC sample record: contains the program counter/instruction pointer observed
|
||||
* during periodic sampling of a kernel
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* ROCMtool General Record base header to identify the id and kind of every
|
||||
* record
|
||||
*/
|
||||
rocprofiler_record_header_t header;
|
||||
/**
|
||||
* PC sample data
|
||||
*/
|
||||
rocprofiler_pc_sample_t pc_sample;
|
||||
} rocprofiler_record_pc_sample_t;
|
||||
```
|
||||
|
||||
PC samples are delivered via the normal ROCProfiler buffer callback mechanism,
|
||||
along with some additional information allowing each sample to be associated
|
||||
with a unique, individual kernel execution:
|
||||
|
||||
```c
|
||||
/**
|
||||
* An individual PC sample
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Kernel dispatch ID. This is used by PC sampling to associate samples with
|
||||
* individual dispatches and is unrelated to any user-supplied correlation ID
|
||||
*/
|
||||
rocprofiler_kernel_dispatch_id_t dispatch_id;
|
||||
union {
|
||||
/**
|
||||
* Host timestamp
|
||||
*/
|
||||
rocprofiler_timestamp_t timestamp;
|
||||
/**
|
||||
* GPU clock counter (not currently used)
|
||||
*/
|
||||
uint64_t cycle;
|
||||
};
|
||||
/**
|
||||
* Sampled program counter
|
||||
*/
|
||||
uint64_t pc;
|
||||
/**
|
||||
* Sampled shader element
|
||||
*/
|
||||
uint32_t se;
|
||||
/**
|
||||
* Sampled GPU agent
|
||||
*/
|
||||
rocprofiler_agent_id_t gpu_id;
|
||||
} rocprofiler_pc_sample_t;
|
||||
```
|
||||
|
||||
PC sampling is started and stopped with `rocprofiler_start_session` and
|
||||
`rocprofiler_terminate_session`, just like other profiling activities.
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <hsa/amd_hsa_kernel_code.h>
|
||||
#include <hsa/hsa_ven_amd_loader.h>
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
#include "rocprofiler.h"
|
||||
|
||||
#include "code_printing.hpp"
|
||||
#include "program.hpp"
|
||||
|
||||
Yeni konuda referans
Bir kullanıcı engelle